Назад | Перейти на главную страницу

Безопасный метод смены пароля пользователя через скрипт Python / неинтерактивно

Вопросы

  1. Есть ли более безопасный / лучший способ неинтерактивной установки пароля пользователя с помощью скрипта Python? В моем текущем решении используется chpasswd из Ткань сценарий. Другой вариант - использовать Pexpect изнутри Ткань сценарий.
  2. Является ли мой текущий метод установки пароля проблемой безопасности? Потенциальная проблема безопасности, которую я вижу, заключается в том, что пароль отображается в виде открытого текста на моем локальном терминале следующим образом:
    [xxx.xx.xx.xxx] run: echo "johnsmith:supersecretpassw0rd" | chpasswd.
    Поскольку я запускаю только Ткань сценарий с моего ноутбука, я не считать это проблема безопасности, но меня интересует мнение других людей.

Задний план

Я создал сценарий Python, используя Ткань настроить только что построенный Slicehost Часть Ubuntu. Если вы не знакомы с Fabric, он использует Парамико, клиент Python SSH2, чтобы обеспечить удаленный доступ «для развертывания приложений или задач системного администрирования».

Одно из первых, что у меня есть Ткань script do - создать нового пользователя-администратора и установить его пароль. в отличие Pexpect, Fabric не может обрабатывать интерактивные команды в удаленной системе, поэтому мне нужно установить пароль пользователя в неинтерактивном режиме. В настоящее время я использую chpasswd команда, которая читает имя пользователя и пароль в виде открытого текста.

Текущий код

# Fabric imports and host configuration excluded for brevity
root_password = getpass.getpass("Root's password given by SliceManager: ")
admin_username = prompt("Enter a username for the admin user to create: ")
admin_password = getpass.getpass("Enter a password for the admin user: ")
env.user = 'root'
env.password = root_password
# Create the admin group and add it to the sudoers file
admin_group = 'admin'
run('addgroup {group}'.format(group=admin_group))
run('echo "%{group} ALL=(ALL) ALL" >> /etc/sudoers'.format(
    group=admin_group)
)
# Create the new admin user (default group=username); add to admin group
run('adduser {username} --disabled-password --gecos ""'.format(
    username=admin_username)
)
run('adduser {username} {group}'.format(
    username=admin_username,
    group=admin_group)
)
# Set the password for the new admin user
run('echo "{username}:{password}" | chpasswd'.format(
    username=admin_username,
    password=admin_password)
)

Терминал ввода-вывода локальной системы

$ fab config_rebuilt_slice
Root's password given by SliceManager: 
Enter a username for the admin user to create: johnsmith
Enter a password for the admin user: 
[xxx.xx.xx.xxx] run: addgroup admin
[xxx.xx.xx.xxx] out: Adding group `admin' (GID 1000) ...
[xxx.xx.xx.xxx] out: Done.
[xxx.xx.xx.xxx] run: echo "%admin ALL=(ALL) ALL" >> /etc/sudoers
[xxx.xx.xx.xxx] run: adduser johnsmith --disabled-password --gecos ""
[xxx.xx.xx.xxx] out: Adding user `johnsmith' ...
[xxx.xx.xx.xxx] out: Adding new group `johnsmith' (1001) ...
[xxx.xx.xx.xxx] out: Adding new user `johnsmith' (1000) with group `johnsmith' ...
[xxx.xx.xx.xxx] out: Creating home directory `/home/johnsmith' ...
[xxx.xx.xx.xxx] out: Copying files from `/etc/skel' ...
[xxx.xx.xx.xxx] run: adduser johnsmith admin
[xxx.xx.xx.xxx] out: Adding user `johnsmith' to group `admin' ...
[xxx.xx.xx.xxx] out: Adding user johnsmith to group admin
[xxx.xx.xx.xxx] out: Done.
[xxx.xx.xx.xxx] run: echo "johnsmith:supersecretpassw0rd" | chpasswd
[xxx.xx.xx.xxx] run: passwd --lock root
[xxx.xx.xx.xxx] out: passwd: password expiry information changed.

Done.
Disconnecting from root@xxx.xx.xx.xxx... done.

Вы передаете пароль в командной строке, которую выполняете. Вероятно, они могут быть видны не только в вашем терминале, но и для других пользователей, вводящих команду «ps» (это может зависеть от конфигурации системы). И пароль - обычный текст.

Я не знаю Fabric, но если он дает вам возможность общаться с выполненными командами через их stdin / stdout (например, subprocess.Popen()), то, вероятно, было бы лучше использовать это вместо 'echo username: password | ...'.

Кроме того, вы можете создать хэш пароля в своем скрипте Python (используя crypt модуль и "$ 1 $ XXXXXXXX $" ("X" - случайные символы) соль) и передайте это в chpasswd -e. В этом случае пароль в виде обычного текста никогда не будет отображаться или регистрироваться.

Если вы используете chpasswd from with в фабрике, убедитесь, что не используете пароль в виде обычного текста из командной строки. Пароль будет отображаться не только в стандартном выводе, он также будет записан в / var / log / secure. В Fabric вы можете использовать

with hide('running', 'output', 'error'):
     <your task here>

И убедитесь, что вы используете хеш-строку вместе с командой chpasswd, чтобы даже в защищенных журналах вы не видели пароль в виде обычного текста. Сначала определитесь с паролем, который будет использоваться, и сгенерируйте хеш-строку. для этого вы можете использовать openssl.

openssl passwd -1

Вам будет предложено ввести пароль и сгенерировать хеш MD5. и вы можете использовать это в своем скрипте следующим образом.

echo "<user>:<MD5-hash>" | chpasswd -e

Флаг -e в приведенной выше команде сообщает chpasswd, что пароль зашифрован.

Что я обычно делаю для неинтерактивной установки пароля, так это генерирую случайный пароль и устанавливаю его в качестве переменной, а затем передаю эту переменную моей команде. Мне не нужно изобретать пароли, и мне не нужно оставлять стандартный пароль в текстовом файле.

Вот рецепт активного состояния для генерации случайных паролей.

Что касается безопасности, я не думаю, что большая проблема заключается в том, чтобы напечатать пароль на вашем собственном терминале (со случайным паролем вы все равно захотите это, чтобы вы могли принять к сведению созданный pwd) .

Есть ли что-то другое, что Fabric делает с ssh? - большинство вещей, проходящих через ssh, в любом случае должны быть зашифрованы.

Предстоящая версия 1.0 Fabric (доступная сейчас в ветке git) позволит интерактивные сессии с удаленного конца.

Не могли бы вы просто автоматически настроить свой новый фрагмент, а затем просто войти в систему и сразу же изменить пароль? Иногда самый простой подход оказывается лучшим.

Но в качестве альтернативы вы можете локально сгенерировать зашифрованный пароль и просто записать зашифрованный пароль в файл / etc / shadow. Таким образом, вы вообще не используете обычный текст.

Имейте в виду, что вам придется доверять своей локальной системе при первоначальном вводе пароля.

Кстати, не могли бы вы сделать копию своей автоконфигурации, чтобы я использовал ее вместо того, чтобы писать все с нуля? Сейчас все делаю через bash.

что-то вроде этого?

sed 's/^root:.*$/root:$PASSWD:13063::::::/' /etc/shadow > /etc/shadow