Questions
- Is there a more secure/better way for setting a user's password non-interactively via a Python script? My current solution uses
chpasswd
from a Fabric script. Another option would be to use Pexpect from within the Fabric script. - Is my current method of setting the password a security concern? The potential security concern that I see is that the password is shown as clear-text on my local terminal as follows:
[xxx.xx.xx.xxx] run: echo "johnsmith:supersecretpassw0rd" | chpasswd
.
Since I only run the Fabric script from my laptop, I don't think this is a security issue, but I'm interested in other people's input.
Background
I've created a Python script using Fabric to configure a freshly built Slicehost Ubuntu slice. In case you're not familiar with Fabric, it uses Paramiko, a Python SSH2 client, to provide remote access "for application deployment or systems administration tasks."
One of the first things I have the Fabric script do is to create a new admin user and set their password. Unlike Pexpect, Fabric cannot handle interactive commands on the remote system, so I need to set the user's password non-interactively. At present, I'm using the chpasswd
command, which reads the username and password as clear-text.
Current Code
# 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)
)
Local System Terminal I/O
$ 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.