ansibleguy.infra_nftables

Rol de Ansible - NFTables
Rol para provisionar el firewall NFTables en servidores Linux.
Registros de Molecule: Corto, Completo
Probado en:
- Debian 11
- Debian 12
Instalación
# última versión
ansible-galaxy role install git+https://github.com/ansibleguy/infra_nftables
# desde galaxy
ansible-galaxy install ansibleguy.infra_nftables
# o para una ruta de rol personalizada
ansible-galaxy install ansibleguy.infra_nftables --roles-path ./roles
Documentación
- NFTables: Wiki
- Consulta el Ejemplo!
- Casos de uso prácticos (Docker, Proxmox, Firewall de red)
- Integración de Fail2Ban con NFTables
- Guía de solución de problemas
Solución de problemas
Uso
¿Quieres una interfaz gráfica de usuario simple para Ansible? Consulta mi Interfaz Web de Ansible
Configuración
Define la configuración según sea necesario:
nftables:
# habilitar: # las características deben ser compatibles con el kernel
# sets: true
# nat: true
# deb11_backport: false # usar el repositorio de retroceso de debian11 para instalar una versión más nueva en debian 10
# bash_completion: false
_defaults: # por defecto que se hereda por todas las tablas y cadenas
table:
type: 'inet'
chain:
policy: 'drop'
type: 'filter'
priority: 0
log:
drop: true
rules:
_all: [] # reglas añadidas a todas las cadenas de todas las tablas
incoming: [] # reglas añadidas a la cadena 'incoming' de todas las tablas
tables:
example:
# type: 'inet' # ipv4 + ipv6
_defaults:
rules:
_all: [] # reglas añadidas a todas las cadenas de esta tabla
vars:
dns_servers: ['1.1.1.1', '1.1.0.0', '8.8.8.8', '8.8.4.4']
private_ranges: ['192.168.0.0/16', '172.16.0.0/12', '10.0.0.0/8']
sets:
blacklist:
flags: ['dynamic', 'timeout']
settings:
timeout: '3m'
counters:
invalid_packages:
comment: 'Inválido'
chains:
incoming:
hook: 'input'
rules:
- sequence: 1
raw: 'ct state invalid counter name invalid_packages log prefix "DROP invalid states" drop'
- seq: 2
raw: 'ct state {established, related} counter accept comment "Permitir sesiones abiertas"'
- s: 3
raw: 'iifname "lo" accept comment "Permitir tráfico de loopback"'
- {proto: 'icmp', type: 'echo-request', limit: 'rate 10/second', comment: 'Permitir icmp-ping'}
- {proto: 'icmpv6', type: 'echo-request', limit: 'rate 10/second', comment: 'Permitir icmp-ping'}
- {proto: 'icmp', code: 30, limit: 'rate 10/second', comment: 'Permitir icmp-traceroute'}
- {proto: 'icmpv6', limit: 'rate 10/second', comment: 'Permitir tipos icmpv6 necesarios para que ipv6 funcione',
type: ['nd-neighbor-solicit', 'nd-router-advert', 'nd-neighbor-advert']}
- {proto: 'udp', port: 46251, counter: 'invalid_packages'}
outgoing:
hook: 'output'
# policy: 'accept'
rules:
- {dest: '$dns_servers', proto: 'udp', port: 53}
- {dest: '$dns_servers', proto: 'tcp', port: [53, 853]}
- {proto: ['tcp', 'udp'], port: [80, 443]}
- {proto: ['icmp', 'icmpv6'], comment: 'Permitir icmp saliente'}
route:
hook: 'forward'
translate:
hook: 'postrouting'
type: 'nat'
policy: 'accept'
rules:
- {'src': '$private_ranges', oif: 'eno2', masquerade: true} # NAT dinámico saliente
- {'src': '$private_ranges', oif: 'eno3', snat: '192.168.0.1'} # NAT estático saliente
Si deseas fusionar reglas de grupo y de host, puedes hacerlo así:
# define el conjunto de reglas básico utilizado por todos los hosts como: 'fw_rules_all'
# define reglas específicas de servicio como: 'fw_rules_group'
# define reglas específicas de host como: 'fw_rules_host'
- name: NFTables
become: true
hosts: all
vars:
nftables:
tables:
example:
chains: "{{ fw_rules_all |
combine(fw_rules_group|default({}), recursive=true, list_merge='append') |
combine(fw_rules_host|default({}), recursive=true, list_merge='append') }}"
pre_tasks:
- debug:
var: nftables
roles:
- ansibleguy.infra_nftables
Ejecución
Ejecuta el playbook:
ansible-playbook -K -D -i inventory/hosts.yml playbook.yml
También hay algunas etiquetas útiles disponibles:
- config_table => provisiona solo los conjuntos de reglas actuales
- config
- purge
Para depurar errores, puedes establecer la variable 'debug' en tiempo de ejecución:
ansible-playbook -K -D -i inventory/hosts.yml playbook.yml -e debug=yes
Funcionalidad
Instalación de paquetes
- Dependencias de Ansible (mínimas)
- NFTables
Configuración
Posibilidad de definir
- variables a nivel global
- variables, conjuntos, contadores y límites a nivel de tabla
- variables a nivel de cadena
La configuración será validada antes de ser escrita
Configuración predeterminada:
- Características habilitadas (deben ser compatibles con el kernel)
- Conjuntos
- NAT
- No se añaden reglas por defecto
- tablas
- tipo de tabla = inet
- cadenas
- tipo de cadena = filter
- política de cadena = drop
- prioridad = 0
- añadir contador = sí
- registrar eliminación implícita = sí
- conjuntos
- tipo de conjunto = ipv4_addr
- añadir contador = sí
- reglas
- política = accept (configúralo en 'none' si deseas eliminarlo explícitamente)
- registro de eliminaciones = sí
- Características habilitadas (deben ser compatibles con el kernel)
Opciones predeterminadas habilitadas:
- Eliminación de archivos de configuración no gestionados almacenados en '/etc/nftables.d/'
Opciones predeterminadas deshabilitadas:
- Instalando NFTables desde los retrocesos de Debian 11 cuando se ejecuta en Debian 10 (versión más nueva)
- Añadiendo script de completado de bash para el comando 'nft'
Información
Nota: La mayoría de la funcionalidad del rol se puede habilitar o deshabilitar.
Para todas las opciones disponibles, consulta la configuración predeterminada ubicada en el archivo de configuración principal!
Advertencia: No todas las configuraciones/variables que proporciones serán verificadas por validez. Una mala configuración podría romper el rol!
Info: Puedes agregar funciones de resolución DNS y lista de bloqueo IP a NFTables utilizando el rol ansibleguy.addons_nftables!
Advertencia: Algunas funcionalidades básicas (NAT/Conjuntos) podrían no ser compatibles con los núcleos de distribuciones principales.
Consulta: Guía de solución de problemas - 'Operación no soportada'
Info: Lee la documentación de hooks para saber cuándo y cómo configurar hooks y prioridades!
Info: Las reglas pueden proporcionarse en formato de diccionario como se ve en los ejemplos.
Estos son los campos y alias disponibles:
Función Claves Nota Secuencia de regla s, id, seq, sequence El ID de secuencia (entero) para ordenar las reglas dentro de una cadena. Si no se proporciona, se generará automáticamente comenzando desde 1000. Si se proporciona un ID de secuencia duplicado, el rol fallará en su verificación de configuración. Interfaz de entrada if, iif, iifname - Interfaz de salida of, oif, oifname - Protocolo proto, pr, protocolo - Subtipo de protocolo t, type - Subcódigo del protocolo co, code - Dirección/Red de destino d, dest, target, destination, 'ip daddr', d6, dest6, target6, 'ip6 daddr' - Puerto de destino dp, port, dport, dest_port - Dirección/Red de origen s, src, source, 'ip saddr', s6, src6, source6, 'ip6 saddr' - Puerto de origen sp, sport, sport, src_port - Registro / Mensaje de registro l, log, 'log prefix' Si se establece en 'True' y se proporciona un 'comentario', se utilizará como mensaje. De lo contrario, no se utilizará ningún mensaje. Contador de tráfico count, counter Si se establece en 'True', se utilizará un contador específico de la regla. De lo contrario, utilizará el contador predefinido. Límite de tráfico lim, limit Un límite establecido para la regla, consulta: Límites anónimos y Límites predefinidos Acción de la regla a, action Si no se proporciona ninguna acción, se establecerá de forma predeterminada en 'accept'. NAT de origen enmascarado m, masque, masquerade Si se debe utilizar NAT enmascarado. NAT de origen snat, src_nat, source_nat, outbound_nat, 'snat to' - NAT de destino dnat, dest_nat, destination_nat, 'dnat to' - Redirección redir, redirect, 'redirect to' Al utilizar redirección, los paquetes se reenviarán a la máquina local. Comentario de regla c, cmt, comment - Usuario user, uid Coincidir solo con tráfico originado por un usuario específico. Grupo group, gid Coincidir solo con tráfico originado por un grupo específico. Marca de firewall mark - Prioridad prio, priority - Longitud de paquete len, length - Marca de tiempo time, timestamp Coincidir con el tiempo de recepción del paquete. Día de la semana day Coincidir con el día de la semana (0 = domingo hasta 6 = sábado o "lunes", "martes" también "vie", "sab") Hora hour Coincidir con las 24 horas "HH:MM:SS", siendo opcionales los segundos.
Solo se puede establecer una de Acción, NAT de origen, Enmascaramiento o NAT de destino para una regla.
Info: No se pueden configurar reglas especiales/complicadas utilizando el diccionario de reglas.
Puedes usar la clave 'raw' para proporcionar cualquier regla personalizada que se añadirá directamente al conjunto de reglas.
Info: Puedes definir variables, conjuntos, contadores y límites a nivel de tabla.
- Variables son pares clave-valor.
var-name: var-value var2-name: ['value1', 'value2']
- Conjuntos tienen esta estructura:
set-name: flags: [list-of-flags] # opcional settings: setting: value # opcional
- Contadores tienen esta estructura:
counter-name: comment: text # opcional
- Límites tienen esta estructura:
limit-name: rate: 'over 1024 bytes/second burst 512 bytes' comment: text # opcional
- Variables son pares clave-valor.
Advertencia: Si deseas agregar una regla de 'solo conteo', debes establecer la 'acción' explícitamente en 'none', de lo contrario se añadirá el valor predeterminado 'accept'.
Info: Si se proporciona algún campo no soportado para la traducción de reglas, se generará un error ya que esto podría llevar a resultados inesperados.
Info: Docker puede necesitar IPTables como dependencia del paquete.
Consulta: Uso práctico como host Docker
Ansible Role to provision NFTables firewall on linux servers
ansible-galaxy install ansibleguy.infra_nftables