Ejercicio 1: Servidor VPS

Una vez obtenido en Student Pack de Github, en Digital Ocean creamos un Droplet eligiendo un datacenter cercano a nuestros potenciales usuarios (en mi caso Farnkfurt).

Como opción de servidor elijo LEMP y el plan de:

Obtengo mi dominio whiletruedo.com en dondominio y pongo los nameservers de DigitalOcean en la configuración de DNS de mi registrador. Creo los records A y CNAME y espero a que propague. Al ser un dominio .com la propagación es bastante rápida.

Conexión

Abro powershell y me conecto con ssh:

ssh root@your_server_ip

(También podremos conectarnos con ssh root@your_domain_server cuando ya hayamos configurado los registros en nuestro proveedor de dominio apuntando a la IP de DigitalOcean).

Creación de usuario

Creo un usuario y lo añado al grupo sudo

adduser nombre_usuario

usermod -aG sudo nombre_usuario

Una vez que compruebo que ya puedo entrar al servidor con mi nuevo usuario, vamos a dejar de permitir el acceso al servidor mediante root. Desactivar el acceso directo como root es la regla número uno de seguridad en cualquier servidor Linux para evitar ataques de fuerza bruta.

Para ello, abrir el fichero de configuración del servidor ssh con nano

sudo nano /etc/ssh/sshd_config

Buscamos la línea que dice PermitRootLogin y cambiamos "yes" por "no". Guardamos cambios y cerramos nano.

Certificado de seguridad Let's Encrypt

Ahora vamos a instalar el certificado de seguridad Let's Encrypt para usar el protocolo https en lugar de http. Como hemos puesto Lemp con Nginx usamos:

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com

Ya podemos ver la plantilla de LEMP.

Let's Encrypt emite certificados que duran 90 días, por lo que la siguiente linea de comando se encarga de automatizar la renovación para que no tengamos que hacerlo manualmente cada tres meses.

sudo systemctl status certbot.timer sudo certbot renew --dry-run

Servidor de correo Postfix y añadir un registro SPF

sudo apt update && sudo apt install postfix -y

Me sale el mensaje de "postfix is already the newest version" y para configurarlo usamos:

sudo dpkg-reconfigure postfix

Configuramos varias pantallas como:

En la terminal nos queda un resumen de la configuración:

Una vez instalado Postfix vamos a configurarlo para poder enviar y recibir correos:

sudo postconf -e 'home_mailbox= Maildir/'

Creamos el archivo virtual donde se guardarán los correos:

sudo nano /etc/postfix/virtual

Creo dos direcciones de correo:

Para grabarlas:

sudo postmap /etc/postfix/virtual
sudo systemctl restart postfix

Me envío un correo desde mi cuenta de gmail y tras esperar unos 30 segundos, instalo s-nail y compruebo:

sudo apt install s-nail
s-nail
sudo nano /etc/s-nail.rc

y al final del archivo escribimos:

set emptystart
set folder=Maildir
set record=+sent

La función de s-nail es abrir la bandeja de entrada local del usuario con el que estás logueado.

Ejecuto:

ls -R ~/Maildir

Pero aún no me salen las carpetas que necesitamos, así que las creo manualmente:

mkdir -p ~/Maildir/{cur,new,tmp}
chmod -R 700 ~/Maildir

Configuro:

sudo nano /etc/postfix/main.cf

Actualizando myhostname y mydestination a:

Nos enviamos un correo a nosotros mismos para comprobar que podemos recibir correos:

echo "Hola, activando el buzon" | s-nail -s "Activacion" mariajo

Miramos dentro de la carpeta:

ls -R ~/Maildir/new

Esa numeración es el correo recibido.

Aunque la instalación y configuración de Webmin se comenta más abajo, aprovecho el dashboard de la plataforma para mostrar la creación de la cuenta de correo mariajo@whiletruedo.com y la recepción del mensaje enviado.

Registro SPF

Para poder enviar un correo a otra dirección que no sea de mi servidor, necesitamos activar un registro SPF. Lo hacemos desde el propio DigitalOcean.

Networking > Domains > Create record

echo "Hola, este es un mensaje enviado desde mi servidor Ubuntu con Postfix." | s-nail -s "Prueba desde WhileTrueDo" -r info@whiletruedo.com mjgamez@gmail.com

No consigo recibirlo y los logs indican que tengo bloqueado el puerto 25. Consulto el asistente de DigitalOcean e indican:

Port 25 is blocked on all DigitalOcean Droplets. DigitalOcean blocks the SMTP ports 25, 465, and 587 by default to prevent abuse: you cannot open or expose them. To send email you should use a dedicated email‑delivery service (e.g., SendGrid) or configure an external mail server.

For more detail, see the Droplet Limits documentation:

Sendgrid

Como es la solución que propone el propio DigitalOcean, paso a activar Sendgrid. Creo los records necesarios en el proveedor de VPs y los configuro según me indica Sendgrid. Actualizo:

sudo apt update
sudo apt install libsasl2-modules -y

Introduzco la API Key que me ha dado Sendgrid con:

sudo nano /etc/postfix/sasl_passwd
[smtp.sendgrid.net]:587 apikey:SG.AQUÍ_TU_API_KEY

Ejecuto uno a uno:

# 1. Protege el archivo para que nadie más lo lea
sudo chmod 600 /etc/postfix/sasl_passwd

# 2. Crea la base de datos que entiende Postfix
sudo postmap /etc/postfix/sasl_passwd

# 3. Reinicia Postfix para que empiece a usarla
sudo systemctl restart postfix

Configuro:

sudo nano /etc/postfix/main.cf
# Configuración de seguridad para SendGrid
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
header_size_limit = 4096000

Nuevo intento de envío de mail a un correo fuera de mi propio servidor.

echo "Hola, este es un mensaje enviado desde mi servidor usando Sendgrid." | s-nail -s "Prueba desde WhileTrueDo" -r info@whiletruedo.com mjgamez@gmail.com

Los logs ahora indican que DigitalOcean también tiene bloqueado el puerto 587 así que pruebo a usar el puerto 2525.

sudo nano /etc/postfix/main.cf
sudo nano /etc/postfix/sasl_passwd
[smtp.sendgrid.net]:2525 apikey:TU_API_KEY

Finalmente ya puedo enviar correos. Como pide el enunciado del ejercicio envío:

echo "Hola, email de prueba enviado desde mi servidor. Maria Jose Gamez" | s-nail -S sendcharsets=utf-8 -s "Comprobacion del servidor de correo" -r info@whiletruedo.com paco.portada@protonmail.com

La siguiente imagen muestra el dashboard de Sendgrid donde se puede ver un listado de correos enviados con la etiqueta de "Delivered"

Configurar ufw

Vamos a habilitar el cortafuegos y abrir únicamente los puertos necesarios.

Por defecto, UFW está configurado para denegar todas las conexiones entrantes y permitir todas las conexiones salientes. Esto significa que quien intente establecer conexión con su servidor no podrá hacerlo, mientras que cualquier aplicación dentro del servidor podrá llegar al mundo exterior. Los pasos son:

Comprobamos el status con:

sudo ufw status

Como ahora usamos SendGrid por el puerto 2525, nos aseguramos de que el servidor permite las conexiones de salida (aunque UFW suele permitir toda la salida por defecto).

sudo ufw allow out 2525/tcp

Para saber qué hemos dejado abierto:

sudo ufw status numbered

Instalar Fail2Ban

Lo que hace Fail2Ban es leer los logs y, si ve que alguien falla la contraseña muchas veces (ataque de fuerza bruta), le banea la IP.

sudo apt update
sudo apt install fail2ban -y

Creamos nuestro propio archivo de configuración y lo editamos.

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

Nos aparece algo como esta imagen:

Fail2ban ya viene con una configuración estándar que puede valer en la mayoría de los casos (a no ser que queramos cambiar algo específico). Si es conveniente saber que desde ahí podemos configurar cosas como:

Webmin

Para descargarlo e instalarlo:

curl -o webmin-setup-repo.sh https://raw.githubusercontent.com/webmin/webmin/master/webmin-setup-repo.sh
sudo sh webmin-setup-repo.sh
sudo apt update
sudo apt install webmin usermin --install-recommends -y

Abro en ufw el puerto que nos hará falta:

sudo ufw allow 10000/tcp

Ponemos en el navegador la ip seguida de 10000 → https://209.38.229.247:10000 Nos pide usuario y contraseña

Para instalar el módulo de Nginx en Webmin, lo hacemos directamente desde la interfaz gráfica de Webmin. En el menú de la izquierda, Webmin Configuration > Webmin Modules > Install from > From uploaded file y ahí subimos el módulo que hemos descargado desde aquí > Refresh Modules y ya nos aparece Nginx Webserver.

Dentro de Nginx Webserver vamos a la rueda dentada de configuración y comprobamos que:

Con esto tenemos una herramienta que nos permite administrar nuestro servidor web como si fuera una aplicación de escritorio, con opciones directas para Arrancar, Parar o Reiniciar Nginx o netdata.

Clicando sobre los Server Name podemos acceder de forma cómoda y rápida a sus archivos de configuración.

Netdata

Netdata nos da gráficas en tiempo real de todo lo que pasa en nuestro servidor: CPU, RAM, discos, red, etc. Para instalarlo:

// Con este me falla
wget -O /tmp/netdata-kickstart.sh https://get.netdata.cloud/kickstart.sh && sh /tmp/netdata-kickstart.sh --prepare-offline-install-source ./netdata-offline

// Pruebo con este
wget -O /tmp/netdata-kickstart.sh https://get.netdata.cloud/kickstart.sh && sh /tmp/netdata-kickstart.sh --stable-channel --disable-telemetry

Para abrir su puerto:

sudo ufw allow 19999

Ahora mismo, Netdata es como una ventana abierta por la que cualquiera puede mirar, por eso tenemos que ponerle un "cerrojo" para evitarlo.

Con apache2-utils generamos un archivo de claves.

sudo apt install apache2-utils -y
sudo htpasswd -c /etc/nginx/.netdata-access mariajo
sudo nano /etc/nginx/sites-available/netdata
upstream netdata-backend {
    server 127.0.0.1:19999;
    keepalive 64;
}

server {
    listen 80;
    server_name 209.38.229.247; # O tu dominio whiletruedo.com

    auth_basic "Acceso Protegido - Solo Mariajo";
    auth_basic_user_file /etc/nginx/.netdata-access;

    location / {
        proxy_pass http://netdata-backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Activamos y reiniciamos:

sudo ln -s /etc/nginx/sites-available/netdata /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Ahora le decimos a Netdata que solo escuche a "sí mismo" (localhost):

sudo nano /etc/netdata/netdata.conf
[web]
    bind to = localhost
sudo systemctl restart netdata

Cerramos el puerto en el Firewall para que no esté abierto para todo el mundo:

sudo ufw delete allow 19999

Ahora para entrar a Netdata ya no ponemos el puerto solo nuestra ip y nos pide el usuario y contraseña que hemos establecido antes.