===== Asegurando el acceso por SSH ===== En lo que sigue resumimos algunas recomendaciones sobre cómo configurar y asegurar el acceso por ''SSH'' a un servidor. En particular desaconsejamos el acceso tradicional mediante usuario y clave. Es mucho más seguro emplear llaves criptográficas (private/public keys). También se desaconseja permitir el acceso de **root** desde el exterior. Es preferible impedir el acceso directo de **root** y sólo habilitar el acceso de un usuario común, que después pueda escalar privilegios mediante **su** o **sudo**. A su vez recomendamos limitar el acceso empleando **tcpwrappers** y utilizar herramientas como **fail2ban** o similares para limitar los intentos de acceso ilegal al servidor. ==== Configuración del cliente de SSH ==== === Crear las llaves criptográficas === Las llaves deben crearse e instalarse en el directorio ''~/.ssh'' (si no existe, crearlo): cd ~/.ssh ssy-keygen -t rsa -b 4096 -f nombre_de_la_llave El comando ''ssh-keygen'' genera dos archivos: ''nombre_de_la_llave'' (que es la llave privada) y ''nombre_de_la_llave.pub'' (con la llave pública). Cuando pida un **passphrase**, conviene asignarle uno, para proteger la llave privada. La llave pública se puede distribuir sin problema. La llave privada debe permanecer siempre protegida. Siempre conviene declarar el tipo de llave (''-t rsa'') y su tamaño en bits (''-b 4096''). No conviene usar llaves de menos de 2048 bits. Si se va a utilizar más de una llave, conviene asignarles algún ''nombre''. De no usarse la opción ''-f'' el comando ''ssh-keygen'' genera nombres automáticamente (id_rsa e id_rsa.pub), pero si ya existen llaves con esos nombres, los va a sobreescribir.. == Crear el archivo config == Como la conexión a diferentes servidores puede involucrar diferentes opciones de ''ssh'', conviene crear un archivo ''config'' en ''~/.ssh'', donde podamos declarar, para cada host, las opciones de ''ssh'' que queremos usar. Supongamos que nos interesa ingresar al host ''servidor.fq.edu.uy'', con el usuario ''juancito'', usando la llave ''~/.ssh/llave''. Para conectarnos tendríamos que ejecutar el comando: ssh -l juancito -i ~/.ssh/llave servidor.fq.edu.uy En cambio si creamos la siguiente entrada en el archivo ''~/.ssh/config'': host servidor hostname servidor.fq.edu.uy IdentityFile ~/.ssh/llave port 22 user juancito protocol 2 Alcanza con ejecutar: ssh servidor El comando ''ssh'' toma del archivo ''~/.ssh/config'' la configuración correspondiente al ''host servidor'' y usa todas las opciones que se declaren allí. El nombre que elijamos como ''host'' actúa como un alias y no se hace necesario ejecutar comandos tan largos explicitando las opciones que queremos usar (puede ser un nombre de fantasía). El nombre que usemos como ''hostname'' tiene que ser el que está registrado en el DNS, o también puede ser el número de ''IP''. En el archivo ''config'' se pueden agregar todas las opciones disponibles para ''ssh'', conviene consultar el manual para ver todas las opciones diponibles. A su vez, en el archivo ''config'' se pueden agregar tantas entradas para ''host'' como uno desee o necesite. Para cada host, se pueden asociar o declarar tantos parámetros como acepte el cliente ''ssh''. Para ver la lista completa de opciones, conviene consultar el manual de ''ssh'' y de ''ssh_config'': man ssh_config == Verificar los permisos en ~/.ssh == Para poder usar las llaves generadas en ''~/.ssh'' es necesario que los permisos sean los adecuados, de lo contrario ''ssh'' no va a usar las llaves. Los permisos de los archivos deben ser tales que sólo el usuario dueño de los mismos tenga posibilidad de leerlos y/o modificarlos: chmod 700 ~/.ssh chmod 600 ~/.ssh/* ==== Configuración del servidor SSH ==== Referencia: * [[http://docs.hardentheworld.org/Applications/OpenSSH/x]] En el archivo ''/etc/ssh/sshd_config'' recomendamos agregar o modificar las siguientes opciones: Obligatorio: AddressFamily inet AllowTcpForwarding no AuthorizedKeysFile .ssh/authorized_keys ChallengeResponseAuthentication no GSSAPIAuthentication no HostbasedAuthentication no IgnoreRhosts yes IgnoreUserKnownHosts no KerberosAuthentication no LoginGraceTime 30 LogLevel INFO PasswordAuthentication no PermitEmptyPasswords no PermitUserEnvironment no Protocol 2 PubkeyAuthentication yes StrictModes yes SyslogFacility AUTH UseDNS no UsePAM yes X11Forwarding no Subsystem sftp /usr/lib/openssh/sftp-server Recomendado: PermitRootLogin no DenyUsers root AllowUsers fulano mengano@192.168.1.10 AllowGroups grupo1 grupo2 ClientAliveInterval 2400 También recomendamos especificar el conjunto de ''MACs'' y tipo de cifrado empleado en la comunicación. Agregar las siguientes líneas al archivo ''sshd_config'': MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr KexAlgorithms curve25519-sha256@libssh.org También conviene agregar estas últimas líneas a la configuración por defecto de los clientes, en el archivo ''ssh_config'': Host * MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr KexAlgorithms curve25519-sha256@libssh.org Verificar que la configuración del servidor quedó bien. Al ejecutar el comando: sshd -t no debería devolver ningún error. === Instalar las llaves públicas en el servidor === Ir al directorio ''~/.ssh'' del usuario con el que se desea acceder al servidor. Si el directorio ''~/.ssh'' no existe, crearlo. Agregar al archivo ''authorized_keys'' la o las llaves públicas que se desean emplear para acceder al servidor. Ejemplo: cd ~/.ssh cat llave.pub >> authorized_keys Asegurarse que los permisos son los adecuados: chmod 700 ~/.ssh chmod 600 ~/.ssh/* El directorio sólo debería ser accesible y modificable por el usuario. Los archivos sólo deberían ser leibles y modificables por el usuario. === Reiniciar el servicio de SSH === Si usa ''systemd'': systemctl restart ssh Verificar que quedó corriendo normalmente: systemctl status ssh ==== Restringiendo acceso ==== === Configrando TcpWrapper === En el archivo ''/etc/hosts.deny'' agregar: sshd: ALL En el archivo ''/etc/hosts.allow'' agregar los dominios, IPs o rangos de IPs (CIDR) desde donde sea permitido acceder por ssh al servidor: sshd: anteldata.net.uy fq.edu.uy 180.34.23.15 164.73.160.0/22 Si se desea limitar a IPs que estén registrados en DNS de Uruguay, se puede poner algo así: sshd: .uy Pero esto tiene el incoveniente de que no siempre los IPs están convenientemente registrados en los servidores de DNS. Para resolver el dominio a que perteneces un IP, debe existir el correspondiente registro reverso en el DNS y esto no siempre ocurre. En particular es bastante habitual que Antel no tenga todos sus IPs con el registro reverso. También ocurre algo parecido dentro de la UdelaR. En ese caso conviene emplear alguna otra estrategia, como por ejemplo emplear algún script para consultar una base de datos de IPs asignados a países. == Configurando un script para controlar acceso con tcpwrappers == En lugar de limitar por IP, rango de IP o dominio, también es posible configurar ''tcpwrappers'' para que use un script evalúe si aceptar o no una conexión. Si el script devuelve ''exit 0'', la conexión se acepta, si devuelve un valor diferente de cero, la conexión se rechaza. En ''/etc/hosts.allow'' poner: sshd: ALL: aclexec /usr/local/bin/ipfilter.sh %a donde el script ''/usr/local/bin/ipfilter.sh'' cumple la función de evaluar si el IP (recibido por ''%a'') tiene permiso para acceder por ssh o no. === Control con fail2ban === ''fail2ban'' permite limitar los intentos de acceso por fuerza bruta y otro tipo de abusos que provengan del exterior. No sólo sirve para controlar el servicio ''ssh'' sino también cualquier otro servicio de iternet (ftp, email, pop3/imap, etc.). ''fail2ban'' debe configurarse adecuadamente para que revise ciertos logs del sistema, a fin de detectar alguna situación de abuso y luego proceder a bloquear el IP de donde provenga. Si bien ''fail2ban'' viene provisto de una amplia variedad de filtros y acciones, no alcanza con instalarlo, hay que habilitar explícitamente los servicios que se desean controlar y las acciones que se desean efectuar cuando se detecta el abuso de un servicio determinado. Incluso conviene verificar, usando ''fail2ban-regex'', si las expresiones regulares que tiene definidas en sus filtros, funcionan correctamente, haciendo alguna prueba con algún logfile que tenga los abusos que se desea detectar. fail2ban === Auditar el servidor === Recomendamos instalar y correr algún software que verifique la vulnerabilidad del servidor. Puede ser [[https://github.com/arthepsy/ssh-audit|ssh-audit]], [[https://github.com/CISOfy/lynis|Lynis]] o similar. Suele ser recomendable atender los consejos que éstas u otras herramientas similares sugieran como resultado de su diagnóstico.