Немного об автоматической генерации паролей
Зачастую возникает необходимость сгенерировать для какой-то цели пароль. Преимущественно это пароль, состоящий из некоторого количества цифр и букв разного регистра.Иногда требуется сгенерировать несколько паролей сразу. Например, для обновления паролей для целой группы пользователей в скрипте или просто хочется выбрать наиболее удобный для набора. Пересмотрев несколько решений, я решил снова ездить на своих велосипедах, так как они имеют минимум зависимостей.
Генерация пароля
После нескольких итераций скрипт для генерации паролей принял следующий вид:
#!/bin/sh
# Script for password generation by Evgeniy Shumilov
# First parameter is password's lenght, second if rows count, third is columns count
[ -z "$1" ] && LENGTH=8 || LENGTH="$1"
[ -z "$2" ] && ROW=10 || ROW="$2"
[ -z "$2" ] && COL=10 || COL="$3"
pwg() {
[ -z "$1" ] && l="$LENGTH" || l="$1"
tr -dc A-Za-z0-9 < /dev/urandom | head -c "$l" | xargs
}
for r in `seq 1 $ROW`; do
ln=''
for c in `seq 1 $COL`; do
ln="$(echo "$ln "`pwg $1`)"
done
echo "$ln" | sed 's/^ *//'
done
Скрипт не очень быстрый, но свою работу выполняет. Синтаксис вызова прост как угол дома:
- без параметров выводит 10 строк по 10 паролей длиной в 8 символов
- первый параметр - длина пароля
- второй - количество паролей (строк)
- третий - количество рядов
Пример вызова:
$ ./pwg 16 4 5 G34CCXwNYzKCJyZ2 PGedVAM5Eg4aGneG PxGUfJ0a7Qlewk7t IcCrmdp6Sbd4yCTe HgEp6aawjXfqxEBS 9kKAvmX8JQnyALnI w7IreIyloijVyp27 12TL0gIL0kY8GzaF Dr00g8jDkvNrse2h d0Sp3mfEftq2gPAL hvw3UV2DOJuzJ3Ji 8J6LriztK4yK2IlK u54mgcToQ1FU0F3u PnLF16DFxmzcRJi4 N2ue6QkwlUIi3ejn KWtBvyWxVSlYzi2i QpZNCoerfCaQufC8 XSJnvJAKSAo5nUdh j8DwaCb8KHoYxymA ZGnEPDE3whZDOCaL
Всё, можно брать любой понравившийся и применить для ваших целей. Так же можно использовать функцию PWD в немного изменённом виде в других скриптах для генерации паролей пользователей.
Получение хэша
Другая частая задача заключается в том, что нам нужно сгенерировать пользовательский пароль, хеш которого будет записан в /etc/shadow, он в свою очередь должен иметь определённый формат: $TYPE$SALT$HASH, где TYPE - это тип шифрования, SALT - дополнительная случайно сгенерированная последовательность, а HASH - собственно, сама зашифрованная часть. Тип шифрования может принимать несколько значений:
- 1: md5
- 5: sha256
- 6: sha512
openssl passwd -1 -salt $salt "$passwd"
Вышеприведённый способ я оставлю на случай, если пароли нужно генерировать например, на роутере, где нет возможности по какой-то причине использовать другой способ, а openssl уже имеется. Конечно, лучше использовать sha256 или sha512. Для этого есть несколько вариантов. Первый - использовать языки высокого уровня (php, perl, python) с соответствующими библиотеками, второй - использовать doveadm, если внезапно на вашей машине стоит dovecot. Третий: использовать утилиту mkpasswd, входящую в пакет whois. Содержимое скрипта для python будет выглядеть следующим образом:
python -c 'import crypt,getpass; print(crypt.crypt("passwordhere",crypt.mksalt(crypt.METHOD_SHA512)))'
Вариант для perl:
perl -e 'print crypt("passwordhere","\$6\$saltsalt\$") . "\n"'
Для doveadm:
echo 'passwordhere' | doveadm pw -s SHA512-CRYPT | cut -c 15-
Следующий вариант, - наименее затратный способ, а заодно и самый простой, на случай, если python или perl не установлены. Ставить python со всеми его зависимостями ради генерацции пароля - это всё-равно что ездить в булочную за углом на карьерном самосвале. Для начала нужно, чтобы на нашей машине стоял пакет whois (по крайней мере в debian-based системах он называется так). Что замечательно, его размер немногим больше 350кб после установки. sudo apt-get -y install whois вам в помощь. И пример использования:
echo 'passwordhere' | mkpasswd -m sha-512 -s
Добавление пользователей.
Теперь собственно, объединив генераццию с шифрованием попробуем написать пару функций для автоматического добавления пользователей в систему с выводом паролей на экран.
#!/bin/sh
# Проверяем, что скрипт запущен с полными правами, иначе запускаем через sudo
# c тем же набором параметров ($*), а затем выходим c тем же кодом ($?),
# чтобы не пытаться выполнять содержимое второй раз
[ `whoami` != "root" ] && sudo $0 $* && exit $?
pwg() {
[ -z "$1" ] && len="8" || len="$1"
tr -dc A-Za-z0-9 < /dev/urandom | head -c "$len" | xargs
}
addusers() {
for u in $1; do
# Заменяем все символы, которые не являются буквами и цифрами на символ "-"
uname="$(echo "$u" | sed 's/[^a-zA-Z0-9]/-/g')"
# Берём пароль длиной в 16 символов
passwd=`pwg 16`
# Генерируем ещё одну случайную последовательность для соли
salt=`pwg 8`
# Получаем хэш пароля
phash=`echo "$passwd" | mkpasswd -s -m sha-512 -S "$salt"`
# Пытаемся создать пользователя и выводим информацию об имени и пароле
if useradd -M -p "$phash" "$uname"; then
echo "User $uname is added, password: $passwd"
# Создаём пользовательскую директорию и выдаём ему права:
mkdir -p "/home/$uname"
chown "$uname:$uname" "/home/$uname"
else
echo "Fail to add user $uname"
fi
done
}
# Передаём нашей функции все параметры запуска
addusers "$*"
Пример запуска и вывода:
$ sudo ./usersadd user1 user2 user3 User user1 is added, password: b73c4054uoxt2nFT User user2 is added, password: MJ7ru2qGW3C5T6NM User user3 is added, password: F8uDTXpP8RnAAC90 $ ls -lah /home/ | grep user drwxr-xr-x 2 user1 user1 4.0K Oct 19 14:34 user1 drwxr-xr-x 2 user2 user2 4.0K Oct 19 14:34 user2 drwxr-xr-x 2 user3 user3 4.0K Oct 19 14:34 user3 $ sudo tail -n 3 /etc/shadow user1:$6$EUKsNJxa$krQnFygpv1vu7yMeouqapIvyhb5wZyn.cb1rp5Ag1xhC8vug3Wh8aJR3p3FqNi8gL8I06WorSaUqzrVHaY3nA1:17823:0:99999:7::: user2:$6$habVCSsr$.zPMsmcjPv9tTpyuICZiOdg7FQNIZBse3lQs7XbpYFwWmAhBhlXcgXPt.ATPw.Fro2ndUAjk5hLxRfyw9XwvD.:17823:0:99999:7::: user3:$6$0CpbD19Q$np1W57a9tHTJDt5lf03oN2LqScYNQWCXpvnmkDULNMqE00LnvoTiMtW6Rn/bu2XOSBSkKA/8spIUINemnnhHG/:17823:0:99999:7::: $ ssh user1@localhost The authenticity of host 'localhost (::1)' can't be established. ECDSA key fingerprint is c3:a8:ce:1e:d4:be:6a:8b:e9:ff:a4:96:37:cc:c6:4c. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts. user1@localhost's password: $ whoami user1
Теги: shell, automatization, админское