Compare commits
98 Commits
testing
...
refactor-s
| Author | SHA1 | Date | |
|---|---|---|---|
| bb069debaf | |||
| 729f931c39 | |||
| 45fe05844e | |||
| f6f5c90d34 | |||
| 6d442bbaa6 | |||
| 28c80118f7 | |||
| 3467f774df | |||
| 80ed2dea5f | |||
| df8b23525e | |||
| 5e45fed446 | |||
| b201c758b7 | |||
| 380a588f0c | |||
| 5ab33a419a | |||
| 02bfbfc2c6 | |||
| fae291cdc9 | |||
| 73a562b449 | |||
| 41b8ee5647 | |||
| 0487ffde12 | |||
| a6c1bcaeff | |||
| 090c397e24 | |||
| 89866df0bf | |||
| 216c81df39 | |||
| a8b3a63807 | |||
| 02b135f486 | |||
| 7e12b7b20a | |||
| 0a99c7f2d1 | |||
| fc76a7fb91 | |||
| 7d5044f1f1 | |||
| f1d37f21f7 | |||
| 66e3c6fcaf | |||
| 1fc58432dd | |||
| d683f8bcd2 | |||
| 5c19e789c4 | |||
| 838cc5833c | |||
| 135edfe527 | |||
| f72983049d | |||
| be5f8fc5e7 | |||
| acdf35e5a7 | |||
| ee5513587e | |||
| 4ad59e5068 | |||
| e17f872aba | |||
| e5a756525b | |||
| c085c99382 | |||
| 890c496b4e | |||
| c86059e319 | |||
| 07dfd834ca | |||
| 554c51e94c | |||
| 7673ccd160 | |||
| ad118402f7 | |||
| 54b24af0b5 | |||
| 08a3e563d4 | |||
| b31a9abcad | |||
| 11ec613ae9 | |||
| 3fb144d02f | |||
| e5dff263d1 | |||
| 06654b9e41 | |||
| 552911286d | |||
| d94cfd89d0 | |||
| 8cf385b5a5 | |||
| 5f914e071a | |||
| 9296b21f91 | |||
| 1a00b8a60c | |||
| 127504cb62 | |||
| 68ca0b5b61 | |||
| f91a3360af | |||
| 76dea140c7 | |||
| 1b69f0d13f | |||
| 5e849ecee2 | |||
| a973291506 | |||
| 43ea3c9a58 | |||
| 4bec6e7fae | |||
| f180972d15 | |||
| ac8dd13d64 | |||
| 0ee1665acb | |||
| 08a9a38fa5 | |||
| 4f18275831 | |||
| 82f6c62803 | |||
| dcc6fe2f48 | |||
| 7b16934a17 | |||
| 0e2d64d39e | |||
| b750293414 | |||
| 1ab755fb10 | |||
| 7e04c03370 | |||
| cdadee266e | |||
| 733c9930e2 | |||
| 71e6eb9429 | |||
| 6ed17848cd | |||
| fd57ecd546 | |||
| dfbd04480c | |||
| 180a7f2ab6 | |||
| edb3a22ec0 | |||
| 6253223fdf | |||
| 06a513799e | |||
| 7f38023c7d | |||
| f106838dc1 | |||
| a3863b9465 | |||
| a27a86ce6b | |||
| 63a21e5145 |
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 \
|
||||||
|
-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
|
||||||
|
```
|
||||||
133
FQDN_AUTHORITATIVE.md
Normal file
133
FQDN_AUTHORITATIVE.md
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
# Soporte para Dominios FQDN Autoritativos
|
||||||
|
|
||||||
|
Esta feature añade soporte para usar dominios FQDN externos (ejemplo.com, kipu.latina.red, etc.) además de subdominios .abyaya.la.
|
||||||
|
|
||||||
|
## Cambios Implementados
|
||||||
|
|
||||||
|
### 1. Generación Automática de Subdominio Default
|
||||||
|
|
||||||
|
Cuando se define un dominio FQDN, el sistema genera automáticamente un subdominio `.abyaya.la` basado en el `service_name` que funciona como alias.
|
||||||
|
|
||||||
|
**Ejemplo:**
|
||||||
|
```yaml
|
||||||
|
- service_name: kipu
|
||||||
|
domains:
|
||||||
|
- kipu.latina.red
|
||||||
|
nodo: kipu.comun
|
||||||
|
force_https: yes
|
||||||
|
```
|
||||||
|
|
||||||
|
El sistema automáticamente añade `kipu.abyaya.la` a la lista de dominios, por lo que ambos dominios funcionarán y redirigirán al primero de la lista.
|
||||||
|
|
||||||
|
### 2. Soporte para TLDs Compuestos
|
||||||
|
|
||||||
|
El sistema detecta automáticamente TLDs compuestos como `.com.ar`, `.co.uk`, `.com.br`, etc., y extrae correctamente la zona DNS.
|
||||||
|
|
||||||
|
**TLDs soportados:**
|
||||||
|
- com.ar, gov.ar, org.ar, gob.ar, net.ar, mil.ar, edu.ar
|
||||||
|
- com.mx
|
||||||
|
- co.uk
|
||||||
|
- com.br
|
||||||
|
- co.nz, net.nz, org.nz
|
||||||
|
|
||||||
|
Para añadir más TLDs, editar `roles/knsupdate/vars/main.yml`.
|
||||||
|
|
||||||
|
### 3. Actualización DNS Multi-Zona
|
||||||
|
|
||||||
|
El sistema ahora actualiza correctamente el DNS en Knot para cada dominio según su tipo:
|
||||||
|
|
||||||
|
- **Subdominios .abyaya.la**: Se actualizan en la zona `abyaya.la.`
|
||||||
|
- **FQDN autoritativos**: Se actualizan en su zona correspondiente (ej: `latina.red.`, `example.com.ar.`)
|
||||||
|
|
||||||
|
La detección es **completamente automática** basada en el sufijo del dominio.
|
||||||
|
|
||||||
|
## Uso
|
||||||
|
|
||||||
|
### Caso Básico: Solo FQDN
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- service_name: ejemplo
|
||||||
|
domains:
|
||||||
|
- ejemplo.latina.red
|
||||||
|
nodo: ejemplo.comun
|
||||||
|
force_https: yes
|
||||||
|
```
|
||||||
|
|
||||||
|
**Resultado:**
|
||||||
|
- `ejemplo.latina.red` → Dominio principal (detectado como FQDN)
|
||||||
|
- `ejemplo.abyaya.la` → Generado automáticamente como alias
|
||||||
|
- Ambos tienen certificados SSL wildcard
|
||||||
|
- Ambos redirigen al primero (ejemplo.latina.red)
|
||||||
|
|
||||||
|
### Caso Avanzado: Múltiples Dominios
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- service_name: miapp
|
||||||
|
domains:
|
||||||
|
- miapp.com.ar
|
||||||
|
- miapp.latina.red
|
||||||
|
- miapp.abyaya.la
|
||||||
|
nodo: miapp.comun
|
||||||
|
force_https: yes
|
||||||
|
```
|
||||||
|
|
||||||
|
**Resultado:**
|
||||||
|
- Los tres dominios funcionan
|
||||||
|
- Todos redirigen al primero (miapp.com.ar)
|
||||||
|
- Certificados SSL para cada dominio + wildcards
|
||||||
|
- DNS actualizado en zonas: `com.ar.`, `latina.red.`, `abyaya.la.`
|
||||||
|
|
||||||
|
### Subdominios de FQDN
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- service_name: api
|
||||||
|
domains:
|
||||||
|
- api.ejemplo.com.ar
|
||||||
|
nodo: api.comun
|
||||||
|
force_https: yes
|
||||||
|
```
|
||||||
|
|
||||||
|
**Resultado:**
|
||||||
|
- `api.ejemplo.com.ar` → Dominio principal (hostname: api, zona: com.ar.)
|
||||||
|
- `api.abyaya.la` → Generado automáticamente
|
||||||
|
|
||||||
|
## Archivos Modificados
|
||||||
|
|
||||||
|
1. **roles/proxy/tasks/main.yml**: Añade dominio default .abyaya.la automáticamente
|
||||||
|
2. **roles/knsupdate/vars/main.yml**: Lista de TLDs compuestos
|
||||||
|
3. **roles/knsupdate/tasks/update.yml**: Procesa múltiples dominios
|
||||||
|
4. **roles/knsupdate/tasks/update_domain.yml**: Nuevo archivo que detecta tipo de dominio
|
||||||
|
5. **roles/knsupdate/tasks/templates/commands.j2**: Usa zona y hostname dinámicos
|
||||||
|
|
||||||
|
## Comportamiento de Certificados SSL
|
||||||
|
|
||||||
|
Certbot obtiene certificados para **todos** los dominios listados más sus wildcards:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
certbot certonly -d ejemplo.com.ar -d *.ejemplo.com.ar -d ejemplo.abyaya.la -d *.ejemplo.abyaya.la
|
||||||
|
```
|
||||||
|
|
||||||
|
Usa el método `dns-standalone` que requiere que el proxy controle el DNS autoritativo. Esto funciona porque knsupdate actualiza Knot con todos los dominios.
|
||||||
|
|
||||||
|
## Migración desde Configuración Anterior
|
||||||
|
|
||||||
|
La configuración anterior sigue funcionando sin cambios:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- service_name: viejo
|
||||||
|
domains:
|
||||||
|
- viejo.abyaya.la
|
||||||
|
nodo: viejo.comun
|
||||||
|
force_https: yes
|
||||||
|
```
|
||||||
|
|
||||||
|
Todo funciona exactamente igual para subdominios .abyaya.la existentes.
|
||||||
|
|
||||||
|
## Notas Técnicas
|
||||||
|
|
||||||
|
- La detección de tipo de dominio es **completamente automática** basada en el sufijo `.abyaya.la`
|
||||||
|
- Los subdominios .abyaya.la siempre se generan automáticamente si no están presentes
|
||||||
|
- La zona DNS se detecta automáticamente considerando TLDs simples y compuestos
|
||||||
|
- Todos los dominios apuntan al mismo nodo en la VPN
|
||||||
|
- El primer dominio en la lista es considerado el principal para certificados SSL
|
||||||
|
- No se requiere ningún flag especial en la configuración
|
||||||
99
README-root-domain.md
Normal file
99
README-root-domain.md
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
# Plan: Añadir Soporte para Dominio Principal www.abyaya.la
|
||||||
|
|
||||||
|
## Objetivo
|
||||||
|
Habilitar que el dominio raíz `abyaya.la` y `www.abyaya.la` apunten al servidor `sutty.comun`, mientras se mantienen funcionando todos los subdominios existentes (ej: `sutty.abyaya.la`, `marmite.abyaya.la`).
|
||||||
|
|
||||||
|
## Estrategia de Desarrollo
|
||||||
|
|
||||||
|
### Rama Tópica
|
||||||
|
Los cambios se implementarán en esta rama tópica:
|
||||||
|
- **Nombre de rama**: `root-domain`
|
||||||
|
- **Bifurcada desde**: `master`
|
||||||
|
|
||||||
|
## Contexto Técnico
|
||||||
|
|
||||||
|
### Arquitectura Actual
|
||||||
|
- **Certificados**: Cada servicio en `abyayala.yml` con `domains` + `nodo` genera un certificado con certbot: `-d DOMAIN -d *.DOMAIN`
|
||||||
|
- **Patron actual**: Todos los dominios siguen el patrón `subdomain.abyaya.la` (ej: `sutty.abyaya.la`)
|
||||||
|
|
||||||
|
### Decisión de Diseño
|
||||||
|
Crear un **servicio separado** para el dominio raíz con un nuevo flag `root: yes` que indica a certbot que NO solicite el certificado wildcard. Esto mantiene limpia la separación de responsabilidades:
|
||||||
|
- Servicio `sutty`: maneja `sutty.abyaya.la` y `*.sutty.abyaya.la`
|
||||||
|
- Servicio `abyaya_root`: maneja únicamente `abyaya.la` y `www.abyaya.la` (sin wildcard)
|
||||||
|
|
||||||
|
## Cambios Implementados
|
||||||
|
|
||||||
|
### 1. `roles/certbot/tasks/certbot.yml`
|
||||||
|
- Lee el flag `root` del servicio y lo mapea a variable `is_root_domain`
|
||||||
|
- Dividido el bloque de certificados en dos tareas condicionales:
|
||||||
|
- Modo estándar (con wildcard): para subdominios (`when: not is_root_domain`)
|
||||||
|
- Modo sin wildcard: para dominios raíz (`when: is_root_domain`)
|
||||||
|
|
||||||
|
### 2. `roles/proxy/templates/vhost.conf`
|
||||||
|
- Agregado condicional para manejar flag `root`
|
||||||
|
- Cuando `root: yes`: genera `server_name` sin punto prefijo (exacto)
|
||||||
|
- Cuando `root: no` (default): genera `server_name .domain` (con wildcard)
|
||||||
|
|
||||||
|
### 3. `abyayala.yml`
|
||||||
|
- Agregado servicio `abyaya_root` con:
|
||||||
|
- Dominios: `abyaya.la` y `www.abyaya.la`
|
||||||
|
- Enrutamiento a: `sutty.comun`
|
||||||
|
- Flag: `root: yes`
|
||||||
|
- HTTPS forzado y compresión habilitada
|
||||||
|
|
||||||
|
## Comandos de Despliegue
|
||||||
|
|
||||||
|
### Despliegue completo
|
||||||
|
```bash
|
||||||
|
ansible-playbook deploy.yml -e "alt=abyayala host=hetzner"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Despliegue solo del servicio nuevo (para testing)
|
||||||
|
```bash
|
||||||
|
ansible-playbook deploy.yml -e "alt=abyayala host=hetzner service=abyaya_root"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verificación Post-Despliegue
|
||||||
|
|
||||||
|
### 1. Verificar certificado
|
||||||
|
```bash
|
||||||
|
ssh root@hetzner
|
||||||
|
ls -la /var/lib/docker/volumes/abyayala_certs_data/_data/live/abyaya.la/
|
||||||
|
docker run --rm -v abyayala_certs_data:/etc/letsencrypt certbot/certbot certificates | grep abyaya.la
|
||||||
|
```
|
||||||
|
|
||||||
|
Debe contener: `abyaya.la`, `www.abyaya.la` (SIN `*.abyaya.la`)
|
||||||
|
|
||||||
|
### 2. Verificar nginx
|
||||||
|
```bash
|
||||||
|
cat /opt/abyayala/proxy/vhosts/abyaya.la.conf
|
||||||
|
docker exec abyayala_proxy nginx -t
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Verificar enrutamiento
|
||||||
|
```bash
|
||||||
|
curl -I http://abyaya.la # Debe redirigir a HTTPS
|
||||||
|
curl -I https://abyaya.la # Debe devolver 200 OK
|
||||||
|
curl -I https://www.abyaya.la # Debe devolver 200 OK
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Verificar subdominios siguen funcionando
|
||||||
|
```bash
|
||||||
|
curl -I https://sutty.abyaya.la
|
||||||
|
curl -I https://marmite.abyaya.la
|
||||||
|
```
|
||||||
|
|
||||||
|
## Requisitos DNS
|
||||||
|
|
||||||
|
Antes del despliegue, configurar:
|
||||||
|
```
|
||||||
|
abyaya.la A <IP-del-proxy>
|
||||||
|
www.abyaya.la A <IP-del-proxy>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Extensibilidad Futura
|
||||||
|
|
||||||
|
Este patrón `root: yes` puede reutilizarse para otros dominios raíz:
|
||||||
|
1. Agregar entrada en `abyayala.yml` con `root: yes`
|
||||||
|
2. Desplegar con ansible-playbook
|
||||||
|
3. Configurar DNS
|
||||||
38
abyayala.yml
38
abyayala.yml
@ -14,7 +14,6 @@ matrix:
|
|||||||
roles:
|
roles:
|
||||||
- rap
|
- rap
|
||||||
nodos:
|
nodos:
|
||||||
- llavero
|
|
||||||
- marmite
|
- marmite
|
||||||
- nodochasqui
|
- nodochasqui
|
||||||
- yanapak
|
- yanapak
|
||||||
@ -59,6 +58,9 @@ matrix:
|
|||||||
- carabobolibre
|
- carabobolibre
|
||||||
- samatuun
|
- samatuun
|
||||||
- kaasavi
|
- kaasavi
|
||||||
|
- llavero
|
||||||
|
- deabajo
|
||||||
|
- testnet
|
||||||
|
|
||||||
- service_name: respaldos
|
- service_name: respaldos
|
||||||
domains:
|
domains:
|
||||||
@ -66,11 +68,9 @@ matrix:
|
|||||||
nodo: respaldos.comun
|
nodo: respaldos.comun
|
||||||
force_https: yes
|
force_https: yes
|
||||||
|
|
||||||
- service_name: marmite
|
- nodo: marmite
|
||||||
domains:
|
|
||||||
- marmite.abyaya.la
|
|
||||||
nodo: marmite.comun
|
|
||||||
force_https: yes
|
force_https: yes
|
||||||
|
# Auto-deduced: domains: [marmite.abyaya.la], rap_dn: marmite.comun
|
||||||
|
|
||||||
- service_name: yanapak
|
- service_name: yanapak
|
||||||
domains:
|
domains:
|
||||||
@ -165,6 +165,15 @@ matrix:
|
|||||||
force_https: yes
|
force_https: yes
|
||||||
enable_compression: yes
|
enable_compression: yes
|
||||||
|
|
||||||
|
- service_name: abyaya_root
|
||||||
|
domains:
|
||||||
|
- abyaya.la
|
||||||
|
- www.abyaya.la
|
||||||
|
nodo: sutty.comun
|
||||||
|
force_https: yes
|
||||||
|
enable_compression: yes
|
||||||
|
root: yes
|
||||||
|
|
||||||
- service_name: mexe
|
- service_name: mexe
|
||||||
domains:
|
domains:
|
||||||
- mexe.abyaya.la
|
- mexe.abyaya.la
|
||||||
@ -204,11 +213,14 @@ matrix:
|
|||||||
|
|
||||||
- service_name: kipu
|
- service_name: kipu
|
||||||
domains:
|
domains:
|
||||||
- kipu.abyaya.la
|
# - abyaya.la
|
||||||
|
# - www.abyaya.la
|
||||||
|
- kipu.latina.red
|
||||||
nodo: kipu.comun
|
nodo: kipu.comun
|
||||||
ports:
|
ports:
|
||||||
- 223
|
- 223
|
||||||
force_https: yes
|
ssl: yes
|
||||||
|
# root: yes
|
||||||
|
|
||||||
- service_name: carabobolibre
|
- service_name: carabobolibre
|
||||||
domains:
|
domains:
|
||||||
@ -227,3 +239,15 @@ matrix:
|
|||||||
- kaasavi.abyaya.la
|
- kaasavi.abyaya.la
|
||||||
nodo: kaasavi.comun
|
nodo: kaasavi.comun
|
||||||
force_https: yes
|
force_https: yes
|
||||||
|
|
||||||
|
- service_name: llavero
|
||||||
|
domains:
|
||||||
|
- llavero.abyaya.la
|
||||||
|
nodo: llavero.comun
|
||||||
|
force_https: yes
|
||||||
|
|
||||||
|
- service_name: deabajo
|
||||||
|
domains:
|
||||||
|
- deabajo.abyaya.la
|
||||||
|
nodo: deabajo.comun
|
||||||
|
force_https: yes
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
host_ip: 5.161.236.18
|
host_ip: 5.161.236.18
|
||||||
|
main_zone: abyaya.la
|
||||||
|
vpn_name: comun
|
||||||
|
vpn_proxy: 10.13.12.1
|
||||||
proxy_scale: 2
|
proxy_scale: 2
|
||||||
domains_default_force_https: yes
|
domains_default_force_https: yes
|
||||||
|
|||||||
@ -1 +1,5 @@
|
|||||||
host_ip: 157.180.114.62
|
host_ip: 157.180.114.62
|
||||||
|
main_zone: abyayala.red
|
||||||
|
vpn_name: comun
|
||||||
|
vpn_proxy: 10.13.12.159
|
||||||
|
proxy_scale: 1
|
||||||
@ -1,5 +1,5 @@
|
|||||||
[localhost]
|
[localhost]
|
||||||
127.0.0.1
|
127.0.0.1 ansible_connection=local
|
||||||
|
|
||||||
[hetzner]
|
[hetzner]
|
||||||
5.161.236.18
|
5.161.236.18
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
- name: check if service volumes exists
|
- name: check if service volumes exists
|
||||||
local_action:
|
stat:
|
||||||
module: stat
|
|
||||||
path: "{{ playbook_dir }}/roles/{{ item.roles[0] | default('proxy') }}/templates/volumes.yml"
|
path: "{{ playbook_dir }}/roles/{{ item.roles[0] | default('proxy') }}/templates/volumes.yml"
|
||||||
|
delegate_to: localhost
|
||||||
register: volumes_def
|
register: volumes_def
|
||||||
|
|
||||||
- name: check if service networks exists
|
- name: check if service networks exists
|
||||||
local_action:
|
stat:
|
||||||
module: stat
|
|
||||||
path: "{{ playbook_dir }}/roles/{{ item.roles[0] | default('proxy') }}/templates/networks.yml"
|
path: "{{ playbook_dir }}/roles/{{ item.roles[0] | default('proxy') }}/templates/networks.yml"
|
||||||
|
delegate_to: localhost
|
||||||
register: networks_def
|
register: networks_def
|
||||||
|
|
||||||
- set_fact:
|
- set_fact:
|
||||||
@ -22,53 +22,53 @@
|
|||||||
when: networks_def.stat.exists
|
when: networks_def.stat.exists
|
||||||
|
|
||||||
- name: define services in local composition
|
- name: define services in local composition
|
||||||
local_action:
|
blockinfile:
|
||||||
module: blockinfile
|
|
||||||
path: "{{ local_compose_path }}/docker-compose.yml"
|
path: "{{ local_compose_path }}/docker-compose.yml"
|
||||||
insertafter: "services:"
|
insertafter: "services:"
|
||||||
marker: "# {mark} {{ service_name|upper }}"
|
marker: "# {mark} {{ service_name|upper }}"
|
||||||
block: "{{ services_content }}"
|
block: "{{ services_content }}"
|
||||||
|
delegate_to: localhost
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: define volumes in local composition
|
- name: define volumes in local composition
|
||||||
local_action:
|
lineinfile:
|
||||||
module: lineinfile
|
|
||||||
path: "{{ local_compose_path }}/docker-compose.yml"
|
path: "{{ local_compose_path }}/docker-compose.yml"
|
||||||
insertafter: "# volumenes compartidos"
|
insertafter: "# volumenes compartidos"
|
||||||
line: "volumes: #"
|
line: "volumes: #"
|
||||||
state: present
|
state: present
|
||||||
regexp: "volumes: #"
|
regexp: "volumes: #"
|
||||||
|
delegate_to: localhost
|
||||||
when: volumes_def.stat.exists
|
when: volumes_def.stat.exists
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: define volumes content in local composition
|
- name: define volumes content in local composition
|
||||||
local_action:
|
lineinfile:
|
||||||
module: lineinfile
|
|
||||||
path: "{{ local_compose_path }}/docker-compose.yml"
|
path: "{{ local_compose_path }}/docker-compose.yml"
|
||||||
insertafter: "volumes: #"
|
insertafter: "volumes: #"
|
||||||
line: "{{ volumes_content }}"
|
line: "{{ volumes_content }}"
|
||||||
state: present
|
state: present
|
||||||
regexp: "{{ volumes_content }}"
|
regexp: "{{ volumes_content }}"
|
||||||
|
delegate_to: localhost
|
||||||
when: volumes_content is defined
|
when: volumes_content is defined
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: define networks in local composition
|
- name: define networks in local composition
|
||||||
local_action:
|
lineinfile:
|
||||||
module: lineinfile
|
|
||||||
path: "{{ local_compose_path }}/docker-compose.yml"
|
path: "{{ local_compose_path }}/docker-compose.yml"
|
||||||
insertafter: "# redes compartidas"
|
insertafter: "# redes compartidas"
|
||||||
line: "networks: #"
|
line: "networks: #"
|
||||||
state: present
|
state: present
|
||||||
regexp: "networks: #"
|
regexp: "networks: #"
|
||||||
|
delegate_to: localhost
|
||||||
when: networks_def.stat.exists
|
when: networks_def.stat.exists
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: define networks content in local composition
|
- name: define networks content in local composition
|
||||||
local_action:
|
lineinfile:
|
||||||
module: lineinfile
|
|
||||||
path: "{{ local_compose_path }}/docker-compose.yml"
|
path: "{{ local_compose_path }}/docker-compose.yml"
|
||||||
insertafter: "networks: #"
|
insertafter: "networks: #"
|
||||||
line: "{{ networks_content }}"
|
line: "{{ networks_content }}"
|
||||||
state: present
|
state: present
|
||||||
|
delegate_to: localhost
|
||||||
when: networks_content is defined
|
when: networks_content is defined
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|||||||
@ -1,28 +1,56 @@
|
|||||||
# DOCKER CE this is specific for Debian
|
# DOCKER CE this is specific for Debian
|
||||||
# https://docs.docker.com/install/linux/docker-ce/debian/
|
# https://docs.docker.com/install/linux/docker-ce/debian/
|
||||||
|
# Soporta Debian 12 (bookworm) y Debian 13 (trixie)
|
||||||
|
|
||||||
|
# Clean up conflicting Docker repositories first (always runs, even with --skip-tags=installation)
|
||||||
|
- name: remove old docker repository files to avoid APT conflicts
|
||||||
|
file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
loop:
|
||||||
|
- /etc/apt/sources.list.d/docker.list
|
||||||
|
- /etc/apt/sources.list.d/download_docker_com_linux_debian.list
|
||||||
|
|
||||||
- block:
|
- block:
|
||||||
- name: "unattended upgrades"
|
- name: "unattended upgrades"
|
||||||
apt:
|
apt:
|
||||||
name: "unattended-upgrades"
|
name: "unattended-upgrades"
|
||||||
state: "present"
|
state: "present"
|
||||||
|
|
||||||
- name: required packages
|
- name: required packages
|
||||||
apt:
|
apt:
|
||||||
name: ['apt-transport-https', 'ca-certificates', 'curl', 'gnupg2', 'software-properties-common', 'python3-pip']
|
name: ['ca-certificates', 'curl', 'python3-pip']
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: docker signing key
|
- name: create keyrings directory
|
||||||
apt_key:
|
file:
|
||||||
|
path: /etc/apt/keyrings
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: download docker gpg key
|
||||||
|
get_url:
|
||||||
url: https://download.docker.com/linux/debian/gpg
|
url: https://download.docker.com/linux/debian/gpg
|
||||||
state: present
|
dest: /etc/apt/keyrings/docker.asc
|
||||||
|
mode: '0644'
|
||||||
- name: docker apt repository
|
|
||||||
apt_repository:
|
|
||||||
repo: deb [arch=amd64] https://download.docker.com/linux/debian bookworm stable
|
|
||||||
|
|
||||||
- name: install docker community edition
|
- name: add docker repository with deb822 format
|
||||||
|
deb822_repository:
|
||||||
|
name: docker
|
||||||
|
types: [deb]
|
||||||
|
uris: https://download.docker.com/linux/debian
|
||||||
|
suites: ["{{ ansible_distribution_release }}"]
|
||||||
|
components: [stable]
|
||||||
|
architectures: [amd64]
|
||||||
|
signed_by: /etc/apt/keyrings/docker.asc
|
||||||
|
|
||||||
|
- name: install docker community edition and compose plugin
|
||||||
apt:
|
apt:
|
||||||
name: docker-ce
|
name:
|
||||||
|
- docker-ce
|
||||||
|
- docker-ce-cli
|
||||||
|
- containerd.io
|
||||||
|
- docker-compose-plugin
|
||||||
update_cache: yes
|
update_cache: yes
|
||||||
|
|
||||||
- name: is node already in swarm mode
|
- name: is node already in swarm mode
|
||||||
@ -48,23 +76,11 @@
|
|||||||
state: present
|
state: present
|
||||||
|
|
||||||
# ansible-docker requirements
|
# ansible-docker requirements
|
||||||
- name: python package docker-py is deprecated
|
# Use system packages instead of pip to avoid break_system_packages
|
||||||
pip:
|
- name: ensure python3-docker package is present
|
||||||
name: docker-py
|
apt:
|
||||||
state: absent
|
name: python3-docker
|
||||||
break_system_packages: true
|
|
||||||
|
|
||||||
- name: ensure python package docker is present
|
|
||||||
pip:
|
|
||||||
name: docker
|
|
||||||
state: present
|
state: present
|
||||||
break_system_packages: true
|
|
||||||
|
|
||||||
- name: ensure python package docker-compose is present
|
|
||||||
pip:
|
|
||||||
name: docker-compose
|
|
||||||
state: present
|
|
||||||
break_system_packages: true
|
|
||||||
|
|
||||||
tags: installation
|
tags: installation
|
||||||
|
|
||||||
@ -74,16 +90,16 @@
|
|||||||
file: path={{ compose_path }} state=directory
|
file: path={{ compose_path }} state=directory
|
||||||
|
|
||||||
- name: make sure local compose path exists
|
- name: make sure local compose path exists
|
||||||
local_action:
|
file:
|
||||||
module: file
|
path: "{{ local_compose_path }}"
|
||||||
path: "{{ local_compose_path }}"
|
|
||||||
state: directory
|
state: directory
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
- name: clean docker-compose.yml
|
- name: clean docker-compose.yml
|
||||||
local_action:
|
template:
|
||||||
module: template
|
|
||||||
dest: "{{ local_compose_path }}/docker-compose.yml"
|
dest: "{{ local_compose_path }}/docker-compose.yml"
|
||||||
src: roles/althost/templates/docker-compose.yml
|
src: roles/althost/templates/docker-compose.yml
|
||||||
|
delegate_to: localhost
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: execute roles per domain mapping
|
- name: execute roles per domain mapping
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
- set_fact:
|
- set_fact:
|
||||||
current_service: "{{ item }}"
|
current_service: "{{ item }}"
|
||||||
service_name: "{{ item.service_name }}"
|
# Deducir service_name: usar 'nodo' si existe, sino 'service_name' (retrocompatibilidad)
|
||||||
|
service_name: "{{ item.nodo | default(item.service_name) }}"
|
||||||
service_roles: "{{ item.roles | default([]) }}"
|
service_roles: "{{ item.roles | default([]) }}"
|
||||||
|
|
||||||
- include_role:
|
- include_role:
|
||||||
name: "{{ current_role_name }}"
|
name: "{{ current_role_name }}"
|
||||||
with_items: "{{ service_roles }}"
|
with_items: "{{ service_roles }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
|
|||||||
@ -10,33 +10,55 @@
|
|||||||
register: vhost_stat
|
register: vhost_stat
|
||||||
|
|
||||||
- set_fact:
|
- set_fact:
|
||||||
needs_cert: (loop.ssl | default(domains_default_ssl) ) or (loop.force_https | default(domains_default_force_https))
|
needs_cert: "{{ ((loop.ssl | default(domains_default_ssl) | bool) or (loop.force_https | default(domains_default_force_https) | bool)) | bool }}"
|
||||||
needs_vhost: needs_cert and not vhost_stat.stat.exists
|
|
||||||
obtain_cert: needs_cert and not ssl_cert.stat.exists
|
- set_fact:
|
||||||
|
needs_vhost: "{{ (needs_cert | bool and not vhost_stat.stat.exists) | bool }}"
|
||||||
|
obtain_cert: "{{ (needs_cert | bool and not ssl_cert.stat.exists) | bool }}"
|
||||||
|
|
||||||
- name: certificate obtention
|
- name: certificate obtention
|
||||||
block:
|
block:
|
||||||
- set_fact:
|
- set_fact:
|
||||||
vhost: "{{ loop }}"
|
vhost: "{{ loop }}"
|
||||||
|
|
||||||
- name: fetch certificate with certbot container
|
- set_fact:
|
||||||
|
is_root_domain: "{{ loop.root | default(false) | bool }}"
|
||||||
|
|
||||||
|
- name: fetch certificate with certbot container (with wildcard)
|
||||||
docker_container:
|
docker_container:
|
||||||
name: chencriptemos
|
name: chencriptemos
|
||||||
image: "{{ CERTBOT_image }}"
|
image: "{{ CERTBOT_image }}"
|
||||||
state: started
|
state: started
|
||||||
volumes:
|
volumes:
|
||||||
- "{{ althost }}_certs_data:/etc/letsencrypt"
|
- "{{ althost }}_certs_data:/etc/letsencrypt"
|
||||||
command: "--non-interactive --agree-tos --email {{ webmaster_email }} certonly --preferred-challenges dns --authenticator dns-standalone --dns-standalone-address={{ host_ip }} --dns-standalone-port=53 --dns-standalone-propagation-seconds=10 {% for domain in loop.domains %} -d {{ domain }} -d *.{{ domain }} {% endfor %}"
|
command: "--non-interactive --agree-tos --expand --email {{ webmaster_email }} certonly --preferred-challenges dns --authenticator dns-standalone --dns-standalone-address={{ host_ip }} --dns-standalone-port=53 --dns-standalone-propagation-seconds=10 {% for domain in loop.domains %} -d {{ domain }} -d *.{{ domain }} {% endfor %}"
|
||||||
detach: no
|
detach: no
|
||||||
cleanup: yes
|
cleanup: yes
|
||||||
ports:
|
ports:
|
||||||
- "{{ host_ip }}:53:53/tcp"
|
- "{{ host_ip }}:53:53/tcp"
|
||||||
- "{{ host_ip }}:53:53/udp"
|
- "{{ host_ip }}:53:53/udp"
|
||||||
notify:
|
notify:
|
||||||
- reload proxy
|
- reload proxy
|
||||||
register: cert_result
|
register: cert_result
|
||||||
|
when: not is_root_domain | bool
|
||||||
|
|
||||||
when: obtain_cert
|
- name: fetch certificate with certbot container (without wildcard, root domain - using webroot)
|
||||||
|
docker_container:
|
||||||
|
name: chencriptemos
|
||||||
|
image: certbot/certbot:latest
|
||||||
|
state: started
|
||||||
|
volumes:
|
||||||
|
- "{{ althost }}_certs_data:/etc/letsencrypt"
|
||||||
|
- "{{ althost }}_certbot_webroot:{{ certbot_webroot }}"
|
||||||
|
command: "--non-interactive --agree-tos --expand --email {{ webmaster_email }} certonly --webroot --webroot-path {{ certbot_webroot }} {% for domain in loop.domains %} -d {{ domain }} {% endfor %}"
|
||||||
|
detach: no
|
||||||
|
cleanup: yes
|
||||||
|
notify:
|
||||||
|
- reload proxy
|
||||||
|
register: cert_result
|
||||||
|
when: is_root_domain | bool
|
||||||
|
|
||||||
|
when: obtain_cert | bool
|
||||||
|
|
||||||
# RESET
|
# RESET
|
||||||
- set_fact:
|
- set_fact:
|
||||||
|
|||||||
@ -30,14 +30,13 @@
|
|||||||
env: yes
|
env: yes
|
||||||
value: /bin/bash
|
value: /bin/bash
|
||||||
|
|
||||||
# TODO
|
- name: automatic letsencrypt certs renewal
|
||||||
# - name: automatic letsencrypt certs renewal
|
cron:
|
||||||
# cron:
|
name: certificate renewal
|
||||||
# name: certificate renewal
|
day: 4,18
|
||||||
# day: 4,18
|
hour: 0
|
||||||
# hour: 0
|
minute: 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"
|
||||||
# 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: proxy update, after certs renewal
|
- name: proxy update, after certs renewal
|
||||||
cron:
|
cron:
|
||||||
@ -45,12 +44,4 @@
|
|||||||
day: 4,18
|
day: 4,18
|
||||||
hour: 6
|
hour: 6
|
||||||
minute: 10
|
minute: 10
|
||||||
job: "docker service update --force {{ althost }}_proxy"
|
job: "docker service update --force {{ althost }}_proxy"
|
||||||
|
|
||||||
- name: mail proxy update, after certs renewal
|
|
||||||
cron:
|
|
||||||
name: mail proxy update
|
|
||||||
day: 4,18
|
|
||||||
hour: 6
|
|
||||||
minute: 20
|
|
||||||
job: "docker service update {{ althost }}_correspondencia_front"
|
|
||||||
@ -2,12 +2,14 @@
|
|||||||
apt:
|
apt:
|
||||||
name: dnsmasq
|
name: dnsmasq
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: configuracion de red comun
|
- name: configuracion de red comun
|
||||||
template:
|
template:
|
||||||
src: dnsmasq.conf
|
src: dnsmasq.conf
|
||||||
dest: "/etc/dnsmasq.conf"
|
dest: "/etc/dnsmasq.conf"
|
||||||
notify:
|
notify:
|
||||||
- restart dnsmasq
|
- restart dnsmasq
|
||||||
|
|
||||||
- name: activar el servicio
|
- name: activar el servicio
|
||||||
systemd_service:
|
systemd_service:
|
||||||
name: dnsmasq
|
name: dnsmasq
|
||||||
|
|||||||
@ -74,8 +74,8 @@ resolv-file=/etc/resolv.local
|
|||||||
|
|
||||||
# Add local-only domains here, queries in these domains are answered
|
# Add local-only domains here, queries in these domains are answered
|
||||||
# from /etc/hosts or DHCP only.
|
# from /etc/hosts or DHCP only.
|
||||||
local=/comun/
|
local=/{{ vpn_name }}/
|
||||||
domain=comun
|
domain={{ vpn_name }}
|
||||||
|
|
||||||
# Add domains which you want to force to an IP address here.
|
# Add domains which you want to force to an IP address here.
|
||||||
# The example below send any host in double-click.net to a local
|
# The example below send any host in double-click.net to a local
|
||||||
@ -117,12 +117,12 @@ domain=comun
|
|||||||
# specified interfaces (and the loopback) give the name of the
|
# specified interfaces (and the loopback) give the name of the
|
||||||
# interface (eg eth0) here.
|
# interface (eg eth0) here.
|
||||||
# Repeat the line for more than one interface.
|
# Repeat the line for more than one interface.
|
||||||
interface=comun
|
interface={{ vpn_name }}
|
||||||
# Or you can specify which interface _not_ to listen on
|
# Or you can specify which interface _not_ to listen on
|
||||||
except-interface=eth0
|
except-interface=eth0
|
||||||
# Or which to listen on by address (remember to include 127.0.0.1 if
|
# Or which to listen on by address (remember to include 127.0.0.1 if
|
||||||
# you use this.)
|
# you use this.)
|
||||||
listen-address=10.13.12.1,127.0.0.1
|
listen-address={{ vpn_proxy }},127.0.0.1
|
||||||
# If you want dnsmasq to provide only DNS service on an interface,
|
# If you want dnsmasq to provide only DNS service on an interface,
|
||||||
# configure it as shown above, and then use the following line to
|
# configure it as shown above, and then use the following line to
|
||||||
# disable DHCP and TFTP on it.
|
# disable DHCP and TFTP on it.
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
-A INPUT -m conntrack --ctstate INVALID -j DROP
|
-A INPUT -m conntrack --ctstate INVALID -j DROP
|
||||||
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
|
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
|
||||||
-A INPUT -i lo -j ACCEPT
|
-A INPUT -i lo -j ACCEPT
|
||||||
-A INPUT -i comun -j ACCEPT
|
-A INPUT -i {{ vpn_name }} -j ACCEPT
|
||||||
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
|
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
|
||||||
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
|
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
|
||||||
-A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
|
-A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
|
||||||
|
|||||||
@ -5,6 +5,6 @@ server {
|
|||||||
client_max_body_size 4k;
|
client_max_body_size 4k;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://10.13.12.1:3000;
|
proxy_pass http://{{ vpn_proxy }}:3000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
roles/knsupdate/files/dns_extras/pilmaiken.abyaya.la
Normal file
8
roles/knsupdate/files/dns_extras/pilmaiken.abyaya.la
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
del pilmaiken mx
|
||||||
|
del pilmaiken txt
|
||||||
|
del pilmaiken spf
|
||||||
|
add pilmaiken mx 10 correspondencia.latina.red.
|
||||||
|
add pilmaiken txt "v=spf1 mx a:correspondencia.latina.red -all"
|
||||||
|
add pilmaiken spf "v=spf1 mx a:correspondencia.latina.red -all"
|
||||||
|
add dkim._domainkey.pilmaiken txt "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQ6JwPaawDzMXuscSgDpvipRFLGXSqgmvvI6jk18lcg0kK2lfxsvXGJ/6U7oCtKa35IEVzdigxD0o7DzklKxAsNIVbcExPJkFWzQuKuP6ATBESo7YUn7Z5qjfxBiNPS0FJp8XpbpUzN+zg/NTgmkggnwwC0tKgcEQ6HnI9AOa1LQIDAQAB"
|
||||||
|
add _dmarc.pilmaiken txt "v=DMARC1; p=reject; rua=mailto:postmaster@correspondencia.latina.red; ruf=mailto:postmaster@correspondencia.latina.red; adkim=s; aspf=s"
|
||||||
@ -2,5 +2,6 @@
|
|||||||
apt:
|
apt:
|
||||||
name: "knot-dnsutils"
|
name: "knot-dnsutils"
|
||||||
state: "present"
|
state: "present"
|
||||||
|
tags: installation
|
||||||
|
|
||||||
- include_tasks: loop.yml
|
- include_tasks: loop.yml
|
||||||
|
|||||||
@ -1,19 +1,31 @@
|
|||||||
{% for dns_server in dns_servers %}
|
{% for dns_server in dns_servers %}
|
||||||
|
|
||||||
server {{ dns_server }}
|
server {{ dns_server }}
|
||||||
zone abyaya.la.
|
zone {{ zone }}
|
||||||
origin abyaya.la.
|
origin {{ zone }}
|
||||||
ttl 60
|
ttl 60
|
||||||
del {{ vho }} a
|
|
||||||
del {{ vho }} ns
|
del {{ hostname }} a
|
||||||
add {{ vho }} a {{ host_ip }}
|
del {{ hostname }} ns
|
||||||
add *.{{ vho }} a {{ host_ip }}
|
add {{ hostname }} a {{ host_ip }}
|
||||||
add _acme-challenge.{{ vho }} a {{ host_ip }}
|
|
||||||
add _acme-challenge.{{ vho }} ns _acme-challenge
|
{% if hostname != '@' and hostname != 'www' %}
|
||||||
{% if vhost.dns_extras is defined %}
|
add *.{{ hostname }} a {{ host_ip }}
|
||||||
{% for dns_extra in vhost.dns_extras %}
|
{% else %}
|
||||||
{{ dns_extra }}
|
add {{ domain }} a {{ host_ip }}
|
||||||
{% endfor %}
|
add *.{{ domain }} a {{ host_ip }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if hostname == '@' %}
|
||||||
|
add _acme-challenge a {{ host_ip }}
|
||||||
|
add _acme-challenge ns _acme-challenge
|
||||||
|
{% else %}
|
||||||
|
add _acme-challenge.{{ hostname }} a {{ host_ip }}
|
||||||
|
add _acme-challenge.{{ hostname }} ns _acme-challenge
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% include "files/dns_extras/" ~ vhost.domains[0] ignore missing %}
|
||||||
|
|
||||||
send
|
send
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
quit
|
quit
|
||||||
|
|||||||
21
roles/knsupdate/tasks/templates/dns_info.j2
Normal file
21
roles/knsupdate/tasks/templates/dns_info.j2
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
========================================
|
||||||
|
Configuracion de DNS requerida: {{ domain }}
|
||||||
|
========================================
|
||||||
|
Por favor configue los siguiente registros DNS en su proveedor:
|
||||||
|
|
||||||
|
{% if hostname == '@' %}
|
||||||
|
{{ zone | regex_replace('\\.$', '') }} IN A {{ host_ip }}
|
||||||
|
*.{{ zone | regex_replace('\\.$', '') }} IN A {{ host_ip }}
|
||||||
|
|
||||||
|
_acme-challenge.{{ zone | regex_replace('\\.$', '') }} IN NS ns-acme.{{ zone | regex_replace('\\.$', '') }}.
|
||||||
|
ns-acme.{{ zone | regex_replace('\\.$', '') }} IN A {{ host_ip }}
|
||||||
|
{% else %}
|
||||||
|
{{ hostname }}.{{ zone | regex_replace('\\.$', '') }} IN A {{ host_ip }}
|
||||||
|
*.{{ hostname }}.{{ zone | regex_replace('\\.$', '') }} IN A {{ host_ip }}
|
||||||
|
|
||||||
|
_acme-challenge.{{ hostname }}.{{ zone | regex_replace('\\.$', '') }} IN NS ns-acme.{{ hostname }}.{{ zone | regex_replace('\\.$', '') }}.
|
||||||
|
ns-acme.{{ hostname }}.{{ zone | regex_replace('\\.$', '') }} IN A {{ host_ip }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
========================================
|
||||||
@ -1,7 +1,5 @@
|
|||||||
- set_fact:
|
- name: process each domain in the list
|
||||||
vho: "{{ vhost.domains[0] | regex_replace('([a-z0-9]+)\\.abyaya\\.la', '\\1')}}"
|
include_tasks: update_domain.yml
|
||||||
|
with_items: "{{ vhost.domains }}"
|
||||||
- name: knsupdate
|
loop_control:
|
||||||
shell: knsupdate
|
loop_var: domain
|
||||||
args:
|
|
||||||
stdin: "{{ lookup('template', 'templates/commands.j2') }}"
|
|
||||||
47
roles/knsupdate/tasks/update_domain.yml
Normal file
47
roles/knsupdate/tasks/update_domain.yml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
- set_fact:
|
||||||
|
is_abyayala_subdomain: "{{ domain.endswith('.' ~ main_zone) }}"
|
||||||
|
|
||||||
|
- name: extract zone and hostname for main zone subdomains
|
||||||
|
set_fact:
|
||||||
|
zone: "{{ main_zone ~ '.' }}"
|
||||||
|
hostname: "{{ domain | regex_replace('([a-z0-9-]+)\\.' ~ main_zone|regex_escape , '\\1') }}"
|
||||||
|
when: is_abyayala_subdomain
|
||||||
|
|
||||||
|
- name: split domain into parts
|
||||||
|
set_fact:
|
||||||
|
domain_parts: "{{ domain.split('.') }}"
|
||||||
|
when: not is_abyayala_subdomain
|
||||||
|
|
||||||
|
- name: detect if domain uses compound TLD
|
||||||
|
set_fact:
|
||||||
|
domain_suffix_2: "{{ domain_parts[-2:] | join('.') }}"
|
||||||
|
uses_compound_tld: "{{ domain_parts[-2:] | join('.') in compound_tlds }}"
|
||||||
|
when: not is_abyayala_subdomain
|
||||||
|
|
||||||
|
- name: extract zone and hostname for FQDN with compound TLD
|
||||||
|
set_fact:
|
||||||
|
zone: "{{ domain_parts[-3:] | join('.') }}."
|
||||||
|
hostname: "{{ domain_parts[:-3] | join('.') if domain_parts | length > 3 else '@' }}"
|
||||||
|
when: not is_abyayala_subdomain and uses_compound_tld
|
||||||
|
|
||||||
|
- name: extract zone and hostname for FQDN with simple TLD
|
||||||
|
set_fact:
|
||||||
|
zone: "{{ domain_parts[-2:] | join('.') }}."
|
||||||
|
hostname: "{{ domain_parts[:-2] | join('.') if domain_parts | length > 2 else '@' }}"
|
||||||
|
when: not is_abyayala_subdomain and not uses_compound_tld
|
||||||
|
|
||||||
|
- name: Debug knsupdate for this domain
|
||||||
|
debug:
|
||||||
|
msg: "{{ lookup('template', 'templates/commands.j2') }}"
|
||||||
|
when: is_abyayala_subdomain
|
||||||
|
|
||||||
|
- name: knsupdate for this domain
|
||||||
|
shell: knsupdate
|
||||||
|
args:
|
||||||
|
stdin: "{{ lookup('template', 'templates/commands.j2') }}"
|
||||||
|
when: is_abyayala_subdomain
|
||||||
|
|
||||||
|
- name: display DNS configuration instructions for external domains
|
||||||
|
debug:
|
||||||
|
msg: "{{ lookup('template', 'templates/dns_info.j2') }}"
|
||||||
|
when: not is_abyayala_subdomain
|
||||||
@ -3,3 +3,10 @@ dns_servers:
|
|||||||
- "athshe.sutty.nl"
|
- "athshe.sutty.nl"
|
||||||
- "gethen.sutty.nl"
|
- "gethen.sutty.nl"
|
||||||
- "ganam.sutty.nl"
|
- "ganam.sutty.nl"
|
||||||
|
|
||||||
|
compound_tlds:
|
||||||
|
- com.ar
|
||||||
|
- com.mx
|
||||||
|
- com.br
|
||||||
|
- org.ar
|
||||||
|
- edu.ar
|
||||||
@ -1,11 +0,0 @@
|
|||||||
proxy_buffering off;
|
|
||||||
proxy_request_buffering off;
|
|
||||||
proxy_redirect off;
|
|
||||||
proxy_connect_timeout 3m;
|
|
||||||
proxy_send_timeout 3m;
|
|
||||||
proxy_read_timeout 3m;
|
|
||||||
|
|
||||||
limit_conn connection_limit 50;
|
|
||||||
limit_req zone=request_limit nodelay burst=20;
|
|
||||||
|
|
||||||
add_header Retry-After $retry_after always;
|
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
add_header X-Frame-Options "sameorigin";
|
|
||||||
add_header X-XSS-Protection "1; mode=block";
|
|
||||||
add_header X-Content-Type-Options "nosniff";
|
|
||||||
add_header Referrer-Policy "strict-origin-when-cross-origin";
|
|
||||||
|
|||||||
@ -10,13 +10,18 @@
|
|||||||
include_role: name=certbot
|
include_role: name=certbot
|
||||||
tags: certbot
|
tags: certbot
|
||||||
|
|
||||||
|
- name: set main_zone_regex from main_zone
|
||||||
|
set_fact:
|
||||||
|
main_zone_regex: "{{ '.' ~ main_zone | replace('.', '\\.') }}"
|
||||||
|
|
||||||
- name: configuration paths
|
- name: configuration paths
|
||||||
file: path={{ comun }} state=directory
|
file: path={{ abc }} state=directory
|
||||||
with_items:
|
with_items:
|
||||||
- "{{ stream_path }}"
|
- "{{ stream_path }}"
|
||||||
- "{{ conf_path }}"
|
- "{{ conf_path }}"
|
||||||
|
- "{{ certbot_webroot }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
loop_var: comun
|
loop_var: abc
|
||||||
|
|
||||||
- name: virtual hosts path
|
- name: virtual hosts path
|
||||||
file: path={{ vhosts_path }} state=directory
|
file: path={{ vhosts_path }} state=directory
|
||||||
@ -32,16 +37,16 @@
|
|||||||
- common.conf
|
- common.conf
|
||||||
- common_ssl.conf
|
- common_ssl.conf
|
||||||
- nginx.conf
|
- nginx.conf
|
||||||
|
- acme_challenge.conf
|
||||||
loop_control:
|
loop_control:
|
||||||
loop_var: common
|
loop_var: common
|
||||||
|
|
||||||
- name: domains' stuff
|
- name: neo stuff
|
||||||
block:
|
block:
|
||||||
- name: slice matrix with those having domains defined
|
- name: normalize and build matrix_loop
|
||||||
set_fact:
|
include_tasks: normalize_node.yml
|
||||||
matrix_loop: "{{ matrix_loop | default([]) | union([ domino ]) }}"
|
with_items: "{{ matrix }}"
|
||||||
with_items: "{{ matrix }}"
|
when: "{{ (domino.domains is defined or domino.nodo is defined or domino.service_name is defined) }}"
|
||||||
when: "{{ domino.domains is defined and domino.nodo is defined }}"
|
|
||||||
loop_control:
|
loop_control:
|
||||||
loop_var: domino
|
loop_var: domino
|
||||||
|
|
||||||
@ -58,7 +63,7 @@
|
|||||||
with_items: "{{ matrix_loop }}"
|
with_items: "{{ matrix_loop }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
loop_var: vhost
|
loop_var: vhost
|
||||||
when: (service is undefined) or (service is defined and service == vhost.service_name)
|
when: ((service is undefined) or (service is defined and service == vhost.service_name)) and not vhost.skip_vhost
|
||||||
|
|
||||||
- name: streams loop
|
- name: streams loop
|
||||||
include_tasks: stream.yml
|
include_tasks: stream.yml
|
||||||
|
|||||||
21
roles/proxy/tasks/normalize_node.yml
Normal file
21
roles/proxy/tasks/normalize_node.yml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
- set_fact:
|
||||||
|
_existing_abyayala_domains: "{{ (domino.domains | default([])) | select('match', '.*' ~ main_zone_regex ~ '$') | list }}"
|
||||||
|
_other_domains: "{{ (domino.domains | default([])) | reject('match', '.*' ~ main_zone_regex ~ '$') | list }}"
|
||||||
|
_node_name: "{{ domino.nodo | default(domino.service_name) }}"
|
||||||
|
_default_domain: "{{ (domino.nodo | default(domino.service_name)) ~ '.' ~ main_zone }}"
|
||||||
|
_default_rap_dn: "{{ (domino.nodo | default(domino.service_name)) ~ '.' ~ vpn_name }}"
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
domino_normalized:
|
||||||
|
nodo: "{{ _node_name }}"
|
||||||
|
rap_dn: "{{ domino.rap_dn | default(_default_rap_dn) }}"
|
||||||
|
domains: "{{ [(_existing_abyayala_domains[0] if (_existing_abyayala_domains | length > 0) else _default_domain)] + _other_domains }}"
|
||||||
|
force_https: "{{ domino.force_https | default(domains_default_force_https) }}"
|
||||||
|
ports: "{{ domino.ports | default([]) }}"
|
||||||
|
enable_compression: "{{ domino.enable_compression | default(domains_default_enable_compression) }}"
|
||||||
|
roles: "{{ domino.roles | default([]) }}"
|
||||||
|
service_name: "{{ domino.service_name | default(_node_name) }}"
|
||||||
|
skip_vhost: "{{ (domino.roles is defined and (domino.roles | length > 0) and domino.domains is not defined) }}"
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
matrix_loop: "{{ matrix_loop | default([]) | union([ domino_normalized ]) }}"
|
||||||
@ -1,10 +1,10 @@
|
|||||||
- set_fact:
|
- set_fact:
|
||||||
vhost_dest: "{{ stream_path }}/{{ vhost.domains[0] }}.conf"
|
vhost_dest: "{{ stream_path }}/{{ vhost.service_name }}.conf"
|
||||||
|
|
||||||
- name: default stream for ssh
|
- name: default stream for ssh
|
||||||
template:
|
template:
|
||||||
src: "{{ default_stream }}"
|
src: "{{ default_stream }}"
|
||||||
dest: "{{ vhost_dest }}"
|
dest: "{{ vhost_dest }}"
|
||||||
when: vhost.ports is defined
|
when: vhost.ports is defined and (vhost.ports | length > 0)
|
||||||
notify:
|
notify:
|
||||||
- reload proxy
|
- reload proxy
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
- set_fact:
|
- set_fact:
|
||||||
vhost_dest: "{{ vhosts_path }}/{{ vhost.domains[0] }}.conf"
|
vhost_dest: "{{ vhosts_path }}/{{ vhost.domains[0] }}.conf"
|
||||||
|
|
||||||
- block:
|
- block:
|
||||||
- set_fact:
|
- set_fact:
|
||||||
custom_vhost: "roles/{{ vhost.roles[0] }}/templates/vhost.conf"
|
custom_vhost: "roles/{{ vhost.roles[0] }}/templates/vhost.conf"
|
||||||
- set_fact:
|
- set_fact:
|
||||||
proxy_conf: "roles/{{ vhost.roles[0] }}/templates/proxy.conf"
|
proxy_conf: "roles/{{ vhost.roles[0] }}/templates/proxy.conf"
|
||||||
when: vhost.roles is defined
|
when: vhost.roles is defined and (vhost.roles | length > 0)
|
||||||
|
|
||||||
- set_fact:
|
- set_fact:
|
||||||
proxy_conf_look: "{{ lookup('template', proxy_conf) }}"
|
proxy_conf_look: "{{ lookup('template', proxy_conf) }}"
|
||||||
@ -16,7 +16,7 @@
|
|||||||
template:
|
template:
|
||||||
src: "{{ default_vhost }}"
|
src: "{{ default_vhost }}"
|
||||||
dest: "{{ vhost_dest }}"
|
dest: "{{ vhost_dest }}"
|
||||||
when: (vhost.roles is undefined or vhost.roles[0] == 'proxy') or (custom_vhost is undefined or custom_vhost is not is_file)
|
when: (vhost.roles is undefined or (vhost.roles | length == 0) or vhost.roles[0] == 'proxy') or (custom_vhost is undefined or custom_vhost is not is_file)
|
||||||
notify:
|
notify:
|
||||||
- reload proxy
|
- reload proxy
|
||||||
|
|
||||||
@ -24,6 +24,6 @@
|
|||||||
template:
|
template:
|
||||||
src: "{{ custom_vhost }}"
|
src: "{{ custom_vhost }}"
|
||||||
dest: "{{ vhost_dest }}"
|
dest: "{{ vhost_dest }}"
|
||||||
when: (vhost.roles is defined and vhost.roles[0] != 'proxy') and custom_vhost is defined and custom_vhost is is_file
|
when: (vhost.roles is defined and (vhost.roles | length > 0) and vhost.roles[0] != 'proxy') and custom_vhost is defined and custom_vhost is is_file
|
||||||
notify:
|
notify:
|
||||||
- reload proxy
|
- reload proxy
|
||||||
|
|||||||
25
roles/proxy/templates/acme_challenge.conf
Normal file
25
roles/proxy/templates/acme_challenge.conf
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Let's Encrypt ACME challenge configuration
|
||||||
|
# This configuration serves the .well-known/acme-challenge directory
|
||||||
|
# for HTTP-01 validation when using webroot method
|
||||||
|
|
||||||
|
location ^~ /.well-known/acme-challenge/ {
|
||||||
|
# Serve files from the certbot webroot
|
||||||
|
root {{ certbot_webroot }};
|
||||||
|
|
||||||
|
# Allow access to challenge files
|
||||||
|
allow all;
|
||||||
|
|
||||||
|
# Ensure plain text content type
|
||||||
|
default_type "text/plain";
|
||||||
|
|
||||||
|
# Disable any authentication
|
||||||
|
auth_basic off;
|
||||||
|
|
||||||
|
# Serve the challenge file directly
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Deny access to other .well-known paths for security
|
||||||
|
location ~ /\.well-known/ {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
add_header X-Frame-Options "sameorigin";
|
||||||
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
|
add_header X-Content-Type-Options "nosniff";
|
||||||
|
add_header Referrer-Policy "strict-origin-when-cross-origin";
|
||||||
|
|||||||
@ -12,12 +12,14 @@
|
|||||||
|
|
||||||
gzip_disable "msie6";
|
gzip_disable "msie6";
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
client_max_body_size 1G;
|
client_max_body_size 1G;
|
||||||
|
|
||||||
proxy_ssl_verify off;
|
proxy_ssl_verify off;
|
||||||
proxy_ssl_server_name on;
|
proxy_ssl_server_name on;
|
||||||
proxy_ssl_name $ssl_server_name;
|
proxy_ssl_name $ssl_server_name;
|
||||||
|
|
||||||
proxy_pass https://$comun_{{ vhost.nodo | replace(".", "") }};
|
proxy_pass https://$comun_{{ vhost.rap_dn | replace(".", "") }};
|
||||||
|
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
@ -27,6 +29,18 @@
|
|||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection upgrade;
|
proxy_set_header Connection upgrade;
|
||||||
|
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_request_buffering off;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_connect_timeout 3m;
|
||||||
|
proxy_send_timeout 3m;
|
||||||
|
proxy_read_timeout 3m;
|
||||||
|
|
||||||
|
limit_conn connection_limit 50;
|
||||||
|
limit_req zone=request_limit nodelay burst=20;
|
||||||
|
|
||||||
|
add_header Retry-After $retry_after always;
|
||||||
|
|
||||||
{% include "files/custom_proxy_includes/" ~ vhost.domains[0] ignore missing %}
|
{% include "files/custom_proxy_includes/" ~ vhost.domains[0] ignore missing %}
|
||||||
}
|
}
|
||||||
# END PROXY
|
# END PROXY
|
||||||
|
|||||||
@ -19,3 +19,4 @@
|
|||||||
- "certs_data:{{ nginx_certs_path }}:ro"
|
- "certs_data:{{ nginx_certs_path }}:ro"
|
||||||
- "{{ conf_path }}/nginx.conf:/etc/nginx/nginx.conf:ro"
|
- "{{ conf_path }}/nginx.conf:/etc/nginx/nginx.conf:ro"
|
||||||
- "{{ stream_path }}:/etc/nginx/stream.d/"
|
- "{{ stream_path }}:/etc/nginx/stream.d/"
|
||||||
|
- "certbot_webroot:{{ certbot_webroot }}"
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
upstream ssh_{{ vhost.nodo | replace(".", "") }} {
|
upstream ssh_{{ vhost.rap_dn | replace(".", "") }} {
|
||||||
server {{ vhost.nodo }}:22;
|
server {{ vhost.rap_dn }}:22;
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen {{ vhost.ports[0] }};
|
listen {{ vhost.ports[0] }};
|
||||||
|
|
||||||
server_name .{{ vhost.domains | join(' .') }};
|
server_name {{ vhost.service_name }}.{{ main_zone }};
|
||||||
|
|
||||||
proxy_pass ssh_{{ vhost.nodo | replace(".", "") }};
|
proxy_pass ssh_{{ vhost.rap_dn | replace(".", "") }};
|
||||||
}
|
}
|
||||||
@ -1,18 +1,31 @@
|
|||||||
map $http_host $comun_{{ vhost.nodo | replace(".", "") }} {
|
map $http_host $comun_{{ vhost.rap_dn | replace(".", "") }} {
|
||||||
hostnames;
|
hostnames;
|
||||||
{% for domain in vhost.domains %}
|
{% for domain in vhost.domains %}
|
||||||
.{{ domain }} {{ vhost.nodo }};
|
{% if vhost.root | default(false) %}
|
||||||
|
{{ domain }} {{ vhost.rap_dn }};
|
||||||
|
{% else %}
|
||||||
|
.{{ domain }} {{ vhost.rap_dn }};
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
|
{% if vhost.root | default(false) %}
|
||||||
|
server_name {{ vhost.domains | join(' ') }};
|
||||||
|
{% else %}
|
||||||
server_name .{{ vhost.domains | join(' .') }};
|
server_name .{{ vhost.domains | join(' .') }};
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
listen 80;
|
listen 80;
|
||||||
|
|
||||||
resolver 10.13.12.1 valid=300s;
|
resolver {{ vpn_proxy }} valid=300s;
|
||||||
resolver_timeout 5s;
|
resolver_timeout 5s;
|
||||||
|
|
||||||
|
{% if vhost.root | default(false) %}
|
||||||
|
# ACME challenge for HTTP-01 validation (webroot method for root domains)
|
||||||
|
include conf/acme_challenge.conf;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if not needs_vhost and ((vhost.ssl | default(domains_default_ssl) ) or (vhost.force_https | default(domains_default_force_https))) %}
|
{% if not needs_vhost and ((vhost.ssl | default(domains_default_ssl) ) or (vhost.force_https | default(domains_default_force_https))) %}
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
|
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
certs_data:
|
certs_data:
|
||||||
|
certbot_webroot:
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
domains_default_ssl: no
|
domains_default_ssl: no
|
||||||
domains_default_force_https: no
|
domains_default_force_https: no
|
||||||
|
domains_default_enable_compression: no
|
||||||
|
|
||||||
# nginx
|
# nginx
|
||||||
vhosts_path: "{{ compose_path }}/proxy/vhosts"
|
vhosts_path: "{{ compose_path }}/proxy/vhosts"
|
||||||
@ -15,3 +16,4 @@ default_stream: roles/proxy/templates/stream.conf
|
|||||||
# certbot
|
# certbot
|
||||||
webmaster_email: webmaster@numerica.cl
|
webmaster_email: webmaster@numerica.cl
|
||||||
CERTBOT_image: numericalatina/certbot-wildcard
|
CERTBOT_image: numericalatina/certbot-wildcard
|
||||||
|
certbot_webroot: /var/www/certbot
|
||||||
|
|||||||
Submodule roles/rap/code/rap updated: ec4cd71e6e...05481cdbc3
@ -2,7 +2,7 @@
|
|||||||
# https://serverfault.com/questions/1108989/isc-dhcp-client-dhclient-alternative
|
# https://serverfault.com/questions/1108989/isc-dhcp-client-dhclient-alternative
|
||||||
- name: instalar dependecias de la RAP
|
- name: instalar dependecias de la RAP
|
||||||
apt:
|
apt:
|
||||||
name: ['tinc', 'rsync', 'dhcp5']
|
name: ['tinc', 'rsync', 'dhcpcd5']
|
||||||
state: latest
|
state: latest
|
||||||
# update_cache: yes
|
# update_cache: yes
|
||||||
tags: installation
|
tags: installation
|
||||||
@ -11,13 +11,13 @@
|
|||||||
|
|
||||||
- name: copiar el codigo fuente
|
- name: copiar el codigo fuente
|
||||||
synchronize:
|
synchronize:
|
||||||
src: ../roles/rap/code/rap
|
src: ../roles/rap/code/rap/
|
||||||
dest: "{{ rap_path }}"
|
dest: "{{ rap_path }}"
|
||||||
perms: true
|
perms: true
|
||||||
|
|
||||||
- name: hacer ejecutable el archivo rap
|
- name: hacer ejecutable el archivo rap
|
||||||
file:
|
file:
|
||||||
path: "{{ rap_path }}/rap/rap"
|
path: "{{ rap_path }}/rap"
|
||||||
state: touch
|
state: touch
|
||||||
mode: '774'
|
mode: '774'
|
||||||
modification_time: preserve
|
modification_time: preserve
|
||||||
@ -26,13 +26,13 @@
|
|||||||
- name: inicializar el nodo
|
- name: inicializar el nodo
|
||||||
shell:
|
shell:
|
||||||
cmd: "./rap init -i {{ nodo }}"
|
cmd: "./rap init -i {{ nodo }}"
|
||||||
chdir: "{{ rap_path }}/rap"
|
chdir: "{{ rap_path }}"
|
||||||
environment:
|
environment:
|
||||||
NETWORK: comun
|
NETWORK: "{{ vpn_name }}"
|
||||||
|
|
||||||
- name: instalar el nodo
|
- name: instalar el nodo
|
||||||
shell:
|
shell:
|
||||||
cmd: "./rap install -v {{ nodo }}"
|
cmd: "./rap install -v {{ nodo }}"
|
||||||
chdir: "{{ rap_path }}/rap"
|
chdir: "{{ rap_path }}"
|
||||||
environment:
|
environment:
|
||||||
NETWORK: comun
|
NETWORK: "{{ vpn_name }}"
|
||||||
|
|||||||
@ -24,9 +24,9 @@
|
|||||||
cmd: "./rap add-host {{ althost }} {{ nod }}"
|
cmd: "./rap add-host {{ althost }} {{ nod }}"
|
||||||
chdir: "{{ rap_path }}"
|
chdir: "{{ rap_path }}"
|
||||||
args:
|
args:
|
||||||
creates: "{{ rap_path }}/networks/comun/abyayala/hosts/{{ nod }}"
|
creates: "{{ rap_path }}/networks/{{ vpn_name }}/abyayala/hosts/{{ nod }}"
|
||||||
environment:
|
environment:
|
||||||
NETWORK: comun
|
NETWORK: "{{ vpn_name }}"
|
||||||
with_items: "{{ item.nodos }}"
|
with_items: "{{ item.nodos }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
loop_var: nod
|
loop_var: nod
|
||||||
@ -36,4 +36,4 @@
|
|||||||
cmd: "./rap install -v {{ althost }}"
|
cmd: "./rap install -v {{ althost }}"
|
||||||
chdir: "{{ rap_path }}"
|
chdir: "{{ rap_path }}"
|
||||||
environment:
|
environment:
|
||||||
NETWORK: comun
|
NETWORK: "{{ vpn_name }}"
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
# Instalacion de la RAP en maquina local
|
# Instalacion de la RAP en maquina local
|
||||||
# ansible-playbook --become tasks/rap.yml -e "host=localhost nodo=chem" -i hosts.local
|
# ansible-playbook --become tasks/rap.yml -e "host=localhost nodo=chem" -i hosts.local
|
||||||
|
# ansible-playbook tasks/rap.yml -e "host=testing nodo=testnet"
|
||||||
---
|
---
|
||||||
- hosts: "{{ host }}"
|
- hosts: "{{ host }}"
|
||||||
tasks:
|
tasks:
|
||||||
|
|||||||
@ -16,8 +16,7 @@ matrix:
|
|||||||
nodos:
|
nodos:
|
||||||
- qi
|
- qi
|
||||||
|
|
||||||
- service_name: qi
|
- nodo: qi
|
||||||
domains:
|
ports:
|
||||||
- qi.abyayala.red
|
- 531
|
||||||
nodo: qi.comun
|
|
||||||
# force_https: yes
|
# force_https: yes
|
||||||
Reference in New Issue
Block a user