Cliente ACME Lego - WildCard SSL
Una guía detallada para desplegar un certificado SSL WildCard tipo estrella mediante el cliente ACME Lego y la validación API DNS con el hosting web VEDOS. El procedimiento está pensado para certificados del tipo example.com y *.example.com, donde la renovación debe ser automática sin introducir manualmente los registros TXT. La guía usa un certificado ACME de la autoridad de certificación Certum. El certificado utilizado sirve solo como ejemplo – el principio de funcionamiento y el procedimiento de despliegue ACME son los mismos para todas las autoridades de certificación.
La guía usa una sintaxis verificada en Lego 5.2.2. Lego v5 cambió algunos parámetros respecto a versiones anteriores, por lo que en caso de un error como flag provided but not defined verifica la sintaxis correcta con lego accounts register --help, lego run --help o lego --help.
Contenido del artículo
- Instalación de Lego
- Proveedor de API DNS
- Archivos de configuración de Lego
- Emisión del certificado
- Despliegue en Apache
- Renovación automática
- Errores comunes
Conceptos básicos
- ACME – protocolo para la emisión y renovación automatizadas de certificados SSL/TLS.
- Lego – un cliente ACME escrito en Go. Puede realizar validación DNS a través de muchos proveedores de DNS (lista de proveedores de DNS compatibles).
- DNS-01 – validación mediante el registro DNS TXT
_acme-challenge. Es necesaria para los certificados WildCard. - EAB kid + hmac – datos de External Account Binding (EAB) de la autoridad de certificación. Vinculan Certbot a una cuenta o producto.
- VEDOS WAPI – la interfaz API de VEDOS a través de la cual Lego crea y elimina los registros DNS TXT.
- Servicio systemd - un archivo de configuración que indica al sistema Linux cómo iniciar una aplicación y mantenerla en ejecución incluso después de reiniciar el servidor.
En todos los ejemplos mostrados, sustituye el dominio example.com por tu propio dominio.
Instalación de Lego
apt update
apt install -y curl tar
cd /tmp
LEGO_URL=$(curl -s https://api.github.com/repos/go-acme/lego/releases/latest | sed -n 's/.*"browser_download_url": "\(.*linux_amd64.tar.gz\)".*/\1/p' | head -n1)
echo "$LEGO_URL"
curl -L -o lego.tar.gz "$LEGO_URL"
tar -xzf lego.tar.gz
install -m 0755 lego /usr/local/bin/lego
lego --version
Tras una instalación correcta, recomendamos eliminar los archivos temporales.
rm -f /tmp/lego /tmp/lego.tar.gz /tmp/LICENSE /tmp/CHANGELOG.md
| Comando / valor | Qué hace / qué sustituir |
|---|---|
apt update |
Actualiza la lista de paquetes. |
apt install -y curl tar |
Instala las herramientas para descargar y extraer Lego. |
LEGO_URL=... |
Encuentra la URL del último paquete de la versión Linux amd64. |
curl -L -o lego.tar.gz |
Descarga el archivo comprimido de Lego. |
tar -xzf lego.tar.gz |
Extrae el archivo comprimido. |
install -m 0755 lego /usr/local/bin/lego |
Instala Lego como un comando ejecutable del sistema. |
lego --version |
Verifica la versión instalada de Lego. |
Proveedor de API DNS
Esta guía usa la API DNS del registrador de dominios Vedos, que ofrece una API para gestionar el DNS de los dominios registrados. Para el hosting web de Vedos, necesitas activar WAPI y también rellenar las direcciones IP permitidas y la contraseña WAPI.
El cliente LEGO es compatible con cientos de otros proveedores de DNS.
Puedes encontrar su lista en el sitio web de LEGO - lista de proveedores de DNS compatibles.
Direcciones IP del servidor VPS
curl -4 ifconfig.me
curl -6 ifconfig.me
| Comando / valor | Qué hace / qué sustituir |
|---|---|
curl -4 ifconfig.me |
Muestra la dirección IPv4 pública del servidor, que debe permitirse en VEDOS WAPI. |
curl -6 ifconfig.me |
Muestra la dirección IPv6 pública del servidor, si el VPS usa una. Es recomendable permitir también esta dirección en VEDOS WAPI. |
En el campo Direcciones IP permitidas, introduce todas las direcciones IP salientes de tu servidor, normalmente tanto IPv4 como IPv6. Los valores se separan con un espacio. VEDOS solo permite peticiones API desde las direcciones IP indicadas.
Importante: Si permites solo IPv4 y alguna petición API sale por IPv6, la emisión del certificado puede tener éxito, pero la limpieza de los registros TXT fallará con el error Access not allowed from this IP address.
Valores recomendados para el proveedor de DNS VEDOS
| Campo | Valor recomendado |
|---|---|
| Activar WAPI | Activado |
| Direcciones IP permitidas | La dirección IPv4 pública del VPS y, si procede, la IPv6 |
| Método de notificación | Cola POLL |
| Protocolo preferido | JSON |
| Contraseña | La contraseña WAPI generada, no la contraseña de administración habitual |
Apache, webroot
La configuración básica de Apache es una parte de apoyo. La validación DNS se realiza a través de la API DNS, no por HTTP, pero el vhost de Apache es necesario para servir el sitio web después de emitir el certificado.
›› Mostrar/Ocultar secciónAntes de ejecutar, sustituye el valor example.com en la línea DOMAIN="example.com" por tu propio dominio sin el asterisco. La variable $DOMAIN se usa luego en los siguientes comandos para las rutas, el vhost de Apache y la página de prueba.
cd /var/www
apt update
apt install -y apache2
systemctl enable --now apache2
a2enmod rewrite headers ssl
systemctl reload apache2
DOMAIN="example.com"
mkdir -p /var/www/$DOMAIN/public
chown -R www-data:www-data /var/www/$DOMAIN
chmod -R 755 /var/www/$DOMAIN
echo "OK $DOMAIN" > /var/www/$DOMAIN/public/index.html
| Comando / valor | Qué hace / qué sustituir |
|---|---|
cd /var/www |
Cambia al directorio donde normalmente se guardan los archivos web. |
apt update |
Actualiza la lista de paquetes. |
apt install -y apache2 |
Instala Apache; -y confirma automáticamente la instalación. |
systemctl enable --now apache2 |
Habilita Apache al arrancar el servidor y lo inicia al mismo tiempo. |
a2enmod rewrite headers ssl |
Habilita los módulos para redirecciones, cabeceras y HTTPS. |
DOMAIN="example.com" |
Establece la variable del dominio. Sustituye example.com por tu propio dominio. |
mkdir/chown/chmod/echo |
Crea el webroot, establece los permisos para Apache y guarda una página de prueba sencilla. |
Vhost HTTP para el apex y los subdominios:
cat > /etc/apache2/sites-available/$DOMAIN.conf <<EOF
<VirtualHost *:80>
ServerName $DOMAIN
ServerAlias *.$DOMAIN
DocumentRoot /var/www/$DOMAIN/public
<Directory /var/www/$DOMAIN/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog \${APACHE_LOG_DIR}/${DOMAIN}_error.log
CustomLog \${APACHE_LOG_DIR}/${DOMAIN}_access.log combined
</VirtualHost>
EOF
a2ensite $DOMAIN.conf
apache2ctl configtest
systemctl reload apache2
curl -I http://$DOMAIN
| Comando / valor | Qué hace / qué sustituir |
|---|---|
cat > ... <<EOF |
Escribe un nuevo vhost HTTP de Apache en un archivo en sites-available. |
ServerName $DOMAIN |
El dominio principal del virtual host. |
ServerAlias *.$DOMAIN |
Permite el manejo de cualquier subdominio de primer nivel. |
DocumentRoot |
El directorio desde el que Apache sirve el contenido. |
a2ensite $DOMAIN.conf |
Habilita el vhost. |
apache2ctl configtest |
Verifica la sintaxis de la configuración de Apache. |
curl -I http://$DOMAIN |
Verifica la respuesta HTTP del dominio. |
Archivos de configuración de Lego
El enfoque recomendado para Lego v5 es almacenar la configuración en un archivo de configuración. Así, el servicio systemd no necesita contener un comando largo con dominios, el proveedor de DNS y hooks.
Archivo de configuración .env
El archivo .env es un archivo de configuración de texto en el que se almacenan variables de entorno, por ejemplo credenciales de acceso, claves de API o ajustes de la aplicación. Para mayor claridad, puedes nombrar el archivo proveedor-dominio.env. El archivo vedos-example.com.env contendrá las credenciales de acceso de VEDOS WAPI, por lo que lo guardamos en /etc/lego y le establecemos permisos restringidos.
DOMAIN="example.com"
mkdir -p /etc/lego/$DOMAIN
nano /etc/lego/vedos-$DOMAIN.env
| Comando / valor | Qué hace / qué sustituir |
|---|---|
DOMAIN="example.com" |
Establece el dominio para los siguientes comandos. Sustitúyelo por tu propio dominio. |
mkdir -p /etc/lego/$DOMAIN |
Crea el directorio para los datos y la configuración de Lego del dominio indicado. |
nano /etc/lego/vedos-$DOMAIN.env |
Abre el archivo para las variables de la API de VEDOS. |
En la configuración de abajo, sustituye WEDOS_LOGIN por tu login de VEDOS y WEDOS_WAPI_PASSWORD por la contraseña generada en VEDOS WAPI. Puedes dejar los valores de timeout e interval tal como están.
WEDOS_USERNAME='WEDOS_LOGIN'
WEDOS_WAPI_PASSWORD='WEDOS_WAPI_PASSWORD'
WEDOS_PROPAGATION_TIMEOUT=3600
WEDOS_POLLING_INTERVAL=30
WEDOS_TTL=300
| Comando / valor | Qué hace / qué sustituir |
|---|---|
WEDOS_USERNAME |
El login de VEDOS de la cuenta que gestiona la zona DNS. |
WEDOS_WAPI_PASSWORD |
La contraseña WAPI generada en la administración de VEDOS. |
WEDOS_PROPAGATION_TIMEOUT |
El tiempo máximo de espera para la propagación DNS en segundos. |
WEDOS_POLLING_INTERVAL |
El intervalo entre comprobaciones de la propagación DNS. |
WEDOS_TTL |
El TTL de los registros TXT creados para el desafío ACME. |
chmod 600 /etc/lego/vedos-$DOMAIN.env
Archivo de configuración lego.yml
El archivo .yml es un archivo de configuración de texto en formato YAML, usado para una notación clara de ajustes, parámetros y datos estructurados. Antes de guardar la configuración YAML, sustituye example.com por tu propio dominio, *.example.com por el nombre comodín, vas@email.cz por tu correo de contacto y los valores KID / HMAC por los datos de tu pedido de certificado ACME. Nombres como certum-example o example-com-wildcard son etiquetas internas; puedes dejarlos, pero con varios dominios es recomendable renombrarlos según el dominio.
mkdir /etc/lego/$DOMAIN
nano /etc/lego/$DOMAIN/lego.yml
storage: /etc/lego/example.com
accounts:
certum-example:
server: certum
email: vas@email.cz
acceptsTermsOfService: true
eab:
kid: KID
hmacKey: HMAC
servers:
certum:
url: https://acme.certum.pl/directory
challenges:
vedos-dns:
dns:
provider: vedos
envFile: /etc/lego/vedos-example-com.env
resolvers:
- 1.1.1.1:53
certificates:
example-com-wildcard:
account: certum-example
challenge: vedos-dns
domains:
- example.com
- "*.example.com"
renew:
days: 30
hooks:
deploy:
command: systemctl reload apache2
| Comando / valor | Qué hace / qué sustituir |
|---|---|
storage |
Directorio para la cuenta de Lego, los certificados y los metadatos. |
accounts |
Definición de la cuenta ACME, incluidos el e-mail y los datos EAB. |
servers.certum.url |
El endpoint ACME de Certum. |
challenges.vedos-dns |
Validación DNS-01 a través del proveedor VEDOS. |
envFile |
El archivo con las credenciales de acceso de la API de VEDOS. |
certificates |
Lista de certificados que Lego debe gestionar. |
domains |
El dominio apex y el dominio comodín del certificado. |
renew.days |
Cuántos días antes de la caducidad debe renovar Lego. |
hooks.deploy.command |
Comando tras una emisión o renovación correcta, aquí la recarga de Apache. |
chmod 600 /etc/lego/$DOMAIN/lego.yml
El archivo lego.yml contiene el EAB HMAC, por lo que debe tener permisos restringidos. En la documentación para clientes, usa solo marcadores de posición.
Emisión del certificado
Antes de ejecutar, sustituye example.com en la ruta por el dominio que usaste al crear el directorio. La primera ejecución crea la cuenta ACME, establece los registros DNS TXT a través de la API DNS, realiza la validación DNS-01 y guarda el certificado.
lego --config /etc/lego/$DOMAIN/lego.yml
Mientras espera, Lego puede imprimir:
dns01: waiting for record propagation timeout=1h0m0s interval=30s
| Comando / valor | Qué hace / qué sustituir |
|---|---|
lego --config |
Ejecuta Lego según el archivo de configuración. En la primera ejecución emite el certificado, en las siguientes gestiona la renovación. |
dns01: waiting for record propagation |
Lego ha creado el registro TXT y espera hasta que sea visible en el DNS. |
timeout=1h0m0s |
Espera como máximo una hora. |
interval=30s |
Comprueba el DNS cada 30 segundos. |
Esto significa que Lego comprueba el DNS cada 30 segundos y espera como máximo 1 hora. Tras el éxito, verifica los archivos:
ls -la /etc/lego/$DOMAIN/certificates/
El directorio certificates/ contiene el .crt emitido, la .key, los certificados intermedios de la autoridad de certificación y los metadatos.
Procedimiento CLI alternativo para Lego v5
›› Mostrar/Ocultar secciónSi no usas un archivo de configuración, en Lego v5 el EAB se introduce durante el registro de la cuenta. Antes de ejecutar, sustituye example.com por tu propio dominio, vas@email.cz por tu propio e-mail y KID / HMAC por los valores de tu pedido.
lego accounts register \
--path /etc/lego/example.com \
--server https://acme.certum.pl/directory \
--email vas@email.cz \
--accept-tos \
--eab \
--eab.kid 'KID' \
--eab.hmac 'HMAC'
| Comando / valor | Qué hace / qué sustituir |
|---|---|
lego accounts register |
Registra la cuenta ACME manualmente a través de la CLI sin lego.yml. |
--path |
Directorio para la cuenta y los certificados. |
--server |
Endpoint ACME de Certum. |
--email |
E-mail de contacto. |
--accept-tos |
Acuerdo con los términos del servicio. |
--eab |
Habilita External Account Binding. |
--eab.kid / --eab.hmac |
Datos EAB de CertManager. |
Listado de cuentas. En la ruta, usa de nuevo el mismo dominio que en el comando anterior:
lego accounts list --path /etc/lego/example.com
Emisión del certificado ahora sin los parámetros EAB. Sustituye example.com por tu propio dominio y *.example.com por el nombre comodín.
set -a
. /etc/lego/vedos-example.com.env
set +a
lego run \
--path /etc/lego/example.com \
--server https://acme.certum.pl/directory \
--email vas@email.cz \
--dns vedos \
--dns.resolvers 1.1.1.1:53 \
--domains example.com \
--domains '*.example.com'
| Comando / valor | Qué hace / qué sustituir |
|---|---|
set -a |
Exporta automáticamente las variables cargadas del archivo. |
. /etc/lego/vedos-example.com.env |
Carga las variables de la API de VEDOS en la shell actual. |
set +a |
Desactiva la exportación automática de variables. |
lego run |
Emite o renueva el certificado sin un archivo de configuración. |
--dns vedos |
Usa la API DNS. |
--domains |
Los dominios que estarán en el certificado. |
Despliegue del certificado en Apache
Antes de crear el vhost HTTPS, sustituye example.com por tu propio dominio en el nombre del archivo, en los valores ServerName y ServerAlias, en las rutas del webroot y en las rutas del certificado. Estas rutas deben coincidir con el dominio usado en la configuración de Lego.
cat > /etc/apache2/sites-available/example.com-le-ssl.conf <<'EOF'
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName example.com
ServerAlias *.example.com
DocumentRoot /var/www/example.com/public
<Directory /var/www/example.com/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
SSLEngine on
SSLCertificateFile /etc/lego/example.com/certificates/example.com.crt
SSLCertificateKeyFile /etc/lego/example.com/certificates/example.com.key
ErrorLog ${APACHE_LOG_DIR}/example.com_ssl_error.log
CustomLog ${APACHE_LOG_DIR}/example.com_ssl_access.log combined
</VirtualHost>
</IfModule>
EOF
a2ensite example.com-le-ssl.conf
apache2ctl configtest
systemctl reload apache2
curl -I https://example.com
curl -I https://test.example.com
| Comando / valor | Qué hace / qué sustituir |
|---|---|
cat > ...-le-ssl.conf |
Crea el vhost HTTPS de Apache. |
ServerName / ServerAlias |
Especifica el dominio apex y los subdominios comodín. |
SSLCertificateFile |
Ruta al certificado de Lego. |
SSLCertificateKeyFile |
Ruta a la clave privada de Lego. |
a2ensite |
Habilita el vhost HTTPS. |
systemctl reload apache2 |
Recarga la nueva configuración de Apache. |
curl -I https://... |
Verifica la respuesta HTTPS. |
Renovación automática
Lego puede renovar el certificado, pero tras la instalación no crea un timer systemd por sí mismo. La ejecución periódica se configura mediante un service y un timer personalizados. Antes de insertarlo, sustituye example-com en el nombre del service/timer por tu propio nombre seguro sin puntos, por ejemplo mojedomena-cz, y sustituye example.com en la ruta de configuración por tu propio dominio.
cat > /etc/systemd/system/lego-example-com-renew.service <<'EOF'
[Unit]
Description=Renew Certum WildCard SSL for example.com using Lego and VEDOS DNS
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/lego --config /etc/lego/example.com/lego.yml
EOF
cat > /etc/systemd/system/lego-example-com-renew.timer <<'EOF'
[Unit]
Description=Daily Lego renewal check for example.com
[Timer]
OnCalendar=*-*-* 03:20:00
RandomizedDelaySec=1800
Persistent=true
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable --now lego-example-com-renew.timer
systemctl list-timers | grep lego
| Comando / valor | Qué hace / qué sustituir |
|---|---|
lego-example-com-renew.service |
Servicio systemd para una ejecución única de Lego renew/run. |
Type=oneshot |
El servicio se inicia, realiza su trabajo y finaliza. |
ExecStart |
Ejecuta Lego según lego.yml. |
lego-example-com-renew.timer |
Timer systemd que ejecuta el servicio de forma periódica. |
OnCalendar |
Hora de la comprobación diaria. |
RandomizedDelaySec |
Retardo aleatorio para que las peticiones no se inicien todas exactamente al mismo tiempo. |
Persistent=true |
Ejecuta una ejecución omitida después de que arranque el servidor. |
systemctl enable --now |
Habilita el timer y lo activa de inmediato. |
Prueba segura del servicio:
systemctl start lego-example-com-renew.service
journalctl -u lego-example-com-renew.service -n 100 --no-pager
| Comando / valor | Qué hace / qué sustituir |
|---|---|
systemctl start ...service |
Ejecuta manualmente el servicio de renovación como prueba. |
journalctl -u ... |
Muestra los últimos logs del servicio. |
Si el certificado no está próximo a caducar, Lego puede informar de que la renovación no es necesaria. Este es el comportamiento correcto.
Errores comunes
Parámetro desconocido en Lego
En Lego v5 los parámetros EAB son --eab.kid y --eab.hmac. Los parámetros siempre pertenecen a un subcomando específico.
lego accounts register --help
lego accounts list --help
lego run --help
La limpieza de los registros TXT falla por una IP no permitida
Cleaning up failed ... Access not allowed from this IP address (2a02:...)
Añade también la dirección IPv6 del servidor a las direcciones IP permitidas en VEDOS WAPI. El certificado puede emitirse correctamente, pero los registros TXT permanecerán en el DNS después de la validación.
Lista de verificación
dig TXT _acme-challenge.example.com +short
lego --config /etc/lego/example.com/lego.yml
systemctl status lego-example-com-renew.timer
apache2ctl configtest
curl -I https://example.com
| Comando / valor | Qué hace / qué sustituir |
|---|---|
dig TXT |
Verifica los registros TXT en el DNS. |
lego --config |
Ejecuta la configuración de Lego. |
systemctl status |
Muestra el estado del timer. |
apache2ctl configtest |
Verifica la configuración de Apache. |
curl -I |
Verifica la respuesta HTTPS. |
¿A dónde ir a continuación?
Volver a Ayuda
¿Encontraste un error o no entiendes algo? ¡Escríbenos!
