Todo sitio web que sirve tráfico en internet debería usar HTTPS. Más allá de cifrar los datos en tránsito entre tus visitantes y tu servidor, HTTPS es un factor de posicionamiento para los motores de búsqueda, un requisito para APIs web modernas como HTTP/2 y service workers, y una señal de confianza que los navegadores muestran prominentemente. Let’s Encrypt ha eliminado completamente la barrera de costo proporcionando certificados SSL/TLS gratuitos y automatizados, y Certbot es la herramienta más utilizada para obtenerlos y administrarlos.

Esta guía cubre todo lo que necesitas saber para configurar Certbot con Nginx o Apache, automatizar la renovación de certificados, obtener certificados wildcard y endurecer tu configuración HTTPS con encabezados de seguridad.

Requisitos previos

Antes de comenzar, asegúrate de tener:

  • Un servidor Ubuntu (22.04 o 24.04) con una dirección IP pública
  • Un nombre de dominio registrado con registros DNS A apuntando a tu servidor
  • Nginx o Apache instalado y sirviendo tu sitio web
  • Acceso por terminal con privilegios sudo
  • Puerto 80 (HTTP) y puerto 443 (HTTPS) abiertos en tu firewall

Por qué HTTPS importa

Aquí está por qué todo administrador de sistemas debería priorizar HTTPS:

  • Cifrado: HTTPS cifra todo el tráfico entre el cliente y el servidor, protegiendo credenciales de inicio de sesión, datos personales y cookies de sesión contra espionaje
  • Autenticación: Los certificados SSL/TLS verifican que los visitantes se están comunicando con tu servidor real, no con un impostor
  • Integridad de datos: HTTPS previene que atacantes intermediarios modifiquen datos en tránsito
  • Posicionamiento SEO: Google usa HTTPS como señal de posicionamiento. Los sitios sin HTTPS están en desventaja en los resultados de búsqueda
  • Confianza del navegador: Los navegadores modernos muestran advertencias de “No seguro” en páginas HTTP, especialmente aquellas con formularios
  • Cumplimiento: Muchas regulaciones (GDPR, PCI DSS, HIPAA) requieren cifrado de datos en tránsito

¿Qué es Let’s Encrypt?

Let’s Encrypt es una Autoridad de Certificación (CA) gratuita, automatizada y abierta operada por el Internet Security Research Group (ISRG). Emite certificados de Validación de Dominio (DV) que son confiados por todos los navegadores y sistemas operativos principales.

Características clave:

  • Gratuito: Sin costo por los certificados
  • Automatizado: Los certificados se pueden obtener y renovar sin intervención manual
  • De corta duración: Los certificados son válidos por 90 días, fomentando la renovación automatizada y reduciendo el impacto de la compromisión de claves
  • Con límite de tasa: Hay límites en cuántos certificados puedes solicitar por dominio por semana (50 certificados por dominio registrado por semana)

Instalando Certbot

Certbot es el cliente oficial de Let’s Encrypt. El método de instalación recomendado es vía snap, que asegura que siempre tengas la última versión:

# Eliminar cualquier certbot empaquetado del SO para evitar conflictos
sudo apt-get remove certbot

# Instalar Certbot vía snap
sudo snap install --classic certbot

# Crear un enlace simbólico para que certbot esté disponible en tu PATH
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Verifica la instalación:

certbot --version

Obtener certificados para Nginx

Configuración automática (Recomendada)

Certbot puede obtener automáticamente el certificado y modificar tu configuración de Nginx para habilitar HTTPS. Este es el enfoque más simple:

sudo certbot --nginx -d knowledgexchange.xyz -d www.knowledgexchange.xyz

Certbot:

  1. Verificará que controlas el dominio colocando un archivo de desafío en tu servidor
  2. Obtendrá el certificado de Let’s Encrypt
  3. Modificará tu bloque de servidor Nginx para habilitar SSL/TLS
  4. Configurará una redirección de HTTP a HTTPS

Se te pedirá que ingreses tu dirección de correo electrónico (para notificaciones de renovación) y que aceptes los términos de servicio.

Después de completarse, tu configuración de Nginx se actualizará automáticamente. Puedes verificar los cambios:

sudo nginx -t
sudo systemctl reload nginx

Consejo: Siempre ejecuta nginx -t para probar la sintaxis de la configuración antes de recargar. Un error de sintaxis puede dejar tu sitio fuera de línea.

Qué agrega Certbot a tu configuración de Nginx

Certbot agrega líneas similares a estas en tu bloque de servidor:

server {
    listen 443 ssl;
    server_name knowledgexchange.xyz www.knowledgexchange.xyz;

    ssl_certificate /etc/letsencrypt/live/knowledgexchange.xyz/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/knowledgexchange.xyz/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    # ... tu configuración existente
}

server {
    listen 80;
    server_name knowledgexchange.xyz www.knowledgexchange.xyz;
    return 301 https://$host$request_uri;
}

Para más detalles sobre la configuración de Nginx, consulta nuestros artículos sobre instalar Nginx y mejorar el rendimiento SSL en Nginx.

Modo Certonly (Configuración manual)

Si prefieres configurar Nginx tú mismo, usa el subcomando certonly para obtener el certificado sin modificar ninguna configuración:

sudo certbot certonly --nginx -d knowledgexchange.xyz -d www.knowledgexchange.xyz

Los certificados se guardarán en /etc/letsencrypt/live/knowledgexchange.xyz/ y puedes referenciarlos en tu configuración de Nginx manualmente.

Obtener certificados para Apache

El proceso para Apache es casi idéntico. Instala el plugin de Certbot para Apache si no está disponible:

sudo apt install -y python3-certbot-apache

Luego ejecuta Certbot con el flag --apache:

sudo certbot --apache -d knowledgexchange.xyz -d www.knowledgexchange.xyz

Certbot:

  1. Verificará la propiedad del dominio
  2. Obtendrá el certificado
  3. Actualizará la configuración de tu virtual host de Apache
  4. Habilitará el módulo SSL y creará una redirección

Verifica y recarga Apache:

sudo apachectl configtest
sudo systemctl reload apache2

Para el modo certonly con Apache:

sudo certbot certonly --apache -d knowledgexchange.xyz -d www.knowledgexchange.xyz

Modo Standalone

Si no estás ejecutando Nginx o Apache, o si quieres obtener certificados independientemente de cualquier servidor web, usa el modo standalone. Certbot iniciará temporalmente su propio servidor web en el puerto 80:

sudo certbot certonly --standalone -d knowledgexchange.xyz -d www.knowledgexchange.xyz

Importante: El puerto 80 debe estar disponible. Si Nginx o Apache están ejecutándose, detenlos primero:

sudo systemctl stop nginx  # o apache2
sudo certbot certonly --standalone -d knowledgexchange.xyz
sudo systemctl start nginx  # o apache2

El modo standalone es particularmente útil para servicios no web que necesitan certificados TLS, como servidores de correo o endpoints VPN.

Configurar la renovación automática

Los certificados de Let’s Encrypt expiran después de 90 días, por lo que la renovación automatizada es esencial. La buena noticia es que Certbot instala un timer de systemd (o trabajo cron) automáticamente que se ejecuta dos veces al día y renueva cualquier certificado que esté dentro de los 30 días de expiración.

Verifica que el timer esté activo:

sudo systemctl status certbot.timer

Deberías ver active (waiting) en la salida. También puedes listar los timers programados:

sudo systemctl list-timers | grep certbot

Probar la renovación automática

Siempre prueba que la renovación funcionará correctamente antes de depender de ella:

sudo certbot renew --dry-run

Esto simula el proceso de renovación sin obtener certificados nuevos realmente. Si la prueba seca tiene éxito, tu renovación automática está correctamente configurada.

Hooks post-renovación

Después de que un certificado es renovado, tu servidor web necesita recargar el nuevo certificado. Certbot maneja esto automáticamente para los plugins de Nginx y Apache, pero si usaste el modo certonly, necesitas agregar un hook de renovación:

sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh << 'EOF'
#!/bin/bash
systemctl reload nginx
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

Para Apache:

sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-apache.sh << 'EOF'
#!/bin/bash
systemctl reload apache2
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-apache.sh

Certificados wildcard con desafío DNS

Los certificados wildcard cubren todos los subdominios de un dominio (por ejemplo, *.knowledgexchange.xyz). Solo se pueden obtener usando el desafío DNS-01, que requiere que crees un registro TXT de DNS específico.

Desafío DNS manual

sudo certbot certonly --manual --preferred-challenges dns \
  -d knowledgexchange.xyz -d "*.knowledgexchange.xyz"

Certbot mostrará un registro TXT que necesitas agregar a tu configuración DNS:

Please deploy a DNS TXT record under the name:
_acme-challenge.knowledgexchange.xyz

with the following value:
dGhpcyBpcyBhIHRlc3Qgc3RyaW5n

Before continuing, verify the record is deployed.

Agrega el registro TXT a través del panel de control de tu proveedor DNS, espera la propagación (generalmente 1-5 minutos), luego presiona Enter para continuar.

Nota: Los desafíos DNS manuales no se pueden renovar automáticamente. Para renovación automatizada de wildcards, usa un plugin DNS.

Desafío DNS automatizado con plugins

Certbot tiene plugins para muchos proveedores DNS que automatizan la creación del registro TXT. Por ejemplo, con Cloudflare:

# Instalar el plugin DNS de Cloudflare
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare

Crea un archivo de credenciales:

sudo mkdir -p /etc/letsencrypt/cloudflare
sudo tee /etc/letsencrypt/cloudflare/credentials.ini << 'EOF'
dns_cloudflare_api_token = TU_TOKEN_API_CLOUDFLARE
EOF
sudo chmod 600 /etc/letsencrypt/cloudflare/credentials.ini

Obtén el certificado wildcard:

sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
  -d knowledgexchange.xyz -d "*.knowledgexchange.xyz"

Este método soporta renovación completamente automatizada ya que Certbot puede crear y limpiar los registros DNS programáticamente.

Monitoreo de certificados

Es importante monitorear tus certificados para detectar fallos de renovación antes de que causen interrupciones.

Verificar la expiración del certificado

# Verificar todos los certificados administrados
sudo certbot certificates

# Verificar el certificado de un dominio específico desde el exterior
echo | openssl s_client -servername knowledgexchange.xyz -connect knowledgexchange.xyz:443 2>/dev/null | openssl x509 -noout -dates

Configurar alertas de expiración

Crea un script de monitoreo simple:

sudo tee /usr/local/bin/check-certs.sh << 'SCRIPT'
#!/bin/bash
THRESHOLD_DAYS=14
ALERT_EMAIL="[email protected]"

for cert_dir in /etc/letsencrypt/live/*/; do
    domain=$(basename "$cert_dir")
    expiry_date=$(openssl x509 -enddate -noout -in "${cert_dir}fullchain.pem" | cut -d= -f2)
    expiry_epoch=$(date -d "$expiry_date" +%s)
    current_epoch=$(date +%s)
    days_remaining=$(( (expiry_epoch - current_epoch) / 86400 ))

    if [ "$days_remaining" -lt "$THRESHOLD_DAYS" ]; then
        echo "WARNING: Certificate for $domain expires in $days_remaining days" | \
            mail -s "SSL Certificate Expiration Warning: $domain" "$ALERT_EMAIL"
    fi
done
SCRIPT
sudo chmod +x /usr/local/bin/check-certs.sh

Agrégalo a cron para ejecutarse diariamente:

echo "0 8 * * * root /usr/local/bin/check-certs.sh" | sudo tee /etc/cron.d/check-ssl-certs

Agregar encabezados de seguridad

Tener HTTPS es solo parte de la ecuación. También deberías configurar encabezados de seguridad para maximizar la protección. Agrega estos a tu bloque de servidor Nginx:

# HTTP Strict Transport Security - indica a los navegadores que siempre usen HTTPS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

# Prevenir MIME type sniffing
add_header X-Content-Type-Options "nosniff" always;

# Prevenir clickjacking
add_header X-Frame-Options "SAMEORIGIN" always;

# Habilitar filtro XSS en navegadores antiguos
add_header X-XSS-Protection "1; mode=block" always;

# Controlar información del referrer
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# Content Security Policy (personalizar para tu sitio)
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';" always;

# Permissions Policy
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

Para Apache, agrega encabezados equivalentes en tu virtual host o .htaccess:

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"

Importante: Antes de habilitar HSTS con preload, asegúrate de que tu dominio completo funcione sobre HTTPS. Una vez precargado, los navegadores se negarán a conectar por HTTP, y eliminar tu dominio de la lista de precarga toma meses.

Solución de problemas comunes

El puerto 80 está bloqueado

El desafío HTTP-01 de Certbot requiere que el puerto 80 sea accesible desde internet. Si está bloqueado:

# Verificar si el puerto 80 está abierto en UFW
sudo ufw status | grep 80

# Permitir el puerto 80 si está bloqueado
sudo ufw allow 80/tcp

# Verificar si algo más está usando el puerto 80
sudo ss -tlnp | grep :80

Si tu proveedor de hosting o ISP bloquea el puerto 80, usa el método de desafío DNS en su lugar.

DNS no propagado

Si Certbot falla con un error relacionado con DNS, el registro A de tu dominio puede no estar apuntando al servidor todavía:

# Verificar la resolución DNS
dig +short knowledgexchange.xyz
nslookup knowledgexchange.xyz

# La IP devuelta debería coincidir con la IP pública de tu servidor
curl -s https://ifconfig.me

Los cambios de DNS pueden tardar hasta 48 horas en propagarse globalmente, aunque la mayoría de la propagación ocurre en minutos. Espera e intenta de nuevo.

Límite de tasa excedido

Si has excedido los límites de tasa de Let’s Encrypt, recibirás un error. No hay forma de reiniciar el límite. Debes esperar hasta que la ventana del límite se reinicie (típicamente una semana). Para evitar alcanzar los límites de tasa:

  • Usa --dry-run para pruebas
  • Usa el entorno de staging para desarrollo: --staging
  • Consolida múltiples subdominios en un solo certificado usando flags -d o un wildcard

La renovación del certificado falla silenciosamente

Si la renovación automática no está funcionando, revisa los logs de Certbot:

sudo cat /var/log/letsencrypt/letsencrypt.log

Causas comunes:

  • El puerto 80 ya no es accesible (el firewall o la configuración del servidor web cambió)
  • Los registros DNS fueron modificados
  • El snap de Certbot está desactualizado: sudo snap refresh certbot

Probar tu configuración SSL

Después de configurar HTTPS, prueba tu configuración usando herramientas externas:

# Prueba rápida desde la línea de comandos
curl -vI https://knowledgexchange.xyz 2>&1 | grep -E "(SSL|subject|expire|issuer)"

Para un análisis completo, visita SSL Labs Server Test e ingresa tu dominio. Apunta a una calificación A+ habilitando HSTS y usando conjuntos de cifrado fuertes.

Conclusión

Let’s Encrypt y Certbot han hecho que los certificados SSL/TLS sean accesibles para todos. Con emisión y renovación automatizadas, no hay excusa para servir cualquier sitio web sobre HTTP plano. Siguiendo esta guía, has configurado certificados gratuitos con renovación automática y endurecido tu configuración HTTPS con encabezados de seguridad.

Para temas relacionados, consulta nuestros artículos sobre mover un sitio web Nginx a HTTPS/SSL, mejorar el rendimiento SSL en Nginx y crear certificados autofirmados en Ubuntu para entornos de desarrollo. Si necesitas entender qué servidor web elegir, consulta nuestra comparación de Apache vs. Nginx.