User management: adduser, usermod, passwd em scripts

1. Introdução ao Gerenciamento de Usuários via Script

Em ambientes multi-usuário, gerenciar contas manualmente torna-se inviável. A automação com scripts Bash permite criar, modificar e gerenciar senhas de dezenas ou centenas de usuários de forma consistente e auditável. Os comandos adduser, usermod e passwd formam a tríade essencial para essa automação.

Para executar esses comandos, é necessário privilégios de root ou uso de sudo. Scripts de gerenciamento de usuários devem sempre verificar permissões antes de prosseguir.

#!/bin/bash
if [[ $EUID -ne 0 ]]; then
    echo "Este script deve ser executado como root ou com sudo."
    exit 1
fi

2. Criando Usuários com adduser em Scripts

O comando adduser (versão amigável do useradd) permite criação não interativa usando opções específicas. As opções --disabled-password e --gecos são essenciais para scripts.

#!/bin/bash
USERNAME="joao.silva"
HOME_DIR="/home/joao.silva"
SHELL="/bin/bash"

# Verifica se o usuário já existe
if id "$USERNAME" &>/dev/null; then
    echo "Erro: Usuário $USERNAME já existe."
    exit 1
fi

# Cria o usuário com configurações personalizadas
adduser --disabled-password \
        --gecos "João Silva,Departamento TI,11999999999,joao@empresa.com" \
        --home "$HOME_DIR" \
        --shell "$SHELL" \
        "$USERNAME"

echo "Usuário $USERNAME criado com sucesso."

A opção --gecos preenche campos como nome completo, departamento e telefone. O --disabled-password cria a conta sem senha, que será configurada posteriormente.

3. Modificando Usuários com usermod

O usermod altera contas existentes. As operações mais comuns em scripts incluem:

Adicionar a grupos secundários:

usermod -aG sudo,developers "$USERNAME"
# -aG adiciona aos grupos sem remover dos existentes

Bloqueio e desbloqueio de contas:

# Bloquear conta
usermod -L "$USERNAME"

# Desbloquear conta
usermod -U "$USERNAME"

Modificar data de expiração e diretório home:

# Expira em 30 dias
usermod -e "$(date -d '+30 days' +%Y-%m-%d)" "$USERNAME"

# Alterar home e mover arquivos
usermod -d /novo/home -m "$USERNAME"

4. Gerenciamento de Senhas com passwd em Lote

Definir senhas via script requer cuidado com segurança. O passwd --stdin (não disponível em todas as distribuições) permite entrada via pipe, mas é preferível usar chpasswd ou métodos mais seguros.

#!/bin/bash
USERNAME="joao.silva"
SENHA_TEMP="Joao@2024#Temp"

# Método 1: passwd com --stdin (Linux)
echo "$USERNAME:$SENHA_TEMP" | chpasswd

# Método 2: Forçar expiração no próximo login
chage -d 0 "$USERNAME"

echo "Senha definida para $USERNAME. Expiração forçada no próximo login."

Boas práticas de segurança:
- Nunca armazenar senhas em texto puro no script
- Usar variáveis de ambiente ou arquivos temporários com permissão 600
- Gerar senhas aleatórias usando openssl rand -base64 12
- Registrar operações em log com timestamp

5. Automação de Criação em Massa

Para criar múltiplos usuários, utilize um arquivo CSV como fonte de dados:

arquivo usuarios.csv:

joao.silva,João Silva,TI,11999999999
maria.oliveira,Maria Oliveira,RH,11888888888
carlos.santos,Carlos Santos,DEV,11777777777

Script de criação em massa:

#!/bin/bash
INPUT_FILE="usuarios.csv"
LOG_FILE="criacao_usuarios.log"
SENHA_PADRAO="Temp@1234"

echo "Iniciando criação de usuários em $(date)" > "$LOG_FILE"

while IFS=',' read -r username nome_completo departamento telefone; do
    # Pula cabeçalho ou linhas vazias
    [[ -z "$username" || "$username" == "username" ]] && continue

    if id "$username" &>/dev/null; then
        echo "AVISO: $username já existe. Pulando..." | tee -a "$LOG_FILE"
        continue
    fi

    # Cria usuário com informações do CSV
    adduser --disabled-password \
            --gecos "$nome_completo,$departamento,$telefone," \
            --shell /bin/bash \
            "$username"

    # Define senha temporária
    echo "$username:$SENHA_PADRAO" | chpasswd
    chage -d 0 "$username"

    # Adiciona ao grupo do departamento
    groupadd -f "$departamento"
    usermod -aG "$departamento" "$username"

    echo "OK: $username criado com sucesso" | tee -a "$LOG_FILE"
done < "$INPUT_FILE"

echo "Processo concluído. Verifique $LOG_FILE para detalhes."

6. Validação e Tratamento de Erros

Scripts robustos devem validar pré-condições e tratar falhas:

#!/bin/bash
set -euo pipefail  # Interrompe em erros, variáveis não definidas e pipes

validar_usuario() {
    local user="$1"

    # Verifica formato do username
    if [[ ! "$user" =~ ^[a-z_][a-z0-9_-]*$ ]]; then
        echo "Erro: Username inválido: $user"
        return 1
    fi

    # Verifica UID disponível
    if getent passwd "$user" &>/dev/null; then
        echo "Erro: Usuário $user já existe"
        return 1
    fi

    return 0
}

# Função de rollback em caso de falha
rollback() {
    local user="$1"
    echo "Falha na criação de $user. Executando rollback..."
    userdel -r "$user" 2>/dev/null || true
}

# Uso no script principal
if validar_usuario "$USERNAME"; then
    trap 'rollback "$USERNAME"' ERR
    adduser --disabled-password "$USERNAME"
    trap - ERR  # Remove trap após sucesso
fi

7. Exemplo Prático Completo

Script funcional que cria um usuário com todas as configurações padrão:

#!/bin/bash
# Script: criar_usuario_completo.sh
# Descrição: Cria usuário com grupo, home, senha e configurações de segurança

set -euo pipefail

# Configurações
NOME_USUARIO="${1:-}"
NOME_COMPLETO="${2:-Usuário Padrão}"
GRUPO_PRINCIPAL="users"
GRUPOS_SECUNDARIOS=""
SHELL="/bin/bash"
DIAS_EXPIRACAO=90

# Verificações iniciais
[[ -z "$NOME_USUARIO" ]] && { echo "Uso: $0 <username> [nome_completo]"; exit 1; }
[[ $EUID -ne 0 ]] && { echo "Execute como root"; exit 1; }

# Função principal
criar_usuario() {
    local user="$1"
    local nome="$2"

    echo "=== Criando usuário: $user ==="

    # 1. Criar grupo primário com mesmo nome
    groupadd -f "$user" 2>/dev/null

    # 2. Criar usuário
    adduser --disabled-password \
            --ingroup "$user" \
            --gecos "$nome,.,.,." \
            --home "/home/$user" \
            --shell "$SHELL" \
            "$user"

    # 3. Adicionar a grupos secundários
    [[ -n "$GRUPOS_SECUNDARIOS" ]] && usermod -aG "$GRUPOS_SECUNDARIOS" "$user"

    # 4. Gerar senha aleatória
    SENHA_TEMP=$(openssl rand -base64 12)
    echo "$user:$SENHA_TEMP" | chpasswd

    # 5. Configurar expiração
    usermod -e "$(date -d "+$DIAS_EXPIRACAO days" +%Y-%m-%d)" "$user"
    chage -d 0 "$user"

    # 6. Configurar cotas (opcional)
    # setquota -u "$user" 100M 200M 0 0 /home

    echo "Usuário criado: $user"
    echo "Senha temporária: $SENHA_TEMP"
    echo "Expira em: $(date -d "+$DIAS_EXPIRACAO days" +%Y-%m-%d)"
    echo "================================"
}

# Execução
criar_usuario "$NOME_USUARIO" "$NOME_COMPLETO"

Saída esperada:

=== Criando usuário: joao.silva ===
Usuário criado: joao.silva
Senha temporária: 3fK9mP2xR8vA
Expira em: 2025-07-20
================================

8. Considerações de Segurança e Manutenção

Armazenamento seguro de senhas:
- Utilize openssl passwd -6 para gerar hashes SHA-512
- Armazene senhas em cofre (Hashicorp Vault, pass, ou banco criptografado)
- Nunca inclua senhas em scripts versionados

Logs e auditoria:

# Registrar ações importantes
logger -t "user-mgmt" "Usuário $USERNAME criado por $SUDO_USER"
echo "$(date '+%Y-%m-%d %H:%M:%S') - $USERNAME criado" >> /var/log/user_mgmt.log

Políticas de senha do sistema:
- Configure /etc/security/pwquality.conf para forçar complexidade
- Use pam_tally2 para bloquear contas após tentativas falhas
- Integre com chage para expiração automática

Manutenção periódica:

# Script de limpeza de contas expiradas
#!/bin/bash
for user in $(getent passwd | awk -F: '$3>=1000{print $1}'); do
    expira=$(chage -l "$user" | grep "Account expires" | awk '{print $NF}')
    if [[ "$expira" != "never" && "$(date +%s)" -gt "$(date -d "$expira" +%s)" ]]; then
        usermod -L "$user"
        echo "Conta $user bloqueada por expiração"
    fi
done

A automação de gerenciamento de usuários com Bash reduz erros humanos, garante consistência e libera tempo para tarefas mais estratégicas. Scripts bem estruturados, com validações e logs, formam a base de uma administração de sistemas profissional e segura.

Referências