No necesita un panel de control para usar HTTPS. Con Certbot o acme.sh puede obtener certificados gratuitos de Let's Encrypt para cualquier sitio en Nginx, emitir certificados wildcard como *.example.com mediante la API DNS de Cloudflare y renovarlos automáticamente. Esta guía cubre ambas herramientas en Debian/Ubuntu y Rocky Linux/AlmaLinux, la configuración HTTPS de Nginx, los sitios detrás del proxy de Cloudflare y cómo comprobar que la renovación funciona de verdad.
dig +short example.com.Certbot puede solicitar el certificado y editar por usted el bloque server de Nginx, incluida la redirección de HTTP a HTTPS.
# Debian / Ubuntu
apt update
apt install -y certbot python3-certbot-nginx
# Rocky Linux / AlmaLinux (EPEL)
dnf install -y epel-release
dnf install -y certbot python3-certbot-nginx
# Request and install a certificate for the domain and www
certbot --nginx -d example.com -d www.example.com \
--agree-tos -m [email protected] --redirect
# Renewal is scheduled automatically; confirm the timer and run a test renewal
systemctl list-timers | grep -i certbot
certbot renew --dry-run
Los certificados se guardan en /etc/letsencrypt/live/example.com/. Si prefiere no tocar su archivo de Nginx, use certbot certonly --nginx -d example.com y añada usted mismo las rutas del certificado, como se muestra más abajo en la configuración HTTPS de Nginx.
acme.sh es un único script de shell que se ejecuta como tarea cron. Tenga en cuenta que su autoridad de certificación predeterminada es ZeroSSL; cámbiela a Let's Encrypt si lo prefiere.
# Install (creates ~/.acme.sh and a daily cron job)
curl https://get.acme.sh | sh -s [email protected]
source ~/.bashrc
# Use Let's Encrypt as the default CA
acme.sh --set-default-ca --server letsencrypt
# Issue using your site's web root (HTTP-01 validation)
acme.sh --issue -d example.com -d www.example.com -w /var/www/example
# Install the certificate where Nginx expects it and reload Nginx on every renewal
mkdir -p /etc/nginx/ssl
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--reloadcmd "systemctl reload nginx"
No apunte nunca Nginx directamente a archivos dentro de ~/.acme.sh; use siempre --install-cert, que copia los archivos y ejecuta el comando de recarga después de cada renovación.
Los certificados wildcard (*.example.com) requieren validación por DNS. Si su dominio usa el DNS de Cloudflare, cree un token de API en el panel de Cloudflare, en My Profile → API Tokens, con la plantilla "Edit zone DNS" y limitado a la zona que necesite.
# acme.sh: dns_cf reads the token from the environment and saves it for renewals
export CF_Token="your-cloudflare-api-token"
export CF_Zone_ID="your-zone-id" # shown on the domain's Overview page in Cloudflare
acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'
# Certbot alternative
apt install -y python3-certbot-dns-cloudflare
mkdir -p ~/.secrets && chmod 700 ~/.secrets
echo 'dns_cloudflare_api_token = your-cloudflare-api-token' > ~/.secrets/cloudflare.ini
chmod 600 ~/.secrets/cloudflare.ini
certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
-d example.com -d '*.example.com'
La validación por DNS también funciona cuando el puerto 80 está cerrado o el sitio todavía no es accesible, lo que la hace útil para servicios internos y servidores nuevos.
Si emitió el certificado con certonly o con acme.sh, añada usted mismo un bloque server HTTPS. Ajuste las rutas del certificado según la herramienta que haya usado.
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on; # Nginx 1.25.1+; older versions: "listen 443 ssl http2;"
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # acme.sh: /etc/nginx/ssl/example.com.crt
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # acme.sh: /etc/nginx/ssl/example.com.key
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:SSL:10m;
root /var/www/example;
index index.html index.php;
}
nginx -t && systemctl reload nginx
Con la nube naranja activada, la validación HTTP normalmente sigue funcionando, porque Cloudflare reenvía a su servidor las solicitudes a /.well-known/acme-challenge/. Configure el modo SSL/TLS de Cloudflare en Full (strict) en cuanto su servidor de origen tenga un certificado válido; "Flexible" envía el tráfico a su servidor sin cifrar y a menudo provoca bucles de redirección. También puede usar la validación por DNS, o un Origin Certificate gratuito de Cloudflare si el sitio solo se sirve a través de Cloudflare. Para impedir que los visitantes se salten Cloudflare, consulte ocultar la IP de su servidor de origen.
# Expiry date of the certificate your site actually serves
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
# Certbot: all certificates and their expiry
certbot certificates
# acme.sh: list certificates and force a test renewal
acme.sh --list
acme.sh --renew -d example.com --force
El puerto 80 está bloqueado, el registro DNS apunta a otro sitio u otro bloque server responde por el dominio. Revise el firewall, ejecute dig +short example.com y asegúrese de que /.well-known/acme-challenge/ no se redirige ni se deniega en su configuración de Nginx. Si nada de esto funciona, cambie a la validación por DNS.
Let's Encrypt limita cuántos certificados puede emitir por semana para los mismos nombres de dominio. Use --dry-run (Certbot) o --staging (acme.sh) mientras experimenta, y solicite un certificado real solo cuando la configuración funcione.
Sí. Añada cada nombre con su propia opción -d. Los wildcards cubren un solo nivel, así que *.example.com coincide con shop.example.com, pero no con a.shop.example.com ni con el propio example.com; añada el dominio raíz por separado.
¿Sigue sin resolverlo después de seguir estos pasos? Abra un ticket de soporte y el equipo técnico de IMIDC, disponible 24/7, le ayudará. Incluya la IP del servidor, la versión del sistema operativo, su dominio, el comando que ejecutó y la salida completa del error para que podamos localizar el problema más rápido.