Role ipt-server: sync with ipt-server repo (93d9af8); adapt extract-fw-host-vars.py.

- Update firewall scripts and shared conf files from firewall/ipt-server
  (HTTP connection limits, IPv6 TCP MSS clamping, ban_ipv6_mask,
  mattermost TCP fallback, rename 'stansard_*' -> 'standard_*').
- New role variables: fw_set_max_new_http_conn_per_ip_per_second,
  fw_max_http_new_conn_per_ip_per_second, fw_set_max_concurrent_http_conn_per_ip,
  fw_max_concurrent_http_conn_per_ip, fw_set_max_new_http_conn_per_second,
  fw_max_new_http_conn_per_second, fw_throttle_tcp6_mss_for_https,
  fw_tcp6_mss_for_https_val, fw_mm_tcp_ports_in, fw_ban_ipv6_mask.
- Split fw_blocked_ips into fw_blocked_ips_v4 / fw_blocked_ips_v6 and
  rename it in host_vars accordingly.
- Restart firewall when scripts or shared conf files change.
- extract-fw-host-vars.py: map new variables, normalize '${var}' and renamed
  bash variables, fall back to IPv6 for shared variables and warn if IPv4
  and IPv6 values differ.
- README.md / MIGRATION.md: document host_vars naming
  (<short-hostname>-ipt-server.yml) and new variables.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-02 22:01:28 +01:00
co-authored by Claude Opus 5.5
parent 4a6fc84c01
commit 402a6c9e89
22 changed files with 666 additions and 55 deletions
+68 -12
View File
@@ -21,7 +21,7 @@ from pathlib import Path
# ---------------------------------------------------------------------------
# Defaults matching roles/ipt-firewall/defaults/main.yml
# Defaults matching roles/ipt-server/defaults/main.yml
# Only values that differ from these will be emitted.
# ---------------------------------------------------------------------------
DEFAULTS = {
@@ -73,8 +73,19 @@ DEFAULTS = {
"fw_http_ports": "$standard_http_ports",
"fw_log_cgi_traffic_out": False,
"fw_cgi_script_users": "",
"fw_set_max_new_http_conn_per_ip_per_second": True,
"fw_max_http_new_conn_per_ip_per_second": "$default_max_http_new_conn_per_ip_per_second",
"fw_set_max_concurrent_http_conn_per_ip": True,
"fw_max_concurrent_http_conn_per_ip": "$default_max_concurrent_http_conn_per_ip",
"fw_set_max_new_http_conn_per_second": True,
"fw_max_new_http_conn_per_second": "$default_max_new_http_conn_per_second",
"fw_throttle_tcp6_mss_for_https": False,
"fw_tcp6_mss_for_https_val": "$min_tcp6_mss_for_https_val",
"fw_mm_server_ips": "",
"fw_forward_mm_server_ips": "",
"fw_mm_udp_ports_in": "$standard_mattermost_udp_ports_in",
"fw_mm_tcp_ports_in": "$standard_mattermost_tcp_ports_in",
"fw_mm_udp_ports_out": "$standard_mattermost_udp_ports_out",
"fw_smtpd_ips": "",
"fw_forward_smtpd_ips": "",
"fw_smtpd_additional_listen_ports": "",
@@ -141,7 +152,9 @@ DEFAULTS = {
"fw_portforward_udp_v4": "",
"fw_portforward_tcp_v6": "",
"fw_portforward_udp_v6": "",
"fw_blocked_ips": "",
"fw_blocked_ips_v4": "",
"fw_blocked_ips_v6": "",
"fw_ban_ipv6_mask": "$default_ban_ipv6_mask",
"fw_block_tcp_ports": "111 113 135 137:139 445",
"fw_block_udp_ports": "111 137:139",
"fw_create_traffic_counter": True,
@@ -207,8 +220,17 @@ MAIN_SHARED = {
"http_ports": "fw_http_ports",
"log_cgi_traffic_out": "fw_log_cgi_traffic_out",
"cgi_script_users": "fw_cgi_script_users",
"set_max_new_http_conn_per_ip_per_second": "fw_set_max_new_http_conn_per_ip_per_second",
"max_http_new_conn_per_ip_per_second": "fw_max_http_new_conn_per_ip_per_second",
"set_max_concurrent_http_conn_per_ip": "fw_set_max_concurrent_http_conn_per_ip",
"max_concurrent_http_conn_per_ip": "fw_max_concurrent_http_conn_per_ip",
"set_max_new_http_conn_per_second": "fw_set_max_new_http_conn_per_second",
"max_new_http_conn_per_second": "fw_max_new_http_conn_per_second",
"mm_server_ips": "fw_mm_server_ips",
"forward_mm_server_ips": "fw_forward_mm_server_ips",
"mm_udp_ports_in": "fw_mm_udp_ports_in",
"mm_tcp_ports_in": "fw_mm_tcp_ports_in",
"mm_udp_ports_out": "fw_mm_udp_ports_out",
"smtpd_ips": "fw_smtpd_ips",
"forward_smtpd_ips": "fw_forward_smtpd_ips",
"smtpd_additional_listen_ports": "fw_smtpd_additional_listen_ports",
@@ -265,7 +287,6 @@ MAIN_SHARED = {
"forward_tcp_out_ports": "fw_forward_tcp_out_ports",
"udp_out_ports": "fw_udp_out_ports",
"forward_udp_out_ports": "fw_forward_udp_out_ports",
"blocked_ips": "fw_blocked_ips",
"block_tcp_ports": "fw_block_tcp_ports",
"block_udp_ports": "fw_block_udp_ports",
"create_traffic_counter": "fw_create_traffic_counter",
@@ -307,6 +328,7 @@ MAIN_V4_ONLY = {
"kernel_log_martians": "fw_kernel_log_martians",
"kernel_deactivate_source_route": "fw_kernel_deactivate_source_route",
"kernel_dont_accept_redirects": "fw_kernel_dont_accept_redirects",
"blocked_ips": "fw_blocked_ips_v4",
}
# IPv6-only variables (from main_ipv6.conf)
@@ -325,6 +347,16 @@ MAIN_V6_ONLY = {
"xmmp_remote_out_services": "fw_xmmp_remote_out_services_v6",
"resolver_allowed_networks": "fw_resolver_allowed_networks_v6",
"kernel_forward_between_interfaces": "fw_kernel_forward_between_interfaces",
"throttle_tcp6_mss_for_https": "fw_throttle_tcp6_mss_for_https",
"tcp6_mss_for_https_val": "fw_tcp6_mss_for_https_val",
"ban_ipv6_mask": "fw_ban_ipv6_mask",
"blocked_ips": "fw_blocked_ips_v6",
}
# Renamed bash variables: old name → new name (applied to $var references)
RENAMED_BASH_VARS = {
"stansard_mattermost_udp_ports_in": "standard_mattermost_udp_ports_in",
"stansard_mattermost_udp_ports_out": "standard_mattermost_udp_ports_out",
}
@@ -430,6 +462,14 @@ def ssh_cat(host, user, port, path, sudo_password=None):
return None
def normalize_value(value):
"""Normalize bash variable references: ${var} → $var, renamed vars → new name."""
value = re.sub(r'\$\{([A-Za-z_][A-Za-z0-9_]*)\}', r'$\1', value)
for old, new in RENAMED_BASH_VARS.items():
value = re.sub(r'\$' + old + r'\b', '$' + new, value)
return value
def coerce_bool(value):
"""Convert bash true/false string to Python bool, or return string."""
if value.lower() in ("true", "yes", "1"):
@@ -456,9 +496,11 @@ def yaml_value(v):
def build_host_vars(parsed_iface_v4, parsed_iface_v6, parsed_main_v4, parsed_main_v6):
"""
Map parsed bash variables to Ansible fw_* variables.
Returns dict of {ansible_var: value} containing only non-default values.
Returns (dict of {ansible_var: value} containing only non-default values,
list of warnings).
"""
result = {}
warnings = []
# --- Interfaces: extract lists from numbered vars ---
def extract_list(parsed, prefix, suffix="", count=3):
@@ -501,11 +543,17 @@ def build_host_vars(parsed_iface_v4, parsed_iface_v6, parsed_main_v4, parsed_mai
if v and v != DEFAULTS.get(ansible_var, ""):
result[ansible_var] = v
# --- Shared main variables (read from ipv4) ---
# --- Shared main variables (read from ipv4, fall back to ipv6) ---
for bash_var, ansible_var in MAIN_SHARED.items():
raw = parsed_main_v4.get(bash_var)
raw_v4 = parsed_main_v4.get(bash_var)
raw_v6 = parsed_main_v6.get(bash_var)
if raw_v4 is not None and raw_v6 is not None \
and normalize_value(raw_v4) != normalize_value(raw_v6):
warnings.append(f" # {ansible_var}: IPv4 '{raw_v4}' != IPv6 '{raw_v6}' — IPv4 value used")
raw = raw_v4 if raw_v4 is not None else raw_v6
if raw is None:
continue
raw = normalize_value(raw)
v = coerce_bool(raw) if raw.lower() in ("true", "false") else raw
default = DEFAULTS.get(ansible_var)
if v != default:
@@ -516,6 +564,7 @@ def build_host_vars(parsed_iface_v4, parsed_iface_v6, parsed_main_v4, parsed_mai
raw = parsed_main_v4.get(bash_var)
if raw is None:
continue
raw = normalize_value(raw)
v = coerce_bool(raw) if raw.lower() in ("true", "false") else raw
default = DEFAULTS.get(ansible_var)
if v != default:
@@ -526,12 +575,13 @@ def build_host_vars(parsed_iface_v4, parsed_iface_v6, parsed_main_v4, parsed_mai
raw = parsed_main_v6.get(bash_var)
if raw is None:
continue
raw = normalize_value(raw)
v = coerce_bool(raw) if raw.lower() in ("true", "false") else raw
default = DEFAULTS.get(ansible_var)
if v != default:
result[ansible_var] = v
return result
return result, warnings
def render_yaml(hostname, host_vars, all_warnings):
@@ -540,7 +590,7 @@ def render_yaml(hostname, host_vars, all_warnings):
"---",
f"# ipt-firewall configuration for {hostname}",
"# Generated by extract-fw-host-vars.py - review before committing!",
"# Place in: host_vars/<hostname>/ipt_firewall.yml",
"# Place in: host_vars/<hostname>/<short-hostname>-ipt-server.yml",
"",
]
@@ -574,7 +624,11 @@ def render_yaml(hostname, host_vars, all_warnings):
"fw_allow_local_service_v6", "fw_allow_local_service_from_networks_v6"]),
("SSH", ["fw_ssh_server_ips", "fw_forward_ssh_server_ips", "fw_ssh_ports"]),
("HTTP", ["fw_http_server_ips", "fw_forward_http_server_ips", "fw_http_ports",
"fw_log_cgi_traffic_out", "fw_cgi_script_users"]),
"fw_log_cgi_traffic_out", "fw_cgi_script_users",
"fw_set_max_new_http_conn_per_ip_per_second", "fw_max_http_new_conn_per_ip_per_second",
"fw_set_max_concurrent_http_conn_per_ip", "fw_max_concurrent_http_conn_per_ip",
"fw_set_max_new_http_conn_per_second", "fw_max_new_http_conn_per_second",
"fw_throttle_tcp6_mss_for_https", "fw_tcp6_mss_for_https_val"]),
("Mail", ["fw_smtpd_ips", "fw_forward_smtpd_ips", "fw_smtpd_additional_listen_ports",
"fw_smtpd_additional_outgoing_ports", "fw_mail_server_ips", "fw_forward_mail_server_ips",
"fw_mail_user_ports", "fw_mail_client_ips", "fw_forward_mail_client_ips",
@@ -601,7 +655,8 @@ def render_yaml(hostname, host_vars, all_warnings):
"fw_jibri_server_ips", "fw_forward_jibri_server_ips", "fw_jibri_remote_jitsi_server"]),
("TURN / STUN", ["fw_nc_turn_server_ips", "fw_forward_nc_turn_server_ips",
"fw_nc_turn_ports", "fw_nc_turn_udp_ports"]),
("Mattermost", ["fw_mm_server_ips", "fw_forward_mm_server_ips"]),
("Mattermost", ["fw_mm_server_ips", "fw_forward_mm_server_ips",
"fw_mm_udp_ports_in", "fw_mm_tcp_ports_in", "fw_mm_udp_ports_out"]),
("Prometheus", ["fw_prometheus_local_server_ips", "fw_prometheus_local_client_ips",
"fw_prometheus_remote_server_ips"]),
("Xymon", ["fw_xymon_server_ips", "fw_local_xymon_client", "fw_xymon_port"]),
@@ -610,7 +665,7 @@ def render_yaml(hostname, host_vars, all_warnings):
"fw_udp_out_ports", "fw_forward_udp_out_ports"]),
("Portforwarding", ["fw_portforward_tcp_v4", "fw_portforward_udp_v4",
"fw_portforward_tcp_v6", "fw_portforward_udp_v6"]),
("Block", ["fw_blocked_ips", "fw_block_tcp_ports", "fw_block_udp_ports"]),
("Block", ["fw_blocked_ips_v4", "fw_blocked_ips_v6", "fw_ban_ipv6_mask", "fw_block_tcp_ports", "fw_block_udp_ports"]),
("Protection / limits", ["fw_protection_against_syn_flooding",
"fw_protection_against_port_scanning",
"fw_protection_against_ssh_brute_force_attacks",
@@ -712,10 +767,11 @@ def main():
if warnings:
all_warnings.extend([f" # [{key}] {w}" for w in warnings])
host_vars = build_host_vars(
host_vars, map_warnings = build_host_vars(
parsed["iface_v4"], parsed["iface_v6"],
parsed["main_v4"], parsed["main_v6"],
)
all_warnings.extend(map_warnings)
yaml_text = render_yaml(hostname, host_vars, all_warnings)