Compare commits
65 Commits
issue-35
...
feat/param
| Author | SHA1 | Date | |
|---|---|---|---|
| 57c31fbd98 | |||
| ce103e4eda | |||
| 4979f6f8b8 | |||
| ad5e18bda2 | |||
| 68ca0b5b61 | |||
| f91a3360af | |||
| a973291506 | |||
| 43ea3c9a58 | |||
| 4bec6e7fae | |||
| f180972d15 | |||
| 08a9a38fa5 | |||
| 51bd9c9935 | |||
| 4f18275831 | |||
| 82f6c62803 | |||
| dcc6fe2f48 | |||
| 7b16934a17 | |||
| 0e2d64d39e | |||
| b750293414 | |||
| 1ab755fb10 | |||
| 7e04c03370 | |||
| cdadee266e | |||
| 733c9930e2 | |||
| 71e6eb9429 | |||
| 6ed17848cd | |||
| fd57ecd546 | |||
| 7cdf7bb885 | |||
| ecab24c02f | |||
| 180a7f2ab6 | |||
| 6253223fdf | |||
| 06a513799e | |||
| 7f38023c7d | |||
| a3863b9465 | |||
| f2668d63ef | |||
| 29182e8eaf | |||
| fa59614c2a | |||
| 94e71c7516 | |||
| 65090c8c2c | |||
| b7139145dc | |||
| 8e17401f12 | |||
| 206f8adf60 | |||
| 1f73abb74f | |||
| a27a86ce6b | |||
| 2aa6ddcc4d | |||
| 41b30d3a8d | |||
| 4361acfde1 | |||
| 7b5669eae8 | |||
| d2569a7e29 | |||
| 47759f5464 | |||
| 3c690dd1f5 | |||
| 3c30dc976d | |||
| b369e9824b | |||
| a75f06474c | |||
| e1b4fb8ba1 | |||
| f0f0c688c9 | |||
| 0d48f04f15 | |||
| 63a21e5145 | |||
| bd07232180 | |||
| f5cd3f2e2e | |||
| d0beebfe12 | |||
| 299f970b95 | |||
| a581e89f22 | |||
| 23ac2f0b64 | |||
| 144f9c9d85 | |||
| 121c07f766 | |||
| 7bc06903eb |
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
|
||||
44
abyayala.yml
44
abyayala.yml
@ -15,7 +15,6 @@ matrix:
|
||||
- rap
|
||||
nodos:
|
||||
- marmite
|
||||
- ka
|
||||
- nodochasqui
|
||||
- yanapak
|
||||
- comun01
|
||||
@ -57,6 +56,9 @@ matrix:
|
||||
- kipu
|
||||
- resistencia
|
||||
- carabobolibre
|
||||
- samatuun
|
||||
- kaasavi
|
||||
- llavero
|
||||
|
||||
- service_name: respaldos
|
||||
domains:
|
||||
@ -70,12 +72,6 @@ matrix:
|
||||
nodo: marmite.comun
|
||||
force_https: yes
|
||||
|
||||
- service_name: ka
|
||||
domains:
|
||||
- 2012k.abyaya.la
|
||||
nodo: ka.comun
|
||||
force_https: yes
|
||||
|
||||
- service_name: yanapak
|
||||
domains:
|
||||
- yanapak.abyaya.la
|
||||
@ -93,16 +89,8 @@ matrix:
|
||||
- pilmaiken.abyaya.la
|
||||
nodo: pilmaiken.comun
|
||||
force_https: yes
|
||||
dns_extras:
|
||||
- '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"'
|
||||
|
||||
ports:
|
||||
- 222
|
||||
|
||||
- service_name: fundeps
|
||||
domains:
|
||||
@ -216,9 +204,10 @@ matrix:
|
||||
|
||||
- service_name: kipu
|
||||
domains:
|
||||
- kipu.abyaya.la
|
||||
- kipu.latina.red
|
||||
nodo: kipu.comun
|
||||
force_https: yes
|
||||
ports:
|
||||
- 223
|
||||
|
||||
- service_name: carabobolibre
|
||||
domains:
|
||||
@ -226,3 +215,20 @@ matrix:
|
||||
nodo: carabobolibre.comun
|
||||
force_https: yes
|
||||
|
||||
- service_name: samatuun
|
||||
domains:
|
||||
- samatuun.abyaya.la
|
||||
nodo: samatuun.comun
|
||||
force_https: yes
|
||||
|
||||
- service_name: kaasavi
|
||||
domains:
|
||||
- kaasavi.abyaya.la
|
||||
nodo: kaasavi.comun
|
||||
force_https: yes
|
||||
|
||||
- service_name: llavero
|
||||
domains:
|
||||
- llavero.abyaya.la
|
||||
nodo: llavero.comun
|
||||
force_https: yes
|
||||
@ -3,15 +3,14 @@
|
||||
---
|
||||
- hosts: "{{ host }}"
|
||||
tasks:
|
||||
- name: "unnattended upgrades"
|
||||
apt:
|
||||
name: "unnattended-upgrades"
|
||||
state: "present"
|
||||
- name: import matrix
|
||||
local_action: "include_vars dir=./ files_matching={{ alt }}.yml"
|
||||
|
||||
- include_role: name=althost
|
||||
|
||||
- include_role: name=firewall
|
||||
tags: firewall
|
||||
|
||||
- include_role: name=proxy
|
||||
tags: proxy
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
ssh_users:
|
||||
- name: numerica
|
||||
- name: berto
|
||||
comment: "Roberto Soto"
|
||||
sudo: yes
|
||||
servers_allow:
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
host_ip: 5.161.236.18
|
||||
main_zone: abyaya.la
|
||||
vpn_name: comun
|
||||
proxy_scale: 2
|
||||
domains_default_force_https: yes
|
||||
|
||||
2
group_vars/testing/vars
Normal file
2
group_vars/testing/vars
Normal file
@ -0,0 +1,2 @@
|
||||
host_ip: 157.180.114.62
|
||||
main_zone: abyayala.red
|
||||
@ -1,5 +1,5 @@
|
||||
[localhost]
|
||||
127.0.0.1
|
||||
127.0.0.1 ansible_connection=local
|
||||
|
||||
[hetzner]
|
||||
5.161.236.18
|
||||
@ -11,3 +11,9 @@ ansible_ssh_user=root
|
||||
sutty.nl
|
||||
|
||||
[sutty:vars]
|
||||
|
||||
[testing]
|
||||
157.180.114.62
|
||||
|
||||
[testing:vars]
|
||||
ansible_ssh_user=root
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
- name: check if service volumes exists
|
||||
local_action:
|
||||
module: stat
|
||||
stat:
|
||||
path: "{{ playbook_dir }}/roles/{{ item.roles[0] | default('proxy') }}/templates/volumes.yml"
|
||||
delegate_to: localhost
|
||||
register: volumes_def
|
||||
|
||||
- name: check if service networks exists
|
||||
local_action:
|
||||
module: stat
|
||||
stat:
|
||||
path: "{{ playbook_dir }}/roles/{{ item.roles[0] | default('proxy') }}/templates/networks.yml"
|
||||
delegate_to: localhost
|
||||
register: networks_def
|
||||
|
||||
- set_fact:
|
||||
@ -22,53 +22,53 @@
|
||||
when: networks_def.stat.exists
|
||||
|
||||
- name: define services in local composition
|
||||
local_action:
|
||||
module: blockinfile
|
||||
blockinfile:
|
||||
path: "{{ local_compose_path }}/docker-compose.yml"
|
||||
insertafter: "services:"
|
||||
marker: "# {mark} {{ service_name|upper }}"
|
||||
block: "{{ services_content }}"
|
||||
delegate_to: localhost
|
||||
changed_when: false
|
||||
|
||||
- name: define volumes in local composition
|
||||
local_action:
|
||||
module: lineinfile
|
||||
lineinfile:
|
||||
path: "{{ local_compose_path }}/docker-compose.yml"
|
||||
insertafter: "# volumenes compartidos"
|
||||
line: "volumes: #"
|
||||
state: present
|
||||
regexp: "volumes: #"
|
||||
delegate_to: localhost
|
||||
when: volumes_def.stat.exists
|
||||
changed_when: false
|
||||
|
||||
- name: define volumes content in local composition
|
||||
local_action:
|
||||
module: lineinfile
|
||||
lineinfile:
|
||||
path: "{{ local_compose_path }}/docker-compose.yml"
|
||||
insertafter: "volumes: #"
|
||||
line: "{{ volumes_content }}"
|
||||
state: present
|
||||
regexp: "{{ volumes_content }}"
|
||||
delegate_to: localhost
|
||||
when: volumes_content is defined
|
||||
changed_when: false
|
||||
|
||||
- name: define networks in local composition
|
||||
local_action:
|
||||
module: lineinfile
|
||||
lineinfile:
|
||||
path: "{{ local_compose_path }}/docker-compose.yml"
|
||||
insertafter: "# redes compartidas"
|
||||
line: "networks: #"
|
||||
state: present
|
||||
regexp: "networks: #"
|
||||
delegate_to: localhost
|
||||
when: networks_def.stat.exists
|
||||
changed_when: false
|
||||
|
||||
- name: define networks content in local composition
|
||||
local_action:
|
||||
module: lineinfile
|
||||
lineinfile:
|
||||
path: "{{ local_compose_path }}/docker-compose.yml"
|
||||
insertafter: "networks: #"
|
||||
line: "{{ networks_content }}"
|
||||
state: present
|
||||
delegate_to: localhost
|
||||
when: networks_content is defined
|
||||
changed_when: false
|
||||
|
||||
@ -1,24 +1,46 @@
|
||||
# DOCKER CE this is specific for Debian
|
||||
# https://docs.docker.com/install/linux/docker-ce/debian/
|
||||
# Soporta Debian 12 (bookworm) y Debian 13 (trixie)
|
||||
- block:
|
||||
|
||||
- name: "unattended upgrades"
|
||||
apt:
|
||||
name: "unattended-upgrades"
|
||||
state: "present"
|
||||
|
||||
- name: required packages
|
||||
apt:
|
||||
name: ['apt-transport-https', 'ca-certificates', 'curl', 'gnupg2', 'software-properties-common', 'python3-pip']
|
||||
name: ['ca-certificates', 'curl', 'python3-pip']
|
||||
state: present
|
||||
|
||||
- name: docker signing key
|
||||
apt_key:
|
||||
- name: create keyrings directory
|
||||
file:
|
||||
path: /etc/apt/keyrings
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: download docker gpg key
|
||||
get_url:
|
||||
url: https://download.docker.com/linux/debian/gpg
|
||||
state: present
|
||||
|
||||
- name: docker apt repository
|
||||
apt_repository:
|
||||
repo: deb [arch=amd64] https://download.docker.com/linux/debian bookworm stable
|
||||
dest: /etc/apt/keyrings/docker.asc
|
||||
mode: '0644'
|
||||
|
||||
- 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:
|
||||
name: docker-ce
|
||||
name:
|
||||
- docker-ce
|
||||
- docker-ce-cli
|
||||
- containerd.io
|
||||
- docker-compose-plugin
|
||||
update_cache: yes
|
||||
|
||||
- name: is node already in swarm mode
|
||||
@ -44,55 +66,30 @@
|
||||
state: present
|
||||
|
||||
# ansible-docker requirements
|
||||
- name: python package docker-py is deprecated
|
||||
pip:
|
||||
name: docker-py
|
||||
state: absent
|
||||
break_system_packages: true
|
||||
|
||||
- name: ensure python package docker is present
|
||||
pip:
|
||||
name: docker
|
||||
# Use system packages instead of pip to avoid break_system_packages
|
||||
- name: ensure python3-docker package is present
|
||||
apt:
|
||||
name: python3-docker
|
||||
state: present
|
||||
break_system_packages: true
|
||||
|
||||
# # https://stackoverflow.com/questions/77490435/attributeerror-cython-sources
|
||||
# - name: fix python package Cython version
|
||||
# pip:
|
||||
# name: Cython
|
||||
# state: present
|
||||
# version: <3.0.0
|
||||
# break_system_packages: true
|
||||
# changed_when: false
|
||||
|
||||
# - name: fix python package PyYAML version
|
||||
# shell: pip install "pyyaml==5.4.1" --no-build-isolation --break-system-packages
|
||||
|
||||
- name: ensure python package docker-compose is present
|
||||
pip:
|
||||
name: docker-compose
|
||||
state: present
|
||||
break_system_packages: true
|
||||
|
||||
tags: installation
|
||||
|
||||
|
||||
# DOCKER COMPOSITION IN MASTER
|
||||
- block:
|
||||
- name: make sure compose path exists
|
||||
file: path={{ compose_path }} state=directory
|
||||
|
||||
- name: make sure local compose path exists
|
||||
local_action:
|
||||
module: file
|
||||
path: "{{ local_compose_path }}"
|
||||
file:
|
||||
path: "{{ local_compose_path }}"
|
||||
state: directory
|
||||
delegate_to: localhost
|
||||
|
||||
- name: clean docker-compose.yml
|
||||
local_action:
|
||||
module: template
|
||||
template:
|
||||
dest: "{{ local_compose_path }}/docker-compose.yml"
|
||||
src: roles/althost/templates/docker-compose.yml
|
||||
delegate_to: localhost
|
||||
changed_when: false
|
||||
|
||||
- name: execute roles per domain mapping
|
||||
|
||||
@ -2,12 +2,14 @@
|
||||
apt:
|
||||
name: dnsmasq
|
||||
state: present
|
||||
|
||||
- name: configuracion de red comun
|
||||
template:
|
||||
src: dnsmasq.conf
|
||||
dest: "/etc/dnsmasq.conf"
|
||||
notify:
|
||||
- restart dnsmasq
|
||||
|
||||
- name: activar el servicio
|
||||
systemd_service:
|
||||
name: dnsmasq
|
||||
|
||||
@ -74,8 +74,8 @@ resolv-file=/etc/resolv.local
|
||||
|
||||
# Add local-only domains here, queries in these domains are answered
|
||||
# from /etc/hosts or DHCP only.
|
||||
local=/comun/
|
||||
domain=comun
|
||||
local=/{{ vpn_name }}/
|
||||
domain={{ vpn_name }}
|
||||
|
||||
# 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
|
||||
@ -117,7 +117,7 @@ domain=comun
|
||||
# specified interfaces (and the loopback) give the name of the
|
||||
# interface (eg eth0) here.
|
||||
# Repeat the line for more than one interface.
|
||||
interface=comun
|
||||
interface={{ vpn_name }}
|
||||
# Or you can specify which interface _not_ to listen on
|
||||
except-interface=eth0
|
||||
# Or which to listen on by address (remember to include 127.0.0.1 if
|
||||
|
||||
14
roles/firewall/tasks/main.yml
Normal file
14
roles/firewall/tasks/main.yml
Normal file
@ -0,0 +1,14 @@
|
||||
- name: "Paquetes"
|
||||
apt:
|
||||
name:
|
||||
- "iptables-persistent"
|
||||
- "ipset-persistent"
|
||||
state: "present"
|
||||
|
||||
- name: "Rules"
|
||||
with_items:
|
||||
- "rules.v4"
|
||||
- "rules.v6"
|
||||
template:
|
||||
src: "{{ item }}.j2"
|
||||
dest: "/etc/iptables/{{ item }}"
|
||||
18
roles/firewall/templates/rules.v4.j2
Normal file
18
roles/firewall/templates/rules.v4.j2
Normal file
@ -0,0 +1,18 @@
|
||||
*filter
|
||||
:INPUT DROP [106:5591]
|
||||
:FORWARD DROP [28:1715]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||
-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 -i lo -j ACCEPT
|
||||
-A INPUT -i {{ vpn_name }} -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 tcp -m tcp --dport 53 -j ACCEPT
|
||||
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
|
||||
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
|
||||
-A INPUT -p udp -m udp --dport 655 -j ACCEPT
|
||||
-A INPUT -p tcp -m tcp --dport 655 -j ACCEPT
|
||||
-A INPUT -p tcp -m tcp --dport 3000 -j ACCEPT
|
||||
COMMIT
|
||||
5
roles/firewall/templates/rules.v6.j2
Normal file
5
roles/firewall/templates/rules.v6.j2
Normal file
@ -0,0 +1,5 @@
|
||||
*filter
|
||||
:INPUT DROP [0:0]
|
||||
:FORWARD DROP [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
COMMIT
|
||||
@ -1,14 +1,19 @@
|
||||
{% for dns_server in dns_servers %}
|
||||
server {{ dns_server }}
|
||||
zone abyaya.la.
|
||||
origin abyaya.la.
|
||||
zone {{ zone }}
|
||||
origin {{ zone }}
|
||||
ttl 60
|
||||
del {{ vho }} a
|
||||
del {{ vho }} ns
|
||||
add {{ vho }} a {{ host_ip }}
|
||||
add *.{{ vho }} a {{ host_ip }}
|
||||
add _acme-challenge.{{ vho }} a {{ host_ip }}
|
||||
add _acme-challenge.{{ vho }} ns _acme-challenge
|
||||
del {{ hostname }} a
|
||||
del {{ hostname }} ns
|
||||
add {{ hostname }} a {{ host_ip }}
|
||||
{% if is_abyayala_subdomain %}
|
||||
add *.{{ hostname }} a {{ host_ip }}
|
||||
{% else %}
|
||||
add {{ domain }} a {{ host_ip }}
|
||||
add *.{{ domain }} a {{ host_ip }}
|
||||
{% endif %}
|
||||
add _acme-challenge.{{ hostname }} a {{ host_ip }}
|
||||
add _acme-challenge.{{ hostname }} ns _acme-challenge
|
||||
{% if vhost.dns_extras is defined %}
|
||||
{% for dns_extra in vhost.dns_extras %}
|
||||
{{ dns_extra }}
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
- set_fact:
|
||||
vho: "{{ vhost.domains[0] | regex_replace('([a-z0-9]+)\\.abyaya\\.la', '\\1')}}"
|
||||
|
||||
- name: knsupdate
|
||||
shell: knsupdate
|
||||
args:
|
||||
stdin: "{{ lookup('template', 'templates/commands.j2') }}"
|
||||
- name: process each domain in the list
|
||||
include_tasks: update_domain.yml
|
||||
with_items: "{{ vhost.domains }}"
|
||||
loop_control:
|
||||
loop_var: domain
|
||||
|
||||
38
roles/knsupdate/tasks/update_domain.yml
Normal file
38
roles/knsupdate/tasks/update_domain.yml
Normal file
@ -0,0 +1,38 @@
|
||||
- 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
|
||||
- debug:
|
||||
msg: "{{ lookup('template', 'templates/commands.j2') }}"
|
||||
|
||||
- name: knsupdate for this domain
|
||||
shell: knsupdate
|
||||
args:
|
||||
stdin: "{{ lookup('template', 'templates/commands.j2') }}"
|
||||
@ -3,3 +3,10 @@ dns_servers:
|
||||
- "athshe.sutty.nl"
|
||||
- "gethen.sutty.nl"
|
||||
- "ganam.sutty.nl"
|
||||
|
||||
compound_tlds:
|
||||
- com.ar
|
||||
- com.mx
|
||||
- com.br
|
||||
- org.ar
|
||||
- edu.ar
|
||||
@ -1,6 +0,0 @@
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
proxy_redirect off;
|
||||
proxy_connect_timeout 3m;
|
||||
proxy_send_timeout 3m;
|
||||
proxy_read_timeout 3m;
|
||||
|
||||
@ -10,17 +10,13 @@
|
||||
include_role: name=certbot
|
||||
tags: certbot
|
||||
|
||||
- include_tasks: ../../althost/tasks/compose.yml
|
||||
vars: # forcing since this role is included statically
|
||||
service_name: proxy
|
||||
|
||||
- name: configuration path
|
||||
file: path={{ conf_path }} state=directory
|
||||
|
||||
# TODO leaving unused vhosts bugs proxy
|
||||
- name: clean vhosts_path
|
||||
file: path={{ vhosts_path }} state=absent
|
||||
when: clean_vhosts is defined
|
||||
- name: configuration paths
|
||||
file: path={{ abc }} state=directory
|
||||
with_items:
|
||||
- "{{ stream_path }}"
|
||||
- "{{ conf_path }}"
|
||||
loop_control:
|
||||
loop_var: abc
|
||||
|
||||
- name: virtual hosts path
|
||||
file: path={{ vhosts_path }} state=directory
|
||||
@ -35,6 +31,7 @@
|
||||
with_items:
|
||||
- common.conf
|
||||
- common_ssl.conf
|
||||
- nginx.conf
|
||||
loop_control:
|
||||
loop_var: common
|
||||
|
||||
@ -48,6 +45,21 @@
|
||||
loop_control:
|
||||
loop_var: domino
|
||||
|
||||
- name: add default main zone subdomain if not present
|
||||
set_fact:
|
||||
matrix_loop_with_defaults: "{{ matrix_loop_with_defaults | default([]) | union([ item_with_default ]) }}"
|
||||
vars:
|
||||
has_abyayala_domain: "{{ item.domains | select('match', '.*\\.' ~ (main_zone | regex_escape) ~ '$') | list | length > 0 }}"
|
||||
default_domain: "{{ item.service_name ~ '.' ~ main_zone }}"
|
||||
domains_with_default: "{{ item.domains + [default_domain] if not has_abyayala_domain else item.domains }}"
|
||||
item_with_default: "{{ item | combine({'domains': domains_with_default}) }}"
|
||||
with_items: "{{ matrix_loop | default([]) }}"
|
||||
|
||||
- name: update matrix_loop with defaults
|
||||
set_fact:
|
||||
matrix_loop: "{{ matrix_loop_with_defaults }}"
|
||||
when: matrix_loop_with_defaults is defined
|
||||
|
||||
- name: certificates loop
|
||||
include_tasks: ../../certbot/tasks/certbot.yml
|
||||
with_items: "{{ matrix_loop | default([]) }}"
|
||||
@ -62,3 +74,22 @@
|
||||
loop_control:
|
||||
loop_var: vhost
|
||||
when: (service is undefined) or (service is defined and service == vhost.service_name)
|
||||
|
||||
- name: streams loop
|
||||
include_tasks: stream.yml
|
||||
with_items: "{{ matrix_loop }}"
|
||||
loop_control:
|
||||
loop_var: vhost
|
||||
when: (service is undefined) or (service is defined and service == vhost.service_name)
|
||||
|
||||
- name: slice matrix with those having ports defined
|
||||
set_fact:
|
||||
matrix_ports: "{{ matrix_ports | default([]) | union(ma.ports) }}"
|
||||
with_items: "{{ matrix }}"
|
||||
when: (ma.ports is defined)
|
||||
loop_control:
|
||||
loop_var: ma
|
||||
|
||||
- include_tasks: ../../althost/tasks/compose.yml
|
||||
vars: # forcing since this role is included statically
|
||||
service_name: proxy
|
||||
10
roles/proxy/tasks/stream.yml
Normal file
10
roles/proxy/tasks/stream.yml
Normal file
@ -0,0 +1,10 @@
|
||||
- set_fact:
|
||||
vhost_dest: "{{ stream_path }}/{{ vhost.domains[0] }}.conf"
|
||||
|
||||
- name: default stream for ssh
|
||||
template:
|
||||
src: "{{ default_stream }}"
|
||||
dest: "{{ vhost_dest }}"
|
||||
when: vhost.ports is defined
|
||||
notify:
|
||||
- reload proxy
|
||||
@ -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";
|
||||
|
||||
@ -6,6 +6,14 @@
|
||||
# openssl dhparam -outform pem -out dhparam2048.pem 2048
|
||||
ssl_dhparam /etc/nginx/conf/dhparam2048.pem;
|
||||
|
||||
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ecdh_curve X25519:prime256v1:secp384r1;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_cache shared:MozSSL:10m;
|
||||
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
|
||||
ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
|
||||
|
||||
@ -12,7 +12,9 @@
|
||||
|
||||
gzip_disable "msie6";
|
||||
{% endif %}
|
||||
|
||||
client_max_body_size 1G;
|
||||
|
||||
proxy_ssl_verify off;
|
||||
proxy_ssl_server_name on;
|
||||
proxy_ssl_name $ssl_server_name;
|
||||
@ -27,6 +29,18 @@
|
||||
proxy_set_header Upgrade $http_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 %}
|
||||
}
|
||||
# END PROXY
|
||||
|
||||
56
roles/proxy/templates/nginx.conf
Normal file
56
roles/proxy/templates/nginx.conf
Normal file
@ -0,0 +1,56 @@
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
|
||||
error_log /var/log/nginx/error.log notice;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
server_tokens off;
|
||||
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
# Limitar cada dirección IP a 50 peticiones por segundo por IP y
|
||||
# servidor.
|
||||
limit_req_zone $server_name$binary_remote_addr zone=request_limit:10m rate=10r/s;
|
||||
limit_req_status 429;
|
||||
|
||||
# Limita la cantidad de conexiones concurrentes por IP. Según la
|
||||
# documentación de Nginx, cada request en HTTP/2 se cuenta como una
|
||||
# conexión separada aunque sean la misma.
|
||||
limit_conn_zone $binary_remote_addr zone=connection_limit:10m;
|
||||
limit_conn_status 429;
|
||||
|
||||
# Informar a los navegadores que cuando reciban un error de muchas
|
||||
# conexiones, esperen un segundo antes de reintentar.
|
||||
map $status $retry_after {
|
||||
default '';
|
||||
429 '1';
|
||||
}
|
||||
|
||||
#gzip on;
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
||||
|
||||
stream {
|
||||
include /etc/nginx/stream.d/*.conf;
|
||||
}
|
||||
|
||||
@ -8,11 +8,14 @@
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
{% for port in matrix_ports %}
|
||||
- "{{ port }}:{{ port }}"
|
||||
{% endfor %}
|
||||
networks:
|
||||
- proxy
|
||||
volumes:
|
||||
- "{{ vhosts_path }}:/etc/nginx/conf.d/"
|
||||
- "{{ conf_path }}:/etc/nginx/conf/"
|
||||
- "certs_data:{{ nginx_certs_path }}:ro"
|
||||
|
||||
|
||||
- "{{ conf_path }}/nginx.conf:/etc/nginx/nginx.conf:ro"
|
||||
- "{{ stream_path }}:/etc/nginx/stream.d/"
|
||||
|
||||
11
roles/proxy/templates/stream.conf
Normal file
11
roles/proxy/templates/stream.conf
Normal file
@ -0,0 +1,11 @@
|
||||
upstream ssh_{{ vhost.nodo | replace(".", "") }} {
|
||||
server {{ vhost.nodo }}:22;
|
||||
}
|
||||
|
||||
server {
|
||||
listen {{ vhost.ports[0] }};
|
||||
|
||||
server_name {{ vhost.service_name }}.{{ main_zone }};
|
||||
|
||||
proxy_pass ssh_{{ vhost.nodo | replace(".", "") }};
|
||||
}
|
||||
@ -3,12 +3,14 @@ domains_default_force_https: no
|
||||
|
||||
# nginx
|
||||
vhosts_path: "{{ compose_path }}/proxy/vhosts"
|
||||
stream_path: "{{ compose_path }}/proxy/stream"
|
||||
conf_path: "{{ compose_path }}/proxy/conf"
|
||||
nginx_certs_path: /etc/nginx/certs
|
||||
|
||||
# defaults
|
||||
needs_vhost: no
|
||||
default_vhost: roles/proxy/templates/vhost.conf
|
||||
default_stream: roles/proxy/templates/stream.conf
|
||||
|
||||
# certbot
|
||||
webmaster_email: webmaster@numerica.cl
|
||||
|
||||
@ -28,11 +28,11 @@
|
||||
cmd: "./rap init -i {{ nodo }}"
|
||||
chdir: "{{ rap_path }}/rap"
|
||||
environment:
|
||||
NETWORK: comun
|
||||
NETWORK: "{{ vpn_name }}"
|
||||
|
||||
- name: instalar el nodo
|
||||
shell:
|
||||
cmd: "./rap install -v {{ nodo }}"
|
||||
chdir: "{{ rap_path }}/rap"
|
||||
environment:
|
||||
NETWORK: comun
|
||||
NETWORK: "{{ vpn_name }}"
|
||||
|
||||
@ -4,25 +4,29 @@
|
||||
state: present
|
||||
tags: installation
|
||||
|
||||
# TODO: ERROR! conflicting action statements: synchronize, creates
|
||||
# - name: copiar el codigo fuente
|
||||
# synchronize:
|
||||
# src: ../roles/rap/code/rap/
|
||||
# dest: "{{ rap_path }}"
|
||||
# perms: true
|
||||
# rsync_opts:
|
||||
# - "--exclude=.git"
|
||||
# tags: rap
|
||||
# creates: "{{ rap_path }}"
|
||||
- name: Verificar si ya existe el codigo fuente
|
||||
stat:
|
||||
path: "{{ rap_path }}"
|
||||
register: rap_status
|
||||
|
||||
- name: copiar el codigo fuente, si no existe
|
||||
synchronize:
|
||||
src: ../roles/rap/code/rap/
|
||||
dest: "{{ rap_path }}"
|
||||
perms: true
|
||||
rsync_opts:
|
||||
- "--exclude=.git"
|
||||
tags: rap
|
||||
when: not rap_status.stat.exists
|
||||
|
||||
- name: agregar nodos a la VPN
|
||||
shell:
|
||||
cmd: "./rap add-host {{ althost }} {{ nod }}"
|
||||
chdir: "{{ rap_path }}"
|
||||
args:
|
||||
creates: "{{ rap_path }}/networks/comun/abyayala/hosts/{{ nod }}"
|
||||
creates: "{{ rap_path }}/networks/{{ vpn_name }}/abyayala/hosts/{{ nod }}"
|
||||
environment:
|
||||
NETWORK: comun
|
||||
NETWORK: "{{ vpn_name }}"
|
||||
with_items: "{{ item.nodos }}"
|
||||
loop_control:
|
||||
loop_var: nod
|
||||
@ -32,4 +36,4 @@
|
||||
cmd: "./rap install -v {{ althost }}"
|
||||
chdir: "{{ rap_path }}"
|
||||
environment:
|
||||
NETWORK: comun
|
||||
NETWORK: "{{ vpn_name }}"
|
||||
|
||||
1
tasks/files/ssh/berto.pub
Normal file
1
tasks/files/ssh/berto.pub
Normal file
@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCrhho0oQcAWX6ndpwxkNykJTohUg6vvEplqBa5pENU1gD61eahP4BU4weGrOWY28fBy3BhXOYFITWOxmdv7V7T9fG8WKXqT8MHkC9zaLzAZJ11tHq8OeDo0QGkBOoetf0dv0e3+FNijA9QKhqiwz+v0t5Ev0bSuSl28zHI3Tr0vF98SZulIR9CxDTTPA+Hel2Tl+LcVDZb80/tG9oAFBctzMK7AWB80X/DgXVfY0qgP97809JPX+Cqo/Q+LK55HxeDnfqDsA3m3KXQPODZm6ATEfmcx3MBYqJ8m0rdMKBwR16xDvAyB/LezHVCgmQvmzTRgzTwwwitOX83F5oIEArTK64s1dm0VLzj+Pw5Tetkde4YPHfajffXUbUxGTgD6M3NCvCLHedDMQDQT3LNOfFJGngGcwWJdStmMCWR6dd81epzPZiWHEZ093UWCPtE8kvrL4fRfIc/qSKWNCIyAoagKw4SwwyOfg0ONBJpjOfI7+vBKJVCZSDZQYyU/+Bo60k= berto@concon
|
||||
23
testnet.yml
Normal file
23
testnet.yml
Normal file
@ -0,0 +1,23 @@
|
||||
althost: testnet
|
||||
matrix:
|
||||
- service_name: comun
|
||||
roles:
|
||||
- kemal
|
||||
domains:
|
||||
- comun.abyayala.red
|
||||
|
||||
- service_name: dns
|
||||
roles:
|
||||
- knsupdate
|
||||
|
||||
- service_name: vpn
|
||||
roles:
|
||||
- rap
|
||||
nodos:
|
||||
- qi
|
||||
|
||||
- service_name: qi
|
||||
domains:
|
||||
- qi.abyayala.red
|
||||
nodo: qi.comun
|
||||
# force_https: yes
|
||||
Reference in New Issue
Block a user