Como adicionar automaticamente uma conta de usuário E senha com um script Bash?

200

Eu preciso ter a capacidade de criar contas de usuário no meu Linux (Fedora 10) e atribuir automaticamente uma senha por meio de um script bash (ou caso contrário, se necessário).

É fácil criar o usuário via Bash, por exemplo:

[whoever@server ]#  /usr/sbin/useradd newuser

É possível atribuir uma senha no Bash, algo funcionalmente semelhante a isso, mas automaticamente:

[whoever@server ]# passwd newuser
Changing password for user testpass.
New UNIX password:
Retype new UNIX password: 
passwd: all authentication tokens updated successfully.
[whoever@server ]#
ModernCarpentry
fonte
11
Por que isso é offtopic?
OrangeTux 28/02
16
Eu acho que essa pergunta está no tópico. Uma das tendências mais fortes agora é a atitude do DevOps de "configuração como código", ou seja, que a plataforma seja criada pela "programação" de uma sequência de etapas administrativas que iniciam a inicialização da plataforma. Fazer o gerenciamento de usuários no modo de script é definitivamente parte dessa programação.
Dan Bergh Johnsson
2
Como DevOps, acho que essa é uma pergunta útil (com respostas úteis), mas com esse chapéu do SysAdmin. Pode fazer mais sentido mover isso para o SuperUser.
Anthony Geoghegan
1
Pergunta semelhante: askubuntu.com/q/94060/250556
ThorSummoner
Isso também pode ser resolvido com um expectscript.
Yaron

Respostas:

122

Você pode executar o comando passwd e enviar a entrada canalizada. Então, faça algo como:

echo thePassword | passwd theUsername --stdin
Tralemonkey
fonte
3
O bônus desse método é que ele é seguro (assumido que echoestá embutido no shell usado, o que geralmente é comum), pelo menos preocupante /proc/.
Marian
8
Eu tive que fazer echo -e "password\npassword\n" | passwdem 13.04
d0c_s4vage 22/03
31
--stdin foi descontinuado em sistemas Linux mais recentes. Por favor, use chpasswd.
Wuxb
16
O @MarkusOrreilly funciona, mas não ao usar uma ferramenta de provisionamento como o Ansible. Como @Nybble afirmou, você deve usar o chpasswd. Então aqui está o que funciona: echo 'myuser:mypass' | chpasswd. Espero que ajude.
Amir Rustamzadeh 11/11
posso colocar isso em um arquivo docker? Eu acho que deve comestível para docker.
qubsup
201

Você também pode usar chpasswd :

echo username:new_password | chpasswd

assim, você alterar a senha de usuário usernamepara new_password.

SilverDaemon
fonte
5
+1, Esta é a ferramenta certa para o trabalho: $ apropos chpasswd...chpasswd (8) - update passwords in batch mode
Steven K
Isso também funciona com busybox, enquanto passwdnão funciona (não há --stdinopção).
Timmmm 24/02
83

Eu estava me perguntando a mesma coisa e não queria confiar em um script Python.

Esta é a linha para adicionar um usuário com uma senha definida em uma linha do bash:

useradd -p $(openssl passwd -1 $PASS) $USER
Damien
fonte
25
useradd -p $(openssl passwd -1 $PASS) $USERé mais moderno, pois os back-ticks são descontinuados e $()são recomendados.
Bryson
Um problema que tive com isso: criei meu usuário com um shell do zsh, sem perceber que naquele momento o zsh não havia sido instalado. O login da senha falhará se você fizer isso, portanto, antes de assumir que isso não está funcionando (ele definitivamente funcionará no Arch de hoje e no Debian 7), você pode verificar isso em uma nova instalação.
Bryson
2
useradd -m -p <password> -s /bin/bash <user>, -m Crates o diretório inicial, -s especifica os usuários com o shell padrão, substitui passworde atende useràs suas necessidades.
ThorSummoner
2
Você também pode sal a senha: useradd -m -p $(openssl passwd -1 -salt $SALT $PASS). Eu acho que isso é necessário mais tarde no Ubuntu.
craigmj
55

O código abaixo funcionou no Ubuntu 14.04. Experimente antes de usá-lo em outras versões / variantes linux.

# quietly add a user without password
adduser --quiet --disabled-password --shell /bin/bash --home /home/newuser --gecos "User" newuser

# set password
echo "newuser:newpassword" | chpasswd
Ying
fonte
3
eu não entendo #--gecos
2179 Alban #
11
pt.wikipedia.org/wiki/Gecos_field O campo gecos, ou GECOS, é uma entrada no arquivo / etc / passwd no Unix e sistemas operacionais similares. Geralmente, é usado para registrar informações gerais sobre a conta ou seus usuários, como nome e número de telefone reais. GECOS significa Sistema Operacional Abrangente da General Electric, que foi renomeado para GCOS quando a divisão de sistemas de grande porte da GE foi vendida para a Honeywell.
Ying
Esta foi a resposta certa para mim no Debian 8, funcionou como um encanto no meu script bash de configuração do servidor!
levelzwo
O campo GECOS é basicamente um campo de descrição do usuário. Escreva o que quiser lá em baixo.
Константин Ван
30

Gostei da abordagem de Tralemonkey, echo thePassword | passwd theUsername --stdinembora não tenha funcionado para mim como está escrito. No entanto, isso funcionou para mim.

echo -e "$password\n$password\n" | sudo passwd $user

-eé reconhecer \ncomo nova linha.

sudo é o acesso root para o Ubuntu.

As aspas duplas são para reconhecer $e expandir as variáveis.

O comando acima passa a senha e uma nova linha, duas vezes, para passwd, que é o que passwdrequer.

Se não estiver usando variáveis, acho que isso provavelmente funciona.

echo -e 'password\npassword\n' | sudo passwd username

Aspas simples devem bastar aqui.

Paul S
fonte
2
Funciona lindamente no bash. No entanto, se estiver executando no sh, a opção -e não funcionará. Eu descobri da maneira mais difícil que realmente gera "-e". Felizmente, a opção -e não é necessária em sh, o escape é o padrão. A versão portátil é usar printf "senha \ npassword \ n" | ... em vez de.
Dan Bergh Johnsson
Resposta perfeita para o ubuntu.
Mashpy Rahman
23

O seguinte funciona para mim e testado no Ubuntu 14.04. É um liner que não requer nenhuma entrada do usuário.

sudo useradd -p $(openssl passwd -1 $PASS) $USERNAME

Retirado de @Tralemonkey

cevaris
fonte
13

Você pode usar a opção -p.

useradd -p encrypted_password newuser

Infelizmente, isso exige que você faça o hash da senha (onde passwd faz isso por você). Infelizmente, não parece haver um utilitário padrão para o hash de alguns dados; portanto, você precisará escrever isso sozinho.

Aqui está um pequeno script Python que preparei para fazer a criptografia para você. Supondo que você o chamou de pcrypt, você escreveria sua linha de comando acima para:

useradd -p $(pcrypt ${passwd}) newuser

Alguns avisos para estar ciente.

  1. Enquanto o pcrypt estiver em execução, o texto sem formatação ficará visível para qualquer usuário através do comando ps.
  2. O pcrypt usa a função de criptografia do estilo antigo - se você estiver usando algo mais moderno, como um hash MD5, precisará alterar o pcrypt.

e aqui está o pcrypt:

#!/usr/bin/env python

import crypt
import sys
import random

saltchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

def salt():
    return random.choice(saltchars) + random.choice(saltchars)

def hash(plain):
    return crypt.crypt(arg, salt())

if __name__ == "__main__":
    random.seed()
    for arg in sys.argv[1:]:
        sys.stdout.write("%s\n" % (hash(arg),))
R Samuel Klatchko
fonte
Obrigado R Klatchko, Isso deve funcionar. Não acredito que não sabia sobre a opção -p. Eu posso cuidar de hashing me :)
ModernCarpentry
5
perl -e 'print crypt ($ ARGV [0], "senha")' 'mypassword'
mikewaters
Você pode explicar um pouco como eu poderia usar a senha e não a senha com hash mais tarde?
answerSeeker
12

Forro único para criar um usuário sudo com diretório inicial e senha.

useradd -m -p $(openssl passwd -1 ${PASSWORD}) -s /bin/bash -G sudo ${USERNAME}
Sandeep
fonte
Impressionante. Funciona bem no script de implantação
TheRealChx101 21/07/19
7

--stdinnão funciona no Debian. Diz:

`passwd: unrecognized option '--stdin'`

Isso funcionou para mim:

#useradd $USER
#echo "$USER:$SENHA" | chpasswd

Aqui podemos encontrar outras boas maneiras:

Roger
fonte
Essa é a maneira correta de fazer isso e a única maneira oficialmente suportada pelos mantenedores do conjunto de sombras. Veja este relatório de bug .
yardena 07/09/11
6

Você pode usar o expect no seu script bash.

Em http://www.seanodonnell.com/code/?id=21

#!/usr/bin/expect 
######################################### 
#$ file: htpasswd.sh 
#$ desc: Automated htpasswd shell script 
######################################### 
#$ 
#$ usage example: 
#$ 
#$ ./htpasswd.sh passwdpath username userpass 
#$ 
###################################### 

set htpasswdpath [lindex $argv 0] 
set username [lindex $argv 1] 
set userpass [lindex $argv 2] 

# spawn the htpasswd command process 
spawn htpasswd $htpasswdpath $username 

# Automate the 'New password' Procedure 
expect "New password:" 
send "$userpass\r" 

expect "Re-type new password:" 
send "$userpass\r"
Carlos Tasada
fonte
5

Sei que vou chegar anos depois, mas não acredito que ninguém sugeriu o usermod.

usermod --password `perl -e "print crypt('password','sa');"` root

Inferno, no caso de alguém querer fazer isso em um HPUX mais antigo, você pode usar usermod.sam.

/usr/sam/lbin/usermod.sam -F -p `perl -e "print crypt('password','sa');"` username

O -F será necessário apenas se a pessoa que estiver executando o script for o usuário atual. Claro que você não precisa usar o Perl para criar o hash. Você pode usar o openssl ou muitos outros comandos em seu lugar.

Jeight
fonte
3

Aqui está um script que fará isso por você ...

Você pode adicionar uma lista de usuários (ou apenas um usuário), se desejar, de uma só vez e cada um terá uma senha diferente. Como bônus, você é apresentado no final do script com uma lista da senha de cada usuário. .... Se você quiser, pode adicionar algumas opções de manutenção do usuário

gostar:

chage -m 18 $user
chage -M 28 $user

para o script que definirá a idade da senha e assim por diante.

=======

#!/bin/bash

# Checks if you have the right privileges
if [ "$USER" = "root" ]
then

# CHANGE THIS PARAMETERS FOR A PARTICULAR USE
PERS_HOME="/home/"
PERS_SH="/bin/bash"

   # Checks if there is an argument
   [ $# -eq 0 ] && { echo >&2 ERROR: You may enter as an argument a text file containing users, one per line. ; exit 1; }
   # checks if there a regular file
   [ -f "$1" ] || { echo >&2 ERROR: The input file does not exists. ; exit 1; }
   TMPIN=$(mktemp)
   # Remove blank lines and delete duplicates 
   sed '/^$/d' "$1"| sort -g | uniq > "$TMPIN"

   NOW=$(date +"%Y-%m-%d-%X")
   LOGFILE="AMU-log-$NOW.log"

   for user in $(more "$TMPIN"); do
      # Checks if the user already exists.
      cut -d: -f1 /etc/passwd | grep "$user" > /dev/null
      OUT=$?
      if [ $OUT -eq 0 ];then
         echo >&2 "ERROR: User account: \"$user\" already exists."
         echo >&2 "ERROR: User account: \"$user\" already exists." >> "$LOGFILE"
      else
         # Create a new user
         /usr/sbin/useradd -d "$PERS_HOME""$user" -s "$PERS_SH" -m "$user"
         # passwdgen must be installed
         pass=$(passwdgen -paq --length 8)
         echo $pass | passwd --stdin $user
         # save user and password in a file
         echo -e $user"\t"$pass >> "$LOGFILE"
         echo "The user \"$user\" has been created and has the password: $pass"
      fi
   done
   rm -f "$TMPIN"
   exit 0
else
   echo >&2 "ERROR: You must be a root user to execute this script."
   exit 1
fi

===========

Espero que isto ajude.

Saúde, Carel

Carel Lubbe
fonte
2

Eu testei no meu próprio script de shell.

  • $new_username significa usuário recém-criado
  • $new_password significa nova senha

Para o CentOS

echo "$new_password" | passwd --stdin "$new_username"

Para Debian / Ubuntu

echo "$new_username:$new_password" | chpasswd

Para OpenSUSE

echo -e "$new_password\n$new_password" | passwd "$new_username"

fonte
1

A solução da Tralemonkey quase funcionou para mim também ... mas não completamente. Acabei fazendo assim:

echo -n '$#@password@#$' | passwd myusername --stdin

2 detalhes importantes que sua solução não incluiu, -nimpede que o eco adicione uma \nsenha que está sendo criptografada e as aspas simples protegem o conteúdo de ser interpretado pelo shell (bash) no meu caso.

BTW Eu executei este comando como root em um sistema CentOS 5.6 no caso de alguém estar se perguntando.

slm
fonte
boa captura, não sei como os outros conseguiram fazê-lo funcionar com a nova linha.
M03
1

A solução que funciona no Debian e no Red Hat. Depende do perl, usa hashes sha-512:

cat userpassadd
    #!/usr/bin/env bash

    salt=$(cat /dev/urandom | tr -dc A-Za-z0-9/_- | head -c16)
    useradd -p $(perl -e "print crypt('$2', '\$6\$' . '$salt' . '\$')") $1

Uso:

userpassadd jim jimslongpassword

Ele pode ser usado efetivamente como uma linha, mas você precisará especificar a senha, o salt e o nome de usuário nos locais certos:

useradd -p $(perl -e "print crypt('pass', '\$6\$salt\$')") username
golem
fonte
1

Na IBM ( https://www.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.cmds1/chpasswd.htm ):

Crie um arquivo de texto, diga text.txt e preencha-o com pares user: password da seguinte maneira:

user1:password1
user2:password2
...
usern:passwordn

Salve o arquivo text.txt e execute

cat text.txt | chpassword

É isso aí. A solução é (a) escalável e (b) não envolve a impressão de senhas na linha de comando.

Vietnhi Phuvan
fonte
0
{ echo $password; echo $password; } | passwd $username 
edacval
fonte
Embora isso possa teoricamente responder à pergunta, seria preferível incluir aqui as partes essenciais da resposta.
Werner
0

Para RedHat / CentOS, eis o código que cria um usuário, adiciona as senhas e torna o usuário um sudoer:

#!/bin/sh
echo -n "Enter username: "
read uname

echo -n "Enter password: "
read -s passwd

adduser "$uname"
echo $uname:$passwd | sudo chpasswd

gpasswd wheel -a $uname
Lefty G Balogh
fonte
0

uso: ./my_add_user.sh USER PASSWD

código:

#!/bin/bash
# my_add_user.sh

if [ "$#" -lt 2 ] 
 then
       echo "$0 username passwd"
       exit
fi

user=$1
passwd=$2

useradd $user -d /data/home/$user  -m  ;
echo $passwd | passwd $user --stdin;
hustljian
fonte