Cómo instalé HTTPS en mi servidor y entendí realmente qué estaba pasando (Certbot + Nginx explicado de verdad)

Durante mucho tiempo tuve mi servidor funcionando con un certificado autofirmado. Era suficiente para pruebas, pero no para una web pública. En este post quiero documentar todo el proceso real que he seguido para instalar un certificado válido de Let's Encrypt usando Certbot, activarlo en Nginx, y entender qué significan los archivos .pem que aparecen en el proceso.

Este post no solo explica los pasos, sino también el porqué técnico detrás de cada uno. Si estás montando tu propio servidor casero, esto te va a ahorrar horas.


1. Instalación de Certbot

El primer paso fue instalar Certbot mediante snap, que es el método recomendado por Let's Encrypt. Después de instalarlo, creé un enlace simbólico para poder ejecutarlo desde cualquier ruta del sistema.

sudo snap install --classic certbot sudo ln -s /snap/bin/certbot /usr/local/bin/certbot

Con esto, Certbot quedó listo para solicitar certificados válidos para mi dominio.


2. Solicitar el certificado HTTPS

Certbot tiene varios modos de funcionamiento, pero cuando usas Nginx lo más cómodo es dejar que él detecte automáticamente tus bloques de servidor y genere el certificado.

Ejecuté:

sudo certbot certonly --nginx

Certbot me preguntó qué dominio quería certificar y, tras confirmarlo, generó dos archivos fundamentales:

Ambos se guardan en:

/etc/letsencrypt/live/serherm.hopto.org/

Estos dos archivos son la base de toda la seguridad de HTTPS.


3. ¿Qué son los archivos PEM y por qué son tan importantes?

Cuando activas HTTPS, tu servidor necesita dos piezas esenciales: un certificado público y una clave privada.

Ambos se guardan en formato PEM, que no es más que texto codificado en Base64 con cabeceras como:

-----BEGIN CERTIFICATE----- -----BEGIN PRIVATE KEY-----

3.1. fullchain.pem — Certificado público + cadena de confianza

Este archivo contiene:

Es lo que el navegador recibe cuando visita tu web. Permite verificar que tu dominio es auténtico y que ha sido firmado por una autoridad reconocida (Let's Encrypt).

3.2. privkey.pem — Clave privada del servidor

Este archivo contiene tu clave privada. Es el archivo más sensible del servidor.

Su función es descifrar la clave de sesión que el navegador envía durante el handshake TLS. Sin esta clave, tu servidor no podría establecer una conexión segura.

Si alguien obtuviera este archivo, podría suplantar tu web. Por eso nunca debe salir del servidor.


4. Cómo funciona realmente el handshake TLS

Para entender por qué HTTPS necesita estos archivos, es útil ver cómo se establece la conexión segura:

  1. El navegador envía un mensaje llamado ClientHello con sus parámetros de cifrado.
  2. Nginx responde enviando el certificado contenido en fullchain.pem.
  3. El navegador valida el certificado y genera una clave de sesión aleatoria.
  4. Esa clave se cifra con la clave pública del certificado.
  5. Nginx la descifra usando privkey.pem.
  6. A partir de ese momento, ambos comparten una clave simétrica y toda la comunicación se cifra con AES.

Este proceso garantiza:

HTTPS no es solo un candado: es criptografía funcionando en tiempo real.


5. Activar el certificado en Nginx

Una vez generado el certificado, solo tuve que modificar mi bloque HTTPS de Nginx para que usara los archivos PEM de Let's Encrypt.

El bloque quedó así:

''' server { listen 443 ssl; server_name serherm.hopto.org;

ssl_certificate /etc/letsencrypt/live/serherm.hopto.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/serherm.hopto.org/privkey.pem;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;

root /var/www/main_web;
index index.html;

location /static/ {
    alias /var/www/main_web/static/;
}

location / {
    proxy_pass http://127.0.0.1:8000;
    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;
}

} '''

Este bloque:

Después de editarlo, solo tuve que probar y recargar Nginx:

sudo nginx -t sudo systemctl reload nginx


6. Renovación automática

Certbot instala un servicio que renueva los certificados automáticamente antes de que caduquen. Puedes comprobarlo con:

sudo certbot renew --dry-run

Esto garantiza que tu web nunca se quede sin HTTPS.


7. Conclusión

Con este proceso:

Ahora mi servidor ofrece una conexión segura, moderna y confiable. Y lo más importante: entiendo realmente qué está pasando detrás del candado verde.