Método seguro de alterar a senha de um usuário via script Python / não interativamente

7

Perguntas

  1. Existe uma maneira mais segura / melhor de definir a senha de um usuário de maneira não interativa por meio de um script Python? Minha solução atual usa chpasswd de um script Fabric . Outra opção seria usar o Pexpect de dentro do Tecido script.
  2. O meu método atual de definir a senha é uma preocupação de segurança? A possível preocupação de segurança que vejo é que a senha é mostrada como texto não criptografado no meu terminal local da seguinte forma:
    [xxx.xx.xx.xxx] run: echo "johnsmith:supersecretpassw0rd" | chpasswd .
    Como eu só executo o script Fabric do meu laptop, não acho que essa é uma questão de segurança, mas estou interessado na opinião de outras pessoas.

Antecedentes

Eu criei um script em Python usando o Fabric para configurar um novo Slicehost fatia do Ubuntu. Caso você não esteja familiarizado com o Fabric, ele usa o Paramiko , um cliente SSH2 do Python, para fornecer acesso remoto "para a implantação de aplicativos ou tarefas de administração de sistemas. "

Uma das primeiras coisas que tenho no script Fabric é criar um novo usuário administrador e definir sua senha. Ao contrário do Pexpect , o Fabric não pode manipular comandos interativos no sistema remoto, portanto, preciso definir a senha do usuário de forma não interativa. Atualmente, estou usando o comando chpasswd , que lê o nome de usuário e a senha como texto não criptografado.

Código atual

# 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)
)

Terminal I / O do sistema local

$ 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 [email protected]... done.
    
por Matthew Rankin 16.03.2010 / 14:53

5 respostas

3

Você passa a senha na linha de comando que está executando. Esses provavelmente podem estar visíveis não apenas no seu terminal, mas também por outros usuários emitindo o comando 'ps' (que pode depender da configuração do sistema). E a senha é texto simples.

Eu não sei o Fabric, mas se isso lhe dá a possibilidade de se comunicar com comandos executados via stdin / stdout (como subprocess.Popen() ), então provavelmente seria uma escolha melhor usar isso em vez de 'echo username : senha | ... '.

Além disso, você pode escolher criar o hash de senha em seu script Python (usando o crypt module e "$ 1 $ XXXXXXXX $" ("X" são caracteres aleatórios) sal) e passe isso para chpasswd -e . A senha de texto simples nunca será exibida ou registrada.

    
por 17.03.2010 / 13:54
2

O que eu costumo fazer para configuração não interativa de senha é gerar uma senha aleatória e configurá-la para uma variável, depois passar a variável para o meu comando. Não preciso ser criativo com senhas e não preciso deixar uma senha padrão em um arquivo de texto simples.

Aqui está uma receita de estado ativo para gerar senhas aleatórias .

No que diz respeito à segurança, não acho que seja um grande problema ter uma senha impressa em seu próprio terminal (com a senha aleatória, você gostaria disso de qualquer maneira, para que possa tomar nota da pwd criado).

Existe algo diferente que o Fabric faz com o ssh? - a maioria das coisas que viajam pelo ssh devem ser criptografadas de qualquer maneira.

    
por 16.03.2010 / 15:07
2

Se você estiver usando o chpasswd a partir do com em uma malha, certifique-se de não usar a senha de texto simples na linha de comando. Não é apenas o stdout onde a senha será exibida, ela também será gravada em / var / log / secure. Em Fabric você pode usar

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

E certifique-se de usar o hash string juntamente com o comando chpasswd para que, mesmo nos logs seguros, você não veja a senha em texto simples. Primeiro, decida a senha a ser usada e gere a string hash. você poderia usar o openssl para isso.

openssl passwd -1

Isso fornecerá um prompt para inserir a senha e gerar o hash MD5. e você pode usar isso em seu script da seguinte forma.

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

O sinalizador -e no comando acima diz ao chpasswd que a senha está criptografada.

    
por 04.08.2014 / 22:34
1

A próxima versão 1.0 do Fabric (disponível agora no ramo do git) permitirá sessões interativas com o final remoto.

    
por 29.09.2010 / 15:31
0

Você poderia apenas configurar automaticamente sua nova fatia e depois apenas fazer o login e alterar a senha imediatamente? Às vezes, a abordagem mais simples é a melhor.

Mas, alternativamente, você pode gerar localmente a senha criptografada e simplesmente ir em frente e gravar a senha criptografada no arquivo / etc / shadow. Desta forma, você não usa texto simples.

Lembre-se de que você terá que confiar em seu sistema local quando inicialmente fornecer a senha inicial.

A propósito, você poderia fazer uma cópia da sua configuração automática disponível para que eu a use em vez de escrever tudo do zero? Atualmente estou fazendo tudo via bash.

algo assim?

sed 's/^root:.*$/root:$PASSWD:13063::::::/' /etc/shadow > /etc/shadow
    
por 26.09.2010 / 18:07