Continuamos Seguridad SSH parte I con más trucos para hacer el servicio un poco más seguro. En esta segunda parte tratamos de mejorar la seguridad de las claves, y dificultar la vida de un aracante que consiga acceso.

5. Limitar el acceso ssh a los usuarios

Por defecto todos los usuarios del sistema pueden conectarse usando ssh, pero si no todos los usuarios necesitan acceso ssh, por ejemplo tiene un usuario sólo para acceder por ftp, es posible restringir su acceso en el archivo /etc/ssh/sshd_config

DenyUsers ftpuser1, ftpuser2

o aún más seguro, restringir el acceso a todo los usuarios excepto los especificados:

AllowUsers secnot, juan

6. Desactivar claves vacías

Comprobar que usuarios con claves vacías no puedan hacer login, normalmente esta incluido en la configuración por defecto, pero es mejor comprobarlo en /etc/ssh/sshd_config:

PermitEmptyPasswords no

7. Firewall para el puerto SSH

Si las conexiones a SSH van a ser siempre desde una ip fija, es posible configurar el firewall para que permita conexiones sólo desde esa ip. Esto no es una guía de iptables, pero para acceso exclusivo desde la ip 82.168.100.7, podría ser algo similar a esto:

iptables -A INPUT -i eth0 -p tcp -s 82.168.100.7 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 22 -j DROP
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

antes de modificar iptables asegúrate que sabes lo que haces, porque te puedes quedar sin acceso remoto, si bloqueas el puerto por error.

8. Caducidad de sesiones inactivas

Cuando exista la posibilidad de que usuarios dejen abiertas sesiones ssh en ordenadores inseguros, es recomendable configurar sshd, para que las sesiones se cierren automáticamente tras un periodo de inactividad. En sshd_config añadimos o modificamos:

# Log Out tras 5 minutos
ClientAliveInterval 300
ClientAliveCountMax 0

Esto establece un periodo de 5 minutos (300 segundos). Cuando la sesión de un usuario está inactiva más de este intervalo, es cerrada automáticamente.

9. Fortaleza de las claves

Aunque no relacionado directamente con el servicio ssh, las claves de los usuarios son uno de sus principales puntos débiles, un usuario con una clave débil puede hacer todo el sistema vulnerable, aunque la mejor solución es desactivar login con claves y usar exclusivamente autenticación pública, desgraciadamente esto no es siempre posible, en estos casos se puede paliar el problema obligando a los usuarios a elegir mejores claves.

Pluggable Authentication Modules (PAM) es el encargado de proporcionar autenticación para usuarios y servicios en linux, y nos permite mediante distintos módulos, configurar prácticamente todos los aspectos del proceso. En este caso el modulo que nos interesa esta en /etc/pam.d/common-passwd donde tendremos que editar la linea:

#password       [success=1 default=ignore]      pam_unix.so obscure sha512
password        [success=1 default=ignore]      pam_unix.so obscure sha512 minlen=8

Así forzamos a que las claves sean al menos de 8 caracteres. Si esto no es suficiente, puedes probar el modulo pam_cracklib

secnot@servidor:~$ sudo apt-get install libpam-cracklib

Tras instalar cracklib editamos /etc/pam.d/common-password:

password requisite    pam_cracklib.so    retry=3 minlen=10 difok=3 ucredit=1 lcredit=1 dcredit=1

Esto forzará que las claves sean como mínimo de 10 caracteres, que al menos 3 caracteres cambiaron respecto a la clave anterior, al menos un carácter esté en minúsculas, uno en mayúsculas, y uno sea un número. Se pueden usar políticas mucho más restrictivas usando cracklib, pero llevado al extremo comienza a ser contraproducente, las claves resultantes son demasiado complejas para recordar, y acaban apuntadas en un post-it pegado al monitor.

10. Apparmor

En muchos casos los usuarios no necesitan tener más acceso que a su directorio personal, y siempre es buena política dar a los usuarios exactamente los mínimos privilegios posibles, tradicionalmente restringir el directorio se ha hecho con chroot, pero hoy en día apparmor me parece una solución más limpia y flexible.

Vamos a restringir el usuario juanjo, lo primero será crear una un link del shell bash a jailbash, para poder modificar las opciones de apparmor de forma independiente.

secnot@servidor:~$ sudo ln /bin/bash /usr/local/bin/jailbash

Añadimos jailbash a la lista de shells disponibles en /etc/shells

Y se asigna el nuevo shell al usuario a restringir

secnot@servidor:~$ sudo chsh -s /usr/local/bin/jaiblash juanjo

Tras esto creamos /etc/apparmor.d/usr.local.bin.jailbash que contiene el perfil apparmor para el nuevo shell, incluyo un ejemplo como patrón del contenido, pero es necesario adaptarlo a las necesidades de cada sistema y las restricciones del usuario.

#include <tunables/global>

/usr/local/bin/jailbash {
        #include <abstractions/base>
        #include <abstractions/bash>
        #include <abstractions/consoles>
        #include <abstractions/nameservice>
        #include <abstractions/user-manpages>
        #include <abstractions/user-tmp>

        deny /bin/df r,
        deny /etc/bash_command_not_found r,

        /bin/ r,
        /bin/bash rix,
        /bin/cat rix,
        /bin/chmod rix,
        /bin/chown rix,
        /bin/cp rix,
        /bin/date rix,
        /bin/egrep rix,
        /bin/grep rix,
        /bin/gunzip rix,
        /bin/gzip rix,
        /usr/local/bin/jailbash rix,
        /bin/ln rix,
        /bin/ls rix,
        /bin/mkdir rix,
        /bin/mktemp rix,
        /bin/more rix,
        /bin/mv rix,
        /bin/ping rix,
        /bin/readlink rix,
        /bin/rm rix,
        /bin/rmdir rix,
        /bin/sed rix,
        /bin/sleep rix,
        /bin/tar rix,
        /bin/touch rix,
        /bin/uname rix,
        /bin/vim rix,
        /bin/vim-normal rix,
        /bin/zcat rix,
        /dev/null rw,
        /dev/urandom r,
        /etc/ r,
        /etc/manpath.config r,
        /etc/opt/ r,
        /etc/sysconfig/console r,
        /etc/sysconfig/mail r,
        /etc/sysconfig/news r,
        /etc/vimrc r,

        owner /home/*/ r,
        owner /home/*/** rwl,
        /opt/ r,
        owner /proc/*/cmdline r,
        owner /proc/*/exe r,
        owner /proc/*/mounts r,

        /tmp/** rw,
        /proc/loadavg r,
        /usr/bin/ r,
        /usr/bin/groups rix,
        /usr/bin/lesspipe rix,
        /usr/bin/cut rix,
        /usr/bin/whereis rix,
        /usr/bin/sort rix,
        /usr/bin/basename rix,
        /usr/bin/head rix,
        /usr/bin/id rix,
        /usr/bin/less rix,
        /usr/bin/man rix,
        /usr/bin/manpath rix,
        /usr/bin/mc rix,
        /usr/bin/scp rix,
        /usr/bin/screen rix,
        /usr/bin/ssh rix,
        /usr/bin/ssh-add rix,
        /usr/bin/ssh-agent rix,
        /usr/bin/ssh-copy-id rix,
        /usr/bin/ssh-keygen rix,
        /usr/bin/ssh-keyscan rix,
        /usr/bin/tail rix,
        /usr/bin/tty rix,
        /usr/bin/vim rix,
        /usr/bin/wget rix,
        /usr/bin/which rix,
        /usr/lib*/mc/cons.saver rix,
        /usr/lib*/ssh/ssh-keysign rix,
        /usr/local/bin/ r,
        /usr/share/mc/** r,
        /usr/share/vim/** r,
}

Por último activamos apparmor para jailbash:

secnot@servidor:~$ sudo aa-enforce jailbash
Setting /etc/apparmor.d/usr.local.bin.jailbash to enforce mode.

comments powered by Disqus