Redundancia web con DNS Round Robin
Por el 11 de Septiembre de 2023
El algoritmo Happy Eyeballs definido en el RFC 6555 propone dar preferencia a las direcciones IPv6, y en caso de que la conexión no se establezca rápidamente se conecte usando IPv4. Happy Eyeballs 2 (RFC 8305) es una actualización que añade nuevas funcionalidades para reducir la latencia usando múltiples conexiones de forma asíncrona.
Usaré dos servidores web con OpenBSD:
- El servidor A genera los certificados tiene las IPs 203.0.113.100 y 2001:0db8:0:cd30::100
- El servidor B sirve los mismos archivos y tiene las IPs 203.0.113.200 y 2001:0db8:0:cd30::200
Voy a mantener una copia exacta de los mismos archivos a servir tanto en A como en B. El servidor A se encargará de renovar los certificados Let's Encrypt por lo cual todas las consultas web que realiza acme.client(1) serán enviadas a éste.
Registros DNS
Esta idea la he sacado de este mensaje de -zero-below. Además de un doble registro para el dominio desnudo (@) y para www.example.com. añado un registro para acme.example.com. que apunta al servidor principal que solicitará los certificados:
Nombre | Tipo | Valor |
---|---|---|
acme.example.com. | A | 203.0.113.100 |
acme.example.com. | AAAA | 2001:0db8:0:cd30::100 |
example.com. | A | 203.0.113.100 |
www.example.com. | A | 203.0.113.100 |
example.com. | AAAA | 2001:0db8:0:cd30::100 |
www.example.com. | AAAA | 2001:0db8:0:cd30::100 |
example.com. | A | 203.0.113.200 |
www.example.com. | A | 203.0.113.200 |
example.com. | AAAA | 2001:0db8:0:cd30::200 |
www.example.com. | AAAA | 2001:0db8:0:cd30::200 |
Configuración de httpd
Cada servidor web tendrá la misma configuración y servirá los mismos archivos. Cuando se ejecuta acme-client éste conectará a una de las dos IPs, de forma que independientemente de a cual conecte recibirá una redirección 302 a acme.example.com que apunta únicamente al servidor A.
Este será el bloque correspondiente a la renovación de certificados a través del puerto HTTP (80).
server "acme.example.com" {
listen on * port 80
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
}
}
server "example.com" {
listen on * port 80
location "/.well-known/acme-challenge/*" {
block return 302 "http://acme.example.com$REQUEST_URI"
}
[...]
}
[...]
Sincronización de certificados
Cada servidor deberá tener una copia actualizada de los más nuevos certificados, tanto la parte pública como la llave. Esto se pueda hacer de forma manual renovando los certificados y copiándolos antes de que caduquen o automatizada mediante scripts.
Una vez actualizados los certificados en A se copian los archivos correspondientes en /etc/ssl/private y /etc/ssl al servidor B y se recarga httpd(8) / relayd(8).