Certbot standalone auto-renewal #77
162
DNS_ARCHITECTURE.md
Normal file
162
DNS_ARCHITECTURE.md
Normal file
@ -0,0 +1,162 @@
|
||||
# Arquitectura DNS y Validación ACME
|
||||
|
||||
Este documento explica cómo funciona el sistema DNS distribuido y la validación de certificados SSL para dominios FQDN.
|
||||
|
||||
## Componentes DNS
|
||||
|
||||
### 1. Servidores Knot (Autoritativos Remotos)
|
||||
|
||||
**Ubicación:** `anarres.sutty.nl`, `athshe.sutty.nl`, `gethen.sutty.nl`, `ganam.sutty.nl`
|
||||
|
||||
**Función:** DNS autoritativo real para:
|
||||
- Zona `abyaya.la`
|
||||
- Zonas FQDN (ej: `latina.red`, `example.com.ar`)
|
||||
|
||||
**Actualización:** Via `knsupdate` ejecutado desde el proxy
|
||||
|
||||
### 2. Proxy (Hetzner: 5.161.236.18)
|
||||
|
||||
**Servicios DNS en diferentes IPs:**
|
||||
|
||||
| Servicio | IP | Puerto | Función |
|
||||
|----------|-------|--------|---------|
|
||||
| **dnsmasq** | `10.13.12.1` + `127.0.0.1` | 53 | DNS cache/resolver para VPN interna |
|
||||
| **certbot dns-standalone** | `5.161.236.18` | 53 | DNS temporal para validación ACME |
|
||||
|
||||
**No hay conflicto de puertos** porque usan IPs diferentes en la misma máquina.
|
||||
|
||||
## Flujo de Validación ACME para Dominios FQDN
|
||||
|
||||
### Ejemplo: Certificado para `kipu.latina.red`
|
||||
|
||||
#### Paso 1: knsupdate configura delegación en Knot
|
||||
|
||||
Cuando se despliega un servicio con FQDN, `knsupdate` crea estos registros en los servidores Knot:
|
||||
|
||||
```dns
|
||||
; En zona latina.red
|
||||
kipu.latina.red IN A 5.161.236.18
|
||||
*.kipu.latina.red IN A 5.161.236.18
|
||||
_acme-challenge.kipu.latina.red IN CNAME abyaya.la.
|
||||
_acme-challenge.kipu.latina.red IN NS _acme-challenge.abyaya.la.
|
||||
|
|
||||
|
||||
; En zona abyaya.la
|
||||
_acme-challenge.abyaya.la IN A 5.161.236.18
|
||||
_acme-challenge IN NS _acme-challenge.abyaya.la.
|
||||
```
|
||||
|
||||
**Propósito de la delegación:**
|
||||
- El CNAME redirige la validación a `abyaya.la`
|
||||
- El NS delega la autoridad a `_acme-challenge.abyaya.la`
|
||||
- Que apunta al proxy donde certbot corre
|
||||
|
||||
#### Paso 2: Certbot obtiene/renueva certificado
|
||||
|
||||
```bash
|
||||
docker run --rm \
|
||||
-v abyayala_certs_data:/etc/letsencrypt \
|
||||
--network host \
|
||||
numericalatina/certbot-wildcard \
|
||||
certonly --dns-standalone-address=5.161.236.18 --dns-standalone-port=53 \
|
||||
|
Numerica marked this conversation as resolved
fauno
commented
está usando la ip del proxy real? sino estas hardcodeando el de producción está usando la ip del proxy real? sino estas hardcodeando el de producción
Numerica
commented
Sip esto está mal hardcodeado Sip esto está mal hardcodeado
|
||||
-d kipu.latina.red -d *.kipu.latina.red
|
||||
```
|
||||
|
||||
**Certbot:**
|
||||
1. Levanta un servidor DNS temporal en `5.161.236.18:53`
|
||||
2. Crea el registro TXT con el token de validación
|
||||
3. Notifica a Let's Encrypt que está listo
|
||||
|
||||
#### Paso 3: Let's Encrypt valida
|
||||
|
||||
```
|
||||
Let's Encrypt consulta: _acme-challenge.kipu.latina.red
|
||||
↓ Consulta a nameservers de latina.red (Knot)
|
||||
↓ Knot responde con CNAME
|
||||
|
||||
Redirigido a: _acme-challenge.abyaya.la
|
||||
↓ Consulta delegación NS
|
||||
↓ Knot indica: usar nameserver _acme-challenge.abyaya.la
|
||||
|
||||
Consulta directa a: 5.161.236.18:53
|
||||
↓ certbot dns-standalone responde
|
||||
↓ Proporciona el token TXT
|
||||
|
||||
✓ Validación exitosa
|
||||
```
|
||||
|
||||
## Configuración Requerida en DNS Externo
|
||||
|
||||
Para que un dominio FQDN externo (no `.abyaya.la`) pueda delegar la validación ACME al proxy, es necesario agregar estos registros en el DNS del dominio:
|
||||
|
||||
```dns
|
||||
_acme-challenge IN CNAME abyaya.la.
|
||||
_acme-challenge IN NS _acme-challenge.abyaya.la.
|
||||
```
|
||||
|
||||
**Ejemplo para `kipu.latina.red`:**
|
||||
```dns
|
||||
; En el DNS de latina.red
|
||||
_acme-challenge.kipu IN CNAME abyaya.la.
|
||||
_acme-challenge.kipu IN NS _acme-challenge.abyaya.la.
|
||||
```
|
||||
|
||||
Esto se hace **una sola vez por dominio** y permite que todos los subdominios deleguen automáticamente.
|
||||
|
||||
## Renovación Automática
|
||||
|
||||
La renovación de certificados funciona automáticamente porque:
|
||||
|
||||
1. ✅ **Delegación persistente**: Los registros `_acme-challenge` ya están en Knot
|
||||
2. ✅ **Cron configurado**: Se ejecuta los días 4 y 18 de cada mes
|
||||
3. ✅ **Sin conflictos**: dnsmasq y certbot usan IPs diferentes
|
||||
4. ✅ **Mismo método**: `certbot renew` usa dns-standalone automáticamente
|
||||
|
||||
```yaml
|
||||
# Configurado en roles/certbot/tasks/main.yml
|
||||
- name: automatic letsencrypt certs renewal
|
||||
cron:
|
||||
name: certificate renewal
|
||||
day: 4,18
|
||||
hour: 0
|
||||
minute: 0
|
||||
job: "docker run --rm -v abyayala_certs_data:/etc/letsencrypt --network host numericalatina/certbot-wildcard renew --dns-standalone-address=5.161.236.18 --dns-standalone-port=53 >> /var/log/renewal.log 2>&1"
|
||||
```
|
||||
|
||||
## Ventajas de esta Arquitectura
|
||||
|
||||
1. **Centralizada**: Un solo proxy maneja validación ACME para todos los dominios
|
||||
2. **Segura**: No requiere credenciales API de proveedores DNS externos
|
||||
3. **Flexible**: Soporta dominios `.abyaya.la` y FQDN externos
|
||||
4. **Automatizada**: Renovación sin intervención manual
|
||||
5. **Escalable**: Agregar nuevos dominios solo requiere actualizar `abyayala.yml`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Verificar delegación DNS
|
||||
|
||||
```bash
|
||||
# Verificar CNAME
|
||||
dig _acme-challenge.kipu.latina.red CNAME
|
||||
|
||||
# Verificar NS delegation
|
||||
dig _acme-challenge.kipu.latina.red NS
|
||||
|
||||
# Probar resolución completa
|
||||
dig @5.161.236.18 _acme-challenge.kipu.latina.red TXT
|
||||
```
|
||||
|
||||
### Ver logs de renovación
|
||||
|
||||
```bash
|
||||
tail -f /var/log/renewal.log
|
||||
```
|
||||
|
||||
### Probar renovación manualmente
|
||||
|
||||
```bash
|
||||
docker run --rm \
|
||||
-v abyayala_certs_data:/etc/letsencrypt \
|
||||
--network host \
|
||||
numericalatina/certbot-wildcard \
|
||||
renew --dns-standalone-address=5.161.236.18 --dns-standalone-port=53 --dry-run
|
||||
```
|
||||
@ -30,14 +30,13 @@
|
||||
env: yes
|
||||
value: /bin/bash
|
||||
|
||||
# TODO
|
||||
# - name: automatic letsencrypt certs renewal
|
||||
# cron:
|
||||
# name: certificate renewal
|
||||
# day: 4,18
|
||||
# hour: 0
|
||||
# minute: 0
|
||||
# job: "docker run --rm -v {{ althost }}_certs_data:/etc/letsencrypt -v {{ althost }}_certs_www:/var/www/letsencrypt certbot/certbot renew >> /var/log/renewal.log 2>&1"
|
||||
- name: automatic letsencrypt certs renewal
|
||||
cron:
|
||||
name: certificate renewal
|
||||
day: 4,18
|
||||
hour: 0
|
||||
minute: 0
|
||||
job: "docker run --rm -v {{ althost }}_certs_data:/etc/letsencrypt --network host {{ CERTBOT_image }} renew --dns-standalone-address={{ host_ip }} --dns-standalone-port=53 --log-driver=journald"
|
||||
|
Numerica marked this conversation as resolved
Outdated
fauno
commented
ah ok no está hardcodeada ah ok no está hardcodeada
fauno
commented
por que los logs van a un archivo separado en vez del journal? por que los logs van a un archivo separado en vez del journal?
Numerica
commented
Esto está copiado de Numérica. Hay que adaptarlo a lo que resuelva este issue #45 Esto está copiado de Numérica. Hay que adaptarlo a lo que resuelva este issue #45
fauno
commented
por ahora sacale el por ahora sacale el `>> /var/log` y agregale `--log-driver=journald`
|
||||
|
||||
- name: proxy update, after certs renewal
|
||||
cron:
|
||||
|
||||
Reference in New Issue
Block a user
esto es lo que decía que no hace falta dar de alta todos los fqdn en knot, porque estos 4 registros se pueden crear en su dns (salvo que no soporte wildcard)
Es que no soportan wildcard, por ej el de Latina.red es Bind9, ¿no fue por eso levantamos Knsupdate de hecho el año pasado?
Lo que aqui estamos pensando hacer es que haya que delegarlos (registros NS) para utilizarlos, lo cual es bastante estándar en cada Hosting. Una vez delegados, como este que lo está, intentar obtener el standalone a través del mismo proxy del certbot.
Si los certificados los tenemos que tener nosotrxs, ¿como haríamos esta conexión entre el certbot y el NS externo si no?
mmm pensemos esto, a ver.
lo que estamos haciendo con *.HUERTA.abyaya.la es dar de alta en un dns dinamico porque no podemos tener ..abyaya.la. de hecho estoy pensando que nos podiamos evitar todo esto con un servidor dns que hice que sí lo permite hacer. quedará para otro momento.
si yo tengo huerta.sutty.coop.ar y lo quiero dar de alta en el proxy, en mi dns creo estos registros:
si mi servidor dns no soporta wildcards, tendré que dar de alta todos los subdominios que necesite.
si en cambio vamos por la delegación a los nameservers de la red (ahora gestionados por sutty):
y el resto se gestiona por knsupdate. pero sutty tiene que dar de alta la delegación en sus knot, que no es lo que pasó (porque no me pediste).
y para que certbot funcione, tendría que crear este registro
Este último registro está, en el Knsupdate de más arriba
La delegación NS no, porque esa si va en el Registrar