SSLmentor

Certificados TLS/SSL de calidad para sitios web y proyectos en Internet.

Lego & ACME WildCard

Lego & ACME WildCard

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.

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ón

Antes 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ón

Si 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.

Volver a Ayuda
¿Encontraste un error o no entiendes algo? ¡Escríbenos!

CA Sectigo
CA RapidSSL
CA Thawte
CA GeoTrust
CA DigiCert
CA Certum