Desde el momento en que se convirtió en ‘mi servidor’, todo es mi responsabilidad
La última vez superé el muro de la CLI de Linux y de los permisos (Permissions). chmod, chown e incluso el chmod 777 que jamás debe hacerse. Hasta cierto punto, había captado el control de acceso de un archivo.
Pero en aquel entonces me equivocaba gravemente. Pensaba que con solo gestionar bien los ‘permisos de archivos’, el servidor estaría seguro.
«¿Seguridad del servidor? ¿Eso no lo hace el equipo de seguridad?»
En una gran empresa quizá sí. Pero yo soy un desarrollador en solitario. Administrador de servidores, responsable de seguridad, ingeniero de redes: todo eso era ‘yo’. Toda la responsabilidad de la seguridad recaía sobre mis hombros.
Y lo que me hizo tomar conciencia de ello fue el registro de acceso al servidor que descubrí una mañana de lunes.

La crisis: alguien estaba llamando a la puerta de mi servidor
Una mañana de lunes, mientras me conectaba por costumbre al servidor por SSH para revisar los registros, detecté algo extraño.
# Comprobar los últimos intentos de acceso SSH fallidos
$ grep "Failed password" /var/log/auth.log | tail -20
Al ver los registros que aparecieron en la pantalla se me puso la piel de gallina.
Feb 10 03:14:22 sshd: Failed password for root from 185.220.xx.xx
Feb 10 03:14:25 sshd: Failed password for root from 185.220.xx.xx
Feb 10 03:14:27 sshd: Failed password for admin from 185.220.xx.xx
Feb 10 03:14:30 sshd: Failed password for ubuntu from 185.220.xx.xx
...
Cientos de intentos de inicio de sesión desde las 3 de la madrugada. La IP, del extranjero. Los nombres de cuenta iban alternando root, admin y ubuntu. Era alguien que estaba ejecutando un ‘programa automatizado (bot)’ para probar contraseñas por fuerza bruta (Brute Force).
«Eh… ¿no me habrán hackeado ya…?»
Por suerte no lograron entrar. Pero ante un ladrón que está probando las llaves una a una delante de tu puerta, ¿se puede decir «no ha entrado, así que todo va bien»? Inmediatamente empecé a revisar el estado de seguridad del servidor.

Paso 1: cerrar la puerta principal — reforzar SSH
La puerta principal del servidor es SSH (Secure Shell). Justo lo que uso para conectarme al servidor. El problema es que los atacantes intentan entrar por esa misma puerta. Lo primero es reforzar esta puerta principal.
Cambiar el puerto SSH (por defecto 22 → otro número)
El puerto SSH por defecto es el 22. Los escáneres automáticos de los atacantes llaman primero al puerto 22. Solo con cambiar el número de puerto se puede filtrar más del 90 % de los ataques de fuerza bruta.
# Abrir el archivo de configuración de SSH
$ sudo vi /etc/ssh/sshd_config
# Cambiar el número de puerto (por defecto 22 → por ejemplo 2222)
Port 2222
# Reiniciar el servicio SSH
$ sudo systemctl restart sshd
Usando una analogía: los ladrones suelen atacar la puerta principal de la planta baja (puerto 22). Si trasladas la entrada a la puerta de la azotea del tercer piso (puerto 2222), la mayoría ni siquiera encontrará dónde está.
Bloquear el inicio de sesión directo como root
Según los registros, la cuenta que los atacantes prueban primero es ‘root’. Como root es la cuenta de administrador supremo en Linux, acceder a ella permite tomar el control completo del servidor.
# En el archivo de configuración de SSH, bloquear el inicio de sesión directo como root
$ sudo vi /etc/ssh/sshd_config
PermitRootLogin no
Ahora ya es imposible acceder por SSH como root. Se inicia sesión con una cuenta normal y, cuando sea necesario, se elevan los privilegios con sudo.
Autenticación por clave SSH en lugar de contraseña
Por muy compleja que sea la contraseña, si un programa automatizado prueba decenas de miles de combinaciones, tarde o temprano la romperá. El método más seguro es desactivar por completo el inicio de sesión por contraseña y permitir solo la conexión con una ‘clave SSH (Key)’.
# Generar un par de claves SSH en mi equipo (local)
$ ssh-keygen -t rsa -b 4096
# Copiar la clave pública al servidor
$ ssh-copy-id -p 2222 user@my-server-ip
# En el servidor, desactivar el inicio de sesión por contraseña
$ sudo vi /etc/ssh/sshd_config
PasswordAuthentication no
La autenticación por clave SSH no es una ‘llave’, sino un ‘reconocimiento de huella dactilar’. La contraseña (llave) se puede copiar, pero la clave privada (huella), que solo está en mi equipo, es prácticamente imposible de duplicar.
Paso 2: levantar un muro — el cortafuegos (Firewall)
Una vez reforzada la puerta principal (SSH), toca levantar un muro alrededor del edificio y controlar las entradas. Esto es el ‘cortafuegos (Firewall)’.
Un servidor tiene un total de 65.535 puertos (accesos). Sin cortafuegos, esas 60.000 puertas están todas abiertas. Hay que abrir solo las necesarias y cerrar todas las demás.
La herramienta de cortafuegos más fácil de usar en Linux es ‘UFW (Uncomplicated Firewall)’.
# Activar UFW
$ sudo ufw enable
# Política por defecto: bloquear todo lo entrante, permitir lo saliente
$ sudo ufw default deny incoming
$ sudo ufw default allow outgoing
# Abrir solo los puertos necesarios
$ sudo ufw allow 2222/tcp # SSH (puerto modificado)
$ sudo ufw allow 80/tcp # HTTP
$ sudo ufw allow 443/tcp # HTTPS
# Comprobar el estado actual del cortafuegos
$ sudo ufw status
| Puerto | Uso | Estado |
|---|---|---|
| 2222 | SSH (puerto modificado) | ✅ Permitido |
| 80 | HTTP (web) | ✅ Permitido |
| 443 | HTTPS (web seguro) | ✅ Permitido |
| 22 | SSH (por defecto, ya no se usa) | ❌ Bloqueado |
| Resto | Todos | ❌ Bloqueados |
De 60.000 puertas, solo 3 quedan abiertas y las demás se han tapiado. Ya no queda ninguna puerta a la que el ladrón pueda llamar.

Paso 3: cifrar las comunicaciones — HTTPS
Si el servidor ofrece servicios web, también hay que proteger la comunicación entre el usuario y el servidor. Eso es ‘HTTPS’.
HTTP envía los datos tal cual, como una ‘postal’. Cualquiera puede ver su contenido por el camino. HTTPS envía los datos dentro de una ‘carta sellada’. Aunque alguien la intercepte, no podrá leer el contenido.
¿Qué pasaría si el usuario y la contraseña que el usuario escribe en un formulario de login se enviaran por HTTP? Cualquiera que comparta el Wi-Fi de la cafetería podría leerlos tal cual.
En la práctica, la forma más sencilla de aplicar HTTPS es obtener un certificado SSL gratuito con ‘Let’s Encrypt’.
# Instalar Certbot (herramienta de automatización de Let's Encrypt)
$ sudo apt install certbot python3-certbot-nginx
# Emitir el certificado y aplicarlo automáticamente en Nginx
$ sudo certbot --nginx -d mydomain.com
# Probar la renovación automática (el certificado debe renovarse cada 90 días)
$ sudo certbot renew --dry-run
Con estas pocas líneas de comandos, la dirección de mi servicio cambia de http:// a https:// y aparece el icono del candado en la barra de direcciones del navegador. Se transmite confianza al usuario: «este sitio es seguro».
Paso 4: sistema de defensa automática — Fail2Ban
Aunque cambie el puerto SSH y configure la autenticación por clave, en el mundo hay bots muy insistentes. Siempre habrá alguno que encuentre el puerto modificado e intente conectarse.
En estos casos resulta útil ‘Fail2Ban’. Es una herramienta que bloquea automáticamente una IP cuando supera cierto número de intentos fallidos de inicio de sesión.
# Instalar Fail2Ban
$ sudo apt install fail2ban
# Configurar la protección de SSH
$ sudo vi /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 2222
maxretry = 5
bantime = 3600
findtime = 600
| Ajuste | Significado |
|---|---|
| maxretry = 5 | Si falla 5 veces |
| bantime = 3600 | se bloquea esa IP durante 1 hora |
| findtime = 600 | Se aplica si hay 5 fallos en menos de 10 minutos |
# Iniciar Fail2Ban
$ sudo systemctl enable fail2ban
$ sudo systemctl start fail2ban
# Consultar las IP actualmente bloqueadas
$ sudo fail2ban-client status sshd
Fail2Ban es una ‘cámara de vigilancia + cerradura automática’ colocada delante de la puerta principal. Si alguien sospechoso se equivoca varias veces con la contraseña, se le prohíbe el acceso automáticamente.

Consejo práctico: lista de comprobación de seguridad
Resumo en una lista de comprobación todo lo configurado hasta ahora. Si sigues esta lista cada vez que montes un servidor nuevo, tendrás una barrera defensiva básica cubierta.
| # | Elemento | Comando/Ajuste |
|---|---|---|
| 1 | Cambiar el puerto SSH | Port 2222 en sshd_config |
| 2 | Bloquear el inicio de sesión como root | PermitRootLogin no |
| 3 | Pasar a autenticación por clave SSH | PasswordAuthentication no |
| 4 | Activar el cortafuegos | ufw enable, permitir solo los puertos necesarios |
| 5 | Aplicar HTTPS | Let’s Encrypt + Certbot |
| 6 | Instalar Fail2Ban | Bloqueo automático de IP ante fallos de login |
| 7 | Actualizaciones periódicas | sudo apt update && sudo apt upgrade |
El punto 7 es más importante de lo que parece. Las vulnerabilidades de seguridad se descubren a diario. Por muy bien montado que esté el cortafuegos, si el propio SO o el software tiene agujeros, no sirve de nada. Las actualizaciones periódicas son la medida de seguridad más básica y, al mismo tiempo, una de las más eficaces.
Para terminar: la seguridad no es algo especial, es un hábito
Al principio la palabra seguridad me sonaba a algo enorme. Defensa contra hackers, detección de intrusiones, cifrado… Me parecían cosas de película.
Pero al ponerme a ello comprobé que no hace falta una técnica espectacular. Cambiar el puerto SSH, activar el cortafuegos, configurar la autenticación por clave e instalar Fail2Ban. Todo se resolvía con unas pocas líneas de comandos. Lo importante no es ‘saber’, sino ‘hacer’.
Los incidentes de seguridad no ocurren por técnicas de hackeo sofisticadas, sino en servidores donde no se han aplicado las medidas básicas.
Desde aquel día, cada vez que monto un servidor nuevo, ejecuto esta lista de comprobación de seguridad sin falta antes de subir el código. Revisar la cerradura antes de abrir la puerta. Esa es la postura más básica para proteger un servidor.
Hasta aquí hemos entrenado la condición física básica (CLI, permisos, seguridad) para sobrevivir en la jungla que es Linux. Pero sigue quedando un problema fundamental: el entorno de mi portátil (Windows) y el del servidor Linux son distintos. La versión de Java también es diferente y las bibliotecas también.
Existe una tecnología que acabará para siempre con la excusa «en mi equipo sí funciona». En la próxima entrega hablaremos de la ‘virtualización y los contenedores’, que eliminan por completo las diferencias de entorno.