¿Cómo agregar automáticamente la cuenta de usuario Y la contraseña con un script Bash?

200

Necesito tener la capacidad de crear cuentas de usuario en mi Linux (Fedora 10) y asignar automáticamente una contraseña a través de un script bash (o de lo contrario, si es necesario).

Es fácil crear el usuario a través de Bash, por ejemplo:

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

¿Es posible asignar una contraseña en Bash, algo funcionalmente similar a esto, pero automáticamente:

[whoever@server ]# passwd newuser
Changing password for user testpass.
New UNIX password:
Retype new UNIX password: 
passwd: all authentication tokens updated successfully.
[whoever@server ]#
Carpintería Moderna
fuente
11
¿Por qué es esto offtopic?
OrangeTux
16
Creo que esta pregunta es sobre el tema. Una de las tendencias más fuertes ahora es la actitud de DevOps de "configuración como código", es decir, que la plataforma se crea al "programar" una secuencia de pasos de administrador que arranca la plataforma. Hacer administración de usuarios en modo script es definitivamente parte de esta programación.
Dan Bergh Johnsson
2
Como DevOps, creo que esta es una pregunta útil (con respuestas útiles) pero eso es con mi sombrero SysAdmin. Podría tener más sentido mover esto a SuperUser.
Anthony Geoghegan
1
Pregunta similar: askubuntu.com/q/94060/250556
ThorSummoner
Esto también se puede resolver con un expectscript.
Yaron

Respuestas:

122

Puede ejecutar el comando passwd y enviarle una entrada canalizada. Entonces, haz algo como:

echo thePassword | passwd theUsername --stdin
Tralemonkey
fuente
3
La ventaja de ese método es que es seguro (se supone que echoestá integrado en el shell utilizado, lo que es común), al menos preocupante /proc/.
Marian
8
Tenía que hacerlo echo -e "password\npassword\n" | passwdel 13.04
d0c_s4vage
31
--stdin ha quedado en desuso en los sistemas Linux más nuevos. Por favor utiliza chpasswd en su lugar.
wuxb
16
@MarkusOrreilly funciona, pero no cuando se usa una herramienta de aprovisionamiento como Ansible. Como dijo @Nybble, deberías estar usando chpasswd. Así que aquí es lo que funciona: echo 'myuser:mypass' | chpasswd. Espero que ayude.
Amir Rustamzadeh
¿Puedo poner esto en un archivo acoplable? Creo que debería ser comestible para Docker.
qubsup
201

También puedes usar chpasswd :

echo username:new_password | chpasswd

Por lo tanto, se cambia la contraseña de usuario usernamea new_password.

SilverDaemon
fuente
55
+1, esta es la herramienta adecuada para el trabajo: $ apropos chpasswd...chpasswd (8) - update passwords in batch mode
Steven K
Esto también funciona con busybox, mientras passwdque no (no hay --stdinopción).
Timmmm
83

Me preguntaba lo mismo, y no quería confiar en un script de Python.

Esta es la línea para agregar un usuario con una contraseña definida en una línea bash:

useradd -p $(openssl passwd -1 $PASS) $USER
Damien
fuente
25
useradd -p $(openssl passwd -1 $PASS) $USERes más moderno, ya que los back-ticks están en desuso y $()se recomiendan.
Bryson
Un problema que tuve con esto: había creado mi usuario con un shell de zsh, sin darme cuenta de que en ese momento no se había instalado zsh. El inicio de sesión con contraseña fallará si hace esto, así que antes de asumir que esto no está funcionando (definitivamente funcionará en el Arch de hoy y en Debian 7) puede verificarlo en una instalación completamente nueva.
Bryson
2
useradd -m -p <password> -s /bin/bash <user>, -m Crates directorio de inicio, -s especifica usuarios defualt shell, sustituto passwordy userpara sus necesidades.
ThorSummoner
2
También puede salar la contraseña useradd -m -p $(openssl passwd -1 -salt $SALT $PASS). Creo que esto es necesario en Ubuntu posteriores.
craigmj
55

El siguiente código funcionó en Ubuntu 14.04. Pruebe antes de usarlo en otras versiones / variantes de 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
fuente
3
no entiendo--gecos
Alban
11
en.wikipedia.org/wiki/Gecos_field El campo gecos o campo GECOS es una entrada en el archivo / etc / passwd en Unix y sistemas operativos similares. Por lo general, se usa para registrar información general sobre la cuenta o sus usuarios, como su nombre real y número de teléfono. GECOS significa Sistema Operativo Integral de General Electric, que pasó a denominarse GCOS cuando la división de grandes sistemas de GE fue vendida a Honeywell.
Ying
¡Esta fue la respuesta correcta para mí en Debian 8, funcionó de maravilla en mi script bash de configuración del servidor!
levelzwo 01 de
El campo GECOS es básicamente un campo de descripción de usuario. Escribe lo que quieras ahí abajo.
Константин Ван
30

Me gustó el enfoque de Tralemonkey de echo thePassword | passwd theUsername --stdin aunque no funcionó para mí tal como está escrito. Sin embargo, esto funcionó para mí.

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

-ees reconocer \ncomo nueva línea.

sudo es el acceso de root para Ubuntu.

Las comillas dobles son para reconocer $ y expandir las variables.

El comando anterior pasa la contraseña y una nueva línea, dos veces, a passwd , que es lo que passwdrequiere.

Si no usa variables, creo que esto probablemente funcione.

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

Las comillas simples deberían ser suficientes aquí.

Paul S
fuente
2
Funciona muy bien en bash. Sin embargo, si se ejecuta en sh, entonces la opción -e no funciona. Descubrí por las malas que en realidad produce "-e". Afortunadamente, la opción -e no es necesaria en sh, el escape está predeterminado allí. La versión portátil es usar printf "contraseña \ npassword \ n" | ... en cambio.
Dan Bergh Johnsson
Respuesta perfecta para ubuntu.
Mashpy Rahman
23

Lo siguiente funciona para mí y lo probé en Ubuntu 14.04. Es un trazador de líneas que no requiere ninguna entrada del usuario.

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

Tomado de @Tralemonkey

cevaris
fuente
13

Puedes usar la opción -p.

useradd -p encrypted_password newuser

Desafortunadamente, esto requiere que ingrese la contraseña usted mismo (donde passwd lo hace por usted). Desafortunadamente, no parece haber una utilidad estándar para hacer hash de algunos datos, por lo que deberá escribirlos usted mismo.

Aquí hay un pequeño script de Python que preparé para hacer el cifrado por usted. Suponiendo que lo llamó pcrypt, luego escribiría su línea de comando anterior a:

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

Un par de advertencias a tener en cuenta.

  1. Mientras se ejecuta pcrypt, el texto sin formato será visible para cualquier usuario a través del comando ps.
  2. pcrypt usa la función de cripta de estilo antiguo: si está usando algo más moderno como un hash MD5, deberá cambiar pcrypt.

y aquí está 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
fuente
Gracias R Klatchko, eso debería funcionar. No puedo creer que no supiera sobre la opción -p. Puedo cuidar de mí mismo hash :)
ModernCarpentry
55
perl -e 'print crypt ($ ARGV [0], "contraseña")' 'mypassword'
mikewaters
¿Puede explicarme un poco cómo podría usar la contraseña y no la contraseña cifrada más adelante?
answerSeeker
12

Revestimiento único para crear un usuario de sudo con directorio de inicio y contraseña.

useradd -m -p $(openssl passwd -1 ${PASSWORD}) -s /bin/bash -G sudo ${USERNAME}
Sandeep
fuente
Increíble. Funciona bien en la secuencia de comandos de implementación
TheRealChx101
7

--stdinNo funciona en Debian. Dice:

`passwd: unrecognized option '--stdin'`

Esto funcionó para mí:

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

Aquí podemos encontrar otras buenas maneras:

Roger
fuente
Esta es la forma correcta de hacerlo, y la única forma oficialmente respaldada por los encargados de la suite shadow. Ver este informe de error .
yardena
6

Puede usar esperar en su script bash.

De 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
fuente
5

Sé que vendré en esto años más tarde, pero no puedo creer que nadie sugirió usermod.

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

Demonios, en caso de que alguien quiera hacer esto en una HPUX anterior, puedes usar usermod.sam .

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

El -F solo es necesario si la persona que ejecuta el script es el usuario actual. Por supuesto, no necesita usar Perl para crear el hash. Puede usar openssl o muchos otros comandos en su lugar.

Jeight
fuente
3

Aquí hay un script que lo hará por usted .....

Puede agregar una lista de usuarios (o solo un usuario) si lo desea, todo de una vez y cada uno tendrá una contraseña diferente. Como beneficio adicional, se le presenta al final del guión una lista de la contraseña de cada usuario. .... Si lo desea, puede agregar algunas opciones de mantenimiento del usuario

me gusta:

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

a la secuencia de comandos que establecerá la antigüedad de la contraseña, etc.

=======

#!/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 esto ayude.

Saludos, Carel

Carel Lubbe
fuente
2

Lo he probado en mi propio script de shell.

  • $new_username significa usuario recién creado
  • $new_password significa nueva contraseña

Para 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"

fuente
1

La solución de Tralemonkey casi también funcionó para mí ... pero no del todo. Terminé haciéndolo de esta manera:

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

2 detalles clave que su solución no incluyó, el -neco evita que se agregue un\n a la contraseña que se está cifrando, y las comillas simples protegen los contenidos para que no sean interpretados por el shell (bash) en mi caso.

Por cierto, ejecuté este comando como root en un sistema CentOS 5.6 en caso de que alguien se lo pregunte.

slm
fuente
buena captura, no estoy seguro de cómo otros lograron que funcione con la nueva línea.
M03
1

La solución que funciona tanto en Debian como en Red Hat. Depende de Perl, utiliza 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

Puede usarse efectivamente como una línea, pero tendrá que especificar la contraseña, la sal y el nombre de usuario en los lugares correctos usted mismo:

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

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

Cree un archivo de texto, diga text.txt y complételo con el usuario: la contraseña se empareja de la siguiente manera:

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

Guarde el archivo text.txt y ejecute

cat text.txt | chpassword

Eso es. La solución es (a) escalable y (b) no implica imprimir contraseñas en la línea de comando.

Vietnhi Phuvan
fuente
0
{ echo $password; echo $password; } | passwd $username 
edacval
fuente
Si bien esto puede responder teóricamente a la pregunta, sería preferible incluir aquí las partes esenciales de la respuesta.
Werner
0

Para RedHat / CentOS, aquí está el código que crea un usuario, agrega las contraseñas y lo convierte en un 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
Zurdo G Balogh
fuente
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
fuente