En entornos corporativos donde se requiere integrar servidores Linux en un dominio de Active Directory (AD), es común restringir el acceso SSH solo a ciertos grupos de usuarios. Para ello, se puede utilizar el demonio SSSD (System Security Services Daemon), que permite gestionar la autenticación mediante AD y aplicar políticas de control de acceso.
Este artículo describe un script Bash automatizado que:
- Detecta la distribución Linux utilizada.
- Instala dependencias necesarias.
- Configura el servicio SSSD con restricciones de acceso basadas en grupo.
- Habilita la creación automática del directorio home.
- Ajusta el demonio SSH para usar PAM.
- Permite un reinicio opcional del sistema.
Variables Genéricas del Script
Para facilitar su adaptación a diferentes entornos, todas las variables están definidas al inicio del script y deben modificarse según cada caso:
DOMAIN_NAME="DOMINIO.LOCAL"
OU_PATH="OU=NombreUnidadUsuarios,DC=dominio,DC=local"
GROUP_NAME="Grupo_AD_SSH"
FORCE_RESTART="false"
DOMAIN_NAME
: Dominio de Active Directory.OU_PATH
: Ruta LDAP de la Unidad Organizativa que contiene los Usuarios.GROUP_NAME
: Nombre del grupo de seguridad del AD que tendrá acceso SSH.FORCE_RESTART
: Si es"true"
, el sistema se reiniciará al finalizar.
También se define un fichero de log para auditoría:
LOGFILE="/var/log/sssd_ssh_config.log"
#!/bin/bash
set -e
# === VARIABLES DEFINIDAS A FUEGO ===
DOMAIN_NAME="DOMINIO.LOCAL"
OU_PATH="OU=NombreUnidadUsuarios,DC=dominio,DC=local"
GROUP_NAME="Grupo_AD_SSH"
FORCE_RESTART="false"
LOGFILE="/var/log/sssd_ssh_config.log"
# === Función de log ===
log() {
local MSG="$1"
echo "$(date '+%Y-%m-%d %H:%M:%S') - $MSG" | tee -a "$LOGFILE"
}
# === DEBUG DE VARIABLES ===
log "DEBUG - DOMAIN_NAME=$DOMAIN_NAME"
log "DEBUG - OU_PATH=$OU_PATH"
log "DEBUG - GROUP_NAME=$GROUP_NAME"
log "DEBUG - FORCE_RESTART=$FORCE_RESTART"
# === Requiere root ===
check_root() {
echo "[Paso 1] Verificando permisos de root..."
if [[ $EUID -ne 0 ]]; then
log "Access Denied. Please run as root."
exit 1
fi
echo "[OK] El script se está ejecutando como root."
}
# === Validación de entradas ===
check_required_inputs() {
echo "[Paso 2] Validando entradas requeridas..."
[[ -z "$DOMAIN_NAME" ]] && { log "DOMAIN_NAME is required"; exit 1; }
[[ -z "$GROUP_NAME" ]] && { log "GROUP_NAME is required"; exit 1; }
[[ -z "$OU_PATH" ]] && { log "OU_PATH is required"; exit 1; }
echo "[OK] Entradas válidas."
}
# === Detectar sistema operativo ===
detect_os() {
echo "[Paso 3] Detectando sistema operativo..."
if [ -f /etc/os-release ]; then
. /etc/os-release
OS_ID=$ID
OS_VERSION_ID=$VERSION_ID
log "Detected OS: $OS_ID $OS_VERSION_ID"
else
log "Unsupported Linux distribution"
exit 1
fi
}
# === Instalar paquetes necesarios ===
install_dependencies() {
echo "[Paso 4] Instalando paquetes necesarios..."
log "Installing required packages..."
if [[ "$OS_ID" =~ (debian|ubuntu) ]]; then
apt update -y
DEBIAN_FRONTEND=noninteractive apt install -y sssd sssd-tools libnss-sss libpam-sss oddjob oddjob-mkhomedir || {
log "Package installation failed"
exit 1
}
elif [[ "$OS_ID" =~ (centos|rhel|rocky|almalinux) ]]; then
yum install -y sssd sssd-tools oddjob oddjob-mkhomedir authselect || {
log "Package installation failed"
exit 1
}
else
log "Unsupported OS: $OS_ID"
exit 1
fi
echo "[OK] Paquetes instalados."
}
# === Habilitar creación de directorios home ===
enable_mkhomedir() {
echo "[Paso 5] Habilitando mkhomedir..."
log "Enabling mkhomedir..."
if [[ "$OS_ID" =~ (debian|ubuntu) ]]; then
PAM_FILE="/etc/pam.d/common-session"
grep -q "pam_mkhomedir.so" "$PAM_FILE" || echo "session required pam_mkhomedir.so skel=/etc/skel umask=0077" >> "$PAM_FILE"
else
authselect select sssd with-mkhomedir --force || true
fi
echo "[OK] mkhomedir configurado."
}
# === Configurar SSSD ===
configure_sssd() {
echo "[Paso 6] Configurando SSSD..."
log "Configuring SSSD..."
REALM="${DOMAIN_NAME^^}"
SSSD_CONF="/etc/sssd/sssd.conf"
mkdir -p /etc/sssd
cat > "$SSSD_CONF" <<EOF
[sssd]
domains = ${DOMAIN_NAME}
config_file_version = 2
services = nss, pam, ssh
[domain/${DOMAIN_NAME}]
ad_domain = ${DOMAIN_NAME}
krb5_realm = ${REALM}
realmd_tags = manages-system joined-with-samba
cache_credentials = True
id_provider = ad
access_provider = ldap
ldap_access_order = filter
ldap_access_filter = (memberOf=CN=${GROUP_NAME},${OU_PATH})
default_shell = /bin/bash
fallback_homedir = /home/%u
ldap_id_mapping = true
EOF
chmod 600 "$SSSD_CONF"
systemctl daemon-reexec
systemctl daemon-reload
systemctl restart sssd || { log "Failed to restart sssd"; exit 1; }
log "SSSD configured and restarted."
echo "[OK] SSSD configurado correctamente."
}
# === Configurar SSH ===
configure_ssh() {
echo "[Paso 7] Configurando SSH..."
log "Ensuring SSH is configured to use PAM..."
SSHD_CONFIG="/etc/ssh/sshd_config"
grep -q "^UsePAM yes" "$SSHD_CONFIG" || echo "UsePAM yes" >> "$SSHD_CONFIG"
systemctl restart ssh || { log "Failed to restart SSH"; exit 1; }
log "SSH daemon restarted."
echo "[OK] SSH reiniciado correctamente."
}
# === Reinicio opcional ===
restart_if_requested() {
echo "[Paso 8] Comprobando si se requiere reinicio..."
if [[ "$FORCE_RESTART" == "true" ]]; then
log "Restarting system in 1 minute..."
shutdown -r +1 "System will restart to apply SSSD and SSH configuration."
else
echo "[OK] No se requiere reinicio."
fi
}
# === Programa principal ===
main() {
echo "=== INICIANDO SCRIPT DE CONFIGURACIÓN SSSD + SSH ==="
check_root
check_required_inputs
detect_os
install_dependencies
enable_mkhomedir
configure_sssd
configure_ssh
restart_if_requested
log "Configuration completed: only members of '${GROUP_NAME}' in '${OU_PATH}' can log in via SSH."
echo "=== SCRIPT FINALIZADO CORRECTAMENTE ==="
}
main
Funcionalidades del Script
1. Verificación de permisos de root
El script verifica que se esté ejecutando como usuario root. De no ser así, aborta la ejecución.
2. Validación de variables requeridas
Asegura que las variables principales estén definidas, previniendo errores por configuraciones incompletas.
3. Detección del sistema operativo
Usa /etc/os-release
para identificar la distribución y versión del sistema operativo, adaptando la instalación de paquetes según se trate de Debian/Ubuntu o CentOS/RHEL/Rocky/AlmaLinux.
4. Instalación de paquetes necesarios
Según el sistema, se instalan los siguientes paquetes:
- Debian/Ubuntu:
sssd
,sssd-tools
,libnss-sss
,libpam-sss
,oddjob
,oddjob-mkhomedir
- RHEL-based:
sssd
,sssd-tools
,oddjob
,oddjob-mkhomedir
,authselect
5. Activación de mkhomedir
Permite que los usuarios autenticados por AD tengan un directorio home creado automáticamente en su primer login.
6. Configuración de SSSD
Genera y aplica el fichero /etc/sssd/sssd.conf
con una política de acceso basada en grupo:
[domain/DOMINIO.LOCAL]
access_provider = ldap
ldap_access_filter = (memberOf=CN=Grupo_AD_SSH,OU=...,DC=...)
Esto asegura que solo los miembros del grupo definido puedan autenticarse.
7. Configuración del demonio SSH
El script se asegura de que el demonio sshd
permita la autenticación PAM (UsePAM yes
), requisito para que SSSD intervenga en el proceso de login.
8. Reinicio del sistema (opcional)
Si la variable FORCE_RESTART
está establecida a "true"
, el script programará un reinicio del sistema en un minuto.
Registro de actividad
Cada paso y mensaje importante se registra en /var/log/sssd_ssh_config.log
, facilitando la depuración y auditoría de los cambios realizados.
Conclusión
Este script es una herramienta eficaz y portable para automatizar la configuración de acceso SSH seguro en servidores Linux integrados en Active Directory. Puede ser fácilmente adaptado a cualquier organización modificando únicamente las variables iniciales.
Buenas prácticas recomendadas
- Validar previamente la conectividad con el controlador de dominio.
- Usar certificados válidos si se configura TLS en SSSD.
- Complementar la seguridad con reglas de firewall y fail2ban.
Compartir: