- Sync ipt-firewall-server, ip6t-firewall-server and default_settings.conf with firewall/ipt-server affa35d: new limit_new_tcp_connections_per_seconds_rate (default 30, burst twice the rate); the rule now only drops SYNs above the limit instead of accepting those below it; several IPv6 fixes. - defaults: fw_limit_new_tcp_connections_per_seconds_per_source_IP: false, fw_limit_new_tcp_connections_per_seconds_ports: "80,110,143,443,465,995", new fw_limit_new_tcp_connections_per_seconds_rate (overridable with _v6). - templates, extract-fw-host-vars.py, README: new variable and defaults. - oolm-shop: drop fw_limit_new_tcp_connections_per_seconds_per_source_IP_v6 (it would have enabled the limit for IPv6 with the new default ports). - piwik: fw_manage_config: true, per_IP_connection_limit 501, no new-connection limit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ipt-server — Ansible Role
Verwaltet die iptables/ip6tables-basierte Firewall (ipt-firewall-server /
ip6t-firewall-server) auf Debian-Hosts.
Die Rolle ist die einzige autorisierte Stelle für Firewall-Änderungen. Direkte
Edits in /etc/ipt-firewall/ auf dem Host werden beim nächsten Ansible-Run
überschrieben, sobald fw_manage_config: true gesetzt ist.
Verzeichnisstruktur
roles/ipt-server/
├── defaults/main.yml # Alle Variablen mit Defaults
├── files/
│ ├── etc/ipt-firewall/ # Geteilte Conf-Dateien (nicht host-spezifisch)
│ │ ├── default_settings.conf
│ │ ├── include_functions.conf
│ │ ├── logging_ipv4.conf
│ │ ├── logging_ipv6.conf
│ │ ├── post_declarations.conf
│ │ ├── ban_ipv4.list.sample
│ │ └── ban_ipv6.list.sample
│ ├── etc/systemd/system/
│ │ ├── ipt-firewall.service
│ │ └── ip6t-firewall.service
│ └── usr/local/sbin/
│ ├── ipt-firewall-server # IPv4-Firewall-Skript
│ └── ip6t-firewall-server # IPv6-Firewall-Skript
├── handlers/main.yml
├── tasks/main.yml
└── templates/
└── etc/ipt-firewall/
├── interfaces_ipv4.conf.j2 # Host-spezifisch: Interfaces + IPs
├── interfaces_ipv6.conf.j2
├── main_ipv4.conf.j2 # Host-spezifisch: Dienste, Regeln
└── main_ipv6.conf.j2
Host-spezifische Konfiguration liegt ausschließlich in:
host_vars/${HOSTNAME}/${HOSTNAME%.*.*}-ipt-server.yml
Der Dateiname beginnt mit dem Hostnamen ohne Domain, z.B.
host_vars/a.mx.oopen.de/a.mx-ipt-server.yml oder
host_vars/backup.oopen.de/backup-ipt-server.yml
(${HOSTNAME%.*.*} schneidet die letzten zwei Labels ab).
Neuen Host aufnehmen
Voraussetzungen
- Host ist im Ansible-Inventory (
hosts) eingetragen. - SSH-Zugang mit
sudo-Rechten ist vorhanden.
Schritt 1 — host_vars anlegen
cd /path/to/ansible/oopen-server
HOSTNAME=<hostname>
mkdir -p host_vars/${HOSTNAME}
cat > host_vars/${HOSTNAME}/${HOSTNAME%.*.*}-ipt-server.yml << 'EOF'
---
fw_manage_config: true
# --- Netzwerk
fw_ext_interfaces:
- "eth0"
fw_ext_ips_v4:
- "1.2.3.4"
fw_ext_ips_v6:
- "2001:db8::1"
EOF
Alle weiteren Variablen sind optional — sie greifen auf die Defaults in
defaults/main.yml zurück. Nur abweichende Werte müssen gesetzt werden.
Für eine vollständige Variablenreferenz: defaults/main.yml.
Schritt 2 — Dry-run
HOSTNAME=<hostname>
ansible-playbook ipt-server.yml --limit ${HOSTNAME} --check --diff
Der Diff zeigt genau, welche Dateien angelegt und welche Config-Werte gesetzt werden. Prüfen, ob Interfaces, IPs und Dienste stimmen.
Schritt 3 — Scharf stellen
ansible-playbook ipt-server.yml --limit ${HOSTNAME}
Was passiert:
- Firewall-Skripte werden nach
/usr/local/sbin/kopiert. - Geteilte Conf-Dateien werden nach
/etc/ipt-firewall/kopiert. - Systemd-Units werden installiert, Dienste werden aktiviert und gestartet.
- Config-Dateien (
interfaces_*.conf,main_*.conf) werden aus den Templates erzeugt und die Firewall wird gestartet.
Konfiguration ändern
Alle Änderungen erfolgen ausschließlich in der host_vars-Datei des Hosts:
host_vars/${HOSTNAME}/${HOSTNAME%.*.*}-ipt-server.yml
Danach:
HOSTNAME=<hostname>
# Vorschau:
ansible-playbook ipt-server.yml --limit ${HOSTNAME} --check --diff
# Anwenden (ändert Config, startet Firewall bei Änderungen neu):
ansible-playbook ipt-server.yml --limit ${HOSTNAME}
Ansible erkennt automatisch, ob sich eine Config-Datei geändert hat. Nur bei tatsächlichen Änderungen wird die Firewall neu gestartet.
Beispiel: HTTP-Server aktivieren
# host_vars/${HOSTNAME}/${HOSTNAME%.*.*}-ipt-server.yml
fw_http_server_ips: "$ext_ips" # oder konkrete IP
Beispiel: SSH auf bestimmten Port einschränken
fw_ssh_ports: "2222"
Beispiel: LXC-Gäste eintragen
fw_lxc_guest_ips_v4:
- "10.0.3.10"
- "10.0.3.11"
fw_lxc_guest_ips_v6:
- "fd00::10"
- "fd00::11"
Abweichende Werte nur für IPv6
Variablen ohne _v4/_v6-Suffix gelten für beide Firewalls. Jede davon
lässt sich für IPv6 mit <name>_v6 überschreiben (ebenso
fw_ext_interfaces_v6 / fw_local_interfaces_v6). extract-fw-host-vars.py
erzeugt diese Overrides automatisch, wenn IPv4- und IPv6-Konfiguration
voneinander abweichen.
fw_mail_server_ips: $ext_1_ip
fw_mail_server_ips_v6: "" # Mail-Ports nur über IPv4
Firewall-Skripte aktualisieren
Wenn ipt-firewall-server oder ip6t-firewall-server im ipt-server-Repository
aktualisiert werden, müssen die neuen Versionen manuell in die Rolle übernommen
werden:
SRC=/path/to/ipt-server
DST=roles/ipt-server/files/usr/local/sbin
cp $SRC/ipt-firewall-server $DST/
cp $SRC/ip6t-firewall-server $DST/
chmod 750 $DST/ipt-firewall-server $DST/ip6t-firewall-server
Ebenso für geteilte Conf-Dateien in roles/ipt-server/files/etc/ipt-firewall/.
Kommen dabei neue Variablen in main_ipv4.conf.sample / main_ipv6.conf.sample
hinzu, müssen sie zusätzlich nachgezogen werden in:
defaults/main.yml(alsfw_*-Variable mit Default),templates/etc/ipt-firewall/main_ipv{4,6}.conf.j2,extract-fw-host-vars.py(DEFAULTS,MAIN_SHAREDbzw.MAIN_V4_ONLY/MAIN_V6_ONLY, Sektion inrender_yaml).
Nach dem Commit werden die neuen Skripte beim nächsten Ansible-Run auf alle Hosts deployed. Geänderte Skripte oder geteilte Conf-Dateien lösen einen Neustart der Firewall aus.
Wichtige Variablen
| Variable | Default | Bedeutung |
|---|---|---|
fw_manage_config |
false |
true = Ansible verwaltet Config-Dateien vollständig |
fw_ext_interfaces |
[] |
Externe Netzwerk-Interfaces, z.B. ["eth0"] |
fw_ext_ips_v4 |
[] |
Externe IPv4-Adressen |
fw_ext_ips_v6 |
[] |
Externe IPv6-Adressen |
fw_ssh_server_ips |
"$ext_ips" |
IPs auf denen SSH erlaubt ist |
fw_ssh_ports |
"$standard_ssh_port" |
SSH-Port(s) |
fw_http_server_ips |
"" |
IPs auf denen HTTP/HTTPS erlaubt ist |
fw_set_max_new_http_conn_per_ip_per_second |
true |
Neue HTTP(S)-Verbindungen/s pro Quell-IP begrenzen |
fw_max_http_new_conn_per_ip_per_second |
"$default_max_http_new_conn_per_ip_per_second" |
Limit dazu |
fw_set_max_concurrent_http_conn_per_ip |
true |
Gleichzeitige HTTP(S)-Verbindungen pro Quell-IP begrenzen |
fw_max_concurrent_http_conn_per_ip |
"$default_max_concurrent_http_conn_per_ip" |
Limit dazu |
fw_set_max_new_http_conn_per_second |
true |
SYN-Rate auf 80/443 insgesamt begrenzen |
fw_max_new_http_conn_per_second |
"$default_max_new_http_conn_per_second" |
Limit dazu |
fw_limit_connections_per_source_IP |
true |
Gleichzeitige TCP-Verbindungen pro Quell-IP begrenzen |
fw_per_IP_connection_limit |
"$default_per_IP_connection_limit" |
Limit dazu (Default 250) |
fw_limit_new_tcp_connections_per_seconds_per_source_IP |
false |
Neue TCP-Verbindungen/s pro Quell-IP begrenzen |
fw_limit_new_tcp_connections_per_seconds_ports |
"80,110,143,443,465,995" |
Ports dazu (kommagetrennt) |
fw_limit_new_tcp_connections_per_seconds_rate |
"$default_limit_new_tcp_connections_per_seconds_rate" |
Neue Verbindungen/s pro Quell-IP (Default 30, Burst = doppelter Wert); darüber wird verworfen |
fw_throttle_tcp6_mss_for_https |
false |
Nur IPv6: MSS eingehender HTTPS-SYNs clampen |
fw_tcp6_mss_for_https_val |
"$min_tcp6_mss_for_https_val" |
Nur IPv6: MSS-Wert (z.B. 1360) |
fw_mm_tcp_ports_in |
"$standard_mattermost_tcp_ports_in" |
Mattermost TCP-Fallback (STUN) |
fw_ban_ipv6_mask |
"$default_ban_ipv6_mask" |
Nur IPv6: Präfixlänge für ban_ipv6.list-Einträge ohne Maske |
munin_remote_ipv4 |
"" |
Munin-Server IPv4 |
munin_remote_ipv6 |
"" |
Munin-Server IPv6 |
Alle Variablen mit Beschreibung und Defaults: defaults/main.yml.
Variablen die mit $ beginnen (z.B. $ext_ips, $standard_ssh_port) sind
Bash-Variablen — sie werden nicht von Ansible aufgelöst, sondern zur Laufzeit
vom Firewall-Skript expandiert.
Ban-Listen
/etc/ipt-firewall/ban_ipv4.list und ban_ipv6.list werden beim ersten
Ausrollen aus den Beispiel-Dateien der Rolle erzeugt und danach nicht mehr
durch Ansible angefasst — sie können auf dem Host direkt bearbeitet werden.