Set-OPS-Public/roles/serveur_relais/templates/nftables.conf.j2
Daniel Allaire f9e45b1676 relais : la face publique d'un site sans adresse fixe, et le site de reprise de TechnoLibre
Le site de TechnoLibre n'a qu'une adresse DHCP. Trois adresses fixes sont louees sur un VPS
(le relais), qui repond a l'ARP pour elles et les route en /32 dans un tunnel WireGuard que la
frontiere initie. Aucune traduction : l'adresse du client arrive intacte.

- underlay.py : `tunnel: wireguard` dispense de VLAN ; role d'hote `relais`.
- devis_opnsense.py : `opnsense_face_publique`. Les entrees publiques s'y posent avec
  reply-to ; les sorties des locataires du pool passent par le relais ; une redirection n'y
  vise plus `wanip`. Le devis de Chezlepro est identique au caractere pres.
- appliquer_opnsense.py : replyto et gateway transmis et dans l'identite (seulement s'ils
  existent) ; le NAT sortant en mode automatic arrete l'application au lieu de dupliquer.
- role serveur_relais, inventorie depuis la carte comme un hyperviseur ; cle privee dans la
  voute du site. Deploye, idempotent.
- site_inventaire.py : les hyperviseurs ne sont plus filtres sur 192.168.11. ; site-appliquer
  charge la voute designee par SETOPS_UNDERLAY ; voute.py n'exige plus d'un locataire un
  secret du site.
- prouver.py : P67 lit le plan par underlay.plan_site() ; P53 couvre la face publique.
- Tests : test_underlay_tunnel, test_face_publique_relais, test_mode_nat_sortant.

95 preuves (make verifier), make test passe. CHANGELOG 144 et 145.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:20:04 -04:00

33 lines
1.9 KiB
Django/Jinja

#!/usr/sbin/nft -f
# {{ ansible_managed }}
# Relais de {{ serveur_relais_site }} — role serveur_relais. Il ne decide d'aucun service : il fait
# suivre les adresses relayees vers {{ serveur_relais_pair_nom }}, qui filtre.
flush ruleset
define CONSOLE = {{ serveur_relais_console }}
define RELAYEES = { {{ serveur_relais_adresses_relayees | join(', ') }} }
table inet relais {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
ct state invalid drop
iif lo accept
udp sport 67 udp dport 68 accept comment "baux DHCP de l'hebergeur"
ip protocol icmp icmp type { echo-request, destination-unreachable, time-exceeded } limit rate 10/second accept
ip6 nexthdr ipv6-icmp icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert, nd-router-advert, destination-unreachable, packet-too-big, time-exceeded } accept
ip daddr $CONSOLE tcp dport 22 accept comment "console SSH"
ip daddr $CONSOLE udp dport {{ serveur_relais_tunnel_port }} accept comment "tunnel de {{ serveur_relais_pair_nom }}"
iifname "{{ serveur_relais_interface_tunnel }}" ip saddr {{ serveur_relais_pair_adresse }} icmp type echo-request accept comment "sonde de {{ serveur_relais_pair_nom }}"
counter comment "refus en entree"
}
chain forward {
type filter hook forward priority filter; policy drop;
tcp flags syn tcp option maxseg size set rt mtu
ct state established,related accept
ct state invalid drop
iifname "{{ serveur_relais_interface_publique }}" oifname "{{ serveur_relais_interface_tunnel }}" ip daddr $RELAYEES accept comment "Internet vers {{ serveur_relais_pair_nom }}"
iifname "{{ serveur_relais_interface_tunnel }}" oifname "{{ serveur_relais_interface_publique }}" ip saddr $RELAYEES accept comment "{{ serveur_relais_pair_nom }} vers Internet, sources relayees seulement"
counter comment "refus en transit"
}
}