Administración - SSH

Instalación

IMPORTANTE: en estos momentos el nivel de seguridad que tiene el Servidor es "Alto". Ver msec para más detalles.

Queremos acceder al Servidor remotamente, tanto desde ciertos puestos de la Red interna como desde Internet: lo haremos con OpenSSH. Pero antes de abrirlo a Internet deberemos tomar todo tipo de precauciones y activar una batería de medidas de seguridad. Por ello, todo lo que sigue debe hacerse antes de conectar nuestro Router a la línea ADSL.

OpenSSH es una implementación libre de "Secure Shell (SSH)" o "Acceso remoto seguro", y es que ssh es un programa para acceder ("loguearse") desde una computadora a otra máquina remota y ejecutar comandos en ésta. Nos proporciona comunicaciones cifradas seguras entre dos anfitriones sobre una red insegura. Además permite que conexiones X11 y puertos arbitrarios tcp/ip puedan redireccionarse hacia el canal seguro (tunelizar).

sshd correrá en el Servidor como un servicio (demonio) que estará a la escucha en el puerto 22/tcp (si no indicamos otra cosa). Se puede configurar autónomo o como hijo de xinetd. Por defecto viene autónomo.

A la hora de instalar, tenemos tres paquetes fundamentales: openssh, openssh-clients y openssh-server. Los nombres son descriptivos, sólo señalo que el primer paquete proporciona los archivos de base necesarios tanto para el cliente como para el servidor de OpenSSH. Lógicamente, el paquete sólo es útil cuando se instala en combinación de uno de los otros dos, o de ambos. La instalación y puesta en marcha de un servidor ssh es tan sencillo como esto:

# urpmi openssh-server
...........................
Generating SSH1 RSA host key... done
Generating SSH2 RSA host key... done
Generating SSH2 DSA host key... done
# /etc/init.d/sshd start
Iniciando sshd: [ OK ]

Para recibir conexiones desde otras máquinas es necesario abrir puertos en el Servidor. Para ello podemos usar el asistente de Mandriva, ejecutando drakfirewall. Ante la pregunta "¿A qué servicios debería permitirse acceder desde Internet?", comprobaremos que está deshabilitada la opción Todo (sin cortafuegos) y marcamos la opción Servidor SSH, que abre el puerto 22. Basta ya con dar en aceptar para que el firewall, que en Mandriva viene gestionado por defecto mediante shorewall quede configurado.

Si vamos a permitir conexiones remotas desde Internet, tendremos que abrir el correspondiente puerto en el Router. Pero sólo lo haremos una vez que hayamos concluido la configuración y tomado las debidas precauciones. Esto puede verse en esta sección.

Acceso mediante usuario/contraseña

Usemos ssh por primera vez: estoy físicamente conectado como el usuario pepe en el equipo acer -cliente 192.168.0.5 - y voy a conectarme como el usuario pealfa al web.iesdelgadohernandez.es -servidor 192.168.0.3-. La conexión se realiza estando ambos en una misma intranet:

[pepe@acer ~]$ ssh pealfa@192.168.0.3
Warning: Permanently added '192.168.0.3' (RSA) to the list of known hosts.
pealfa@192.168.0.3's password: **********
Last login: Sun Dic 28 11:43:39 2005
[pealfa@web ~]$

Observemos esa última línea: aparecemos como pealfa conectado a web. Aprovechemos para crear un directorio en el Servidor que luego necesitaremos:

[pealfa@web ~]$ mkdir .ssh
[pealfa@web ~]$ chmod 700 .ssh/

Si ahora necesitáramos convertirnos en el root de nuestro Servidor para realizar las tareas que se precisen, bastaría con:

[pealfa@web ~]$ su -
Password: **********
[root@web ~]#

Bueno, con exit vamos cerrando sesiones, hasta abandonar la conexión.

Unas notas:

  • Si tuviéramos el mismo nombre de usuario o login, digamos pealfa, en ambos equipos bastaría con teclear:

    [pealfa@acer ~]$ ssh 192.168.0.3

  • Y si además el cliente puede traducir el nombre del Servidor a su ip, por ejemplo porque en su fichero /etc/hosts aparece la relación "192.168.0.3 web web.iesdelgadohernandez.es" podría escribirse:

    [pealfa@acer ~]$ ssh web.iesdelgadohernandez.es

Ahora, como tengo Konqueror en el cliente, escribiendo en la barra de direcciones fish://192.168.0.3 aparece la solicitud de autenticación en web; tras lo cual puedo entrar en todas aquellas zonas del Servidor a las que que pealfa tiene acceso. De este modo puedo subir archivos a web, borrarlos, renombrarlos,... cómodamente aún sin tener instalado entorno gráfico en él.

Pero SSH es algo más que la herramienta ssh (shell remoto, comando remoto y envío de sesiones), también nos proporciona scp (que permite transferir archivos de forma automatizada), sftp (para transferir archivos de forma interactiva), ssh-keygen (para generar pares de claves pública/privada), ssh-agent (servicio para automatizar autenticaciones en el cliente) y ssh-add (para cargar la clave privada en un proceso de ssh-agent), entre otras.

Acceso mediante llaves

Hay otra forma de conectar los dos equipos: usando la autenticación mediante llaves criptográficas (pública/privada).

PRIMERO genero una pareja de claves, pública y privada, en cada cliente que vaya conectarse al Servidor. Ello se hace con la utilidad ssh-keygen:

[pepe@acer ~]$ ssh-keygen -t dsa
Generando la pareja de claves pública/privada.
Escriba el nombre del archivo que contendrá la clave (/home/pepe/.ssh/id_dsa):
Introduzca una frase de paso (si no escribe nada no hay palabra de paso):
Introduzca de nuevo esa palabra de paso:
Su identificación ha sido correctamemente salvada en /home/pepe/.ssh/acer_id_dsa.
Su clave pública ha quedado correctamente guardada en /home/pepe/.ssh/acer_id_dsa.pub.
La huella de la clave es:
7b:42:e3:81:56:93:58:79:8b:d1:c5:04:be:6c:25:8e pepe@acer

SEGUNDO copio la clave pública que hemos generado en el cliente (fichero /home/pepe/.ssh/acer_id_dsa.pub de acer) en el Servidor (en el directorio /home/pealfa/.ssh/acer_id_dsa.pub de web). Esto puede hacerse de varias formas: físicamente, conectando con konqueror usando fish, o así:

[pepe@acer ~]$ scp .ssh/id_dsa.pub pealfa@192.168.0.3:.ssh/acer_id_dsa.pub
pealfa@192.168.0.3's password:
id_dsa.pub 100% 620 0.6KB/s 00:00

TERCERO ahora nos conectamos al Servidor y añadimos la clave pública del cliente al archivo del Servidor /home/pealfa/.ssh/authorized_keys2, ajustaremos los permisos de éste y borraremos el archivo acer_id_dsa.pub pues ya no lo necesitaremos.

[pepe@acer ~]$ ssh pealfa@192.168.0.3
pealfa@192.168.0.3's password:
Last login: Sun Dic 28 11:45:53 2005 from 192.168.0.5
[pealfa@web ~]$ cd .ssh
[pealfa@web .ssh]$ cat acer_id_dsa.pub >> authorized_keys2
[pealfa@web .ssh]$ chmod 644 authorized_keys2
[pealfa@web .ssh]$ rm acer_id_dsa.pub
rm: ¿borrar el fichero regular «acer_id_dsa.pub»? (s/n) s
[pealfa@web .ssh]$ exit
logout
Connection to 192.168.0.3 closed.

Para conectarnos ahora al Servidor, desde el equipo acer, ya no precisamos introducir contraseñas, confiamos únicamente en las claves pública y privada:

[pepe@acer ~]$ ssh pealfa@web.iesdelgadohernandez.es
Last login: ...
[pealfa@web ~]

Notas:

  • Hemos dejado en blanco la "frase de paso". Si quisiéramos crear una o si fuésemos a cambiar una ya creada, ejecutaríamos:

    [pepe@acer ~]$ ssh-keygen -t dsa -p

  • Y si no recordamos la antigua pues entonces:

    [pepe@acer ~]$ ssh-keygen -t dsa -N "nueva frase de paso"

  • Aunque configuremos el acceso exigiendo introducir una "frase de paso", podemos configurar OpenSSH para que abra conexiones sin tener que introducirla. Puede automatizarse el proceso mediante ssh-add, ssh-agent y, yendo más lejos, keychain. Pero eso aquí no toca.

Breves notas sobre el funcionamiento de ssh

Las conexiones ssh funcionan de forma semejante a las https. En primer lugar, el cliente y el servidor comparten la clave de host. Si el cliente no encontró previamente la clave pública del servidor, se pregunta al usuario si acepta una clave que, en principio, no es confiable. Una vez hecho esto, se utilizan las claves públicas para negociar una clave de sesión; con ella se cifraran todos los datos posteriores de ésta.

De forma predeterminada el servidor intenta autenticar al cliente utilizando certificados RSA o DSA (un par de claves). Si el servidor reconoce el certificado del cliente, entonces solicitará el certificado de la clave privada del cliente; si todo va bien, ambos lo usatrán para completar la autenticación mediante una "frase de paso" (que puede ser vacía) y que le indica al servidor que el cliente tiene la clave privada que corresponde a la pública que tiene registrada. Pero la clave privada nunca abandonará al cliente. Si este mecanismo de autenticación falla o si no hay certificado cliente disponible, el servidor solicitará entonces una autenticación del tipo usuario/contraseña. Observemos que esos datos ya viajarían cifrados. La idea, globalmente, suele resumirse así: "la clave pública cifra y la privada descifra. La claves públicas se comparten, las privadas jamás".

Seguridad

Bueno, en cuanto se abre el puerto 22 en Internet y permitimos la identificación por usuario/contraseña viene una avalancha de intentos de entrada, los que se llaman ataques de diccionario. Debemos poner limitaciones. Veamos algunas ideas.

Una buena idea es configurar sshd para que no permita la conexión remota de root y para que sólo permita la conexión mediante claves. Veamos un ejemplo de archivo de configuración /etc/ssh/sshd_config que incluye esas dos medidas:

# cat /etc/ssh/sshd_config
Port 22
ListenAddress 0.0.0.0
PermitRootLogin no
PasswordAuthentication no
X11Forwarding yes
Subsystem sftp /usr/lib/sftp-server
# AllowUsers pealfa colego@*.dominio.com

La línea comentada diría que sólo se permite conexión a los usuarios pealfa desde cualquier máquina y a colego desde cualquier máquina de dominio.com. Nótese que puede cambiarse ahí fácilmente el puerto por el que sshd escucha las peticiones.

Veamos ahora qué ocurre cuando intentamos conectarnos desde un equipo que cuya clave pública no está en el Servidor:

[usuario@clientes ~]$ ssh user@web.iesdelgadohernandez.es
Warning: Permanently added 'web.iesdelgadohernandez.es,80.33.124.154' (RSA) to the list of known hosts.
Permission denied (publickey,keyboard-interactive).

En otro orden de cosas, cuando pasamos el Nivel de Seguridad global de nuestro sistema, gestionado por msec, de "Alto" a "Muy alto", nos encontramos con esta fuerte restricción a nivel de tcp-wrappers: todas las conexiones denegadas salvo las locales.

[root@web ~]# cat /etc/hosts.deny
ALL:ALL EXCEPT 127.0.0.1:DENY

Para poder acceder desde equipos remotos debemos modificar /etc/hosts.allow. Con la siguiente configuración se aceptarían sólo conexiones de la red local 192.168.0.x y de direcciones de internet 81.x.y.z:

[root@web ~]# cat /etc/hosts.deny
sshd : 81. 192.168.0.
ssh : localhost

Por supuesto, podemos limitar las ip desde las que se permitirán conexiones a nivel de firewall. Y ahora un interesantísimo ejemplo que he visto aquí sobre cómo limitar la ratio de conexiones (o tentativas). Las dos reglas siguientes permitirán hasta 3 intentos de conexión al puerto 22 desde una ip; los paquetes que pretendan establecer nuevas conexiones por encima de ese límite serán eliminados:

iptables -i INPUT -p tcp --dport 22 -i eth0 -m state NEW -m recent --set
iptables -i INPUT -p tcp --dport 22 -i eth0 -m state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP

Aún más: la herramienta DenyHosts. La he probado en otros equipos y funciona satisfactoriamente.

. : .