From 9798ca9cd6f1bc87e78ceeddf6df408ae72b5e98 Mon Sep 17 00:00:00 2001 From: Christoph Date: Fri, 26 Jun 2026 19:30:01 +0200 Subject: [PATCH] Add ipt-server role with firewall configuration and management - Created handlers for reloading systemd and restarting firewall services. - Implemented tasks to ensure the existence of configuration directories and files. - Deployed host-specific and shared configuration files using templates. - Added scripts for managing IPv4 and IPv6 firewalls. - Configured systemd service units for ipt-firewall and ip6t-firewall. - Enabled and started firewall services on system boot. --- .gitignore | 14 + extract-fw-host-vars.py | 726 ++++ host_vars/test.mx.oopen.de/ipt_firewall.yml | 47 + ipt-server.yml | 5 + roles/ipt-server/MIGRATION.md | 199 ++ roles/ipt-server/README.md | 204 ++ roles/ipt-server/defaults/main.yml | 376 ++ .../etc/ipt-firewall/ban_ipv4.list.sample | 36 + .../etc/ipt-firewall/ban_ipv6.list.sample | 20 + .../etc/ipt-firewall/default_settings.conf | 157 + .../etc/ipt-firewall/include_functions.conf | 268 ++ .../files/etc/ipt-firewall/logging_ipv4.conf | 62 + .../files/etc/ipt-firewall/logging_ipv6.conf | 63 + .../etc/ipt-firewall/post_declarations.conf | 621 ++++ .../etc/systemd/system/ip6t-firewall.service | 13 + .../etc/systemd/system/ipt-firewall.service | 13 + .../files/usr/local/sbin/ip6t-firewall-server | 2952 +++++++++++++++ .../files/usr/local/sbin/ipt-firewall-server | 3178 +++++++++++++++++ roles/ipt-server/handlers/main.yml | 15 + roles/ipt-server/tasks/main.yml | 215 ++ .../etc/ipt-firewall/interfaces_ipv4.conf.j2 | 74 + .../etc/ipt-firewall/interfaces_ipv6.conf.j2 | 67 + .../etc/ipt-firewall/main_ipv4.conf.j2 | 357 ++ .../etc/ipt-firewall/main_ipv6.conf.j2 | 337 ++ 24 files changed, 10019 insertions(+) create mode 100755 extract-fw-host-vars.py create mode 100644 host_vars/test.mx.oopen.de/ipt_firewall.yml create mode 100644 ipt-server.yml create mode 100644 roles/ipt-server/MIGRATION.md create mode 100644 roles/ipt-server/README.md create mode 100644 roles/ipt-server/defaults/main.yml create mode 100644 roles/ipt-server/files/etc/ipt-firewall/ban_ipv4.list.sample create mode 100644 roles/ipt-server/files/etc/ipt-firewall/ban_ipv6.list.sample create mode 100644 roles/ipt-server/files/etc/ipt-firewall/default_settings.conf create mode 100644 roles/ipt-server/files/etc/ipt-firewall/include_functions.conf create mode 100644 roles/ipt-server/files/etc/ipt-firewall/logging_ipv4.conf create mode 100644 roles/ipt-server/files/etc/ipt-firewall/logging_ipv6.conf create mode 100644 roles/ipt-server/files/etc/ipt-firewall/post_declarations.conf create mode 100644 roles/ipt-server/files/etc/systemd/system/ip6t-firewall.service create mode 100644 roles/ipt-server/files/etc/systemd/system/ipt-firewall.service create mode 100755 roles/ipt-server/files/usr/local/sbin/ip6t-firewall-server create mode 100755 roles/ipt-server/files/usr/local/sbin/ipt-firewall-server create mode 100644 roles/ipt-server/handlers/main.yml create mode 100644 roles/ipt-server/tasks/main.yml create mode 100644 roles/ipt-server/templates/etc/ipt-firewall/interfaces_ipv4.conf.j2 create mode 100644 roles/ipt-server/templates/etc/ipt-firewall/interfaces_ipv6.conf.j2 create mode 100644 roles/ipt-server/templates/etc/ipt-firewall/main_ipv4.conf.j2 create mode 100644 roles/ipt-server/templates/etc/ipt-firewall/main_ipv6.conf.j2 diff --git a/.gitignore b/.gitignore index 1377554..18c96c0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,15 @@ +# Editor *.swp +*.swo +*~ + +# Python +__pycache__/ +*.py[cod] + +# Ansible +*.retry +.vault_pass + +# OS +.DS_Store diff --git a/extract-fw-host-vars.py b/extract-fw-host-vars.py new file mode 100755 index 0000000..b8a429b --- /dev/null +++ b/extract-fw-host-vars.py @@ -0,0 +1,726 @@ +#!/usr/bin/env python3 +""" +Extract ipt-firewall configuration from a host and generate host_vars YAML. + +Reads /etc/ipt-firewall/{interfaces,main}_ipv{4,6}.conf via SSH, +maps all variables to Ansible fw_* names, and writes a host_vars file. + +Usage: + ./extract-fw-host-vars.py [--user USER] [--port PORT] [--dry-run] + +Example: + ./extract-fw-host-vars.py cl-01.oopen.de + ./extract-fw-host-vars.py cl-01.oopen.de --user root --dry-run +""" + +import argparse +import re +import subprocess +import sys +from pathlib import Path + + +# --------------------------------------------------------------------------- +# Defaults matching roles/ipt-firewall/defaults/main.yml +# Only values that differ from these will be emitted. +# --------------------------------------------------------------------------- +DEFAULTS = { + "fw_do_not_firewall_bridged_traffic": False, + "fw_do_not_firewall_lx_guest_systems": False, + "fw_drop_icmp": False, + "fw_drop_mndp": True, + "fw_drop_mdns": True, + "fw_allow_all_outgoing_traffic": False, + "fw_blocked_ifs": "", + "fw_unprotected_ifs": "", + "fw_forward_private_ips_v4": "", + "fw_forward_private_ips_v6": "", + "fw_restrict_local_service_to_net_v4": "", + "fw_restrict_local_service_to_net_v6": "", + "fw_restrict_local_net_to_net_v4": "", + "fw_restrict_local_net_to_net_v6": "", + "fw_allow_ext_service_v4": "", + "fw_allow_ext_service_v6": "", + "fw_allow_ext_net_v4": "", + "fw_allow_ext_net_v6": "", + "fw_allow_local_service_v4": "", + "fw_allow_local_service_v6": "", + "fw_allow_local_service_from_networks_v4": "", + "fw_allow_local_service_from_networks_v6": "", + "fw_vpn_server_ips": "", + "fw_forward_vpn_server_ips": "", + "fw_vpn_ports": "$standard_vpn_port", + "fw_wireguard_server_ips": "", + "fw_forward_wireguard_server_ips": "", + "fw_wireguard_server_ports": "$standard_wireguard_port", + "fw_wireguard_out_ports": "$standard_wireguard_port", + "fw_local_ntp_service": False, + "fw_ntp_port": "$standard_ntp_port", + "fw_ntp_allowed_net": "", + "fw_dhcp_server_ifs": "", + "fw_dhcp_client_ifs": "", + "fw_dns_server_ips": "", + "fw_forward_dns_server_ips": "", + "fw_local_resolver_service": False, + "fw_resolver_port": "$standard_dns_port", + "fw_resolver_allowed_networks_v4": "", + "fw_resolver_allowed_networks_v6": "", + "fw_ssh_server_ips": "$ext_ips", + "fw_forward_ssh_server_ips": "", + "fw_ssh_ports": "$standard_ssh_port", + "fw_http_server_ips": "", + "fw_forward_http_server_ips": "", + "fw_http_ports": "$standard_http_ports", + "fw_log_cgi_traffic_out": False, + "fw_cgi_script_users": "", + "fw_mm_server_ips": "", + "fw_forward_mm_server_ips": "", + "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": "$standard_mailuser_ports", + "fw_mail_client_ips": "", + "fw_forward_mail_client_ips": "", + "fw_dovecot_auth_service": False, + "fw_dovecot_auth_port": "$dovecot_external_auth_port", + "fw_dovecot_auth_allowed_networks_v4": "", + "fw_dovecot_auth_allowed_networks_v6": "", + "fw_ftp_server_ips": "", + "fw_forward_ftp_server_ips": "", + "fw_ftp_passive_port_range": "50000:50400", + "fw_xmpp_server_ips": "", + "fw_forward_xmpp_server_ips": "", + "fw_xmmp_tcp_in_ports": "5222 5223 5269", + "fw_xmmp_tcp_out_ports": "5269", + "fw_xmmp_remote_out_services_v4": "", + "fw_xmmp_remote_out_services_v6": "", + "fw_mumble_server_ips": "", + "fw_forward_mumble_server_ips": "", + "fw_mumble_ports": "$standard_mumble_port", + "fw_jitsi_server_ips": "", + "fw_forward_jitsi_server_ips": "", + "fw_jitsi_dovecot_auth": False, + "fw_jitsi_dovecot_host": "", + "fw_jitsi_jibri_remote_auth": False, + "fw_jitsi_jibri_remote_ips": "", + "fw_jibri_server_ips": "", + "fw_forward_jibri_server_ips": "", + "fw_jibri_remote_jitsi_server": "", + "fw_nc_turn_server_ips": "", + "fw_forward_nc_turn_server_ips": "", + "fw_nc_turn_ports": "$standard_turn_service_ports", + "fw_nc_turn_udp_ports": "$standard_turn_service_udp_ports", + "fw_tftp_server_ips": "", + "fw_prometheus_local_server_ips": "", + "fw_prometheus_local_client_ips": "", + "fw_prometheus_remote_server_ips": "", + "fw_munin_server_ips": "", + "fw_forward_munin_server_ips": "", + "fw_munin_remote_port": "$standard_munin_port", + "fw_munin_local_port": "4949", + "munin_remote_ipv4": "", + "munin_remote_ipv6": "", + "fw_xymon_server_ips": "", + "fw_local_xymon_client": False, + "fw_xymon_port": "$standard_xymon_port", + "fw_rsync_out_ips": "", + "fw_forward_rsync_out_ips": "", + "fw_rsync_ports": "873", + "fw_tcp_out_ports": "", + "fw_forward_tcp_out_ports": "", + "fw_udp_out_ports": "", + "fw_forward_udp_out_ports": "", + "fw_portforward_tcp_v4": "", + "fw_portforward_udp_v4": "", + "fw_portforward_tcp_v6": "", + "fw_portforward_udp_v6": "", + "fw_blocked_ips": "", + "fw_block_tcp_ports": "111 113 135 137:139 445", + "fw_block_udp_ports": "111 137:139", + "fw_create_traffic_counter": True, + "fw_create_iperf_rules": True, + "fw_protection_against_syn_flooding": True, + "fw_protection_against_port_scanning": True, + "fw_protection_against_ssh_brute_force_attacks": True, + "fw_limit_connections_per_source_IP": True, + "fw_per_IP_connection_limit": "$default_per_IP_connection_limit", + "fw_limit_new_tcp_connections_per_seconds_per_source_IP": True, + "fw_limit_new_tcp_connections_per_seconds_ports": "", + "fw_kernel_activate_forwarding": False, + "fw_kernel_support_dynaddr": False, + "fw_dynaddr_flag": "5", + "fw_kernel_reduce_timeouts": True, + "fw_kernel_tcp_syncookies": True, + "fw_kernel_protect_against_icmp_bogus_messages": True, + "fw_kernel_ignore_broadcast_ping": True, + "fw_kernel_deactivate_source_route": True, + "fw_kernel_dont_accept_redirects": True, + "fw_kernel_activate_rp_filter": True, + "fw_kernel_log_martians": False, + "fw_kernel_forward_between_interfaces": False, + "fw_vpn_ifs": "tun+", + "fw_wg_ifs": "wg+", + "fw_nat_devices": "", +} + +# --------------------------------------------------------------------------- +# Variable mapping: (bash_varname, source) → ansible_varname +# source: 'iface_v4', 'iface_v6', 'main_v4', 'main_v6', 'main_shared' +# --------------------------------------------------------------------------- + +# Shared service variables (read from main_ipv4.conf, same in both) +MAIN_SHARED = { + "do_not_firewall_bridged_traffic": "fw_do_not_firewall_bridged_traffic", + "do_not_firewall_lx_guest_systems": "fw_do_not_firewall_lx_guest_systems", + "drop_icmp": "fw_drop_icmp", + "drop_mndp": "fw_drop_mndp", + "drop_mdns": "fw_drop_mdns", + "allow_all_outgoing_traffic": "fw_allow_all_outgoing_traffic", + "blocked_ifs": "fw_blocked_ifs", + "unprotected_ifs": "fw_unprotected_ifs", + "vpn_server_ips": "fw_vpn_server_ips", + "forward_vpn_server_ips": "fw_forward_vpn_server_ips", + "vpn_ports": "fw_vpn_ports", + "wireguard_server_ips": "fw_wireguard_server_ips", + "forward_wireguard_server_ips": "fw_forward_wireguard_server_ips", + "wireguard_server_ports": "fw_wireguard_server_ports", + "wireguard_out_ports": "fw_wireguard_out_ports", + "local_ntp_service": "fw_local_ntp_service", + "ntp_port": "fw_ntp_port", + "ntp_allowed_net": "fw_ntp_allowed_net", + "dns_server_ips": "fw_dns_server_ips", + "forward_dns_server_ips": "fw_forward_dns_server_ips", + "local_resolver_service": "fw_local_resolver_service", + "resolver_port": "fw_resolver_port", + "ssh_server_ips": "fw_ssh_server_ips", + "forward_ssh_server_ips": "fw_forward_ssh_server_ips", + "ssh_ports": "fw_ssh_ports", + "http_server_ips": "fw_http_server_ips", + "forward_http_server_ips": "fw_forward_http_server_ips", + "http_ports": "fw_http_ports", + "log_cgi_traffic_out": "fw_log_cgi_traffic_out", + "cgi_script_users": "fw_cgi_script_users", + "mm_server_ips": "fw_mm_server_ips", + "forward_mm_server_ips": "fw_forward_mm_server_ips", + "smtpd_ips": "fw_smtpd_ips", + "forward_smtpd_ips": "fw_forward_smtpd_ips", + "smtpd_additional_listen_ports": "fw_smtpd_additional_listen_ports", + "smtpd_additional_outgoung_ports": "fw_smtpd_additional_outgoing_ports", + "mail_server_ips": "fw_mail_server_ips", + "forward_mail_server_ips": "fw_forward_mail_server_ips", + "mail_user_ports": "fw_mail_user_ports", + "mail_client_ips": "fw_mail_client_ips", + "forward_mail_client_ips": "fw_forward_mail_client_ips", + "dovecot_auth_service": "fw_dovecot_auth_service", + "dovecot_auth_port": "fw_dovecot_auth_port", + "ftp_server_ips": "fw_ftp_server_ips", + "forward_ftp_server_ips": "fw_forward_ftp_server_ips", + "ftp_passive_port_range": "fw_ftp_passive_port_range", + "xmpp_server_ips": "fw_xmpp_server_ips", + "forward_xmpp_server_ips": "fw_forward_xmpp_server_ips", + "xmmp_tcp_in_ports": "fw_xmmp_tcp_in_ports", + "xmmp_tcp_out_ports": "fw_xmmp_tcp_out_ports", + "mumble_server_ips": "fw_mumble_server_ips", + "forward_mumble_server_ips": "fw_forward_mumble_server_ips", + "mumble_ports": "fw_mumble_ports", + "jitsi_server_ips": "fw_jitsi_server_ips", + "forward_jitsi_server_ips": "fw_forward_jitsi_server_ips", + "jitsi_tcp_ports": "fw_jitsi_tcp_ports", + "jitsi_udp_port_range": "fw_jitsi_udp_port_range", + "jitsi_tcp_ports_out": "fw_jitsi_tcp_ports_out", + "jitsi_udp_ports_out": "fw_jitsi_udp_ports_out", + "jitsi_dovecot_auth": "fw_jitsi_dovecot_auth", + "jitsi_dovecot_host": "fw_jitsi_dovecot_host", + "jitsi_jibri_remote_auth": "fw_jitsi_jibri_remote_auth", + "jitsi_jibri_remote_ips": "fw_jitsi_jibri_remote_ips", + "jibri_server_ips": "fw_jibri_server_ips", + "forward_jibri_server_ips": "fw_forward_jibri_server_ips", + "jibri_remote_jitsi_server": "fw_jibri_remote_jitsi_server", + "nc_turn_server_ips": "fw_nc_turn_server_ips", + "forward_nc_turn_server_ips": "fw_forward_nc_turn_server_ips", + "nc_turn_ports": "fw_nc_turn_ports", + "nc_turn_udp_ports": "fw_nc_turn_udp_ports", + "tftp_server_ips": "fw_tftp_server_ips", + "prometheus_local_server_ips": "fw_prometheus_local_server_ips", + "prometheus_local_client_ips": "fw_prometheus_local_client_ips", + "prometheus_remote_server_ips": "fw_prometheus_remote_server_ips", + "munin_server_ips": "fw_munin_server_ips", + "forward_munin_server_ips": "fw_forward_munin_server_ips", + "munin_remote_port": "fw_munin_remote_port", + "munin_local_port": "fw_munin_local_port", + "xymon_server_ips": "fw_xymon_server_ips", + "local_xymon_client": "fw_local_xymon_client", + "xymon_port": "fw_xymon_port", + "rsync_out_ips": "fw_rsync_out_ips", + "forward_rsync_out_ips": "fw_forward_rsync_out_ips", + "rsync_ports": "fw_rsync_ports", + "tcp_out_ports": "fw_tcp_out_ports", + "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", + "create_iperf_rules": "fw_create_iperf_rules", + "protection_against_syn_flooding": "fw_protection_against_syn_flooding", + "protection_against_port_scanning": "fw_protection_against_port_scanning", + "protection_against_ssh_brute_force_attacks": "fw_protection_against_ssh_brute_force_attacks", + "limit_connections_per_source_IP": "fw_limit_connections_per_source_IP", + "per_IP_connection_limit": "fw_per_IP_connection_limit", + "limit_new_tcp_connections_per_seconds_per_source_IP": "fw_limit_new_tcp_connections_per_seconds_per_source_IP", + "limit_new_tcp_connections_per_seconds_ports": "fw_limit_new_tcp_connections_per_seconds_ports", +} + +# IPv4-only variables (from main_ipv4.conf) +MAIN_V4_ONLY = { + "forward_private_ips": "fw_forward_private_ips_v4", + "restrict_local_service_to_net": "fw_restrict_local_service_to_net_v4", + "restrict_local_net_to_net": "fw_restrict_local_net_to_net_v4", + "allow_ext_service": "fw_allow_ext_service_v4", + "allow_ext_net": "fw_allow_ext_net_v4", + "allow_local_service": "fw_allow_local_service_v4", + "allow_local_service_from_networks": "fw_allow_local_service_from_networks_v4", + "portforward_tcp": "fw_portforward_tcp_v4", + "portforward_udp": "fw_portforward_udp_v4", + "munin_remote_ip": "munin_remote_ipv4", + "dovecot_auth_allowed_networks": "fw_dovecot_auth_allowed_networks_v4", + "xmmp_remote_out_services": "fw_xmmp_remote_out_services_v4", + "resolver_allowed_networks": "fw_resolver_allowed_networks_v4", + "dhcp_server_ifs": "fw_dhcp_server_ifs", + "dhcp_client_ifs": "fw_dhcp_client_ifs", + "kernel_activate_forwarding": "fw_kernel_activate_forwarding", + "kernel_support_dynaddr": "fw_kernel_support_dynaddr", + "dynaddr_flag": "fw_dynaddr_flag", + "kernel_reduce_timeouts": "fw_kernel_reduce_timeouts", + "kernel_tcp_syncookies": "fw_kernel_tcp_syncookies", + "kernel_protect_against_icmp_bogus_messages": "fw_kernel_protect_against_icmp_bogus_messages", + "kernel_ignore_broadcast_ping": "fw_kernel_ignore_broadcast_ping", + "kernel_activate_rp_filter": "fw_kernel_activate_rp_filter", + "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", +} + +# IPv6-only variables (from main_ipv6.conf) +MAIN_V6_ONLY = { + "forward_private_ips": "fw_forward_private_ips_v6", + "restrict_local_service_to_net": "fw_restrict_local_service_to_net_v6", + "restrict_local_net_to_net": "fw_restrict_local_net_to_net_v6", + "allow_ext_service": "fw_allow_ext_service_v6", + "allow_ext_net": "fw_allow_ext_net_v6", + "allow_local_service": "fw_allow_local_service_v6", + "allow_local_service_from_networks": "fw_allow_local_service_from_networks_v6", + "portforward_tcp": "fw_portforward_tcp_v6", + "portforward_udp": "fw_portforward_udp_v6", + "munin_remote_ip": "munin_remote_ipv6", + "dovecot_auth_allowed_networks": "fw_dovecot_auth_allowed_networks_v6", + "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", +} + + +# --------------------------------------------------------------------------- +# Parsing +# --------------------------------------------------------------------------- + +def parse_bash_config(text): + """ + Parse key=value pairs from a bash config file. + Handles: var="value", var=value, var=true/false + Multiline values (var="line1\n line2\n") are joined as a single string. + Returns dict of {varname: value_string} + """ + result = {} + warnings = [] + + # Collapse multiline quoted strings: "...\n ..." → "... ..." + # Strategy: scan char by char for opening " after =, collect until closing " + lines = text.splitlines() + i = 0 + while i < len(lines): + line = lines[i].strip() + + # Skip comments and blank lines + if not line or line.startswith('#'): + i += 1 + continue + + # Match assignment + m = re.match(r'^([A-Za-z_][A-Za-z0-9_]*)=(.*)', line) + if not m: + i += 1 + continue + + varname = m.group(1) + rest = m.group(2).strip() + + # Quoted value + if rest.startswith('"'): + # Collect until closing quote (may span multiple lines) + collected = rest[1:] # strip opening " + closed = False + extra_lines = [] + + while True: + # Check if closing " is in collected + close_pos = collected.find('"') + if close_pos != -1: + value = collected[:close_pos].strip() + if extra_lines: + warnings.append(f" # {varname}: multiline value — verify manually") + result[varname] = value + closed = True + break + else: + # Value continues on next line + extra_lines.append(collected.strip()) + i += 1 + if i >= len(lines): + break + collected = lines[i].strip() + + if not closed: + warnings.append(f" # {varname}: unterminated quoted string — skipped") + + else: + # Unquoted value (true, false, $var_ref, number, etc.) + # Strip trailing comment + value = re.sub(r'\s+#.*$', '', rest).strip() + result[varname] = value + + i += 1 + + return result, warnings + + +def ssh_cat(host, user, port, path, sudo_password=None): + """Read a file from a remote host via SSH. Returns file content or None.""" + ssh_cmd = ["ssh"] + if user: + ssh_cmd += ["-l", user] + if port: + ssh_cmd += ["-p", str(port)] + ssh_cmd += ["-o", "BatchMode=yes", "-o", "ConnectTimeout=10", host] + + if sudo_password is not None: + # Use sudo -S to read password from stdin; -p '' suppresses the prompt + ssh_cmd += [f"sudo -S -p '' cat {path}"] + stdin_data = sudo_password + "\n" + else: + ssh_cmd += [f"cat {path}"] + stdin_data = None + + try: + result = subprocess.run( + ssh_cmd, input=stdin_data, capture_output=True, text=True, timeout=30 + ) + if result.returncode != 0: + print(f" WARNING: could not read {path}: {result.stderr.strip()}", file=sys.stderr) + return None + return result.stdout + except subprocess.TimeoutExpired: + print(f" ERROR: SSH timeout reading {path}", file=sys.stderr) + return None + + +def coerce_bool(value): + """Convert bash true/false string to Python bool, or return string.""" + if value.lower() in ("true", "yes", "1"): + return True + if value.lower() in ("false", "no", "0"): + return False + return value # keep as string (e.g. $standard_ssh_port) + + +def yaml_value(v): + """Format a Python value as a YAML-safe string.""" + if isinstance(v, bool): + return "true" if v else "false" + if v == "": + return '""' + # Quote if contains special YAML characters + if any(c in str(v) for c in [':', '#', '{', '}', '[', ']', ',', '&', '*', '?', '|', '-', '<', '>', '=', '!', '%', '@', '`', '"', "'"]): + # Use double-quote with escaping + escaped = str(v).replace('\\', '\\\\').replace('"', '\\"') + return f'"{escaped}"' + return str(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. + """ + result = {} + + # --- Interfaces: extract lists from numbered vars --- + def extract_list(parsed, prefix, suffix="", count=3): + items = [] + for i in range(1, count + 1): + v = parsed.get(f"{prefix}{i}{suffix}", "").strip() + if v: + items.append(v) + return items + + fw_ext_interfaces = extract_list(parsed_iface_v4, "ext_if_") + fw_ext_ips_v4 = extract_list(parsed_iface_v4, "ext_", suffix="_ip") # ext_1_ip, ext_2_ip, ext_3_ip + fw_ext_ips_v6 = extract_list(parsed_iface_v6, "ext_", suffix="_ip") + fw_local_interfaces = extract_list(parsed_iface_v4, "local_if_") + fw_local_ips_v4 = extract_list(parsed_iface_v4, "local_", suffix="_ip") + fw_local_ips_v6 = extract_list(parsed_iface_v6, "local_", suffix="_ip") + fw_lxc_guest_ips_v4 = extract_list(parsed_iface_v4, "lxc_guest_", suffix="_ip", count=7) + fw_lxc_guest_ips_v6 = extract_list(parsed_iface_v6, "lxc_guest_", suffix="_ip", count=7) + + if fw_ext_interfaces: + result["fw_ext_interfaces"] = fw_ext_interfaces + if fw_ext_ips_v4: + result["fw_ext_ips_v4"] = fw_ext_ips_v4 + if fw_ext_ips_v6: + result["fw_ext_ips_v6"] = fw_ext_ips_v6 + if fw_local_interfaces: + result["fw_local_interfaces"] = fw_local_interfaces + if fw_local_ips_v4: + result["fw_local_ips_v4"] = fw_local_ips_v4 + if fw_local_ips_v6: + result["fw_local_ips_v6"] = fw_local_ips_v6 + if fw_lxc_guest_ips_v4: + result["fw_lxc_guest_ips_v4"] = fw_lxc_guest_ips_v4 + if fw_lxc_guest_ips_v6: + result["fw_lxc_guest_ips_v6"] = fw_lxc_guest_ips_v6 + + # vpn_ifs / wg_ifs / nat_devices (same in both interface files) + for bash_var, ansible_var in [("vpn_ifs", "fw_vpn_ifs"), ("wg_ifs", "fw_wg_ifs"), ("nat_devices", "fw_nat_devices")]: + v = parsed_iface_v4.get(bash_var, "") + if v and v != DEFAULTS.get(ansible_var, ""): + result[ansible_var] = v + + # --- Shared main variables (read from ipv4) --- + for bash_var, ansible_var in MAIN_SHARED.items(): + raw = parsed_main_v4.get(bash_var) + if raw is None: + continue + v = coerce_bool(raw) if raw.lower() in ("true", "false") else raw + default = DEFAULTS.get(ansible_var) + if v != default: + result[ansible_var] = v + + # --- IPv4-only main variables --- + for bash_var, ansible_var in MAIN_V4_ONLY.items(): + raw = parsed_main_v4.get(bash_var) + if raw is None: + continue + v = coerce_bool(raw) if raw.lower() in ("true", "false") else raw + default = DEFAULTS.get(ansible_var) + if v != default: + result[ansible_var] = v + + # --- IPv6-only main variables --- + for bash_var, ansible_var in MAIN_V6_ONLY.items(): + raw = parsed_main_v6.get(bash_var) + if raw is None: + continue + 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 + + +def render_yaml(hostname, host_vars, all_warnings): + """Render the host_vars as YAML text.""" + lines = [ + "---", + f"# ipt-firewall configuration for {hostname}", + "# Generated by extract-fw-host-vars.py - review before committing!", + "# Place in: host_vars//ipt_firewall.yml", + "", + ] + + if all_warnings: + lines.append("# WARNINGS — manual review needed:") + for w in all_warnings: + lines.append(w) + lines.append("") + + # Group output by section + sections = [ + ("Network", ["fw_ext_interfaces", "fw_ext_ips_v4", "fw_ext_ips_v6", + "fw_local_interfaces", "fw_local_ips_v4", "fw_local_ips_v6", + "fw_lxc_guest_ips_v4", "fw_lxc_guest_ips_v6", + "fw_vpn_ifs", "fw_wg_ifs", "fw_nat_devices"]), + ("Munin", ["munin_remote_ipv4", "munin_remote_ipv6", "fw_munin_local_port", + "fw_munin_server_ips", "fw_forward_munin_server_ips", "fw_munin_remote_port"]), + ("Bridged / LXC", ["fw_do_not_firewall_bridged_traffic", "fw_do_not_firewall_lx_guest_systems"]), + ("Drop policies", ["fw_drop_icmp", "fw_drop_mndp", "fw_drop_mdns"]), + ("Outgoing / interfaces", ["fw_allow_all_outgoing_traffic", "fw_blocked_ifs", "fw_unprotected_ifs"]), + ("Forwarding", ["fw_forward_private_ips_v4", "fw_forward_private_ips_v6", + "fw_kernel_activate_forwarding", "fw_kernel_forward_between_interfaces"]), + ("Access control IPv4", ["fw_restrict_local_service_to_net_v4", "fw_restrict_local_net_to_net_v4", + "fw_allow_ext_service_v4", "fw_allow_ext_net_v4", + "fw_allow_local_service_v4", "fw_allow_local_service_from_networks_v4"]), + ("Access control IPv6", ["fw_restrict_local_service_to_net_v6", "fw_restrict_local_net_to_net_v6", + "fw_allow_ext_service_v6", "fw_allow_ext_net_v6", + "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"]), + ("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", + "fw_dovecot_auth_service", "fw_dovecot_auth_port", + "fw_dovecot_auth_allowed_networks_v4", "fw_dovecot_auth_allowed_networks_v6"]), + ("DNS", ["fw_dns_server_ips", "fw_forward_dns_server_ips", + "fw_local_resolver_service", "fw_resolver_port", + "fw_resolver_allowed_networks_v4", "fw_resolver_allowed_networks_v6"]), + ("NTP", ["fw_local_ntp_service", "fw_ntp_port", "fw_ntp_allowed_net"]), + ("DHCP", ["fw_dhcp_server_ifs", "fw_dhcp_client_ifs"]), + ("VPN / WireGuard", ["fw_vpn_server_ips", "fw_forward_vpn_server_ips", "fw_vpn_ports", + "fw_wireguard_server_ips", "fw_forward_wireguard_server_ips", + "fw_wireguard_server_ports", "fw_wireguard_out_ports"]), + ("FTP", ["fw_ftp_server_ips", "fw_forward_ftp_server_ips", "fw_ftp_passive_port_range"]), + ("XMPP", ["fw_xmpp_server_ips", "fw_forward_xmpp_server_ips", + "fw_xmmp_tcp_in_ports", "fw_xmmp_tcp_out_ports", + "fw_xmmp_remote_out_services_v4", "fw_xmmp_remote_out_services_v6"]), + ("Mumble", ["fw_mumble_server_ips", "fw_forward_mumble_server_ips", "fw_mumble_ports"]), + ("Jitsi", ["fw_jitsi_server_ips", "fw_forward_jitsi_server_ips", + "fw_jitsi_tcp_ports", "fw_jitsi_udp_port_range", + "fw_jitsi_dovecot_auth", "fw_jitsi_dovecot_host", + "fw_jitsi_jibri_remote_auth", "fw_jitsi_jibri_remote_ips", + "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"]), + ("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"]), + ("Rsync", ["fw_rsync_out_ips", "fw_forward_rsync_out_ips", "fw_rsync_ports"]), + ("Out ports", ["fw_tcp_out_ports", "fw_forward_tcp_out_ports", + "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"]), + ("Protection / limits", ["fw_protection_against_syn_flooding", + "fw_protection_against_port_scanning", + "fw_protection_against_ssh_brute_force_attacks", + "fw_limit_connections_per_source_IP", "fw_per_IP_connection_limit", + "fw_limit_new_tcp_connections_per_seconds_per_source_IP", + "fw_limit_new_tcp_connections_per_seconds_ports"]), + ("Kernel IPv4", ["fw_kernel_support_dynaddr", "fw_dynaddr_flag", + "fw_kernel_reduce_timeouts", "fw_kernel_tcp_syncookies", + "fw_kernel_protect_against_icmp_bogus_messages", + "fw_kernel_ignore_broadcast_ping", + "fw_kernel_deactivate_source_route", "fw_kernel_dont_accept_redirects", + "fw_kernel_activate_rp_filter", "fw_kernel_log_martians"]), + ("Special", ["fw_create_traffic_counter", "fw_create_iperf_rules"]), + ] + + emitted = set() + for section_name, keys in sections: + section_lines = [] + for k in keys: + if k in host_vars: + v = host_vars[k] + if isinstance(v, list): + section_lines.append(f"{k}:") + for item in v: + section_lines.append(f" - \"{item}\"") + elif isinstance(v, bool): + section_lines.append(f"{k}: {'true' if v else 'false'}") + else: + section_lines.append(f"{k}: {yaml_value(str(v))}") + emitted.add(k) + + if section_lines: + lines.append(f"# --- {section_name}") + lines.extend(section_lines) + lines.append("") + + # Anything not covered by sections + remaining = {k: v for k, v in host_vars.items() if k not in emitted} + if remaining: + lines.append("# --- Other") + for k, v in remaining.items(): + if isinstance(v, list): + lines.append(f"{k}:") + for item in v: + lines.append(f" - \"{item}\"") + elif isinstance(v, bool): + lines.append(f"{k}: {'true' if v else 'false'}") + else: + lines.append(f"{k}: {yaml_value(str(v))}") + lines.append("") + + return "\n".join(lines) + + +def main(): + parser = argparse.ArgumentParser(description="Extract ipt-firewall host_vars from a remote host") + parser.add_argument("hostname", help="Target hostname (must be in SSH config or known_hosts)") + parser.add_argument("--user", "-u", default="chris", help="SSH user (default: chris)") + parser.add_argument("--port", "-p", type=int, default=None, help="SSH port (default: 22)") + parser.add_argument("--output", "-o", default=None, help="Output file (default: stdout)") + parser.add_argument("--sudo", "-s", action="store_true", + help="Read files via sudo (prompts for sudo password once)") + parser.add_argument("--dry-run", action="store_true", help="Print SSH commands without executing") + args = parser.parse_args() + + hostname = args.hostname + conf_dir = "/etc/ipt-firewall" + files = { + "iface_v4": f"{conf_dir}/interfaces_ipv4.conf", + "iface_v6": f"{conf_dir}/interfaces_ipv6.conf", + "main_v4": f"{conf_dir}/main_ipv4.conf", + "main_v6": f"{conf_dir}/main_ipv6.conf", + } + + if args.dry_run: + cmd = "sudo -S -p '' cat" if args.sudo else "cat" + for key, path in files.items(): + print(f"ssh {args.user}@{hostname} {cmd} {path}") + return + + sudo_password = None + if args.sudo: + import getpass + sudo_password = getpass.getpass(f"sudo password for {args.user}@{hostname}: ") + + print(f"Connecting to {hostname} as {args.user} ...", file=sys.stderr) + + contents = {} + for key, path in files.items(): + print(f" Reading {path} ...", file=sys.stderr) + content = ssh_cat(hostname, args.user, args.port, path, sudo_password=sudo_password) + contents[key] = content or "" + + all_warnings = [] + parsed = {} + for key, text in contents.items(): + p, warnings = parse_bash_config(text) + parsed[key] = p + if warnings: + all_warnings.extend([f" # [{key}] {w}" for w in warnings]) + + host_vars = build_host_vars( + parsed["iface_v4"], parsed["iface_v6"], + parsed["main_v4"], parsed["main_v6"], + ) + + yaml_text = render_yaml(hostname, host_vars, all_warnings) + + if args.output: + out_path = Path(args.output) + out_path.parent.mkdir(parents=True, exist_ok=True) + out_path.write_text(yaml_text) + print(f"Written to {out_path}", file=sys.stderr) + else: + print(yaml_text) + + +if __name__ == "__main__": + main() diff --git a/host_vars/test.mx.oopen.de/ipt_firewall.yml b/host_vars/test.mx.oopen.de/ipt_firewall.yml new file mode 100644 index 0000000..63d3e2d --- /dev/null +++ b/host_vars/test.mx.oopen.de/ipt_firewall.yml @@ -0,0 +1,47 @@ +--- +# ipt-firewall configuration for test.mx.oopen.de +# Generated by extract-fw-host-vars.py - review before committing! + +fw_manage_config: true + +# --- Network +fw_ext_interfaces: + - "eth0" + - "eth1" +fw_ext_ips_v4: + - "83.223.85.205" + - "83.223.85.206" +fw_ext_ips_v6: + - "2a01:30:0:505:2eb:f4ff:feaa:d996 2a01:30:0:13:2eb:f4ff:feaa:d996" + - "2a01:30:0:505:2eb:f4ff:feaa:d997 2a01:30:0:13:2eb:f4ff:feaa:d997" + +# --- Munin +munin_remote_ipv4: 37.27.121.227 +munin_remote_ipv6: "2a01:4f9:3070:2bda::227" + +# --- HTTP +fw_http_server_ips: $ext_1_ip $ext_2_ip + +# --- Mail +fw_smtpd_ips: $ext_1_ip +fw_mail_server_ips: $ext_1_ip +fw_mail_client_ips: $ext_1_ip $ext_2_ip +fw_dovecot_auth_service: true +fw_dovecot_auth_allowed_networks_v4: 192.68.11.79 + +# --- Mumble +fw_mumble_server_ips: 138.201.33.54 + +# --- Jitsi +fw_jitsi_tcp_ports: $standard_jitsi_tcp_ports +fw_jitsi_udp_port_range: $standard_jitsi_udp_port_range + +# --- Rsync +fw_rsync_out_ips: $ext_1_ip + +# --- Block +fw_blocked_ips: 222.184.0.0/13 61.160.0.0/16 116.8.0.0/14 + +# --- Other +fw_jitsi_tcp_ports_out: "$standard_turn_service_ports,4443,4444,4445,4446" +fw_jitsi_udp_ports_out: "$standard_http_ports,$standard_turn_service_ports,4443,4444,4445,4446" diff --git a/ipt-server.yml b/ipt-server.yml new file mode 100644 index 0000000..8d346a4 --- /dev/null +++ b/ipt-server.yml @@ -0,0 +1,5 @@ +--- + +- hosts: all + roles: + - ipt-server diff --git a/roles/ipt-server/MIGRATION.md b/roles/ipt-server/MIGRATION.md new file mode 100644 index 0000000..1bdae67 --- /dev/null +++ b/roles/ipt-server/MIGRATION.md @@ -0,0 +1,199 @@ +# ipt-server — Migrationsleitfaden + +Dieser Leitfaden beschreibt, wie ein bestehender Host vom alten Verfahren +(manuell verwaltete `/etc/ipt-firewall/`-Dateien, ggf. `firewall`- oder +`modify-ipt-server`-Rolle) auf die neue `ipt-server`-Ansible-Rolle umgestellt +wird. + +--- + +## Überblick + +Das alte Verfahren: +- Firewall-Skripte und Conf-Dateien wurden manuell oder über die alte `firewall`-Rolle + (lineinfile/blockinfile) gepflegt. +- Änderungen direkt in `/etc/ipt-firewall/` auf dem Host. + +Das neue Verfahren: +- Alle Firewall-Einstellungen liegen in `host_vars//ipt_firewall.yml`. +- Ansible deployt die Config-Dateien aus Jinja2-Templates. +- Direktes Editieren auf dem Host ist nicht mehr vorgesehen. + +Die Migration ist **nicht-destruktiv**: Bestehende Config-Dateien werden erst +dann überschrieben, wenn die Migration explizit freigegeben wird (`fw_manage_config: true`). + +--- + +## Schritt 1 — Aktuelle Konfiguration auslesen + +Das Skript `extract-fw-host-vars.py` liest die vier Conf-Dateien vom Host via SSH, +mappt alle Variablen auf die `fw_*`-Ansible-Variablen und schreibt eine fertige +`host_vars`-Datei: + +```bash +cd /path/to/ansible/oopen-server + +./extract-fw-host-vars.py --sudo \ + -o host_vars//ipt_firewall.yml +``` + +Das Skript fragt einmalig nach dem `sudo`-Passwort. + +**Ergebnis prüfen:** + +```bash +cat host_vars//ipt_firewall.yml +``` + +Kontrollpunkte: +- Sind `fw_ext_interfaces`, `fw_ext_ips_v4`, `fw_ext_ips_v6` korrekt? +- Sind aktivierte Dienste (Mail, HTTP, VPN usw.) vorhanden? +- Sind `munin_remote_ipv4` / `munin_remote_ipv6` eingetragen (falls Munin läuft)? + +Fehlende oder falsche Werte können direkt in der YAML-Datei korrigiert werden. +Alle Variablen und ihre Bedeutung stehen in `defaults/main.yml`. + +--- + +## Schritt 2 — Erste Ausrollung (Safety-Guard aktiv) + +Solange `fw_manage_config` nicht auf `true` gesetzt ist (Default: `false`), +überschreibt Ansible **keine** bestehenden Config-Dateien. Es werden nur +installiert: +- Firewall-Skripte → `/usr/local/sbin/` +- Geteilte Conf-Dateien → `/etc/ipt-firewall/` +- Systemd-Units → `/etc/systemd/system/` + +```bash +# Vorschau: +ansible-playbook ipt-server.yml --limit --check --diff + +# Ausrollen: +ansible-playbook ipt-server.yml --limit +``` + +Die Firewall wird dabei **nicht neu gestartet** — die bestehenden Config-Dateien +bleiben unangetastet. + +--- + +## Schritt 3 — Verifizieren: sind die Rules identisch? + +Dieser Schritt prüft, ob ein Neustart der Firewall mit den neuen Skripten und +den bestehenden Config-Dateien exakt dieselben iptables-Rules erzeugt wie aktuell +geladen. + +```bash +ssh ' + # Aktuellen Stand einfrieren (Timestamps und Zähler normalisieren) + iptables-save | grep -v "^#" | sed "s/\[[0-9]*:[0-9]*\]/[0:0]/g" \ + > /tmp/fw_before_v4.rules + ip6tables-save | grep -v "^#" | sed "s/\[[0-9]*:[0-9]*\]/[0:0]/g" \ + > /tmp/fw_before_v6.rules + + # Firewall neu starten + systemctl restart ipt-firewall + systemctl restart ip6t-firewall + + # Neuen Stand einfrieren + iptables-save | grep -v "^#" | sed "s/\[[0-9]*:[0-9]*\]/[0:0]/g" \ + > /tmp/fw_after_v4.rules + ip6tables-save | grep -v "^#" | sed "s/\[[0-9]*:[0-9]*\]/[0:0]/g" \ + > /tmp/fw_after_v6.rules + + # Vergleichen + echo "=== IPv4 diff ===" + diff /tmp/fw_before_v4.rules /tmp/fw_after_v4.rules + echo "=== IPv6 diff ===" + diff /tmp/fw_before_v6.rules /tmp/fw_after_v6.rules +' +``` + +**Erwartetes Ergebnis:** Beide Diffs sind leer. + +Falls Unterschiede erscheinen: die abweichenden Rules identifizieren, die +entsprechenden Variablen in `host_vars//ipt_firewall.yml` nachpflegen +und den Diff wiederholen bevor weitergemacht wird. + +--- + +## Schritt 4 — Ansible als autoritative Quelle freischalten + +Erst wenn Schritt 3 erfolgreich war (leere Diffs), wird die Migration abgeschlossen. +Dazu `fw_manage_config: true` in der host_vars-Datei setzen: + +```yaml +# host_vars//ipt_firewall.yml +--- +fw_manage_config: true # ← hinzufügen / auf true setzen + +fw_ext_interfaces: + - "eth0" +# ... +``` + +Dann erneut ausrollen: + +```bash +# Vorschau — zeigt jetzt auch die Config-Dateien im Diff: +ansible-playbook ipt-server.yml --limit --check --diff + +# Anwenden: +ansible-playbook ipt-server.yml --limit +``` + +Ab jetzt: +- Ansible überschreibt die vier Config-Dateien bei jedem Run aus den Templates. +- Bei Änderungen an Templates oder host_vars wird die Firewall automatisch + neu gestartet. +- Direktes Editieren von `/etc/ipt-firewall/interfaces_*.conf` oder `main_*.conf` + auf dem Host wird beim nächsten Ansible-Run überschrieben. + +--- + +## Schritt 5 — Altes System deaktivieren + +### Altes Ansible-Vorgehen abschalten + +Sicherstellen, dass der Host nicht mehr durch die alte `firewall`-Rolle oder +`modify-ipt-server`-Rolle verwaltet wird. Falls der Host in einem Playbook +eingetragen ist, das diese Rollen verwendet, den Host dort entfernen oder das +Playbook anpassen. + +### Altes git-Repository auf dem Host entfernen (optional) + +Das Repository `/usr/local/src/ipt-server` wird von der neuen Rolle nicht mehr +benötigt. Es kann entfernt werden: + +```bash +ssh 'rm -rf /usr/local/src/ipt-server' +``` + +Vorher prüfen, ob das Verzeichnis noch anderweitig verwendet wird. + +### Sicherstellen, dass niemand mehr direkt editiert + +Da `fw_manage_config: true` gesetzt ist, werden direkte Änderungen in +`/etc/ipt-firewall/` beim nächsten Ansible-Run überschrieben. Als zusätzliche +Absicherung kann eine kurze Warnung oben in die Config-Dateien geschrieben +werden — das erledigt Ansible automatisch über den `{{ ansible_managed }}`-Kommentar +am Anfang jedes generierten Templates: + +```bash +# Ansible managed +# DO NOT EDIT - changes will be overwritten on the next Ansible run. +# Edit host_vars//ipt_firewall.yml instead. +``` + +--- + +## Zusammenfassung + +| Schritt | Befehl / Aktion | Wann | +|---|---|---| +| 1 | `extract-fw-host-vars.py` ausführen | Einmalig pro Host | +| 2 | `ansible-playbook ... --check --diff` + ausrollen | Einmalig pro Host | +| 3 | iptables-Rules vergleichen (vor/nach Restart) | Einmalig pro Host | +| 4 | `fw_manage_config: true` setzen + ausrollen | Einmalig pro Host | +| 5 | Alte Rolle deaktivieren, git-Repo auf Host entfernen | Einmalig pro Host | +| — | Änderungen: host_vars editieren + `ansible-playbook` | Ab jetzt immer so | diff --git a/roles/ipt-server/README.md b/roles/ipt-server/README.md new file mode 100644 index 0000000..c6f2b9a --- /dev/null +++ b/roles/ipt-server/README.md @@ -0,0 +1,204 @@ +# 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//ipt_firewall.yml +``` + +--- + +## Neuen Host aufnehmen + +### Voraussetzungen + +- Host ist im Ansible-Inventory (`hosts`) eingetragen. +- SSH-Zugang mit `sudo`-Rechten ist vorhanden. +- `git` ist auf dem Host installiert (wird für keinen anderen Zweck gebraucht — + die Rolle selbst benötigt kein git auf dem Host). + +### Schritt 1 — host_vars anlegen + +```bash +cd /path/to/ansible/oopen-server + +# Interfaces und IPs von Hand in die Datei eintragen: +mkdir -p host_vars/ +cat > host_vars//ipt_firewall.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 + +```bash +ansible-playbook ipt-server.yml --limit --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 + +```bash +ansible-playbook ipt-server.yml --limit +``` + +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//ipt_firewall.yml +``` + +Danach: + +```bash +# Vorschau: +ansible-playbook ipt-server.yml --limit --check --diff + +# Anwenden (ändert Config, startet Firewall bei Änderungen neu): +ansible-playbook ipt-server.yml --limit +``` + +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 + +```yaml +# host_vars//ipt_firewall.yml +fw_http_server_ips: "$ext_ips" # oder konkrete IP +``` + +### Beispiel: SSH auf bestimmten Port einschränken + +```yaml +fw_ssh_ports: "2222" +``` + +### Beispiel: LXC-Gäste eintragen + +```yaml +fw_lxc_guest_ips_v4: + - "10.0.3.10" + - "10.0.3.11" +fw_lxc_guest_ips_v6: + - "fd00::10" + - "fd00::11" +``` + +--- + +## 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: + +```bash +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/`. + +Nach dem Commit werden die neuen Skripte beim nächsten Ansible-Run auf alle +Hosts deployed. + +--- + +## 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 | +| `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. diff --git a/roles/ipt-server/defaults/main.yml b/roles/ipt-server/defaults/main.yml new file mode 100644 index 0000000..d043198 --- /dev/null +++ b/roles/ipt-server/defaults/main.yml @@ -0,0 +1,376 @@ +--- + +# --- +# ipt-firewall role defaults +# Override per host in host_vars//ipt_firewall.yml +# --- + + +# --- +# Config management mode. +# false (default): config files are only deployed when absent (safe for unmanaged hosts). +# true: Ansible is authoritative — config is always written from templates and +# the firewall is restarted on any change. Set this after migrating a host. +# --- + +fw_manage_config: false + + +# --- +# Network interfaces and addresses (set per host in host_vars) +# --- + +fw_ext_interfaces: [] # e.g. ["eth0"] +fw_ext_ips_v4: [] # e.g. ["83.223.86.98"] +fw_ext_ips_v6: [] # e.g. ["2a01:30:0:13:211:84ff:feb7:7f9c"] +fw_local_interfaces: [] +fw_local_ips_v4: [] +fw_local_ips_v6: [] +fw_vpn_ifs: "tun+" +fw_wg_ifs: "wg+" +fw_lxc_guest_ips_v4: [] +fw_lxc_guest_ips_v6: [] +fw_nat_devices: "" + + +# --- +# Munin monitoring (often set in group_vars or role defaults) +# --- + +munin_remote_ipv4: "" +munin_remote_ipv6: "" + + +# --- +# Bridged / LXC traffic +# --- + +fw_do_not_firewall_bridged_traffic: false +fw_do_not_firewall_lx_guest_systems: false + + +# --- +# Drop policies +# --- + +fw_drop_icmp: false +fw_drop_mndp: true +fw_drop_mdns: true + + +# --- +# Outgoing / interface policy +# --- + +fw_allow_all_outgoing_traffic: false +fw_blocked_ifs: "" +fw_unprotected_ifs: "" + + +# --- +# Forwarding (protocol-specific addresses) +# --- + +fw_forward_private_ips_v4: "" +fw_forward_private_ips_v6: "" + + +# --- +# Access control (protocol-specific: IPv4 uses ':', IPv6 uses ',') +# --- + +fw_restrict_local_service_to_net_v4: "" +fw_restrict_local_service_to_net_v6: "" +fw_restrict_local_net_to_net_v4: "" +fw_restrict_local_net_to_net_v6: "" +fw_allow_ext_service_v4: "" +fw_allow_ext_service_v6: "" +fw_allow_ext_net_v4: "" +fw_allow_ext_net_v6: "" +fw_allow_local_service_v4: "" +fw_allow_local_service_v6: "" +fw_allow_local_service_from_networks_v4: "" +fw_allow_local_service_from_networks_v6: "" + + +# --- +# Services: VPN / WireGuard +# --- + +fw_vpn_server_ips: "" +fw_forward_vpn_server_ips: "" +fw_vpn_ports: "$standard_vpn_port" +fw_wireguard_server_ips: "" +fw_forward_wireguard_server_ips: "" +fw_wireguard_server_ports: "$standard_wireguard_port" +fw_wireguard_out_ports: "$standard_wireguard_port" + + +# --- +# Services: NTP +# --- + +fw_local_ntp_service: false +fw_ntp_port: "$standard_ntp_port" +fw_ntp_allowed_net: "" + + +# --- +# Services: DHCP (IPv4 only) +# --- + +fw_dhcp_server_ifs: "" +fw_dhcp_client_ifs: "" + + +# --- +# Services: DNS +# --- + +fw_dns_server_ips: "" +fw_forward_dns_server_ips: "" +fw_local_resolver_service: false +fw_resolver_port: "$standard_dns_port" +fw_resolver_allowed_networks_v4: "" +fw_resolver_allowed_networks_v6: "" + + +# --- +# Services: SSH +# Uses $ext_ips by default so SSH is always reachable via all external IPs. +# Override in host_vars to restrict to specific IPs. +# --- + +fw_ssh_server_ips: "$ext_ips" +fw_forward_ssh_server_ips: "" +fw_ssh_ports: "$standard_ssh_port" + + +# --- +# Services: HTTP(S) +# --- + +fw_http_server_ips: "" +fw_forward_http_server_ips: "" +fw_http_ports: "$standard_http_ports" +fw_log_cgi_traffic_out: false +fw_cgi_script_users: "" + + +# --- +# Services: Mattermost +# --- + +fw_mm_server_ips: "" +fw_forward_mm_server_ips: "" +fw_mm_udp_ports_in: "$stansard_mattermost_udp_ports_in" +fw_mm_udp_ports_out: "$stansard_mattermost_udp_ports_out" + + +# --- +# Services: 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: "$standard_mailuser_ports" +fw_mail_client_ips: "" +fw_forward_mail_client_ips: "" +fw_dovecot_auth_service: false +fw_dovecot_auth_port: "$dovecot_external_auth_port" +fw_dovecot_auth_allowed_networks_v4: "" +fw_dovecot_auth_allowed_networks_v6: "" + + +# --- +# Services: FTP +# --- + +fw_ftp_server_ips: "" +fw_forward_ftp_server_ips: "" +fw_ftp_passive_port_range: "50000:50400" + + +# --- +# Services: XMPP (Jabber / Prosody) +# --- + +fw_xmpp_server_ips: "" +fw_forward_xmpp_server_ips: "" +fw_xmmp_tcp_in_ports: "5222 5223 5269" +fw_xmmp_tcp_out_ports: "5269" +fw_xmmp_remote_out_services_v4: "" +fw_xmmp_remote_out_services_v6: "" + + +# --- +# Services: Mumble +# --- + +fw_mumble_server_ips: "" +fw_forward_mumble_server_ips: "" +fw_mumble_ports: "$standard_mumble_port" + + +# --- +# Services: Jitsi / Jibri +# --- + +fw_jitsi_server_ips: "" +fw_forward_jitsi_server_ips: "" +fw_jitsi_tcp_ports: "$standard_jitsi_tcp_ports" +fw_jitsi_udp_port_range: "$standard_jitsi_udp_port_range" +fw_jitsi_tcp_ports_out: "$standard_turn_service_ports,4443,4444,4445,4446" +fw_jitsi_udp_ports_out: "$standard_http_ports,$standard_turn_service_ports,4443,4444,4445,4446" +fw_jitsi_dovecot_auth: false +fw_jitsi_dovecot_host: "" +fw_jitsi_dovecot_port: "$default_jitsi_dovecout_auth_port" +fw_jitsi_jibri_remote_auth: false +fw_jitsi_jibri_remote_ips: "" +fw_jitsi_jibri_remote_auth_port: "$default_jibri_out_port" +fw_jibri_server_ips: "" +fw_forward_jibri_server_ips: "" +fw_jibri_remote_jitsi_server: "" +fw_jibri_remote_auth_port: "$default_jibri_out_port" + + +# --- +# Services: TURN / STUN (Nextcloud Talk) +# --- + +fw_nc_turn_server_ips: "" +fw_forward_nc_turn_server_ips: "" +fw_nc_turn_ports: "$standard_turn_service_ports" +fw_nc_turn_udp_ports: "$standard_turn_service_udp_ports" + + +# --- +# Services: TFTP +# --- + +fw_tftp_server_ips: "" + + +# --- +# Services: Prometheus +# --- + +fw_prometheus_local_server_ips: "" +fw_prometheus_remote_client_ports: "$standard_prometheus_ports" +fw_prometheus_local_client_ips: "" +fw_prometheus_local_client_ports: "$standard_prometheus_ports" +fw_prometheus_remote_server_ips: "" + + +# --- +# Services: Munin +# --- + +fw_munin_server_ips: "" +fw_forward_munin_server_ips: "" +fw_munin_remote_port: "$standard_munin_port" +fw_munin_local_port: "4949" + + +# --- +# Services: Xymon +# --- + +fw_xymon_server_ips: "" +fw_local_xymon_client: false +fw_xymon_port: "$standard_xymon_port" + + +# --- +# Protocols out: Rsync +# --- + +fw_rsync_out_ips: "" +fw_forward_rsync_out_ips: "" +fw_rsync_ports: "873" + + +# --- +# Special ports (OUT) +# --- + +fw_tcp_out_ports: "" +fw_forward_tcp_out_ports: "" +fw_udp_out_ports: "" +fw_forward_udp_out_ports: "" + + +# --- +# Portforwarding (protocol-specific formats) +# IPv4: "::::" +# IPv6: ",,,," +# --- + +fw_portforward_tcp_v4: "" +fw_portforward_udp_v4: "" +fw_portforward_tcp_v6: "" +fw_portforward_udp_v6: "" + + +# --- +# Blocked IPs / ports +# --- + +fw_blocked_ips: "" +fw_block_tcp_ports: "111 113 135 137:139 445" +fw_block_udp_ports: "111 137:139" + + +# --- +# Special / counters +# --- + +fw_create_traffic_counter: true +fw_create_iperf_rules: true + + +# --- +# Protection +# --- + +fw_protection_against_syn_flooding: true +fw_protection_against_port_scanning: true +fw_protection_against_ssh_brute_force_attacks: true + + +# --- +# Connection limits +# --- + +fw_limit_connections_per_source_IP: true +fw_per_IP_connection_limit: "$default_per_IP_connection_limit" +fw_limit_new_tcp_connections_per_seconds_per_source_IP: true +fw_limit_new_tcp_connections_per_seconds_ports: "" + + +# --- +# Kernel parameters — IPv4 +# --- + +fw_kernel_activate_forwarding: false +fw_kernel_support_dynaddr: false +fw_dynaddr_flag: "5" +fw_kernel_reduce_timeouts: true +fw_kernel_tcp_syncookies: true +fw_kernel_protect_against_icmp_bogus_messages: true +fw_kernel_ignore_broadcast_ping: true +fw_kernel_deactivate_source_route: true +fw_kernel_dont_accept_redirects: true +fw_kernel_activate_rp_filter: true +fw_kernel_log_martians: false + + +# --- +# Kernel parameters — IPv6 +# --- + +fw_kernel_forward_between_interfaces: false diff --git a/roles/ipt-server/files/etc/ipt-firewall/ban_ipv4.list.sample b/roles/ipt-server/files/etc/ipt-firewall/ban_ipv4.list.sample new file mode 100644 index 0000000..59848fc --- /dev/null +++ b/roles/ipt-server/files/etc/ipt-firewall/ban_ipv4.list.sample @@ -0,0 +1,36 @@ +# - IPv4 addresses listet here will be completly banned by the firewall +# - +# - - Line beginning with '#' will be ignored. +# - - Blank lines will be ignored +# - - Only the first entry (until space sign or end of line) of each line will be considered. +# - +# - Valid values are: +# - complete IPv4 adresses like 1.2.3.4 (will be converted to 1.2.3.0/32) +# - partial IPv4 addresses like 1.2.3 (will be converted to 1.2.3.0/24) +# - network/nn CIDR notation like 1.2.3.0/27 +# - network/netmask notaions like 1.2.3.0/255.255.255.0 +# - network/partial_netmask like 1.2.3.4/255 +# - +# - Note: +# - - wrong addresses like 1.2.3.256 or 1.2.3.4/33 will be ignored +# - +# - Example: +# - 79.171.81.0/24 +# - 79.171.81.0/255.255.255.0 +# - 79.171.81.0/255.255.255 +# - 79.171.81 + +# CHINANET-JS +222.184.0.0/13 +61.160.0.0/16 + +# CHINANET-GX +116.8.0.0/14 + +# BAIDU-HK - Hong Kong +103.235.44.0/22 +# UNICOM-HE - China Unicom Hebei province network +110.240.0.0/12 +# CMNET - China Mobile Communications Corporation +39.128.0.0/10 + diff --git a/roles/ipt-server/files/etc/ipt-firewall/ban_ipv6.list.sample b/roles/ipt-server/files/etc/ipt-firewall/ban_ipv6.list.sample new file mode 100644 index 0000000..bbc3a73 --- /dev/null +++ b/roles/ipt-server/files/etc/ipt-firewall/ban_ipv6.list.sample @@ -0,0 +1,20 @@ +# - IPv6 addresses listet here will be completly banned by the firewall +# - +# - - Line beginning with '#' will be ignored. +# - - Blank lines will be ignored +# - - Only the first entry (until space sign or end of line) of each line will be considered. +# - +# - Valid values are: +# - complete IPv6 adresses like 240e:1ec0:4ab1:feba:e8b4:4fb1:7984:4c +# - network/nn CIDR notation like 240e:1ec0:4ab1:feba:e8b4:4fb1:7984:4c/56 +# - +# - +# - Note: +# - - If no mask is given mask will be set to '64' +# - - wrong addresses like '2g01::1' or '2a01::1/129' will be ignored +# - +# - Example: +# - 240e:ec:4ab1:feba:e8b4:4fb1:7984:4c +# - 2a01:30:0:13:5054:ff::1 +# - 2a01:30:0:13:5054:ff::1/56 + diff --git a/roles/ipt-server/files/etc/ipt-firewall/default_settings.conf b/roles/ipt-server/files/etc/ipt-firewall/default_settings.conf new file mode 100644 index 0000000..d212560 --- /dev/null +++ b/roles/ipt-server/files/etc/ipt-firewall/default_settings.conf @@ -0,0 +1,157 @@ +#!/usr/bin/env bash + +# ------------- +# --- Default Parameter / Options +# ------------- + +default_per_IP_connection_limit=111 + + +# ------------- +# --- Default Ports for Services out +# ------------- + +standard_checkmk_port=6556 +standard_cpan_wait_port=1404 +standard_dns_port=53 +standard_ftp_port=21 +standard_ftp_data_port=20 +standard_git_port=9418 +standard_hbci_port=3000 +standard_http_port=80 +standard_https_port=443 +standard_ident_port=113 +standard_ipp_port=631 +standard_cups_port=$standard_ipp_port +standard_irc_port=6667 +standard_jabber_port=5222 +standard_ldap_port=389 +standard_ldaps_port=636 +standard_mdns_port=5353 +standard_mndp_port=5678 +standard_mumble_port=64738 +standard_munin_port=4949 +standard_mysql_port=3306 +standard_ntp_port=123 +standard_pgp_keyserver_port=11371 +standard_print_port=9100 +standard_print_raw_port=515 +standard_remote_console_port=5900 +standard_silc_port=706 +standard_smtp_port=25 +standard_snmp_port=161 +standard_snmp_trap_port=162 +standard_ssh_port=22 +standard_telnet_port=23 +standard_tftp_udp_port=69 +standard_timeserver_port=37 +standard_vpn_port=1194 +standard_wireguard_port=51820 +standard_whois_port=43 +standard_xymon_port=1984 + +# - Prometheus services +# - +standard_prometheus_ports="9100,9256" + +# - Mattermost (MM) Service +# - +stansard_mattermost_udp_ports_in="8443" +stansard_mattermost_udp_ports_out="3478" + +# - IPsec - Internet Security Association and +# - Key Management Protocol +standard_isakmp_port=500 +standard_ipsec_nat_t=4500 + + +# - Comma separated lists +# - +standard_http_ports="80,443" +standard_mailuser_ports="587,465,110,995,143,993" + +# - Dovecot Service +# - +dovecot_external_auth_port="44444" + +# - Jitsi Video Conference Service +# - +standard_jitsi_tcp_ports="$standard_http_ports" +standard_jitsi_udp_port_range="10000:20000" +default_jitsi_dovecout_auth_port="$dovecot_external_auth_port" + +# - Jibri Service +# - +default_jibri_out_port=5222 +# default_outbound_streaming_tcp_ports +# +# - outbound port 1935/TCP : outbound streaming over RTMP to most +# streaming providers such as YouTube Live, Vimeo or Twitch +# +# - outbound port 1936/TCP : outbound streaming over RTMP to LinkedIn +# Live (port 1935 is also used for RTMP streaming to LinkedIn) +# +# - outbound ports 2935/TCP and 2396/TCP : outbound streaming over +# RTMPS to LinkedIn Live +# +# - outbound port 443/TCP (HTTPS) : used for authentication with the +# built-in providers such as YouTube Live, Facebook Live, Ustream, +# Livestream, and Twitch +# +# - outbound port 53/UDP (DNS) used for DNS lookups converting +# hostnames to IP addresses +# +default_outbound_streaming_tcp_ports="1935,1936,2935,2396" + + +# - TURN Server (Stun Server) (for Nextcloud 'talk' app) +# - +standard_turn_service_ports="3478:3479,5349:5350" +standard_turn_service_udp_ports="49152:65535" + + +# ------------- +# --- Predefined Ports +# ------------- + +# - unpriviligierte Ports +# - +unprivports="1024:65535" + + +# ------------- +# --- Some IPv4-Address Configuration +# ------------- + +# - Loopback +loopback_ipv4="127.0.0.0/8" + +# - Private Networks +priv_class_a="10.0.0.0/8" +priv_class_b="172.16.0.0/12" +priv_class_c="192.168.0.0/16" + +link_local_rfc_5735="169.254.0.0/16" + +test_net_1_rfc_5735="192.0.2.0/24" +this_net_rfc_5735="0.0.0.0/8" + +# - Multicast Addresse +class_d_multicast="224.0.0.0/3" + +# Reserved Addresse +class_e_reserved="240.0.0.0/5" + + +# ------------- +# --- Some IPv6-Address Configuration +# ------------- + +# unique local address (ULA) - private address block +ula_block="fc00::/7" +link_local_unicast_block="fe80::/10" +multicast_ipv6="ff00::/8" + +# - Loopback +loopback_ipv6="::1/128" + diff --git a/roles/ipt-server/files/etc/ipt-firewall/include_functions.conf b/roles/ipt-server/files/etc/ipt-firewall/include_functions.conf new file mode 100644 index 0000000..ae7182c --- /dev/null +++ b/roles/ipt-server/files/etc/ipt-firewall/include_functions.conf @@ -0,0 +1,268 @@ +#!/usr/bin/env bash + +# - Set firewall command (either iptables or ip6tables) +# +if [[ -x "${ip6t}" ]] ; then + fw_command="${ip6t}" +elif [[ -x "${ipt}" ]] ; then + fw_command="${ipt}" +fi + +# ------------- +# --- Some functions +# ------------- + +echononl(){ + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ +} +echo_done() { + echo -e "\033[75G[ \033[32mdone\033[m ]" +} +echo_ok() { + echo -e "\033[75G[ \033[32mok\033[m ]" +} +echo_warning() { + echo -e "\033[75G[ \033[33m\033[1mwarn\033[m ]" +} +echo_failed(){ + echo -e "\033[75G[ \033[1;31mfailed\033[m ]" +} +echo_skipped() { + echo -e "\033[75G[ \033[33m\033[1mskipped\033[m ]" +} + + +fatal (){ + echo "" + echo -e "fatal Error: $*" + echo "" + echo -e "\t\033[31m\033[1mScript will be interrupted..\033[m\033[m" + echo "" + exit 1 +} + +error(){ + echo "" + echo -e "\t[ \033[31m\033[1mFehler\033[m ]: $*" + echo "" +} + +warn (){ + echo "" + echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*" + echo "" +} + +info (){ + echo "" + echo -e "\t[ \033[32m\033[1mInfo\033[m ]: $*" + echo "" +} + +## - Check if a given array (parameter 2) contains a given string (parameter 1) +## - +containsElement () { + local e + for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done + return 1 +} + +is_number() { + + return $(test ! -z "${1##*[!0-9]*}" > /dev/null 2>&1); + + # - also possible + # - + #[[ ! -z "${1##*[!0-9]*}" ]] && return 0 || return 1 + #return $([[ ! -z "${1##*[!0-9]*}" ]]) +} + +trim() { + local var="$*" + var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters + var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters + echo -n "$var" +} + + +is_container() { + command -v systemd-detect-virt >/dev/null 2>&1 && systemd-detect-virt --container >/dev/null 2>&1 +} + + +# ------------- +# - IPv6 handling +# ------------- + +ENABLE_IPV6="auto" # auto | yes | no +IPV6_ACTIVE=0 + +ipv6_sysctl_enabled() { + sysctl -n net.ipv6.conf.all.disable_ipv6 2>/dev/null | grep -qx 0 +} + +has_ipv6_addr() { + ip -6 addr show scope global 2>/dev/null | grep -q "inet6" +} + +detect_ipv6() { + case "$ENABLE_IPV6" in + yes) return 0 ;; + no) return 1 ;; + auto) ipv6_sysctl_enabled ;; + *) return 1 ;; + esac +} + + +# ------------- +# - Network Device Stuff +# ------------- + +# get virtual ethernet interfaces and the master of the given bridge +# +get_vth_ports() { + local br="$1" + # lists virtual interfaces (veth*)) and the master interface of the given bridge + ip -o link show master "$br" 2>/dev/null | awk -F': ' '{print $2}' +} + +# ------------- +# - Fail2ban +# ------------- + +FAIL2BAN_CONFIG_FILE="/etc/fail2ban/jail.local" +FAIL2BAN_WAS_RUNNING=false +fail2ban_client="$(command -v fail2ban-client 2>/dev/null)" +has_fail2ban() { + command -v fail2ban-client >/dev/null 2>&1 +} + +fail2ban_running() { + systemctl is-active --quiet fail2ban >/dev/null 2>&1 +} + +# ------------- +# - Debian 12/13 compatibility helpers (best effort) +# ------------- +ensure_mod() { + + # --- + # Load a kernel module if possible (no hard failure). + # NOTE: In containers module loading is not possible; modules must be loaded on the host. + # --- + + local m="$1" + + # Already loaded? + if lsmod 2>/dev/null | awk '{print $1}' | grep -qx "$m" ; then + return 0 + fi + + # Skip in containers/guests without module loading capability + # + is_container && return 0 + + # Best effort modprobe + /sbin/modprobe "$m" >/dev/null 2>&1 || warn "Loading module '$m' failed (ok if not needed on this host)." +} + +# --- Feature detection helpers (Debian 12/13 + containers) +module_loaded() { + lsmod 2>/dev/null | awk '{print $1}' | grep -qx "$1" +} + +can_use_recent() { + # xt_recent is the kernel module behind "-m recent" + # In containers lsmod may be restricted; also accept presence of /proc/net/xt_recent. + module_loaded xt_recent && return 0 + [ -d /proc/net/xt_recent ] && return 0 + # As a last resort, ask iptables to parse the match (works if userspace has it) + "$ipt" -m recent -h >/dev/null 2>&1 && return 0 + return 1 +} + +can_use_hashlimit() { + # xt_hashlimit is the kernel module behind "-m hashlimit" + module_loaded xt_hashlimit && return 0 + [ -d /proc/net/xt_hashlimit ] && return 0 + "${fw_command}" -m hashlimit -h >/dev/null 2>&1 && return 0 + return 1 +} + +can_use_connlimit() { + # xt_connlimit is the kernel module behind "-m connlimit" + module_loaded xt_connlimit && return 0 + "${fw_command}" -m connlimit -h >/dev/null 2>&1 && return 0 + return 1 +} + +can_use_owner() { + # xt_owner is the kernel module behind "-m owner" + module_loaded xt_owner && return 0 + "${fw_command}" -m owner -h >/dev/null 2>&1 && return 0 + return 1 +} + +can_use_ct_target() { + # Check if iptables CT target exists (iptables-nft should support it when kernel has nf_tables CT support) + "${fw_command}" -t raw -j CT -h >/dev/null 2>&1 && return 0 + return 1 +} + +can_use_helper_match() { + # Check if helper match exists + "${fw_command}" -m helper -h >/dev/null 2>&1 && return 0 + return 1 +} + +can_use_nft() { + command -v nft >/dev/null 2>&1 && return 0 + return 1 +} + +setup_ftp_conntrack_helper_output() { + # Prefer explicit helper assignment (safe with nf_conntrack_helper=0) + if can_use_ct_target ; then + "${fw_command}" -A OUTPUT -t raw -p tcp --dport "$standard_ftp_port" -j CT --helper ftp + return 0 + fi + + # nft fallback (nft-native helper assignment); keeps us "nft-ready" + if can_use_nft ; then + # Best-effort; may fail in containers without CAP_NET_ADMIN + nft add table ip fwhelper >/dev/null 2>&1 || true + nft add chain ip fwhelper output '{ type filter hook output priority raw; policy accept; }' >/dev/null 2>&1 || true + nft add ct helper ip fwhelper ftp '{ type "ftp" protocol tcp; }' >/dev/null 2>&1 || true + nft add rule ip fwhelper output tcp dport "$standard_ftp_port" ct helper set "ftp" >/dev/null 2>&1 && return 0 + fi + + warn "No CT helper assignment available (iptables CT target and nft fallback both unavailable). FTP active/passive may fail; FTPS workaround relies on recent/port rules." + return 1 +} + +setup_ftp_conntrack_helper_prerouting() { + # Prefer explicit helper assignment (safe with nf_conntrack_helper=0) + if can_use_ct_target ; then + "$ipt" -A PREROUTING -t raw -p tcp --dport "$standard_ftp_port" -j CT --helper ftp + return 0 + fi + + # nft fallback (nft-native helper assignment); keeps us "nft-ready" + if can_use_nft ; then + nft add table ip fwhelper >/dev/null 2>&1 || true + nft add chain ip fwhelper prerouting '{ type filter hook prerouting priority raw; policy accept; }' >/dev/null 2>&1 || true + nft add ct helper ip fwhelper ftp '{ type "ftp" protocol tcp; }' >/dev/null 2>&1 || true + nft add rule ip fwhelper prerouting tcp dport "$standard_ftp_port" ct helper set "ftp" >/dev/null 2>&1 && return 0 + fi + + warn "No CT helper assignment available (iptables CT target and nft fallback both unavailable). FTP server traffic may fail; consider enabling passive port ranges." + return 1 +} + diff --git a/roles/ipt-server/files/etc/ipt-firewall/logging_ipv4.conf b/roles/ipt-server/files/etc/ipt-firewall/logging_ipv4.conf new file mode 100644 index 0000000..db2cab1 --- /dev/null +++ b/roles/ipt-server/files/etc/ipt-firewall/logging_ipv4.conf @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + + +# ------------- +# --- Logging +# ------------- + +if $(ps -e f | grep -q -E "/usr/sbin/ulogd2?\s" 2>/dev/null) ; then + tag_log_prefix="--nflog-prefix" + LOG_TARGET="NFLOG --nflog-group 11" +else + # - Log using the specified syslog level. 7 (debug) is a good choice + # - unless you specifically need something else. + # - + log_level=debug + LOG_TARGET="LOG --log-level $log_level" + tag_log_prefix="--log-prefix" +fi + +log_all=false + +log_syn_flood=false +log_port_scanning=false +log_ssh_brute_force=false +log_fragments=false +log_mdns=false +log_mndp=false +log_new_not_sync=false +log_syn_with_suspicious_mss=false +log_invalid_packets=false +log_invalid_state=false +log_invalid_flags=false +log_spoofed=false +log_spoofed_out=false +log_private_network_out=false +log_to_lo=false +log_not_wanted=false +log_blocked=false +log_unprotected=false +log_forwarding_priv_ip=false +log_prohibited=false +log_voip=false +log_rejected=true + +log_blocked_ip=false + +log_ssh=false + +# - logging messages +# - +log_prefix="[ IPv4 ]" + + +# --- +# - Log all traffic for givven ip address +# --- + +# - You can also give hostname(s) +# - +# - Blank seoarated list of ips/hostnames +# - +log_ips="" diff --git a/roles/ipt-server/files/etc/ipt-firewall/logging_ipv6.conf b/roles/ipt-server/files/etc/ipt-firewall/logging_ipv6.conf new file mode 100644 index 0000000..da09863 --- /dev/null +++ b/roles/ipt-server/files/etc/ipt-firewall/logging_ipv6.conf @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + + +# ------------- +# --- Logging +# ------------- + +if $(ps -e f | grep -q -E "/usr/sbin/ulogd2?\s" 2>/dev/null) ; then + tag_log_prefix="--nflog-prefix" + LOG_TARGET="NFLOG --nflog-group 12" +else + # - Log using the specified syslog level. 7 (debug) is a good choice + # - unless you specifically need something else. + # - + log_level=debug + LOG_TARGET="LOG --log-level $log_level" + tag_log_prefix="--log-prefix" +fi + +log_all=false + +log_syn_flood=false +log_port_scanning=false +log_ssh_brute_force=false +log_fragments=false +log_mdns=false +log_mndp=false +log_new_not_sync=false +log_syn_with_suspicious_mss=false +log_invalid_packets=false +log_invalid_state=false +log_invalid_flags=false +log_spoofed=false +log_spoofed_out=false +log_private_network_out=false +log_to_lo=false +log_not_wanted=false +log_blocked=false +log_unprotected=false +log_forwarding_priv_ip=false +log_prohibited=false +log_voip=false +log_rejected=true + +log_blocked_ip=false + +log_ssh=false + +# - logging messages +# - +log_prefix="[ IPv6 ]" + + +# --- +# - Log all traffic for givven ip address +# --- + +# - You can also give hostname(s) +# - +# - Blank seoarated list of ips/hostnames +# - +log_ips="" + diff --git a/roles/ipt-server/files/etc/ipt-firewall/post_declarations.conf b/roles/ipt-server/files/etc/ipt-firewall/post_declarations.conf new file mode 100644 index 0000000..e6a8137 --- /dev/null +++ b/roles/ipt-server/files/etc/ipt-firewall/post_declarations.conf @@ -0,0 +1,621 @@ +#!/usr/bin/env bash + + +# ----------- +# --- Define Arrays +# ----------- + +# --- +# NAT (Masquerade) Network interfaces +# --- + +declare -a nat_device_arr=() +for _dev in $nat_devices ; do + if ! containsElement $_dev "${nat_device_arr[@]}" ; then + nat_device_arr+=("$_dev") + fi +done + + +# --- +# IP Addresses LX Guest System +# --- + +declare -a lxc_guest_ip_arr=() +for _ip in $lxc_guest_ips ; do + lxc_guest_ip_arr+=("$_ip") +done + + +# --- +# local Interfaces +# --- + +declare -a local_ip_arr=() +for _ip in $local_ips ; do + local_ip_arr+=("$_ip") +done + + +# --- +# - IP Addresses to log +# --- +declare -a log_ip_arr +for _ip in $log_ips ; do + log_ip_arr+=("$_ip") +done + + +# --- +# - LOG CGI script Traffic out +# --- +declare -a cgi_script_user_arr=() +for _user in $cgi_script_users ; do + cgi_script_user_arr+=($_user) +done + + +# --- +# - IP-Addresses (Host, Guests (VServer, LX_Container) +# --- +declare -a ext_ip_arr +for _ip in $ext_ips ; do + host_ip_arr+=("$_ip") +done + +# --- +# - Extern Interfaces +# --- +declare -a ext_if_arr +for _dev in $ext_ifs ; do + ext_if_arr+=("$_dev") +done + +# --- +# - VPN Interfaces +# --- +declare -a vpn_if_arr +for _dev in $vpn_ifs ; do + vpn_if_arr+=("$_dev") +done + +# --- +# - WireGuard Interfaces +# --- +declare -a wg_if_arr +for _dev in $wg_ifs ; do + wg_if_arr+=("$_dev") +done + +# --- +# - Local Network Interfaces +# --- +declare -a local_if_arr +for _dev in $local_ifs ; do + local_if_arr+=("$_dev") +done + +# --- +# - Network Interfaces completly blocked +# --- +declare -a blocked_if_arr +for _dev in $blocked_ifs ; do + blocked_if_arr+=("$_dev") +done + +# --- +# - Network Interfaces not firewalled +# --- +declare -a unprotected_if_arr +for _dev in $unprotected_ifs ; do + unprotected_if_arr+=("$_dev") +done + +# --- +# - Restrict local Servive to given IP-Address/Network +# --- +declare -a restrict_local_service_to_net_arr +for _val in $restrict_local_service_to_net ; do + restrict_local_service_to_net_arr+=("$_val") +done + +# --- +# - Restrict local Network to given IP-Address/Network +# --- +declare -a restrict_local_net_to_net_arr +for _val in $restrict_local_net_to_net ; do + restrict_local_net_to_net_arr+=("$_val") +done + +# --- +# - Allow extern Service +# --- +declare -a allow_ext_service_arr +for _val in $allow_ext_service ; do + allow_ext_service_arr+=("$_val") +done + +# --- +# - Allow extern IP-Address/Network +# --- +declare -a allow_ext_net_arr +for _net in $allow_ext_net ; do + allow_ext_net_arr+=("$_net") +done + +# --- +# - Allow (non-standard) local Services +# --- +declare -a allow_local_service_arr +for _val in $allow_local_service ; do + allow_local_service_arr+=("$_val") +done + +# --- +# - Allow (non-standard) local Services from specified network +# --- +declare -a allow_local_service_from_network_arr +for _service in $allow_local_service_from_networks ; do + allow_local_service_from_network_arr+=("$_service") +done + +# --- +# - Generally block ports +# --- +declare -a block_tcp_port_arr +for _port in $block_tcp_ports ; do + block_tcp_port_arr+=("$_port") +done + +declare -a block_udp_port_arr +for _port in $block_udp_ports ; do + block_udp_port_arr+=("$_port") +done + +# --- +# - Private IPs / IP-Ranges allowed to forward +# --- +declare -a forward_private_ip_arr +for _ip in $forward_private_ips ; do + forward_private_ip_arr+=("$_ip") +done + +# --- +# - Network Interfaces DHCP Service +# --- +declare -a dhcp_server_if_arr +for _dev in $dhcp_server_ifs ; do + dhcp_server_if_arr+=($_dev) +done +declare -a dhcp_client_if_arr +for _dev in $dhcp_client_ifs ; do + dhcp_client_if_arr+=($_dev) +done + +# --- +# - IP Addresses DNS Server +# --- +# - local +declare -a dns_server_ip_arr +for _ip in $dns_server_ips ; do + dns_server_ip_arr+=("$_ip") +done +# DMZ +declare -a forward_dns_server_ip_arr +for _ip in $forward_dns_server_ips ; do + forward_dns_server_ip_arr+=("$_ip") +done + +# --- +# - Netwoks allowed access to local DNS Resolver +# --- +declare -a resolver_allowed_network_arr +for _net in $resolver_allowed_networks ; do + resolver_allowed_network_arr+=("$_net") +done + +# --- +# - IP Addresses VPN Server +# --- +# local +declare -a vpn_server_ip_arr +for _ip in $vpn_server_ips ; do + vpn_server_ip_arr+=("$_ip") +done +# DMZ +declare -a forward_vpn_server_ip_arr +for _ip in $forward_vpn_server_ips ; do + forward_vpn_server_ip_arr+=("$_ip") +done + +# --- +# - IP Addresses WireGuard Service +# --- +# local +declare -a wireguard_server_ip_arr +for _ip in $wireguard_server_ips ; do + wireguard_server_ip_arr+=("$_ip") +done +# DMZ +declare -a forward_wireguard_server_ip_arr +for _ip in $forward_wireguard_server_ips ; do + forward_wireguard_server_ip_arr+=("$_ip") +done + +# --- +# - IP Addresses SSH Server +# --- +# local +declare -a ssh_server_ip_arr +for _ip in $ssh_server_ips ; do + ssh_server_ip_arr+=("$_ip") +done +# DMZ +declare -a forward_ssh_server_ip_arr +for _ip in $forward_ssh_server_ips ; do + forward_ssh_server_ip_arr+=("$_ip") +done + +# --- +# - IP Addresses HTTP Server +# --- +# local +declare -a http_server_ip_arr +for _ip in $http_server_ips ; do + http_server_ip_arr+=("$_ip") +done +# DMZ +declare -a forward_http_server_ip_arr +for _ip in $forward_http_server_ips ; do + forward_http_server_ip_arr+=("$_ip") +done + +# --- +# - IP Addresses MatterMost Service +# --- +# local +declare -a mm_server_ip_arr +for _ip in $mm_server_ips ; do + mm_server_ip_arr+=("$_ip") +done +# DMZ +declare -a forward_mm_server_ip_arr +for _ip in $forward_mm_server_ips ; do + forward_mm_server_ip_arr+=("$_ip") +done + +# --- +# - IP Addresses FTP Server +# --- +# local +declare -a ftp_server_ip_arr +for _ip in $ftp_server_ips ; do + ftp_server_ip_arr+=("$_ip") +done +# DMZ +declare -a forward_ftp_server_ip_arr +for _ip in $forward_ftp_server_ips ; do + forward_ftp_server_ip_arr+=("$_ip") +done + +# --- +# - Mail SMTP Server +# --- +# local +declare -a smtpd_ips_arr +for _ip in $smtpd_ips ; do + smtpd_ips_arr+=("$_ip") +done +# DMZ +declare -a forward_smtpd_ip_arr +for _ip in $forward_smtpd_ips ; do + forward_smtpd_ip_arr+=("$_ip") +done + + +# --- +# Additional SMTP Listen Ports +# --- +declare -a smtpd_additional_listen_port_arr +for _port in $smtpd_additional_listen_ports ; do + smtpd_additional_listen_port_arr+=("$_port") +done + + +# --- +# Additional SMTP Outgoing Ports +# --- +declare -a smtpd_additional_outgoung_port_arr +for _port in $smtpd_additional_outgoung_ports ; do + smtpd_additional_outgoung_port_arr+=("$_port") +done + + + +# --- +# - IP Addresses XMPP Service (Jabber - Prosody) +# --- +declare -a xmpp_server_ip_arr +for _ip in $xmpp_server_ips ; do + xmpp_server_ip_arr+=("$_ip") +done + +declare -a forward_xmpp_server_ip_arr +for _ip in $forward_xmpp_server_ips ; do + forward_xmpp_server_ip_arr+=("$_ip") +done + +# --- +# - XMPP Remote Dovecote Out Service +# --- +declare -a xmmp_remote_out_service_arr +for _val in $xmmp_remote_out_services ; do + xmmp_remote_out_service_arr+=("$_val") +done + +# --- +# - Mail Services (smtps/pop(s)/imap(s) +# --- +# local +declare -a mail_server_ips_arr +for _ip in $mail_server_ips ; do + mail_server_ips_arr+=("$_ip") +done +# DMZ +declare -a forward_mail_server_ip_arr +for _ip in $forward_mail_server_ips ; do + forward_mail_server_ip_arr+=("$_ip") +done + +# --- +# - Mail client (smtps/pop(s)/imap(s) +# --- +# local +declare -a mail_client_ips_arr +for _ip in $mail_client_ips ; do + mail_client_ips_arr+=("$_ip") +done +# DMZ +declare -a forward_mail_client_ip_arr +for _ip in $forward_mail_client_ips ; do + forward_mail_client_ip_arr+=("$_ip") +done + +# --- +# - (local) Dovecot auth service +# --- +declare -a dovecot_auth_allowed_network_arr +for _ip in $dovecot_auth_allowed_networks ; do + dovecot_auth_allowed_network_arr+=("$_ip") +done + +# --- +# - IP Addresses Mumble Server +# --- +# local +declare -a mumble_server_ip_arr +for _ip in $mumble_server_ips ; do + mumble_server_ip_arr+=("$_ip") +done +# DMZ +declare -a forward_mumble_server_ip_arr +for _ip in $forward_mumble_server_ips ; do + forward_mumble_server_ip_arr+=("$_ip") +done + +# --- +# - IP Addresses Jitsi Video Conferencing Server +# --- +declare -a jitsi_server_ip_arr +for _ip in $jitsi_server_ips ; do + jitsi_server_ip_arr+=("$_ip") +done +# DMZ +declare -a forward_jitsi_server_ip_arr +for _ip in $forward_jitsi_server_ips ; do + forward_jitsi_server_ip_arr+=("$_ip") +done + +# --- +# - IP Addresses Remote Jibri Server +# --- +declare -a jitsi_jibri_remote_ip_arr +for _ip in $jitsi_jibri_remote_ips ; do + jitsi_jibri_remote_ip_arr+=("$_ip") +done + +# --- +# - IP Addresses Jibri Recording / Streaming Server +# --- +declare -a jibri_server_ip_arr +for _ip in $jibri_server_ips ; do + jibri_server_ip_arr+=("$_ip") +done +# DMZ +declare -a forward_jibri_server_ip_arr +for _ip in $forward_jibri_server_ips ; do + forward_jibri_server_ip_arr+=("$_ip") +done + +# --- +# - IP Addresses TURN Server (Stun Server) (for Nextcloud 'talk' app) +# --- +# local +declare -a nc_turn_server_ip_arr +for _ip in $nc_turn_server_ips ; do + nc_turn_server_ip_arr+=("$_ip") +done +# DMZ +declare -a forward_nc_turn_server_ip_arr +for _ip in $forward_nc_turn_server_ips ; do + forward_nc_turn_server_ip_arr+=("$_ip") +done + +# --- +# - IP Addresses Telephone Systems +# --- +declare -a tel_sys_ip_arr +for _ip in $tel_sys_ips ; do + tel_sys_ip_arr+=("$_ip") +done + +# --- +# - Prometheus Monitoring - local Server +# --- +declare -a prometheus_local_server_ip_arr +for _ip in $prometheus_local_server_ips ; do + prometheus_local_server_ip_arr+=("$_ip") +done + +# --- +# - Prometheus Monitoring - local Client +# --- +declare -a prometheus_local_client_ip_arr +for _ip in $prometheus_local_client_ips; do + prometheus_local_client_ip_arr+=("$_ip") +done +declare -a prometheus_remote_server_ip_arr +for _ip in $prometheus_remote_server_ips ; do + prometheus_remote_server_ip_arr+=("$_ip") +done + + +# --- +# - IP Addresses Munin +# --- +# local +declare -a munin_server_ip_arr +for _ip in $munin_server_ips ; do + munin_server_ip_arr+=("$_ip") +done +# DMZ +declare -a forward_munin_server_ip_arr +for _ip in $forward_munin_server_ips ; do + forward_munin_server_ip_arr+=("$_ip") +done + +# --- +# - IP Addresses XyMon +# --- +declare -a xymon_server_ip_arr +for _ip in $xymon_server_ips ; do + xymon_server_ip_arr+=("$_ip") +done + +# --- +# - IP Addresses Rsync Out +# --- +# local +declare -a rsync_out_ip_arr +for _ip in $rsync_out_ips ; do + rsync_out_ip_arr+=("$_ip") +done +# DMZ +declare -a forward_rsync_out_ip_arr +for _ip in $forward_rsync_out_ips ; do + forward_rsync_out_ip_arr+=("$_ip") +done + +# --- +# - SSH Ports +# --- +declare -a ssh_port_arr +for _port in $ssh_ports ; do + ssh_port_arr+=("$_port") +done + +# --- +# - XMPP Service (Jabber - Prosody) +# --- +declare -a xmmp_tcp_in_port_arr +for _port in $xmmp_tcp_in_ports ; do + xmmp_tcp_in_port_arr+=("$_port") +done + +declare -a xmmp_tcp_out_port_arr +for _port in $xmmp_tcp_out_ports ; do + xmmp_tcp_out_port_arr+=("$_port") +done + +# --- +# - VPN Ports +# --- +# local +declare -a vpn_port_arr +for _port in $vpn_ports ; do + vpn_port_arr+=("$_port") +done + +# --- +# - Wireguard Ports (local Service) +# --- +# local +declare -a wireguard_server_port_arr +for _port in $wireguard_server_ports ; do + wireguard_server_port_arr+=("$_port") +done + +# --- +# - Wireguard out Ports +# --- +# local +declare -a wireguard_out_port_port_arr +for _port in $wireguard_out_ports ; do + wireguard_out_port_port_arr+=("$_port") +done + + +# --- +# - Rsync Out Ports +# -- +declare -a rsync_port_arr +for _port in $rsync_ports ; do + rsync_port_arr+=("$_port") +done + + +# --- +# - Special TCP Ports OUT +# --- +# local +declare -a tcp_out_port_arr +for _port in $tcp_out_ports ; do + tcp_out_port_arr+=("$_port") +done +# DMZ +declare -a forward_tcp_out_port_arr +for _port in $forward_tcp_out_ports ; do + forward_tcp_out_port_arr+=("$_port") +done + +# --- +# - Special UDP Ports OUT +# --- +# local +declare -a udp_out_port_arr +for _port in $udp_out_ports ; do + udp_out_port_arr+=("$_port") +done +# DMZ +declare -a forward_udp_out_port_arr +for _port in $forward_udp_out_ports ; do + forward_udp_out_port_arr+=("$_port") +done + + +# --- +# - Portforwrds TCP +# --- +declare -a portforward_tcp_arr +for _str in $portforward_tcp ; do + portforward_tcp_arr+=("$_str") +done + +# --- +# - Portforwrds UDP +# --- +declare -a portforward_udp_arr +for _str in $portforward_udp ; do + portforward_udp_arr+=("$_str") +done + diff --git a/roles/ipt-server/files/etc/systemd/system/ip6t-firewall.service b/roles/ipt-server/files/etc/systemd/system/ip6t-firewall.service new file mode 100644 index 0000000..7944ef1 --- /dev/null +++ b/roles/ipt-server/files/etc/systemd/system/ip6t-firewall.service @@ -0,0 +1,13 @@ +[Unit] +Description=IPv6 Firewall with ip6tables +After=network.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/local/sbin/ip6t-firewall-server start +ExecStop=/usr/local/sbin/ip6t-firewall-server stop +User=root + +[Install] +WantedBy=multi-user.target diff --git a/roles/ipt-server/files/etc/systemd/system/ipt-firewall.service b/roles/ipt-server/files/etc/systemd/system/ipt-firewall.service new file mode 100644 index 0000000..37e3e60 --- /dev/null +++ b/roles/ipt-server/files/etc/systemd/system/ipt-firewall.service @@ -0,0 +1,13 @@ +[Unit] +Description=IPv4 Firewall with iptables +After=network.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/local/sbin/ipt-firewall-server start +ExecStop=/usr/local/sbin/ipt-firewall-server stop +User=root + +[Install] +WantedBy=multi-user.target diff --git a/roles/ipt-server/files/usr/local/sbin/ip6t-firewall-server b/roles/ipt-server/files/usr/local/sbin/ip6t-firewall-server new file mode 100755 index 0000000..052a608 --- /dev/null +++ b/roles/ipt-server/files/usr/local/sbin/ip6t-firewall-server @@ -0,0 +1,2952 @@ +#!/usr/bin/env bash + + +# ------------- +# - Settings +# ------------- + +ipt_conf_dir="/etc/ipt-firewall" + +inc_functions_file="${ipt_conf_dir}/include_functions.conf" + +load_modules_file=${ipt_conf_dir}/load_modules_ipv6.conf + +conf_logging=${ipt_conf_dir}/logging_ipv6.conf +conf_interfaces=${ipt_conf_dir}/interfaces_ipv6.conf +conf_default_settings=${ipt_conf_dir}/default_settings.conf +conf_main=${ipt_conf_dir}/main_ipv6.conf +conf_post_declarations=${ipt_conf_dir}/post_declarations.conf +conf_ban_ipv6_list="${ipt_conf_dir}/ban_ipv6.list" + + +ip6t="$(command -v ip6tables 2>/dev/null)" + +if [[ -z "$ip6t" ]] ; then + echo "" + echo -e "\tip6tables was not found on this server!" + echo + echo -e "\tFirewall Script was stopped!" + echo + exit 1 +fi + + +# ------------- +# - Load Default Settings and Functions +# ------------- + +if [[ ! -f "$conf_default_settings" ]]; then + fatal "Missing configuration for default_settings - file '$conf_default_settings'" +else + source $conf_default_settings +fi + +if [[ ! -f "$inc_functions_file" ]] ; then + echo "" + echo -e "\tMissing include file '$inc_functions_file'" + echo + echo -e "\tFirewall Script was stopped!" + echo + exit 1 +else + source $inc_functions_file +fi + + +# ------------- +# - Some checks and preloads.. +# ------------- + +# Check IPv6 presence +if detect_ipv6; then + IPV6_ACTIVE=1 + if has_ipv6_addr; then + info "IPv6 enabled (global address present)." + else + warn "IPv6 enabled but no global address configured yet." + fi +else + IPV6_ACTIVE=0 + warn "IPv6 disabled via sysctl." +fi + +# Fail if ip6tables points to legacy (helps avoid surprises on dual-stack hosts / fail2ban) +if command -v ip6tables >/dev/null 2>&1; then + if ! ip6tables --version 2>/dev/null | grep -q "nf_tables"; then + echo "" + echo "ERROR: ip6tables is NOT using nf_tables backend (ip6tables-nft)." + echo "Fix (on the host, as root):" + echo " update-alternatives --set ip6tables /usr/sbin/ip6tables-nft" + echo "" + echo "Current: $(ip6tables --version 2>/dev/null || echo 'unknown')" + exit 1 + fi +fi + + +# ------------- +# --- Ensure required modules for this script (best effort; host-side in containers) +# ------------- + + +echo +echononl "\tEnsure required modules are loaded.." +if is_container ; then + echo_skipped +else + + ensure_mod nf_conntrack + ensure_mod nf_nat + ensure_mod nf_conntrack_ftp + ensure_mod nf_nat_ftp + ensure_mod xt_recent + ensure_mod xt_hashlimit + ensure_mod xt_connlimit + ensure_mod xt_owner + ensure_mod xt_helper + ensure_mod br_netfilter + + echo_done +fi + + +# Disable automatic conntrack helper assignment (keep explicit CT --helper rules) +if ! is_container; then + sysctl -w net.netfilter.nf_conntrack_helper=0 >/dev/null 2>&1 || true +fi + +if [[ ! -f "$conf_logging" ]]; then + fatal "Missing configuration for logging - file '$conf_logging'" +else + source $conf_logging +fi + +if [[ ! -f "$conf_interfaces" ]]; then + fatal "Missing interface configurations - file '$conf_interfaces'" +else + source $conf_interfaces +fi + +if [[ ! -f "$conf_main" ]]; then + fatal "Missing main configurations - file '$conf_main'" +else + source $conf_main +fi + +if [[ ! -f "$conf_post_declarations" ]]; then + fatal "Missing post declarations - file '$conf_post_declarations'" +else + source $conf_post_declarations +fi + + + +echo +echo -e "\033[37m\033[1m\tStarting firewall iptables (IPv6)..\033[m" +echo + + +# ------------- +# --- Activate IP Forwarding +# ------------- + +if ! is_container ; then + + # --- + # - Disable ip forwarding between interfaces + # --- + if $kernel_forward_between_interfaces ; then + echononl "\tActivate Forwarding.." + echo 1 > /proc/sys/net/ipv6/conf/all/forwarding + else + echononl "\t\033[33m\033[1mDisable Forwarding..\033[m" + echo 0 > /proc/sys/net/ipv6/conf/all/forwarding + fi + + echo_done + +fi + +# ------------- +# --- Adjust Kernel Parameters (Security/Tuning) +# ------------- + +echononl "\tAdjust Kernel Parameters (Security/Tuning).." + +if ! is_container ; then + + # --- + # - Deactivate Source Routed Packets + # --- + for asr in /proc/sys/net/ipv6/conf/*/accept_source_route; do + if $kernel_deactivate_source_route ; then + echo 0 > $asr + fi + done + + + # --- + # - Deactivate sending ICMP redirects + # --- + if $kernel_dont_accept_redirects ; then + echo "0" > /proc/sys/net/ipv6/conf/all/accept_redirects + fi + + echo_done # Adjust Kernel Parameters (Security/Tuning) +else + echo_skipped + +fi # if ! is_container + + + +# ------------- +# --- Prevent bridged traffic getting pushed through the host's iptables rules +# ------------- + +echo +echononl "\tDo not firewall bridged / LX Gust System traffic" + +if ${do_not_firewall_bridged_traffic} || ${do_not_firewall_lx_guest_systems} ; then + + if ! is_container; then + + _done=false + + for _dev in ${ext_if_arr[@]} ; do + + # Try to detect virtual interfaces (veth*)) and the master interface + # of the given bridge dynamically + # + # ports="$(get_bridge_ports "$br")" + # + # or directly here: + # + # ports="$(ip -o link show master "${_dev}" 2>/dev/null | awk -F': ' '{print $2}')" + # + # ports="$(ip -o link show master "${_dev}" 2>/dev/null | awk -F': ' '{print $2}')" + # + ports="$(ip -o link show master "${_dev}" 2>/dev/null | awk -F': ' '{print $2}')" + + for _port in $ports ; do + $ip6t -A FORWARD -i "${_port}" -j ACCEPT + $ip6t -A FORWARD -o "${_port}" -j ACCEPT + _done=true + done + + done + + if ! ${_done} ; then + $ip6t -A FORWARD -i veth+ -j ACCEPT + $ip6t -A FORWARD -o veth+ -j ACCEPT + fi + + echo_done + else + echo_skipped + fi +else + echo_skipped +fi + + +echononl "\tTake care 'net.bridge.bridge-nf-call-ip6tables' is set to '1'.." +if ${do_not_firewall_bridged_traffic} || ${do_not_firewall_lx_guest_systems} ; then + + if ! is_container; then + + _bridge_sysctl_ok=true + + # IPv6: keep bridge netfilter on, but bypass host filtering for container ports + # (do NOT set bridge-nf-call-ip6tables=0) + sysctl -w net.bridge.bridge-nf-call-ip6tables=1 >/dev/null 2>&1 || _bridge_sysctl_ok=false + + if ${_bridge_sysctl_ok} ; then + echo_done + else + echo_failed + fi + + else + echo_skipped + fi +fi + + + +# ------------- Fail2ban handling (do not stop/start; keep bans stable) ------------- +# +echo +echononl "\tCheck presence and configuration of Fail2ban .." +echo_done +if ! has_fail2ban ; then + warn "Fail2ban is not installed.." +elif ! fail2ban_running ; then + warn "Fail2ban is installed but not running.." +else + CURRENT_BANACTION=$(grep -E '^\s*banaction\s*=' "$FAIL2BAN_CONFIG_FILE" | head -1 | tr -d ' ' | cut -d'=' -f2) + if [[ -n ${CURRENT_BANACTION} ]] ; then + if [ "$CURRENT_BANACTION" = "nftables" ]; then + info "Fail2ban is running, banaction is et to nftables." + else + warn "Change banaction from ${CURRENT_BANACTION} to \033[1mbanaction=nftables\033[m" + fi + else + warn "banaction seems not to be configured. Take care that \033[1mbanaction=nftables\033[m" + fi + FAIL2BAN_WAS_RUNNING=true +fi +# +# ------------- Ende: Fail2ban handling (do not stop/start; keep bans stable) ------------- + + +# ------------- +# --- Set default policies / Flush Rules +# ------------- + + +echo +echononl "\tFlushing firewall iptable (IPv6).." + +# - default policies +# - +$ip6t -P INPUT ACCEPT +$ip6t -P OUTPUT ACCEPT +$ip6t -P FORWARD ACCEPT + +## - flush chains +## - +$ip6t -F +$ip6t -F INPUT +$ip6t -F OUTPUT +$ip6t -F FORWARD +$ip6t -F -t mangle +$ip6t -F -t nat +$ip6t -F -t raw +$ip6t -X +$ip6t -Z + +echo_done # Flushing firewall iptable (IPv6).. +echo + + +echononl "\tMasquerade (NAT) interfaces.." +if [[ ${#nat_device_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _dev in ${nat_device_arr[@]} ; do + $ip6t -t nat -A POSTROUTING -o $_dev -j MASQUERADE + done + echo_done +else + echo_skipped +fi +echo + +# ------------- +# ---- Log given IP Addresses +# ------------- + +echononl "\tLog given IPv6 Addresses" +if [[ ${#log_ip_arr[@]} -gt 0 ]]; then + for _ip in ${log_ip_arr[@]} ; do + $ip6t -A INPUT -s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix $_ip IN: " + $ip6t -A OUTPUT -d $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix $_ip OUT: " + $ip6t -A FORWARD -s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix $_ip FORWARD FROM: " + $ip6t -A FORWARD -d $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix $_ip FORWARD TO: " + done + + echo_done +else + echo_skipped +fi + + + +# ------------- +# ------------ Stopping firewall if only flushing was requested (parameter flush) +# ------------- + +case $1 in + flush) + echo + echo -e "\t\033[37m\033[1mFlushing firewall was requested. No more rules..\033[m" + echo + exit 0;; +esac + + +# --- +# - Permit all traffic through WireGuard lines +# --- +echononl "\tPermit all traffic through WireGuard lines.." +for _wg_if in ${wg_if_arr[@]} ; do + $ip6t -A INPUT -i $_wg_if -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -i $_wg_if -j ACCEPT + fi +done +echo_done + + +# --- +# - Permit all traffic through VPN lines +# --- +echononl "\tPermit all traffic through VPN lines.." +for _vpn_if in ${vpn_if_arr[@]} ; do + $ip6t -A INPUT -i $_vpn_if -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A OUTPUT -o $_vpn_if -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -i $_vpn_if -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A FORWARD -o $_vpn_if -m conntrack --ctstate NEW -j ACCEPT + fi +done +echo_done + + + +# ------------- +# --- Pass through Devices Interfaces (not firewalled) +# ------------- + +echononl "\tPass through Devices (not firewalled)" +if [[ ${#unprotected_if_arr[@]} -gt 0 ]]; then + for _dev in ${unprotected_if_arr[@]} ; do + if $log_unprotected || $log_all ; then + $ip6t -t mangle -A PREROUTING -i $_dev -j $LOG_TARGET $tag_log_prefix "$log_prefix Not firewalled ${_dev}: " + $ip6t -A OUTPUT -o $_dev -j $LOG_TARGET $tag_log_prefix "$log_prefix Not firewalled ${_dev}: " + $ip6t -A INPUT -i $_dev -j $LOG_TARGET $tag_log_prefix "$log_prefix Not firewalled ${_dev}: " + $ip6t -A FORWARD -o $_dev -j $LOG_TARGET $tag_log_prefix "$log_prefix Not firewalled ${_dev}: " + fi + $ip6t -t mangle -A PREROUTING -i $_dev -j ACCEPT + $ip6t -A OUTPUT -o $_dev -j ACCEPT + $ip6t -A INPUT -i $_dev -j ACCEPT + $ip6t -A FORWARD -o $_dev -j ACCEPT + done + echo_done +else + echo_skipped +fi + + +# --- +# - Allow Forwarding certain private Addresses +# --- + +echononl "\tAllow forwarding (private) IPs / IP-Ranges.." +if [[ ${#forward_private_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${forward_private_ip_arr[@]}; do + if $log_forwarding_priv_ip || $log_all ; then + $ip6t -t mangle -A PREROUTING -d $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Accept priv ip $_ip: " + $ip6t -t mangle -A PREROUTING-s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Accept priv ip $_ip: " + fi + $ip6t -t mangle -A PREROUTING -d $_ip -j ACCEPT + $ip6t -t mangle -A PREROUTING-s $_ip -j ACCEPT + done + echo_done +else + echo_skipped +fi + + + +# ------------- +# --- Block IPs / Networks / Interfaces +# ------------- +echononl "\tBlock IPs / Networks / Interfaces.." + + +# --- +# - Block IPs +# --- + +for _ip in $blocked_ips ; do + for _dev in ${ext_if_arr[@]} ; do + if $log_blocked_ip || $log_all ; then + $ip6t -A INPUT -i $_dev -s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked ${_ip}: " + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -i $_dev -s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked ${_ip}: " + fi + fi + $ip6t -A INPUT -i $_dev -s $_ip -j DROP + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -i $_dev -s $_ip -j DROP + fi + done +done + + +# --- +# - Block Interfaces +# --- + +for _if in ${blocked_if_arr[@]} ; do + if $log_blocked_if || $log_all ; then + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -i $_if -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked IF ${_if}: " + $ip6t -A FORWARD -o $_if -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked IF ${_if}: " + fi + $ip6t -A INPUT -i $_if -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked IF ${_if}: " + $ip6t -A OUTPUT -o $_if -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked IF ${_if}: " + fi + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -i $_if -j DROP + $ip6t -A FORWARD -o $_if -j DROP + fi + $ip6t -A INPUT -i $_if -j DROP + $ip6t -A OUTPUT -o $_if -j DROP +done + +echo_done # Block IPs / Networks / Interfaces.. + + + +# --- +# - Block IPs/Netwoks reading from file 'ban_ipv6.list'" +# --- + +echononl "\tBlock IPs/Netwoks reading from file 'ban_ipv6.list' .." + +if [[ -f "$conf_ban_ipv6_list" ]] ; then + + declare -a ban_ipv6_arr=() + declare -a no_valid_ipv6=() + + # Regex valid ipv6 address + # + _regex_ipv6='^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$' + + while IFS='' read -r _line || [[ -n $_line ]] ; do + + is_valid_ipv6=false + is_valid_mask=false + ipv6="" + mask="" + + # Ignore comment lines + # + [[ $_line =~ ^[[:space:]]{0,}# ]] && continue + + # Ignore blank lines + # + [[ $_line =~ ^[[:space:]]*$ ]] && continue + + # Remove leading whitespace characters + # + _line="${_line#"${_line%%[![:space:]]*}"}" + + + # Catch ipv6 Address + # + given_ipv6="$(echo $_line | cut -d ' ' -f1)" + + + # Splitt ipv6 address from possible given CIDR number + # + IFS='/' read -ra _addr <<< "$given_ipv6" + ipv6="${_addr[0]}" + + # Test mask if given + # + if [[ -n "${_addr[1]}" ]] ; then + mask="${_addr[1]}" + + # Is 'mask' a valid CIDR number? If not, test agains a valid netmask + # + if $(test -z "${mask##*[!0-9]*}" > /dev/null 2>&1) ; then + + # Its not a vaild mask number, but naybe a valit netmask. + # + no_valid_ipv6_arr+=("$given_ipv6") + + else + if [[ $mask -gt 128 ]]; then + + # Its not a vaild cidr number, but naybe a valit netmask. + # + no_valid_ipv6_arr+=("$given_ipv6") + else + is_valid_mask=true + fi + fi + else + mask=64 + is_valid_mask=true + fi + + # Check if given ipv6 address is valif + if [[ "$ipv6" =~ ${_regex_ipv6} ]]; then + is_valid_ipv6=true + fi + + + if $is_valid_ipv6 && $is_valid_mask; then + + _ip="${ipv6}/${mask}" + + if containsElement "$_ip" "${ban_ipv6_arr[@]}" ; then + continue + fi + + for _dev in ${ext_if_arr[@]} ; do + if $log_blocked_ip || $log_all ; then + $ip6t -A INPUT -i $_dev -s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked by ban_ipv6.list: " + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -i $_dev -s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked by ban_ipv6.list: " + fi + fi + + $ip6t -A INPUT -i $_dev -s $_ip -j DROP + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -i $_dev -s $_ip -j DROP + fi + done + + ban_ipv6_arr+=("$_ip") + + else + if ! containsElement "$given_ipv6" "${no_valid_ipv6_arr[@]}" ; then + no_valid_ipv6_arr+=("$given_ipv6") + fi + fi + + done < "$conf_ban_ipv6_list" + echo_done + + if [[ ${#no_valid_ipv6_arr[@]} -gt 0 ]]; then + warn "Ignored: ${no_valid_ipv6_arr[@]}" + fi +else + echo_skipped +fi + + + +# ------------- +# --- Protections against several attacks / unwanted packages +# ------------- +echo +echo -e "\t\033[37m\033[1mProtections against several attacks / unwanted packages..\033[m" + + +# --- +# - Drop invalid packets +# --- +echononl "\tDrop invalid packets" + +# --- +# Ersatzlos gestrichen +# --- +echo_skipped + +#if $log_invalid_packets || $log_all ; then +# $ip6t -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid packets:" +#fi +#$ip6t -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP +#echo_done + + +# --- +# Drop TCP packets that are new and are not SYN +# --- + +echononl "\tDrop TCP packets that are new and are not SYN" +if $log_new_not_sync || $log_all ; then + $ip6t -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j $LOG_TARGET $tag_log_prefix "$log_prefix New but not SYN:" +fi +$ip6t -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP +echo_done + + +# --- +# - Drop SYN packets with suspicious MSS value +# --- + +echononl "\tDrop SYN packets with suspicious MSS value" +if $log_syn_with_suspicious_mss || $log_all ; then + $ip6t -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j $LOG_TARGET $tag_log_prefix "$log_prefix suspicious MSS:" +fi +$ip6t -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP +echo_done + + +# --- +# - Block packets with bogus TCP flags +# --- + +echononl "\tBlock packets with bogus TCP flags" +if $log_invalid_flags || $log_all ; then + $ip6t -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ip6t -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ip6t -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ip6t -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ip6t -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" +fi +$ip6t -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP +$ip6t -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP +$ip6t -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP +$ip6t -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP +$ip6t -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP +$ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP +$ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP +$ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP +$ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP +$ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP +$ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP +$ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP +$ip6t -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP +echo_done + + +# --- +# - Block spoofed (own ip) packets +# --- + +echononl "\tBlock spoofed (own ip) packets" +if $log_spoofed || $log_all ; then + for _ip in ${ext_ip_arr[@]} ; do + $ip6t -t mangle -A PREROUTING -s $_ip -d $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Spoofed (own ip): " + done +fi +for _ip in ${ext_ip_arr[@]} ; do + $ip6t -t mangle -A PREROUTING -s $_ip -d $_ip -j DROP +done +echo_done + + +# --- +# - Block spoofed (private/reserved) packets +# --- + +echononl "\tBlock spoofed (private/reserved) packets" +for _dev in ${ext_if_arr[@]} ; do + if $log_spoofed || $log_all ; then + $ip6t -t mangle -A PREROUTING -i $_dev -s $ula_block -j $LOG_TARGET $tag_log_prefix "$log_prefix Private (ula_block): " + #$ip6t -t mangle -A PREROUTING -i $_dev -s $link_local_unicast_block -j $LOG_TARGET $tag_log_prefix "$log_prefix Private (Link Local Unicast): " + $ip6t -t mangle -A PREROUTING -i $_dev -s $multicast_ipv6 -j $LOG_TARGET $tag_log_prefix "$log_prefix Multicast: " + fi +done + +if $log_spoofed || $log_all ; then + $ip6t -t mangle -A PREROUTING -s $loopback_ipv6 ! -i lo -j $LOG_TARGET $tag_log_prefix "$log_prefix Loopback: " +fi + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -t mangle -A PREROUTING -i $_dev -s $ula_block -j DROP + + # !! Does NOT work !! + # + #$ip6t -t mangle -A PREROUTING -i $_dev -s $link_local_unicast_block -j DROP + + $ip6t -t mangle -A PREROUTING -i $_dev -s $multicast_ipv6 -j DROP +done +$ip6t -t mangle -A PREROUTING -s $loopback_ipv6 ! -i lo -j DROP +echo_done + + +# --- +# - Drop ICMP all ICMP traffic (you usually don't need this protocol) +# --- + +echononl "\tDrop all ICMP traffic.." +echo_skipped + +if [[ -n "$drop_icmp" ]] && $drop_icmp ; then + + warn " No ICMPv6 packets were dropped - they are essential." + +fi + + +# ------------- +# --- Drop Mikrotik RouterOS Neighbor Discovery Protocol (MNDP) Traffic +# --- Drop Tinc VPN Traffic +# ------------- + +[ "${drop_mndp,,}" == "yes" ] && drop_mndp=true +[ "${drop_mndp,,}" == "no" ] && drop_mndp=false + +echononl "\tDrop Tinc VPN / Mikrotik RouterOS Neighbor Discovery Traffic" +if [[ -n "$drop_mndp" ]] && $drop_mndp ; then + for _dev in ${ext_if_arr[@]} ; do + + if $log_mndp || $log_all ; then + $ip6t -A OUTPUT -o $_dev -p udp --dport $standard_mndp_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MNDP Out: " + $ip6t -A INPUT -i $_dev -p udp --dport $standard_mndp_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MNDP IN: " + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p udp --dport $standard_mndp_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MNDP fwd Out: " + $ip6t -A FORWARD -i $_dev -p udp --dport $standard_mndp_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MNDP fwd In: " + fi + fi + + $ip6t -A OUTPUT -o $_dev -p udp --dport $standard_mndp_port -j DROP + $ip6t -A INPUT -i $_dev -p udp --dport $standard_mndp_port -j DROP + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p udp --dport $standard_mndp_port -j DROP + $ip6t -A FORWARD -i $_dev -p udp --dport $standard_mndp_port -j DROP + fi + + done + echo_done +else + echo_skipped +fi + + +# ------------- +# --- Drop Multicast DNS Traffic +# ------------- + +[ "${drop_mdns,,}" == "yes" ] && drop_mdns=true +[ "${drop_mdns,,}" == "no" ] && drop_mdns=false + +echononl "\tDrop Multicast DNS Traffic" +if [[ -n "$drop_mdns" ]] && ${drop_mdns} ; then + for _dev in ${ext_if_arr[@]} ; do + + if $log_mdns || $log_all ; then + $ip6t -A OUTPUT -o $_dev -p udp --dport $standard_mdns_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MDNS Out: " + $ip6t -A INPUT -i $_dev -p udp --dport $standard_mdns_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MDNS IN: " + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p udp --dport $standard_mdns_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MDNS fwd Out: " + $ip6t -A FORWARD -i $_dev -p udp --dport $standard_mdns_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MDNS fwd In: " + fi + fi + + $ip6t -A OUTPUT -o $_dev -p udp --dport $standard_mdns_port -j DROP + $ip6t -A INPUT -i $_dev -p udp --dport $standard_mdns_port -j DROP + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p udp --dport $standard_mdns_port -j DROP + $ip6t -A FORWARD -i $_dev -p udp --dport $standard_mdns_port -j DROP + fi + + done + echo_done +else + echo_skipped +fi + + +# --- +# - Don't allow spoofing out from this server +# --- + +echo "" +echononl "\tDon't allow spoofing out from this server" +if $log_spoofed_out || $log_all ; then + for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -s $ula_block -j $LOG_TARGET $tag_log_prefix "$log_prefix Spoofing Out: " + #$ip6t -A OUTPUT -o $_dev -s $link_local_unicast_block -j $LOG_TARGET $tag_log_prefix "$log_prefix Spoofing Out: " + $ip6t -A OUTPUT -o $_dev -s $multicast_ipv6 -j $LOG_TARGET $tag_log_prefix "$log_prefix Spoofing Out: " + $ip6t -A OUTPUT -o $_dev -s $loopback_ipv6 -j $LOG_TARGET $tag_log_prefix "$log_prefix Spoofing Out: " + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -s $ula_block -j $LOG_TARGET $tag_log_prefix "$log_prefix Spoofing Out: " + #$ip6t -A FORWARD -o $_dev -s $link_local_unicast_block -j $LOG_TARGET $tag_log_prefix "$log_prefix Spoofing Out: " + $ip6t -A FORWARD -o $_dev -s $multicast_ipv6 -j $LOG_TARGET $tag_log_prefix "$log_prefix Spoofing Out: " + $ip6t -A FORWARD -o $_dev -s $loopback_ipv6 -j $LOG_TARGET $tag_log_prefix "$log_prefix Spoofing Out: " + fi + done +fi + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -s $ula_block -j DROP + #$ip6t -A OUTPUT -o $_dev -s $link_local_unicast_block -j DROP + $ip6t -A OUTPUT -o $_dev -s $multicast_ipv6 -j DROP + $ip6t -A OUTPUT -o $_dev -s $loopback_ipv6 -j DROP + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -s $ula_block -j DROP + #$ip6t -A FORWARD -o $_dev -s $link_local_unicast_block -j DROP + $ip6t -A FORWARD -o $_dev -s $multicast_ipv6 -j DROP + $ip6t -A FORWARD -o $_dev -s $loopback_ipv6 -j DROP + fi +done +echo_done + + +# ------------- +# --- Traffic generally allowed +# ------------- + +echo +echononl "\tLoopback device generally allowed.." + +# --- +# - Loopback device +# --- + +$ip6t -A INPUT -i lo -j ACCEPT +$ip6t -A OUTPUT -o lo -j ACCEPT + +echo_done + + +# --- +# - Already established connections +# --- + +echononl "\tAccept already established connections.." + +$ip6t -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT +$ip6t -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT + +$ip6t -A INPUT -m conntrack --ctstate INVALID -j DROP + +if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT +fi + +echo_done + +echononl "\tICMPv6 - mandatory for IPv6 to work correctly!" + +# ICMPv6 essentials (numbers to be compatible with ip6tables-nft) +# 1 = destination-unreachable +# 2 = packet-too-big +# 3 = time-exceeded +# 4 = parameter-problem +# 128= echo-request +# 129= echo-reply +# 133= router-solicitation +# 134= router-advertisement +# 135= neighbor-solicitation +# 136= neighbor-advertisement +for t in 1 2 3 4 128 129 133 134 135 136; do + $ip6t -A INPUT -p ipv6-icmp --icmpv6-type $t -j ACCEPT + $ip6t -A OUTPUT -p ipv6-icmp --icmpv6-type $t -j ACCEPT + + # Normaly, 'do_not_firewall_bridged_traffic' and 'do_not_firewall_lx_guest_systems' must + # not be part of the if-clause, but in SINMA systems, this is needed for LX Container to + # work + # + if ${kernel_forward_between_interfaces} \ + || ${do_not_firewall_bridged_traffic} \ + || ${do_not_firewall_lx_guest_systems} ; then + + $ip6t -A FORWARD -p ipv6-icmp --icmpv6-type "$t" -j ACCEPT + fi +done + +echo_done + +# --- +# - Protection against syn-flooding +# --- + +echo +echononl "\tProtection against syn-flooding" +if $protection_against_syn_flooding ; then + $ip6t -N syn-flood + $ip6t -A syn-flood -m limit --limit 1/second --limit-burst 3 -j RETURN + if $log_syn_flood || $log_all ; then + $ip6t -A syn-flood -j $LOG_TARGET $tag_log_prefix "$log_prefix SYN flood: " + fi + $ip6t -A syn-flood -j DROP + echo_done +else + echo_skipped +fi + + +# --- +# - Protection against port scanning +# --- + +echononl "\tProtection against port scanning" +if $protection_against_port_scanning ; then + $ip6t -N port-scanning + $ip6t -A port-scanning -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j RETURN + if $log_port_scanning || $log_all ; then + $ip6t -A port-scanning -j $LOG_TARGET $tag_log_prefix "$log_prefix Port Scan:" + fi + $ip6t -A port-scanning -j DROP + echo_done +else + echo_skipped +fi + + +# --- +# - Protection against SSH brute-force attacks +# --- + +echononl "\tProtection against SSH brute-force attacks" +if $protection_against_ssh_brute_force_attacks ; then + $ip6t -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --set + if $log_ssh_brute_force || $log_all ; then + $ip6t -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j $LOG_TARGET $tag_log_prefix "$log_prefix SSH brute-force:" + fi + $ip6t -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j DROP + echo_done +else + echo_skipped +fi + + +# --- +# - Limit connections per source IP +# --- + +echononl "\tLimit connections per source IP" +if $limit_connections_per_source_IP ; then + + if ! is_number $per_IP_connection_limit ; then + per_IP_connection_limit=$default_per_IP_connection_limit + fi + + if $log_rejected || $log_all ; then + + $ip6t -A INPUT -p tcp --syn \ + -m connlimit --connlimit-above $per_IP_connection_limit --connlimit-mask 128 --connlimit-saddr \ + -j $LOG_TARGET $tag_log_prefix "$log_prefix CONN limit per IP:" + + fi + + $ip6t -A INPUT -p tcp --syn \ + -m connlimit --connlimit-above $per_IP_connection_limit --connlimit-mask 128 --connlimit-saddr \ + -j REJECT --reject-with tcp-reset + + echo_done +else + echo_skipped +fi + + +# --- +# - Limit RST packets +# --- + +echononl "\tLimit RST packets" + +# --- +# Ersatzlos gestrichen +# --- +echo_skipped + +#if $limit_rst_packets ; then +# $ip6t -A INPUT -p tcp --tcp-flags RST RST -m limit --limit 2/s --limit-burst 2 -j ACCEPT +# if $log_rejected || $log_all ; then +# $ip6t -A INPUT -p tcp --tcp-flags RST RST -j $LOG_TARGET $tag_log_prefix "$log_prefix Limit RST packets: " +# fi +# $ip6t -A INPUT -p tcp --tcp-flags RST RST -j DROP +# echo_done +#else +# echo_skipped +#fi + + +# --- +# - Limit new TCP connections per second per source IP +# --- + +echononl "\tLimit new (syn) TCP connections per second per source IP (multiport)" + +if $limit_new_tcp_connections_per_seconds_per_source_IP \ + && [[ ${#limit_new_tcp_connections_per_seconds_ports} -gt 0 ]]; then + + #$ip6t -A INPUT -p tcp -m conntrack --ctstate NEW -m limit --limit 60/s --limit-burst 20 -j ACCEPT + + # Rate-Limit für neue SYNs auf 443 pro IP + $ip6t -A INPUT -p tcp --syn \ + -m multiport --dports $limit_new_tcp_connections_per_seconds_ports \ + -m hashlimit --hashlimit-name syn_multi_v4 \ + --hashlimit 30/second --hashlimit-burst 60 \ + --hashlimit-mode srcip --hashlimit-srcmask 32 \ + -j ACCEPT + + if $log_rejected || $log_all ; then + + #$ip6t -A INPUT -p tcp -m conntrack --ctstate NEW -j $LOG_TARGET $tag_log_prefix "$log_prefix Limit new TCP conn's: " + + # rate-limited logging für Überschreiter + $ip6t -A INPUT -p tcp --syn \ + -m multiport --dports $limit_new_tcp_connections_per_seconds_ports \ + -m hashlimit --hashlimit-name syn_multi_v4_log \ + --hashlimit 2/second --hashlimit-burst 10 \ + --hashlimit-mode srcip --hashlimit-srcmask 32 \ + -j $LOG_TARGET $tag_log_prefix "$log_prefix SYN over limit (multiport):" + fi + $ip6t -A INPUT -p tcp -m conntrack --ctstate NEW -j DROP + echo_done +else + echo_skipped +fi + + +# --- +# - Use SYNPROXY on all ports (disables connection limiting rule) +# --- + +#echononl "\tUse SYNPROXY on all ports (disables connection limiting rule)" +#$ip6t -t raw -A PREROUTING -p tcp -m tcp --syn -j CT --notrack +#$ip6t -A INPUT -p tcp -m tcp -m conntrack --ctstate INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460 +#$ip6t -A INPUT -m conntrack --ctstate INVALID -j DROP +#echo_done + + + +# ------------- +# ------------- Stopping firewall here if requested (parameter stop) +# ------------- + +case $1 in + sto*) + #echononl "Stopping firewall iptable (IPv6).." + echo + echo -e "\t\033[37m\033[1mStop was requested. No more rules..\033[m" + echo + exit 0;; +esac + + +echo + +# ------------- +# --- Traffic Counter (used by munin) +# ------------- + +echononl "\tCreate Traffic Counter (used by munin)" +if $create_traffic_counter ; then + for _ip in ${ext_ip_arr[@]} ; do + $ip6t -A INPUT -d $_ip + $ip6t -A INPUT -s $_ip + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -d $_ip + $ip6t -A FORWARD -s $_ip + fi + done + echo_done +else + echo_skipped +fi + + +# ------------- +# --- iPerf +# ------------- + +# iPerf is a tool for active measurements of the maximum achievable bandwidth on IP networks. +# It supports tuning of various parameters related to timing, buffers and protocols (TCP, UDP, +# SCTP with IPv4 and IPv6). For each test it reports the bandwidth, loss, and other parameters. + +echononl "\tCreate \"iPerf\" rules.." +if $create_iperf_rules ; then + $ip6t -A INPUT -p tcp --dport 5001 -j ACCEPT + $ip6t -A INPUT -p tcp --sport 5001 -j ACCEPT + # + $ip6t -A OUTPUT -p tcp --dport 5001 -j ACCEPT + $ip6t -A OUTPUT -p tcp --sport 5001 -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -p tcp --dport 5001 -j ACCEPT + $ip6t -A FORWARD -p tcp --sport 5001 -j ACCEPT + fi + echo_done +else + echo_skipped +fi + + +# ------------- +# --- Generally prohibited +# ------------- + +echononl "\tGenerally prohibited traffic.." + +for _dev in ${ext_if_arr[@]} ; do + if $log_prohibited || $log_all ; then + for _port in ${block_tcp_port_arr[@]} ; do + $ip6t -A INPUT -p tcp -i $_dev --dport $_port -j $LOG_TARGET $tag_log_prefix "$log_prefix gen. prohibited: " + done + for _port in ${block_udp_port_arr[@]} ; do + $ip6t -A INPUT -p udp -i $_dev --dport $_port -j $LOG_TARGET $tag_log_prefix "$log_prefix gen. prohibited: " + done + if $kernel_forward_between_interfaces ; then + for _port in ${block_tcp_port_arr[@]} ; do + $ip6t -A FORWARD -p tcp -i $_dev --dport $_port -j $LOG_TARGET $tag_log_prefix "$log_prefix gen. prohibited: " + done + for _port in ${block_udp_port_arr[@]} ; do + $ip6t -A FORWARD -p udp -i $_dev --dport $_port -j $LOG_TARGET $tag_log_prefix "$log_prefix gen. prohibited: " + done + fi + fi + for _port in ${block_tcp_port_arr[@]} ; do + $ip6t -A INPUT -p tcp -i $_dev --dport $_port -j DROP + done + for _port in ${block_udp_port_arr[@]} ; do + $ip6t -A INPUT -p udp -i $_dev --dport $_port -j DROP + done + if $kernel_forward_between_interfaces ; then + for _port in ${block_tcp_port_arr[@]} ; do + $ip6t -A FORWARD -p tcp -i $_dev --dport $_port -j DROP + done + for _port in ${block_udp_port_arr[@]} ; do + $ip6t -A FORWARD -p udp -i $_dev --dport $_port -j DROP + done + fi +done + +echo_done +echo + + +# ------------- +# ---- Restrict local Servive to given (extern) IP-Address/Network +# ------------- + +echononl "\tRestrict local Servive to given (extern) IP-Address/Network" +if [[ ${#restrict_local_service_to_net_arr[@]} -gt 0 ]] ; then + + _deny_service_arr=() + + for _val in "${restrict_local_service_to_net_arr[@]}" ; do + IFS=',' read -a _val_arr <<< "${_val}" + + for _dev in ${ext_if_arr[@]} ; do + $ip6t -A INPUT -i $_dev -p ${_val_arr[3]} -s ${_val_arr[0]} -d ${_val_arr[1]} --dport ${_val_arr[2]} -j ACCEPT + + if ! containsElement "${_dev},${_val_arr[1]},${_val_arr[2]},${_val_arr[3]}" "${_deny_service_arr[@]}" ; then + _deny_service_arr+=("${_dev},${_val_arr[1]},${_val_arr[2]},${_val_arr[3]}") + fi + done + + done + + for _val in "${_deny_service_arr[@]}" ; do + IFS=',' read -a _val_arr <<< "${_val}" + $ip6t -A INPUT -i ${_val_arr[0]} -p ${_val_arr[3]} -d ${_val_arr[1]} --dport ${_val_arr[2]} -j DROP + done + + echo_done +else + echo_skipped +fi + + +# ------------- +# ---- Restrict local Network to given extern IP-Address/Network +# ------------- + +echononl "\tRestrict local Address/Network to given extern Address/Network" +if [[ ${#restrict_local_net_to_net_arr[@]} -gt 0 ]] ; then + + _deny_net_arr=() + + for _val in "${restrict_local_net_to_net_arr[@]}" ; do + IFS=',' read -a _val_arr <<< "${_val}" + for _dev in ${ext_if_arr[@]} ; do + $ip6t -A INPUT -i $_dev -s ${_val_arr[0]} -d ${_val_arr[1]} -j ACCEPT + + if ! containsElement "${_dev},${_val_arr[1]}" "${_deny_net_arr[@]}" ; then + _deny_net_arr+=("${_dev},${_val_arr[1]}") + fi + done + + done + + for _val in "${_deny_net_arr[@]}" ; do + IFS=',' read -a _val_arr <<< "${_val}" + $ip6t -A INPUT -i ${_val_arr[0]} -d ${_val_arr[1]} -j DROP + done + + echo_done +else + echo_skipped +fi + +echo + + +# --- +# - LOG CGI script Traffic out +# --- + +echo +echononl "\tLOG CGI/PHP traffic out." + +if $log_cgi_traffic_out && [[ ${#cgi_script_user_arr[@]} -gt 0 ]] ; then + for _dev in ${ext_if_arr[@]} ; do + for _user in ${cgi_script_user_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -m owner --uid-owner $_user -j $LOG_TARGET $tag_log_prefix "$log_prefix $_user PHP-OUT: " + done + done + echo_done +else + echo_skipped +fi +echo + + +# ------------- +# --- Allow all outgoing traffic +# ------------- +echononl "\tAllow all outgoing traffic.." +if [[ -n "$allow_all_outgoing_traffic" ]] && $allow_all_outgoing_traffic ; then + for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p ALL -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p ALL -m conntrack --ctstate NEW -j ACCEPT + fi + done + echo_done +else + echo_skipped +fi + + +# --- +# - Don't allow traffik into Unique local network (ULA) +# --- + +echo "" +echononl "\tDon't allow traffic into Unique local network (ULA)" +if $log_private_network_out || $log_all ; then + for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -d $ula_block -j $LOG_TARGET $tag_log_prefix "$log_prefix Spoofing Out: " + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -d $ula_block -j $LOG_TARGET $tag_log_prefix "$log_prefix Spoofing Out: " + fi + done +fi + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -d $ula_block -j DROP + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -d $ula_block -j DROP + fi +done +echo_done + + +# ------------- +# --- Services +# ------------- + +echo +echo -e "\t\033[37m\033[1mAdd Rules for Services..\033[m" +echo + + +# ------------- +# ---- Allow extern Service +# ------------- + +echononl "\t\tAllow extern Service" + +if [[ ${#allow_ext_service_arr[@]} -gt 0 ]] ; then + for _dev in "${ext_if_arr[@]}" ; do + for _val in "${allow_ext_service_arr[@]}" ; do + IFS=',' read -a _val_arr <<< "${_val}" + $ip6t -A OUTPUT -o $_dev -p ${_val_arr[2]} -d ${_val_arr[0]} --dport ${_val_arr[1]} -m conntrack --ctstate NEW -j ACCEPT + done + done + echo_done +else + echo_skipped +fi + + +# ------------- +# ---- Allow extern IP-Address/Network +# ------------- + +echononl "\t\tAllow extern IP-Address/Network" + +if [[ ${#allow_ext_net_arr[@]} -gt 0 ]] ; then + for _dev in "${ext_if_arr[@]}" ; do + for _net in "${allow_ext_net_arr[@]}" ; do + $ip6t -A OUTPUT -o $_dev -p all -d $_net -m conntrack --ctstate NEW -j ACCEPT + done + done + echo_done +else + echo_skipped +fi + +echo + + +# ------------- +# ---- Allow (non-standard) local Services +# ------------- + +echononl "\t\tAllow (non-standard) local Services" + +if [[ ${#allow_local_service_arr[@]} -gt 0 ]] ; then + for _dev in "${ext_if_arr[@]}" ; do + for _val in "${allow_local_service_arr[@]}" ; do + IFS=',' read -a _val_arr <<< "${_val}" + $ip6t -A INPUT -i $_dev -p ${_val_arr[1]} --dport ${_val_arr[0]} -m conntrack --ctstate NEW -j ACCEPT + done + done + echo_done +else + echo_skipped +fi + + +# ------------- +# ---- Allow local Services from given (extern) network +# ------------- + +echononl "\t\tAllow local Services from given (extern) network" + +if [[ ${#allow_local_service_from_network_arr[@]} -gt 0 ]] ; then + for _dev in "${ext_if_arr[@]}" ; do + for _val in "${allow_local_service_from_network_arr[@]}" ; do + IFS=',' read -a _val_arr <<< "${_val}" + $ip6t -A INPUT -i $_dev -p ${_val_arr[2]} -s ${_val_arr[0]} --dport ${_val_arr[1]} -m conntrack --ctstate NEW -j ACCEPT + done + done + echo_done +else + echo_skipped +fi + +echo + + +# --- +# - DHCP +# --- + +echononl "\t\tDHCP Clients" + +if [[ ${#dhcp_client_if_arr[@]} -gt 0 ]] ; then + for _dev in ${dhcp_if_arr[@]} ; do + # - out + $ip6t -A OUTPUT -p udp -o $_dev --dport 67 -d ::/0 --sport 1024:65535 -j ACCEPT + # - in + $ipt -A INPUT -p udp -i $_dev --sport 67 -d ::/0 --dport 68 -j ACCEPT + done + echo_done +else + echo_skipped +fi + +echononl "\t\tDHCP Server" + +if [[ ${#dhcp_server_if_arr[@]} -gt 0 ]] ; then + for _dev in ${dhcp_server_if_arr[@]} ; do + # - in + $ip6t -A INPUT -p udp -i $_dev -s ::/0 --sport 68 --dport 67 -j ACCEPT + # - out + $ip6t -A OUTPUT -p udp -o $_dev --sport 67 -d ::/0 --dport 68 -j ACCEPT + done + echo_done +else + echo_skipped +fi + + + +# --- +# - DNS out only +# --- + +echononl "\t\tDNS out only" + +# - Nameservers on the INET must be reachable for the local recursiv nameserver +# - but also for all others +# - +for _dev in ${ext_if_arr[@]} ; do + # - out from local and virtual mashine(s) + $ip6t -A OUTPUT -o $_dev -p udp --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + + # - Only useful (needed) if kernel forwarding is activated (kernel_forward_between_interfaces=true) + if $kernel_forward_between_interfaces ; then + # - forward from virtual mashine(s) + $ip6t -A FORWARD -o $_dev -p udp --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A FORWARD -o $_dev -p tcp --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + + +# --- +# - DNS Service +# --- + +echononl "\t\tDNS Service" + +if [[ ${#dns_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_dns_server_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#dns_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${dns_server_ips[@]} ; do + # dns requests + # + # Note: + # If the total size of the DNS record is larger than 512 bytes, + # it will be sent over TCP, not UDP. + # + $ip6t -A INPUT -p udp -d $_ip --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A INPUT -p tcp -d $_ip --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + # Zonetransfer + $ip6t -A OUTPUT -p tcp -s $_ip --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + done + fi + + if [[ ${#forward_dns_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_dns_server_ip_arr[@]} ; do + # dns requests + # + # Note: + # If the total size of the DNS record is larger than 512 bytes, + # it will be sent over TCP, not UDP. + # + $ip6t -A FORWARD -p udp -d $_ip --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A FORWARD -p tcp -d $_ip --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + # Zonetransfer + $ip6t -A FORWARD -p tcp -s $_ip --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + done + fi + echo_done +else + echo_skipped +fi + + +# --- +# - local Resolver" +# --- + +echononl "\t\tlocal Resolver" +if [[ -n "$local_resolver_service" ]] && $local_resolver_service ; then + if [[ ${#resolver_allowed_network_arr[@]} -gt 0 ]] ; then + for _net in ${resolver_allowed_network_arr[@]} ; do + $ip6t -A INPUT -p udp -s $_net --dport $resolver_port -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A INPUT -p tcp -s $_net --dport $resolver_port -m conntrack --ctstate NEW -j ACCEPT + done + echo_done + else + echo_failed + fi +else + echo_skipped +fi + + +# --- +# - SSH out only +# --- + +echononl "\t\tSSH out only" + +# ausgehende Anfragen +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_ssh_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p tcp --dport $standard_ssh_port -m conntrack --ctstate NEW -j ACCEPT + fi + + if [[ ${#ssh_port_arr[@]} -gt 0 ]] ; then + for _port in ${ssh_port_arr[@]} ; do + + [[ "$_port" = "$standard_ssh_port" ]] && continue + + $ip6t -A OUTPUT -o $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + fi + + done + fi + +done + +if [[ ${#local_if_arr[@]} -gt 0 ]] ; then + for _dev in ${local_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_ssh_port -m conntrack --ctstate NEW -j ACCEPT + + if [[ ${#ssh_port_arr[@]} -gt 0 ]] ; then + for _port in ${ssh_port_arr[@]} ; do + + [[ "$_port" = "$standard_ssh_port" ]] && continue + + $ip6t -A OUTPUT -o $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -i $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + fi + done + fi + done +fi + +echo_done + + +# --- +# - SSH Service +# --- + +echononl "\t\tSSH Service" + +if [[ ${#ssh_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_ssh_server_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#ssh_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${ssh_server_ip_arr[@]} ; do + for _port in ${ssh_port_arr[@]} ; do + $ip6t -A INPUT -p tcp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + if [[ ${#forward_ssh_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_ssh_server_ip_arr[@]} ; do + for _port in ${ssh_port_arr[@]} ; do + $ip6t -A FORWARD -p tcp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - VPN +# --- + +echononl "\t\tVPN Service only out" +if [[ ${#vpn_port_arr[@]} -gt 0 ]] ; then + + for _dev in ${ext_if_arr[@]} ; do + for _port in ${vpn_port_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p udp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + + echo_done +else + echo_skipped +fi + +echononl "\t\tVPN Services.." +if [[ ${#vpn_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_vpn_server_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#vpn_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${vpn_server_ip_arr[@]} ; do + for _port in ${vpn_port_arr[@]} ; do + $ip6t -A INPUT -p udp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + if [[ ${#forward_vpn_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_vpn_server_ip_arr[@]} ; do + $ip6t -A FORWARD -p udp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Wireguard +# --- + +echononl "\t\tWireguard Service only out" +if [[ ${#wireguard_out_port_port_arr[@]} -gt 0 ]] ; then + + for _dev in ${ext_if_arr[@]} ; do + for _port in ${wireguard_out_port_port_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p udp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + + echo_done +else + echo_skipped +fi + +echononl "\t\tWireguard Services.." +if [[ ${#wireguard_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_wireguard_server_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#wireguard_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${wireguard_server_ip_arr[@]} ; do + for _port in ${wireguard_server_port_arr[@]} ; do + $ip6t -A INPUT -p udp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + if [[ ${#forward_wireguard_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_wireguard_server_ip_arr[@]} ; do + $ip6t -A FORWARD -p udp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Rsync Out +# --- + +echononl "\t\tRsync (only OUT)" + +if [[ ${#rsync_out_ip_arr[@]} -gt 0 ]] || [[ ${#forward_rsync_out_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#rsync_out_ip_arr[@]} -gt 0 ]] ; then + for _port in ${rsync_port_arr[@]} ; do + + for _ip in ${rsync_out_ip_arr[@]} ; do + $ip6t -A OUTPUT -p tcp -s $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + + done + fi + + if [[ ${#forward_rsync_out_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _port in ${rsync_port_arr[@]} ; do + + for _ip in ${forward_rsync_out_ip_arr[@]} ; do + $ip6t -A FORWARD -p tcp -s $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Telnet +# --- + +echononl "\t\tTelnet (only OUT)" + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_telnet_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p tcp --dport $standard_telnet_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - MySQL +# --- + +echononl "\t\tMySQL (only OUT)" + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_mysql_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p tcp --dport $standard_mysql_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - Prometheus Monitoring - local Server +# --- + +echononl "\t\tLocal Prometheus Service" + +if [[ ${#prometheus_local_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${prometheus_local_server_ip_arr[@]} ; do + $ip6t -A OUTPUT -p tcp -s $_ip -m multiport --dports $prometheus_remote_client_ports -m conntrack --ctstate NEW -j ACCEPT + done + echo_done +else + echo_skipped +fi + + +# --- +# - Prometheus Monitoring - local client +# --- + +echononl "\t\tLocal Prometheus Client" + +if [[ ${#prometheus_local_client_ip_arr[@]} -gt 0 ]] && [[ ${#prometheus_remote_server_ip_arr[@]} -gt 0 ]]; then + for _ip in ${prometheus_local_client_ip_arr[@]} ; do + for _ip in ${prometheus_remote_server_ip_arr[@]} ; do + $ip6t -A INPUT -p tcp -d $_ip -m multiport --dports $prometheus_local_client_ports -m conntrack --ctstate NEW -j ACCEPT + done + done + echo_done +else + echo_skipped +fi + + +# --- +# - Munin remote service +# --- + +echononl "\t\tMunin remote service" + +if [ "X$munin_remote_ip" != "X" ]; then + for _dev in ${ext_if_arr[@]} ; do + $ip6t -A INPUT -i $_dev -p tcp --syn -s $munin_remote_ip --dport $munin_local_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -i $_dev -p tcp --syn -s $munin_remote_ip --dport $munin_local_port -m conntrack --ctstate NEW -j ACCEPT + fi + done + echo_done +else + echo_skipped +fi + + +# --- +# - Munin local service +# --- + +echononl "\t\tMunin local service" + + +if [[ ${#munin_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_munin_server_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#munin_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${munin_server_ip_arr[@]} ; do + $ip6t -A OUTPUT -p tcp -s $_ip --dport $munin_remote_port -m conntrack --ctstate NEW -j ACCEPT + done + fi + + if [[ ${#forward_munin_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_munin_server_ip_arr[@]} ; do + $ip6t -A FORWARD -p tcp -s $_ip --dport $munin_remote_port -m conntrack --ctstate NEW -j ACCEPT + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Mail (SMTP OUT) +# --- + +echononl "\t\tMail (SMTP OUT)" + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_smtp_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p tcp --dport $standard_smtp_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - Mail (additional smtp ports OUT) +# --- + +echononl "\t\tMail (additional smtp ports OUT)" + +if [[ ${#smtpd_additional_outgoung_port_arr[@]} -gt 0 ]] ; then + + for _port in ${smtpd_additional_outgoung_port_arr[@]} ; do + for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + fi + done + done + + echo_done +else + echo_skipped +fi + + +# --- +# - Mail SMTP Server (Port 25) including Spam Control +# --- + +echononl "\t\tMail SMTP Server (Port 25) including Spam Control" + +if [[ ${#smtpd_ips_arr[@]} -gt 0 ]] || [[ ${#forward_smtpd_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#smtpd_ips_arr[@]} > 0 ]] ; then + + for _ip in ${smtpd_ips_arr[@]} ; do + $ip6t -A INPUT -p tcp -d $_ip --dport $standard_smtp_port -m conntrack --ctstate NEW -j ACCEPT + # + # Razor2 (TCP Port 2703) + $ip6t -A OUTPUT -p tcp -s $_ip --dport 2703 -m conntrack --ctstate NEW -j ACCEPT + # DEPRECATED: TCP Port 7 (echo) + $ip6t -A OUTPUT -p tcp -s $_ip --dport 7 -m conntrack --ctstate NEW -j ACCEPT + # + # Pyzor (UDP Port 24441 or TCP Port 24441 or both ?) + $ip6t -A OUTPUT -p udp -s $_ip --dport 24441 -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A OUTPUT -p tcp -s $_ip --dport 24441 -m conntrack --ctstate NEW -j ACCEPT + # + # - DCC (port udp:6277) + $ip6t -A OUTPUT -s $_ip -p udp -m udp --dport 6277 -m conntrack --ctstate NEW -j ACCEPT + # if DCC Server is running (port tcp:6277) + $ip6t -A INPUT -p tcp -d $_ip --dport 6277 -j ACCEPT + $ip6t -A OUTPUT -p tcp -s $_ip --dport 6277 -j ACCEPT + done + fi + + if [[ ${#forward_smtpd_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_smtpd_ip_arr[@]} ; do + $ip6t -A FORWARD -p tcp -d $_ip --dport $standard_smtp_port -m conntrack --ctstate NEW -j ACCEPT + # + # Razor2 (TCP Port 2703) + $ip6t -A FORWARD -p tcp -s $_ip --dport 2703 -m conntrack --ctstate NEW -j ACCEPT + # DEPRECATED: TCP Port 7 (echo) + $ip6t -A FORWARD -p tcp -s $_ip --dport 7 -m conntrack --ctstate NEW -j ACCEPT + # + # Pyzor (UDP Port 24441 or TCP Port 24441 or both ?) + $ip6t -A FORWARD -p udp -s $_ip --dport 24441 -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A FORWARD -p tcp -s $_ip --dport 24441 -m conntrack --ctstate NEW -j ACCEPT + # + # DCC (port udp:6277) + $ip6t -A FORWARD -s $_ip -p udp -m udp --dport 6277 -m conntrack --ctstate NEW -j ACCEPT + # if DCC Server is running (port tcp:6277) + $ip6t -A FORWARD -p tcp -d $_ip --dport 6277 -j ACCEPT + $ip6t -A FORWARD -p tcp -s $_ip --dport 6277 -j ACCEPT + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Mail (additional smtp ports IN) +# --- + +echononl "\t\tMail (additional smtp ports IN)" + +if [[ ${#smtpd_additional_listen_port_arr[@]} -gt 0 ]] ; then + + for _port in ${smtpd_additional_listen_port_arr[@]} ; do + for _dev in ${ext_if_arr[@]} ; do + $ip6t -A INPUT -i $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -i $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + fi + done + done + + echo_done +else + echo_skipped +fi + + +# --- +# - Mailservice (Submission/SMTPS/POP/IMAP Server) +# --- + +echononl "\t\tMailservice (Submission/SMTPS/POP/IMAP Server)" + +if [[ ${#mail_server_ips_arr[@]} -gt 0 ]] || [[ ${#forward_mail_server_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#mail_server_ips_arr[@]} -gt 0 ]] ; then + for _ip in ${mail_server_ips_arr[@]} ; do + # mail ports + # + $ip6t -A INPUT -p tcp -d $_ip -m multiport --dports $mail_user_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi # if [[ ${#mail_server_ips_arr[@]} -gt 0 ]] + + if [[ ${#forward_mail_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_mail_server_ip_arr[@]} ; do + # mail ports + # + $ip6t -A FORWARD -p tcp -d $_ip -m multiport --dports $mail_user_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi # if [[ ${#forward_mail_server_ip_arr[@]} -gt 0 ]] ; then + + echo_done +else + echo_skipped +fi + + +# --- +# - (local) Dovecot auth service +# --- + +echononl "\t\t(local) Dovecot auth service" + +if [[ -n "$dovecot_auth_service" ]] && $dovecot_auth_service ; then + + if [[ ${#dovecot_auth_allowed_network_arr[@]} -gt 0 ]] && [[ -n "$dovecot_auth_port" ]]; then + for _ip in ${dovecot_auth_allowed_network_arr[@]} ; do + $ip6t -A INPUT -p tcp -s $_ip --dport $dovecot_auth_port -m conntrack --ctstate NEW -j ACCEPT + done + echo_done + else + echo_failed + fi +else + echo_skipped +fi + + +# --- +# - Mail Client (Submission/SMTPS/POPS/IMAPS) out only +# --- + +echononl "\t\tMail Client (Submission/SMTPS/POPS/IMAPS) out only" + +if [[ ${#mail_client_ips_arr[@]} -gt 0 ]] || [[ ${#forward_mail_client_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#mail_client_ips_arr[@]} -gt 0 ]] ; then + for _ip in ${mail_client_ips_arr[@]} ; do + # mail ports + # + $ip6t -A OUTPUT -p tcp -s $_ip -m multiport --dports $mail_user_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi # if [[ ${#mail_client_ips_arr[@]} -gt 0 ]] + + if [[ ${#forward_mail_client_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_mail_client_ip_arr[@]} ; do + # mail ports + # + $ip6t -A FORWARD -p tcp -s $_ip -m multiport --dports $mail_user_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi # if [[ ${#forward_mail_client_ip_arr[@]} -gt 0 ]] ; then + + echo_done +else + echo_skipped +fi + + +# --- +# - HTTP(S) OUT +# --- + +echononl "\t\tHTTP(S) out only" + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp -m multiport --dports $standard_http_ports -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p tcp -m multiport --dports $standard_http_ports -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - HTTP(S) (local) Webserver +# --- + +echononl "\t\tHTTP(S) (local) Webserver" + +if [[ ${#http_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_http_server_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#http_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${http_server_ip_arr[@]} ; do + $ip6t -A INPUT -p tcp -d $_ip -m multiport --dports $http_ports -m conntrack --ctstate NEW -j ACCEPT + done + + if [[ ${#forward_http_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_http_server_ip_arr[@]} ; do + $ip6t -A FORWARD -p tcp -d $_ip -m multiport --dports $http_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Mattermost Service +# --- + +echononl "\t\tMattermost (MM) Service" +if [[ ${#mm_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_mm_server_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#mm_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${mm_server_ip_arr[@]} ; do + $ip6t -A INPUT -p udp -d $_ip -m multiport --dports $mm_udp_ports_in -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A OUTPUT -p udp -s $_ip -m multiport --dports $mm_udp_ports_out -m conntrack --ctstate NEW -j ACCEPT + done + + if [[ ${#forward_mm_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_mm_server_ip_arr[@]} ; do + $ip6t -A FORWARD -p udp -d $_ip -m multiport --dports $mm_udp_ports_in -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A FORWARD -p udp -s $_ip -m multiport --dports $mm_udp_ports_out -m conntrack --ctstate NEW -j ACCEPT + done + fi + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - FTP out only" +# --- + +echononl "\t\tFTP out only (using CT target)" + +# - (Re)define helper +# - +$ip6t -A OUTPUT -t raw -p tcp --dport $standard_ftp_port -j CT --helper ftp + +# - Used for different ftpdata recent lists 'ftp6data_out_$j' +# - +declare -i j=1 + +for _dev in ${ext_if_arr[@]} ; do + + # - (1) + # - + # - Open FTP connection and add the destination ip (--rdest) to ftpdata recent list 'ftpdata_out_$j'. + # - + $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_ftp_port -m conntrack --ctstate NEW \ + -m recent --name ftp6data_out_$j --rdest --set -j ACCEPT + + # - (2) + # - - Accept packets if the destination ip-address (--rdest) is in the 'ftpdata_$i' list (--update) + # - and the destination ip-address was seen within the last 1800 seconds (--seconds 1800). + # - + # - - If matched, the "last seen" timestamp of the destination address will be updated (--update). + # - + # - - Entries in the ftpdata list not seen in the last 1800 will be removed (--reap). + # - + $ip6t -A OUTPUT -o $_dev -p tcp -m conntrack --ctstate NEW --dport 1024: \ + -m recent --name ftp6data_out_$j --rdest --update --seconds 1800 --reap -j ACCEPT + + ((j++)) + + # - Accept (helper ftp) related connections + # - + $ip6t -A OUTPUT -m conntrack --ctstate RELATED -m helper --helper ftp -o $_dev -p tcp --dport 1024: -j ACCEPT + +done + +echo_done + + +#echononl "\t\tFTP out only" +# +#for _dev in ${ext_if_arr[@]} ; do +# # (Datenkanal aktiv) +# $ip6t -A INPUT -i $_dev -p tcp --sport $standard_ftp_data_port -m conntrack --ctstate NEW -j ACCEPT +# # (Datenkanal passiv) +# $ip6t -A OUTPUT -o $_dev -p tcp --sport $unprivports --dport $unprivports -m conntrack --ctstate NEW -j ACCEPT +# # (Kontrollverbindung) +# $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_ftp_port -m conntrack --ctstate NEW -j ACCEPT +# if $kernel_forward_between_interfaces ; then +# # (Datenkanal aktiv) +# $ip6t -A FORWARD -i $_dev -p tcp --sport $standard_ftp_data_port -m conntrack --ctstate NEW -j ACCEPT +# # (Datenkanal passiv) +# $ip6t -A FORWARD -o $_dev -p tcp --sport $unprivports --dport $unprivports -m conntrack --ctstate NEW -j ACCEPT +# # (Kontrollverbindung) +# $ip6t -A FORWARD -o $_dev -p tcp --dport $standard_ftp_port -m conntrack --ctstate NEW -j ACCEPT +# fi +#done +# +#echo_done + + +# --- +# - FTP Server" +# --- + +echononl "\t\tFTP Server (using CT target)" + +if [[ ${#ftp_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_ftp_server_ip_arr[@]} -gt 0 ]] ; then + + # - Used for different ftpdata recent lists 'ftpdata_$i' + # - + declare -i i=1 + + # - (Re)define helper + # - + # - !! Note: !! + # - for both, local FTP server (ftp_server_ip_arr) + # - and forward to FTP server (forward_ftp_server_ip_arr) + # - + $ip6t -A PREROUTING -t raw -p tcp --dport $standard_ftp_port -j CT --helper ftp + + if [[ ${#ftp_server_ip_arr[@]} -gt 0 ]] ; then + + for _ip in ${ftp_server_ip_arr[@]} ; do + + # ===== + # - + # - ip_conntrack_ftp cannot see the TLS-encrypted traffic + # - ====================================================== + # - + # - Workaround: + # - (1) add source ip to a 'recent list' named 'ftpdata_$i! if ftp control connections appear + # - (2) accept packets of the formaly created recent list 'ftpdata_$i! + # - + # ===== + + # - (1) + # - + # - Accept initial FTP connection and add the source ip to ftpdata recent list 'ftpdata_$i'. + # - + $ip6t -A INPUT -p tcp -m conntrack --ctstate NEW -d $_ip --dport 21 -m recent --name ftpdata_$i --set -j ACCEPT + + # - (2) + # - - Accept packets if the source ip-address is in the 'ftpdata_$i' list (--update) and the + # - source ip-address was seen within the last 1800 seconds (--seconds 1800). + # - + # - - If matched, the "last seen" timestamp of the source address will be updated (--update). + # - + # - - Entries in the ftpdata list not seen in the last 1800 will be removed (--reap). + # - + $ip6t -A INPUT -p tcp -m conntrack --ctstate NEW --sport 1024: -d $_ip --dport $ftp_passive_port_range \ + -m recent --name ftpdata_$i --update --seconds 1800 --reap -j ACCEPT + + # - Accept (helper ftp) related connections + # - + $ip6t -A INPUT -m conntrack --ctstate RELATED -m helper --helper ftp -d $_ip -p tcp --dport 1024: -j ACCEPT + + ((i++)) + + done + fi + + if [[ ${#forward_ftp_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + + for _ip in ${forward_ftp_server_ip_arr[@]} ; do + + # ===== + # - + # - ip_conntrack_ftp cannot see the TLS-encrypted traffic + # - ====================================================== + # - + # - Workaround: + # - (1) add source ip to a 'recent list' named 'ftpdata_$i! if ftp control connections appear + # - (2) accept packets of the formaly created recent list 'ftpdata_$i! + # - + # ===== + + # - (1) + # - + # - Accept initial FTP connection and add the source ip to ftpdata recent list 'ftpdata_$i'. + # - + $ip6t -A FORWARD -p tcp -m conntrack --ctstate NEW -d $_ip --dport $standard_ftp_port -m recent --name ftpdata_$i --set -j ACCEPT + + # - (2) + # - - Accept packets if the source ip-address is in the 'ftpdata_$i' list (--update) and the + # - source ip-address was seen within the last 1800 seconds (--seconds 1800). + # - + # - - If matched, the "last seen" timestamp of the source address will be updated (--update). + # - + # - - Entries in the ftpdata list not seen in the last 1800 will be removed (--reap). + # - + $ip6t -A FORWARD -p tcp -m conntrack --ctstate NEW --sport 1024: -d $_ip --dport $ftp_passive_port_range \ + -m recent --name ftpdata_$i --update --seconds 1800 --reap -j ACCEPT + $ip6t -A FORWARD -p tcp -m conntrack --ctstate NEW --dport 1024: -s $_ip --sport $ftp_passive_port_range \ + -m recent --name ftpdata_$i --update --seconds 1800 --reap -j ACCEPT + + # - Accept (helper ftp) related connections + # - + $ip6t -A FORWARD -m conntrack --ctstate RELATED -m helper --helper ftp -d $_ip -p tcp --dport 1024: -j ACCEPT + $ip6t -A FORWARD -m conntrack --ctstate RELATED -m helper --helper ftp -s $_ip -p tcp --sport 1024: -j ACCEPT + + ((i++)) + + done + fi + + echo_done +else + echo_skipped +fi + + +#echononl "\t\tFTP Server" +# +#if [[ ${#ftp_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_ftp_server_ip_arr[@]} -gt 0 ]] ; then +# if [[ ${#ftp_server_ip_arr[@]} -gt 0 ]] ; then +# for _ip in ${ftp_server_ip_arr[@]} ; do +# # (Datenkanal aktiv) +# $ip6t -A OUTPUT -p tcp -s $_ip --sport $standard_ftp_data_port -m conntrack --ctstate NEW -j ACCEPT +# # Datenkanal (passiver modus) +# $ip6t -A INPUT -p tcp -d $_ip --dport $unprivports --sport $unprivports -m conntrack --ctstate NEW -j ACCEPT +# # - Kontrollverbindung +# $ip6t -A INPUT -p tcp -d $_ip --dport $standard_ftp_port --sport $unprivports -m conntrack --ctstate NEW -j ACCEPT +# done +# fi +# +# if [[ ${#forward_ftp_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then +# for _ip in ${forward_ftp_server_ip_arr[@]} ; do +# # (Datenkanal aktiv) +# $ip6t -A FORWARD -p tcp -s $_ip --sport $standard_ftp_data_port -m conntrack --ctstate NEW -j ACCEPT +# # Datenkanal (passiver modus) +# $ip6t -A FORWARD -p tcp -d $_ip --dport $unprivports --sport $unprivports -m conntrack --ctstate NEW -j ACCEPT +# # - Kontrollverbindung +# $ip6t -A FORWARD -p tcp -d $_ip --dport $standard_ftp_port --sport $unprivports -m conntrack --ctstate NEW -j ACCEPT +# done +# fi +# +# echo_done +#else +# echo_skipped +#fi + + +# --- +# - XMPP Service (Jabber) +# --- + +echononl "\t\tXMPP Service" + +if [[ ${#xmpp_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_xmpp_server_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#xmpp_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${xmpp_server_ip_arr[@]} ; do + for _port in ${xmmp_tcp_in_port_arr[@]} ; do + $ip6t -A INPUT -p tcp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + + for _port in ${xmmp_tcp_out_port_arr[@]} ; do + $ip6t -A OUTPUT -p tcp -s $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + + if [[ ${#forward_xmpp_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_xmpp_server_ip_arr[@]} ; do + for _port in ${xmmp_tcp_in_port_arr[@]} ; do + $ip6t -A FORWARD -p tcp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + + for _port in ${xmmp_tcp_out_port_arr[@]} ; do + $ip6t -A FORWARD -p tcp -s $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - XMPP Remote Dovecote Out Service +# --- + +echononl "\t\tXMPP Remote Dovecote Out Service" + +if [[ ${#xmmp_remote_out_service_arr[@]} -gt 0 ]] ; then + for _dev in "${ext_if_arr[@]}" ; do + for _val in "${xmmp_remote_out_service_arr[@]}" ; do + IFS=',' read -a _val_arr <<< "${_val}" + $ip6t -A OUTPUT -o $_dev -p tcp -d ${_val_arr[0]} --dport ${_val_arr[1]} -m conntrack --ctstate NEW -j ACCEPT + done + done + echo_done +else + echo_skipped +fi + + +# --- +# - Mumble Service +# --- + +echononl "\t\tMumble Service" + + +if [[ ${#mumble_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_mumble_server_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#mumble_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${mumble_server_ip_arr[@]} ; do + $ip6t -A INPUT -p tcp -d $_ip -m multiport --dports $mumble_ports -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A INPUT -p udp -d $_ip -m multiport --dports $mumble_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi + + if [[ ${#forward_mumble_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_mumble_server_ip_arr[@]} ; do + $ip6t -A FORWARD -p tcp -d $_ip -m multiport --dports $mumble_ports -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A FORWARD -p udp -d $_ip -m multiport --dports $mumble_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Jitsi Video Conferencing Service +# --- + +echononl "\t\tJitsi Meet Video Conferencing Service Incoming Ports" + + +if [[ ${#jitsi_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_jitsi_server_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#jitsi_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${jitsi_server_ip_arr[@]} ; do + if ! containsElement "$_ip" "${http_server_ip_arr[@]}" || [[ "$jitsi_tcp_ports" != "$standard_http_ports" ]] ; then + $ip6t -A INPUT -p tcp -d $_ip -m multiport --dports $jitsi_tcp_ports -m conntrack --ctstate NEW -j ACCEPT + fi + $ip6t -A INPUT -p udp -d $_ip -m multiport --dports $jitsi_udp_port_range -m conntrack --ctstate NEW -j ACCEPT + done + fi + + if [[ ${#forward_jitsi_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_jitsi_server_ip_arr[@]} ; do + if ! containsElement "$_ip" "${http_server_ip_arr[@]}" || [[ "$jitsi_tcp_ports" != "$standard_http_ports" ]] ; then + $ip6t -A FORWARD -p tcp -d $_ip -m multiport --dports $jitsi_tcp_ports -m conntrack --ctstate NEW -j ACCEPT + fi + $ip6t -A FORWARD -p udp -d $_ip -m multiport --dports $jitsi_udp_port_range -m conntrack --ctstate NEW -j ACCEPT + done + fi + + echo_done +else + echo_skipped +fi + +echononl "\t\tJitsi Meet Video Conferencing Service Outgoing Ports" +if [[ ${#jitsi_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_jitsi_server_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#jitsi_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${jitsi_server_ip_arr[@]} ; do + $ip6t -A OUTPUT -p tcp -s $_ip -m multiport --dports $jitsi_tcp_ports_out -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A OUTPUT -p udp -s $_ip -m multiport --dports $jitsi_udp_ports_out -m conntrack --ctstate NEW -j ACCEPT + done + fi + + if [[ ${#forward_jitsi_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_jitsi_server_ip_arr[@]} ; do + $ip6t -A FORWARD -p tcp -s $_ip -m multiport --dports $jitsi_tcp_ports_out -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A FORWARD -p udp -s $_ip -m multiport --dports $jitsi_udp_ports_out -m conntrack --ctstate NEW -j ACCEPT + done + fi + echo_done +else + echo_skipped +fi + +echononl "\t\tJitsi Meet Dovecot Authentication" +if [[ ${#jitsi_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_jitsi_server_ip_arr[@]} -gt 0 ]] ; then + if $jitsi_dovecot_auth && [[ -n "$jitsi_dovecot_host" ]] && [[ -n "$jitsi_dovecot_port" ]] ; then + if [[ ${#jitsi_server_ip_arr[@]} -gt 0 ]] ; then + $ip6t -A OUTPUT -p tcp -d $jitsi_dovecot_host --dport $jitsi_dovecot_port -m conntrack --ctstate NEW -j ACCEPT + fi + + if [[ ${#forward_jitsi_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -p tcp -d $jitsi_dovecot_host --dport $jitsi_dovecot_port -m conntrack --ctstate NEW -j ACCEPT + fi + echo_done + else + echo_skipped + fi +else + echo_skipped +fi + +echononl "\t\tJitsi Remote Jibri Client" +if [[ ${#jitsi_server_ip_arr[@]} -gt 0 ]] \ + && $jitsi_jibri_remote_auth \ + && [[ ${#jitsi_jibri_remote_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${jitsi_jibri_remote_ip_arr[@]} ; do + $ip6t -A INPUT -p tcp -s $_ip --dport $jitsi_jibri_remote_auth_port -m conntrack --ctstate NEW -j ACCEPT + done + + echo_done +else + echo_skipped +fi + + +# --- +# - Jibri Recording / Streaming Service +# --- + +echononl "\t\tJibri Recording / Streaming Service" +if [[ ${#jibri_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_jibri_server_ip_arr[@]} -gt 0 ]]; then + + if [[ -z "$jibri_remote_jitsi_server" ]]; then + echo_skipped + else + if [[ ${#jibri_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${jibri_server_ip_arr[@]} ; do + $ip6t -A OUTPUT -p tcp -s $_ip -d $jibri_remote_jitsi_server --dport $jibri_remote_auth_port -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A OUTPUT -p udp -s $_ip -d $jibri_remote_jitsi_server -m multiport --dports $standard_jitsi_udp_port_range -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A OUTPUT -p udp -s $_ip -m multiport --dports $default_outbound_streaming_tcp_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi + + if [[ ${#forward_jibri_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_jibri_server_ip_arr[@]} ; do + $ip6t -A FORWARD -p tcp -s $_ip -d $jibri_remote_jitsi_server --dport $jibri_remote_auth_port -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A FORWARD -p udp -s $_ip -d $jibri_remote_jitsi_server -m multiport --dports $standard_jitsi_udp_port_range -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A FORWARD -p udp -s $_ip -m multiport --dports $default_outbound_streaming_tcp_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi + + echo_done + fi +else + echo_skipped +fi + + +# --- +# - TURN Service (for NC Talk App) +# --- + +echononl "\t\tTURN Service (for NC Talk App) both: udp and tcp" + +if [[ ${#nc_turn_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_nc_turn_server_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#nc_turn_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${nc_turn_server_ip_arr[@]} ; do + $ip6t -A INPUT -p tcp -d $_ip -m multiport --dports $nc_turn_ports -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A INPUT -p udp -d $_ip -m multiport --dports $nc_turn_ports -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A INPUT -p udp -d $_ip -m multiport --dports $nc_turn_udp_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi + + if [[ ${#forward_nc_turn_server_ip_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _ip in ${forward_nc_turn_server_ip_arr[@]} ; do + $ip6t -A FORWARD -p tcp -d $_ip -m multiport --dports $nc_turn_ports -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A FORWARD -p udp -d $_ip -m multiport --dports $nc_turn_ports -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A FORWARD -p udp -d $_ip -m multiport --dports $nc_turn_udp_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi + + + echo_done +else + echo_skipped +fi + + +# --- +# - Timeserver (Port 37 NOT NTP!)" +# --- + +echononl "\t\tTimeserver (Port 37 NOT NTP!) out only" + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_timeserver_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p tcp --dport $standard_timeserver_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - NTP out only" +# --- + +echononl "\t\tNTP out only" + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_ntp_port -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A OUTPUT -o $_dev -p udp --dport $standard_ntp_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p tcp --dport $standard_ntp_port -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A FORWARD -o $_dev -p udp --dport $standard_ntp_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - NTP local Service" +# --- + +echononl "\t\tNTP local Service" +if [[ -n "$local_ntp_service" ]] && $local_ntp_service ; then + if [[ -z "$ntp_allowed_net" ]] ; then + echo_failed + else + $ip6t -A OUTPUT -p udp -d $ntp_allowed_net --dport $ntp_port -m conntrack --ctstate NEW -j ACCEPT + $ip6t -A INPUT -p udp -s $ntp_allowed_net --dport $ntp_port -m conntrack --ctstate NEW -j ACCEPT + echo_done + fi +else + echo_skipped +fi + + +# --- +# - LDAP out only +# --- + +echononl "\t\tLDAP out only" + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_ldap_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p tcp --dport $standard_ldap_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - LDAPS out only +# --- + +echononl "\t\tLDAPS out only" + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_ldaps_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p tcp --dport $standard_ldaps_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - Whois out only +# --- + +echononl "\t\tWhois out only" + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_whois_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p tcp --dport $standard_whois_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - PGP Keyserver out only +# --- + +echononl "\t\tPGP/GPG Key server - out only" + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_pgp_keyserver_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p tcp --dport $standard_pgp_keyserver_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - GIT out only +# --- + +echononl "\t\tGIT out only" + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp --dport $standard_git_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p tcp --dport $standard_git_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done +echo + + +# --- +# - Special TCP Ports OUT +# --- + +echononl "\t\tSpecial TCP Ports OUT" + +if [[ ${#tcp_out_port_arr[@]} -gt 0 ]] || [[ ${#forward_tcp_out_port_arr[@]} -gt 0 ]] ; then + + if [[ ${#tcp_out_port_arr[@]} -gt 0 ]] ; then + + for _dev in ${ext_if_arr[@]} ; do + for _port in ${tcp_out_port_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + if [[ ${#forward_tcp_out_port_arr[@]} -gt 0 ]] && $kernel_forward_between_interfaces ; then + for _dev in ${ext_if_arr[@]} ; do + for _port in ${tcp_out_port_arr[@]} ; do + $ip6t -A FORWARD -o $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Special UDP Ports OUT +# --- + +echononl "\t\tSpecial UDP Ports OUT" + +if [[ ${#udp_out_port_arr[@]} -gt 0 ]] || [[ ${#forward_udp_out_port_arr[@]} -gt 0 ]] ; then + if [[ ${#udp_out_port_arr[@]} -gt 0 ]] ; then + for _dev in ${ext_if_arr[@]} ; do + for _port in ${udp_out_port_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p udp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + if [[ ${#forward_udp_out_port_arr[@]} -gt 0 ]] ; then + for _dev in ${ext_if_arr[@]} ; do + for _port in ${forward_udp_out_port_arr[@]} ; do + $ip6t -A FORWARD -o $_dev -p udp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + echo_done +else + echo_skipped +fi + +echo + +# ------------- +# --- Portforwarding +# ------------- + +# --- +# - Portforwarding TCP +# --- + +echononl "\t\tPortforwarding TCP" + +if [[ ${#portforward_tcp_arr[@]} -gt 0 ]] ; then + for _val in "${portforward_tcp_arr[@]}" ; do + + # - Split value + # - + IFS=',' read -a _val_arr <<< "${_val}" + + # - Allow Packets IN + # - + $ip6t -A INPUT -i ${_val_arr[0]} -p tcp -d ${_val_arr[1]} --dport ${_val_arr[2]} -m conntrack --ctstate NEW -j ACCEPT + + # - Allow Packets FORWARD + # - + $ip6t -A FORWARD -i ${_val_arr[0]} -p tcp -d ${_val_arr[3]} --dport ${_val_arr[4]} -m conntrack --ctstate NEW -j ACCEPT + + _job_id="$(ps ax | grep "TCP6-LISTEN:${_val_arr[2]},fork,bind=\[${_val_arr[1]}\]" | grep -v grep | awk '{print$1}')" + if [[ -n "$_job_id" ]]; then + kill ${_job_id} > /dev/null 2>&1 + fi + + socat TCP6-LISTEN:${_val_arr[2]},fork,bind=[${_val_arr[1]}] TCP:[${_val_arr[3]}]:${_val_arr[4]} & + + done + echo_done +else + echo_skipped +fi + + +# --- +# - Portforwarding UDP +# --- + +echononl "\t\tPortforwarding UDP" + +if [[ ${#portforward_udp_arr[@]} -gt 0 ]] ; then + for _val in "${portforward_udp_arr[@]}" ; do + + # - Split value + # - + IFS=',' read -a _val_arr <<< "${_val}" + + # - Allow Packets IN + # - + $ip6t -A INPUT -i ${_val_arr[0]} -p udp -d ${_val_arr[1]} --dport ${_val_arr[2]} -m conntrack --ctstate NEW -j ACCEPT + + # - Allow Packets FORWARD + # - + $ip6t -A FORWARD -i ${_val_arr[0]} -p udp -d ${_val_arr[3]} --dport ${_val_arr[4]} -m conntrack --ctstate NEW -j ACCEPT + + _job_id="$(ps ax | grep "UDP6-LISTEN:${_val_arr[2]},fork,bind=\[${_val_arr[1]}\]" | grep -v grep | awk '{print$1}')" + if [[ -n "$_job_id" ]]; then + kill ${_job_id} > /dev/null 2>&1 + fi + + socat UDP6-LISTEN:${_val_arr[2]},fork,bind=[${_val_arr[1]}] UDP:[${_val_arr[3]}]:${_val_arr[4]} & + + done + echo_done +else + echo_skipped +fi + + +echo + +# --- +# - UNIX Traceroute +# --- + +echononl "\t\tUNIX Traceroute" + +# versendet udp packete im gegensatz zu tracert von windows +# der icmp-echo-request pakete versendet +# einige implementierungen von traceroute (linux) erm�lichens +# die option -I und versenden dann ebenfalls icmp-echo-request pakete + +for _dev in ${ext_if_arr[@]} ; do + $ip6t -A OUTPUT -o $_dev -p udp -m conntrack --ctstate NEW --dport 33434:33530 -j ACCEPT + $ip6t -A INPUT -i $_dev -p udp -m conntrack --ctstate NEW --dport 33434:33530 -j ACCEPT + if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -o $_dev -p udp -m conntrack --ctstate NEW --dport 33434:33530 -j ACCEPT + $ip6t -A FORWARD -i $_dev -p udp -m conntrack --ctstate NEW --dport 33434:33530 -j ACCEPT + fi +done + +echo_done + + +# --- +# - Ping +# --- + +echononl "\t\tPing" + +$ip6t -A INPUT -p ipv6-icmp -j ACCEPT +$ip6t -A OUTPUT -p ipv6-icmp -j ACCEPT +if $kernel_forward_between_interfaces ; then + $ip6t -A FORWARD -p ipv6-icmp -j ACCEPT +fi + +#for _dev in ${ext_if_arr[@]} ; do +# $ip6t -A INPUT -i $_dev -p ipv6-icmp -j ACCEPT +# $ip6t -A OUTPUT -o $_dev -p ipv6-icmp -j ACCEPT +# if $kernel_forward_between_interfaces ; then +# $ip6t -A FORWARD -i $_dev -p ipv6-icmp -j ACCEPT +# $ip6t -A FORWARD -o $_dev -p ipv6-icmp -j ACCEPT +# fi +#done +#for _dev in ${local_if_arr[@]} ; do +# $ip6t -A INPUT -i $_dev -p ipv6-icmp -j ACCEPT +# $ip6t -A OUTPUT -o $_dev -p ipv6-icmp -j ACCEPT +# if $kernel_forward_between_interfaces ; then +# $ip6t -A FORWARD -i $_dev -p ipv6-icmp -j ACCEPT +# $ip6t -A FORWARD -o $_dev -p ipv6-icmp -j ACCEPT +# fi +#done + +echo_done + + +# --- +# - log all rejected traffic +# --- + +echo +echononl "\tLogging all rejected traffic" + +if $log_rejected || $log_all ; then + + $ip6t -A OUTPUT -m limit --limit-burst 5 -p tcp ! --tcp-flags ACK,FIN ACK,FIN -j $LOG_TARGET $tag_log_prefix "$log_prefix Rejected (end of firewall): " + $ip6t -A OUTPUT -m limit --limit-burst 5 -p udp -j $LOG_TARGET $tag_log_prefix "$log_prefix Rejected (end of firewall): " + $ip6t -A INPUT -m limit --limit-burst 5 -j $LOG_TARGET $tag_log_prefix "$log_prefix Rejected (end of firewall): " + + if $kernel_forward_between_interfaces ; then + #$ip6t -A FORWARD -j $LOG_TARGET $tag_log_prefix "$log_prefix Rejected: " + $ip6t -A FORWARD -m limit --limit-burst 5 -j $LOG_TARGET $tag_log_prefix "$log_prefix Rejected (end of firewall): " + fi + echo_done +else + echo_skipped +fi + + +# --- +# - Drop all other +# --- + +echo +echononl "\tDrop all other on all interfaces" + +$ip6t -A INPUT -j DROP +$ip6t -A OUTPUT -j DROP + +# Normaly FORWARD pakages shoul be dropped fpr all packages. but on sinma systems it is needed +# to question also 'do_not_firewall_bridged_traffic' and 'do_not_firewall_lx_guest_systems'. +# Otherwise, LX Container won't work on SINMA systems. +# +if ${do_not_firewall_bridged_traffic} \ + || ${do_not_firewall_lx_guest_systems} ; then + $ip6t -A FORWARD -j ACCEPT +else + $ip6t -A FORWARD -j DROP +fi + +echo_done + + + +# ------------- +# ------------- Reload Fail2Ban if installed +# ------------- + +if ${FAIL2BAN_WAS_RUNNING}; then + echo + echononl "\tReloading fail2ban.." + $fail2ban_client reload > /dev/null 2>&1 + if [ "$?" = "0" ]; then + echo_done + else + # Fallback: reload + restart jails if needed + $fail2ban_client reload --restart > /dev/null 2>&1 + if [ "$?" = "0" ]; then + echo_done + else + echo_skipped + warn "Fail2ban reload failed. Leaving fail2ban unchanged. Check: fail2ban-client -d and /var/log/fail2ban.log" + fi + fi +else + # fail2ban not running before; do not start it here + : +fi + + +echo +exit 0 + diff --git a/roles/ipt-server/files/usr/local/sbin/ipt-firewall-server b/roles/ipt-server/files/usr/local/sbin/ipt-firewall-server new file mode 100755 index 0000000..ea05b4b --- /dev/null +++ b/roles/ipt-server/files/usr/local/sbin/ipt-firewall-server @@ -0,0 +1,3178 @@ +#!/usr/bin/env bash + + +# ------------- +# - Settings +# ------------- + +ipt_conf_dir="/etc/ipt-firewall" + +inc_functions_file="${ipt_conf_dir}/include_functions.conf" + +conf_logging=${ipt_conf_dir}/logging_ipv4.conf +conf_interfaces=${ipt_conf_dir}/interfaces_ipv4.conf +conf_default_settings=${ipt_conf_dir}/default_settings.conf +conf_main=${ipt_conf_dir}/main_ipv4.conf +conf_post_declarations=${ipt_conf_dir}/post_declarations.conf +conf_ban_ipv4_list="${ipt_conf_dir}/ban_ipv4.list" + + +ipt="$(command -v iptables 2>/dev/null)" + +if [[ -z "$ipt" ]] ; then + echo "" + echo -e "\tiptables was not found on this server!" + echo + echo -e "\tFirewall Script was stopped!" + echo + exit 1 +fi + + +# ------------- +# - Load Default Settings and Functions +# ------------- + +if [[ ! -f "$conf_default_settings" ]]; then + fatal "Missing configuration for default_settings - file '$conf_default_settings'" +else + source $conf_default_settings +fi + +if [[ ! -f "$inc_functions_file" ]] ; then + echo "" + echo -e "\tMissing include file '$inc_functions_file'" + echo + echo -e "\tFirewall Script was stopped!" + echo + exit 1 +else + source $inc_functions_file +fi + + +# ------------- +# - Some checks and preloads.. +# ------------- + +# --- Debian 12/13: enforce iptables-nft backend (nf_tables) and prevent legacy/nft mix +if ! "$ipt" --version 2>/dev/null | grep -q "nf_tables"; then + echo "" + echo "ERROR: Your iptables is NOT using nf_tables backend (iptables-nft)." + echo "This script expects iptables-nft on Debian 12/13 to avoid legacy/nft mixed rules." + echo "" + echo "Fix (on the host, as root):" + echo " update-alternatives --set iptables /usr/sbin/iptables-nft" + echo " update-alternatives --set ip6tables /usr/sbin/ip6tables-nft" + echo "" + echo "Current: $($ipt --version 2>/dev/null || echo 'unknown')" + exit 1 +fi + + +# ------------- +# --- Ensure required modules for this script (best effort; host-side in containers) +# ------------- + +echo +echononl "\tEnsure required modules are loaded.." +if is_container ; then + echo_skipped +else + + ensure_mod nf_conntrack + ensure_mod nf_nat + ensure_mod nf_conntrack_ftp + ensure_mod nf_nat_ftp + ensure_mod xt_recent + ensure_mod xt_hashlimit + ensure_mod xt_connlimit + ensure_mod xt_owner + ensure_mod xt_helper + ensure_mod br_netfilter + + echo_done +fi + + +# --- Security hardening / predictable conntrack behavior: +# Disable automatic conntrack helper assignment (keep explicit CT --helper rules) +if ! is_container ; then + sysctl -w net.netfilter.nf_conntrack_helper=0 >/dev/null 2>&1 || true +fi + +if [[ ! -f "$conf_logging" ]]; then + fatal "Missing configuration for logging - file '$conf_logging'" +else + source $conf_logging +fi + +if [[ ! -f "$conf_interfaces" ]]; then + fatal "Missing interface configurations - file '$conf_interfaces'" +else + source $conf_interfaces +fi + +if [[ ! -f "$conf_main" ]]; then + fatal "Missing main configurations - file '$conf_main'" +else + source $conf_main +fi + +if [[ ! -f "$conf_post_declarations" ]]; then + fatal "Missing post declarations - file '$conf_post_declarations'" +else + source $conf_post_declarations +fi + + + +echo +echo -e "\033[37m\033[1m\tStarting firewall iptables (IpV4)..\033[m" +echo + + + +# ------------- +# --- Activate IP Forwarding +# ------------- + +## - IP Forwarding deaktivieren. +## - +## - Activate if kernel_activate_forwarding ist set to true, deactivate otherwise +## - +## - Only needed, if hosts acts as a router. +## - +if $kernel_activate_forwarding ; then + echo 1 > /proc/sys/net/ipv4/ip_forward + echononl "\tActivate Forwarding.." + echo_done +else + echo 0 > /proc/sys/net/ipv4/ip_forward + echononl "\t\033[33m\033[1mDisable Forwarding..\033[m" + echo_done +fi + +if $kernel_support_dynaddr ; then + echononl "\tActivate kernel support for dynamic addresses.." + if [[ -n $dynaddr_flag ]] && [[ $dynaddr_flag =~ ^-?[0-9]+$ ]]; then + echo $dynaddr_flag > /proc/sys/net/ipv4/ip_dynaddr + echo_done + else + echo_failed + fi +else + echo 0 > /proc/sys/net/ipv4/ip_dynaddr + echononl "\t\033[33m\033[1mDisable kernel support for dynamic addresses..\033[m" + echo_done +fi + + +# ------------- +# --- Adjust Kernel Parameters (Security/Tuning) +# ------------- + +echo "" +echononl "\tAdjust Kernel Parameters (Security/Tuning).." + +if ! is_container ; then + ## - Reduce DoS'ing ability by reducing timeouts + ## - + if $kernel_reduce_timeouts ; then + echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout + echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_time + echo 1 > /proc/sys/net/ipv4/tcp_window_scaling + echo 0 > /proc/sys/net/ipv4/tcp_sack + fi + + + ## - SYN COOKIES + ## - + if $kernel_tcp_syncookies ; then + echo 1 > /proc/sys/net/ipv4/tcp_syncookies + echo 2048 > /proc/sys/net/ipv4/tcp_max_syn_backlog + echo 3 > /proc/sys/net/ipv4/tcp_synack_retries + fi + + ## - Protection against ICMP bogus error responses + ## - + if $kernel_protect_against_icmp_bogus_messages ; then + echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses + fi + + ## - Ignore Broadcast Pings + ## - + if $kernel_ignore_broadcast_ping ; then + echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts + fi + + ## - Deactivate Source Routed Packets + ## - + if $kernel_deactivate_source_route ; then + for asr in /proc/sys/net/ipv4/conf/*/accept_source_route ; do + echo 0 > $asr + done + fi + + ## - Deactivate sending ICMP redirects + ## - + if $kernel_dont_accept_redirects ; then + for rp_filter in /proc/sys/net/ipv4/conf/*/rp_filter ; do + echo 1 > $rp_filter + done + fi + + ## - Logging of spoofed (source routed" and "redirect") packets + ## - + if $kernel_log_martians ; then + echo "1" > /proc/sys/net/ipv4/conf/all/log_martians + fi + + ## - Keine ICMP Umleitungspakete akzeptieren. + ## - + ## - Diese können zur Veränderung der Routing Tables verwendet + ## - werden, möglicherweise mit einem böswilligen Ziel. + ## - + #echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects + + ## - NUMBER OF CONNECTIONS TO TRACK + ## - + #echo "65535" > /proc/sys/net/ipv4/netfilter/ip_conntrack_max + + echo_done # Adjust Kernel Parameters (Security/Tuning) +else + echo_skipped +fi + + +# ------------- +# --- Prevent bridged traffic getting pushed through the host's iptables rules +# ------------- + +echo +echononl "\tDo not firewall bridged / LX Gust System traffic" + +if ${do_not_firewall_bridged_traffic} || ${do_not_firewall_lx_guest_systems} ; then + + if ! is_container; then + + _done=false + + for _dev in ${ext_if_arr[@]} ; do + + # Try to detect virtual interfaces (veth*)) and the master interface + # of the given bridge dynamically + # + # ports="$(get_bridge_ports "$br")" + # + # or directly here: + # + # ports="$(ip -o link show master "${_dev}" 2>/dev/null | awk -F': ' '{print $2}')" + # + # ports="$(ip -o link show master "${_dev}" 2>/dev/null | awk -F': ' '{print $2}')" + # + ports="$(ip -o link show master "${_dev}" 2>/dev/null | awk -F': ' '{print $2}')" + + for _port in $ports ; do + $ipt -A FORWARD -i "${_port}" -j ACCEPT + $ipt -A FORWARD -o "${_port}" -j ACCEPT + _done=true + done + + done + + if ! ${_done} ; then + $ipt -A FORWARD -i veth+ -j ACCEPT + $ipt -A FORWARD -o veth+ -j ACCEPT + fi + + echo_done + else + echo_skipped + fi +else + echo_skipped +fi + + +echononl "\tIPv4: bypass host filtering for container ports.." +if ${do_not_firewall_bridged_traffic} || ${do_not_firewall_lx_guest_systems} ; then + + if ! is_container; then + + _bridge_sysctl_ok=true + + # IPv4: if you keep the sysctl bypass (recommended if it's working) + sysctl -w net.bridge.bridge-nf-call-iptables=0 >/dev/null 2>&1 || _bridge_sysctl_ok=false + + if ${_bridge_sysctl_ok} ; then + echo_done + else + echo_failed + fi + + else + echo_skipped + fi +fi + + +# ------------- Fail2ban handling (do not stop/start; keep bans stable) ------------- +echo +echononl "\tCheck presence and configuration of Fail2ban .." +echo_done +if ! has_fail2ban ; then + warn "Fail2ban is not installed.." +elif ! fail2ban_running ; then + warn "Fail2ban is installed but not running.." +else + CURRENT_BANACTION=$(grep -E '^\s*banaction\s*=' "$FAIL2BAN_CONFIG_FILE" | head -1 | tr -d ' ' | cut -d'=' -f2) + if [[ -n ${CURRENT_BANACTION} ]] ; then + if [ "$CURRENT_BANACTION" = "nftables" ]; then + info "Fail2ban is running, banaction is et to nftables." + else + warn "Change banaction from ${CURRENT_BANACTION} to \033[1mbanaction=nftables\033[m" + fi + else + warn "banaction seems not to be configured. Take care that \033[1mbanaction=nftables\033[m" + fi + FAIL2BAN_WAS_RUNNING=true +fi +# +# ------------- Ende: Fail2ban handling (do not stop/start; keep bans stable) ------------- + + +# ------------- +# --- Set default policies / Flush Rules +# ------------- + + +echo +echononl "\tFlushing firewall iptable (IPv4).." + +# - default policies +# - +$ipt -P INPUT ACCEPT +$ipt -P OUTPUT ACCEPT +$ipt -P FORWARD ACCEPT + +## - flush chains +## - +$ipt -F +$ipt -F INPUT +$ipt -F OUTPUT +$ipt -F FORWARD +$ipt -F -t mangle +$ipt -F -t nat +$ipt -F -t raw +$ipt -X +$ipt -Z + +echo_done # Flushing firewall iptable (IPv6).. +echo + + +echononl "\tMasquerade (NAT) interfaces.." +if [[ ${#nat_device_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _dev in ${nat_device_arr[@]} ; do + $ipt -t nat -A POSTROUTING -o $_dev -j MASQUERADE + done + echo_done +else + echo_skipped +fi +echo + + + +# ------------- +# ---- Log given IP Addresses +# ------------- + +echononl "\tLog given IPv4 Addresses" +if [[ ${#log_ip_arr[@]} -gt 0 ]]; then + for _ip in ${log_ip_arr[@]} ; do + $ipt -A INPUT -s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix $_ip IN: " + $ipt -A OUTPUT -d $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix $_ip OUT: " + $ipt -A FORWARD -s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix $_ip FORWARD FROM: " + $ipt -A FORWARD -d $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix $_ip FORWARD TO: " + done + + echo_done +else + echo_skipped +fi + + + +# ------------- +# ------------ Stopping firewall if only flushing was requested (parameter flush) +# ------------- + +case $1 in + flush) + echo + echo -e "\t\033[37m\033[1mFlushing firewall was requested. No more rules..\033[m" + echo + exit 0;; +esac + + +# --- +# - Permit all traffic through WireGuard lines +# --- +echononl "\tPermit all traffic through WireGuard lines.." +for _wg_if in ${wg_if_arr[@]} ; do + $ipt -A INPUT -i $_wg_if -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -i $_wg_if -j ACCEPT + fi +done +echo_done + + +# --- +# - Permit all traffic through VPN lines +# --- +echononl "\tPermit all traffic through VPN lines.." +for _vpn_if in ${vpn_if_arr[@]} ; do + $ipt -A INPUT -i $_vpn_if -m conntrack --ctstate NEW -j ACCEPT + $ipt -A OUTPUT -o $_vpn_if -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -i $_vpn_if -m conntrack --ctstate NEW -j ACCEPT + $ipt -A FORWARD -o $_vpn_if -m conntrack --ctstate NEW -j ACCEPT + fi +done +echo_done + + + +# ------------- +# --- Pass through Devices Interfaces (not firewalled) +# ------------- + +echononl "\tPass through Devices (not firewalled)" +if [[ ${#unprotected_if_arr[@]} -gt 0 ]]; then + for _dev in ${unprotected_if_arr[@]} ; do + if $log_unprotected || $log_all ; then + $ipt -t mangle -A PREROUTING -i $_dev -j $LOG_TARGET $tag_log_prefix "$log_prefix Not firewalled ${_dev}:" + $ipt -A OUTPUT -o $_dev -j $LOG_TARGET $tag_log_prefix "$log_prefix Not firewalled ${_dev}:" + $ipt -A INPUT -i $_dev -j $LOG_TARGET $tag_log_prefix "$log_prefix Not firewalled ${_dev}:" + $ipt -A FORWARD -o $_dev -j $LOG_TARGET $tag_log_prefix "$log_prefix Not firewalled ${_dev}:" + fi + $ipt -t mangle -A PREROUTING -i $_dev -j ACCEPT + $ipt -A OUTPUT -o $_dev -j ACCEPT + $ipt -A INPUT -i $_dev -j ACCEPT + $ipt -A FORWARD -o $_dev -j ACCEPT + done + echo_done +else + echo_skipped +fi + + +# --- +# - Allow Forwarding certain private Addresses +# --- + +echononl "\tAllow forwarding (private) IPs / IP-Ranges.." +if [[ ${#forward_private_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${forward_private_ip_arr[@]}; do + # NOTE: These IPs/IP-ranges are intentionally not firewalled (pass-through). + if $log_forwarding_priv_ip || $log_all ; then + $ipt -A FORWARD -d $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Not firewalled (forward) $_ip: " + $ipt -A FORWARD -s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Not firewalled (forward) $_ip: " + fi + $ipt -A FORWARD -d $_ip -j ACCEPT + $ipt -A FORWARD -s $_ip -j ACCEPT + done + echo_done +else + echo_skipped +fi + + +# ------------- +# --- Block IPs / Networks / Interfaces +# ------------- +echononl "\tBlock IPs / Networks / Interfaces.." + + +# --- +# - Block IPs +# --- + +for _ip in $blocked_ips ; do + for _dev in ${ext_if_arr[@]} ; do + if $log_blocked_ip || $log_all ; then + $ipt -A INPUT -i $_dev -s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked ${_ip}:" + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -i $_dev -s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked ${_ip}:" + fi + fi + $ipt -A INPUT -i $_dev -s $_ip -j DROP + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -i $_dev -s $_ip -j DROP + fi + done +done + + +# --- +# - Block Interfaces +# --- + +for _if in ${blocked_if_arr[@]} ; do + if $log_blocked_if || $log_all ; then + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -i $_if -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked IF ${_if}:" + $ipt -A FORWARD -o $_if -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked IF ${_if}:" + fi + $ipt -A INPUT -i $_if -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked IF ${_if}:" + $ipt -A OUTPUT -o $_if -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked IF ${_if}:" + fi + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -i $_if -j DROP + $ipt -A FORWARD -o $_if -j DROP + fi + $ipt -A INPUT -i $_if -j DROP + $ipt -A OUTPUT -o $_if -j DROP +done + +echo_done # Block IPs / Networks / Interfaces.. + + + +# --- +# - Block IPs/Netwoks reading from file 'ban_ipv4.list'" +# --- + +echononl "\tBlock IPs/Netwoks reading from file 'ban_ipv4.list' .." + +if [[ -f "$conf_ban_ipv4_list" ]] ; then + + declare -a octets + declare -i index + + while IFS='' read -r _line || [[ -n $_line ]] ; do + + is_valid_ipv4=true + is_valid_mask=true + ipv4="" + mask="" + + # Ignore comment lines + # + [[ $_line =~ ^[[:space:]]{0,}# ]] && continue + + # Ignore blank lines + # + [[ $_line =~ ^[[:space:]]*$ ]] && continue + + # Remove leading whitespace characters + # + _line="${_line#"${_line%%[![:space:]]*}"}" + + + # Catch IPv4 Address + # + given_ipv4="$(echo $_line | cut -d ' ' -f1)" + + + # Splitt Ipv4 address from possible given CIDR number + # + IFS='/' read -ra _addr <<< "$given_ipv4" + _ipv4="${_addr[0]}" + + if [[ -n "${_addr[1]}" ]] ; then + _mask="${_addr[1]}" + test_netmask=false + + # Is 'mask' a valid CIDR number? If not, test agains a valid netmask + # + if $(test -z "${_mask##*[!0-9]*}" > /dev/null 2>&1) ; then + + # Its not a vaild mask number, but naybe a valit netmask. + # + test_netmask=true + else + if [[ $_mask -gt 32 ]]; then + + # Its not a vaild cidr number, but naybe a valit netmask. + # + test_netmask=true + else + + # OK, we have a vaild cidr number between '0' and '32' + # + mask=$_mask + fi + fi + + # Test if given '_mask' is a valid netmask. + # + if $test_netmask ; then + octets=( ${_mask//\./ } ) + + # Complete netmask if necessary + # + while [[ ${#octets[@]} -lt 4 ]]; do + octets+=(0) + done + + [[ ${#octets[@]} -gt 4 ]] && is_valid_mask=false + + index=0 + for octet in ${octets[@]} ; do + if [[ ${octet} =~ ^[0-9]{1,3}$ ]] ; then + if [[ $octet -gt 255 ]] ; then + is_valid_mask=false + fi + if [[ $index -gt 0 ]] ; then + mask="${mask}.${octet}" + else + mask="${octet}" + fi + + else + is_valid_mask=false + fi + + ((index++)) + done + fi + + adjust_mask=false + else + mask=32 + adjust_mask=true + fi + + # Splitt given address into their octets + # + octets=( ${_ipv4//\./ } ) + + # Complete IPv4 address if necessary + # + while [[ ${#octets[@]} -lt 4 ]]; do + octets+=(0) + + # Only adjust CIDR number if not given + # + if $adjust_mask ; then + mask="$(expr $mask - 8)" + fi + done + + # Pre-check if given IPv4 Address seems to be a valid address + # + [[ ${#octets[@]} -gt 4 ]] && is_valid_ipv4=false + + # Check if given IPv4 Address is a valid address + # + if $is_valid_ipv4 ; then + index=0 + for octet in ${octets[@]} ; do + if [[ ${octet} =~ ^[0-9]{1,3}$ ]] ; then + if [[ $octet -gt 255 ]] ; then + is_valid_ipv4=false + fi + if [[ $index -gt 0 ]] ; then + ipv4="${ipv4}.${octet}" + else + ipv4="${octet}" + fi + + else + is_valid_ipv4=false + fi + + ((index++)) + done + fi + + if $is_valid_ipv4 && $is_valid_mask; then + + _ip="${ipv4}/${mask}" + + if containsElement "$_ip" "${ban_ipv4_arr[@]}" ; then + continue + fi + + for _dev in ${ext_if_arr[@]} ; do + if $log_blocked_ip || $log_all ; then + $ipt -A INPUT -i $_dev -s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked by ban_ipv4.list:" + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -i $_dev -s $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Blocked by ban_ipv4.list::" + fi + fi + $ipt -A INPUT -i $_dev -s $_ip -j DROP + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -i $_dev -s $_ip -j DROP + fi + done + + ban_ipv4_arr+=("$_ip") + + else + msg="$msg '${given_ipv4}'" + fi + + done < "$conf_ban_ipv4_list" + echo_done + + if [[ -n "$msg" ]]; then + warn "Ignored:$msg" + fi +else + echo_skipped +fi + + + +# ------------- +# --- Protections against several attacks / unwanted packages +# ------------- +echo +echo -e "\t\033[37m\033[1mProtections against several attacks / unwanted packages..\033[m" + + +# --- +# - Drop invalid packets +# --- + +echononl "\tDrop invalid packets" +if $log_invalid_packets|| $log_all ; then + $ipt -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid packets:" +fi +$ipt -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP +echo_done + + +# --- +# Drop TCP packets that are new and are not SYN +# --- + +echononl "\tDrop TCP packets that are new and are not SYN" +if $log_new_not_sync || $log_all ; then + $ipt -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j $LOG_TARGET $tag_log_prefix "$log_prefix New but not SYN:" +fi +$ipt -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP +echo_done + + +# --- +# - Drop SYN packets with suspicious MSS value +# --- + +echononl "\tDrop SYN packets with suspicious MSS value" +if $log_syn_with_suspicious_mss || $log_all ; then + $ipt -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j $LOG_TARGET $tag_log_prefix "$log_prefix suspicious MSS:" +fi +$ipt -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP +echo_done + + +# --- +# - Block packets with bogus TCP flags +# --- + +echononl "\tBlock packets with bogus TCP flags" +if $log_invalid_flags || $log_all ; then + $ipt -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ipt -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ipt -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ipt -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ipt -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ipt -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ipt -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ipt -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ipt -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ipt -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ipt -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ipt -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" + $ipt -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j $LOG_TARGET $tag_log_prefix "$log_prefix Invalid flags:" +fi +$ipt -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP +$ipt -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP +$ipt -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP +$ipt -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP +$ipt -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP +$ipt -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP +$ipt -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP +$ipt -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP +$ipt -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP +$ipt -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP +$ipt -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP +$ipt -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP +$ipt -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP +echo_done + + +# --- +# - Block spoofed (own ip) packets +# --- + +echononl "\tBlock spoofed (own ip) packets" +if $log_spoofed || $log_all ; then + for _ip in ${ext_ip_arr[@]} ; do + $ipt -t mangle -A PREROUTING -s $_ip -d $_ip -j $LOG_TARGET $tag_log_prefix "$log_prefix Spoofed (own ip): " + done +fi +for _ip in ${ext_ip_arr[@]} ; do + $ipt -t mangle -A PREROUTING -s $_ip -d $_ip -j DROP +done +echo_done + + +# --- +# - Block spoofed (private/reserved) packets +# --- + +echononl "\tBlock spoofed (private/reserved) packets" +for _dev in ${ext_if_arr[@]} ; do + if $log_spoofed || $log_all ; then + $ipt -t mangle -A PREROUTING -i $_dev -s $class_d_multicast -j $LOG_TARGET $tag_log_prefix "$log_prefix Class D Multicast: " + $ipt -t mangle -A PREROUTING -i $_dev -s $link_local_rfc_5735 -j $LOG_TARGET $tag_log_prefix "$log_prefix link local block: " + $ipt -t mangle -A PREROUTING -i $_dev -s $priv_class_b -j $LOG_TARGET $tag_log_prefix "$log_prefix Class A private net: " + $ipt -t mangle -A PREROUTING -i $_dev -s $test_net_1_rfc_5735 -j $LOG_TARGET $tag_log_prefix "$log_prefix TEST-NET-1: " + $ipt -t mangle -A PREROUTING -i $_dev -s $priv_class_c -j $LOG_TARGET $tag_log_prefix "$log_prefix Class C private net: " + $ipt -t mangle -A PREROUTING -i $_dev -s $priv_class_a -j $LOG_TARGET $tag_log_prefix "$log_prefix Class A private net: " + $ipt -t mangle -A PREROUTING -i $_dev -s $this_net_rfc_5735 -j $LOG_TARGET $tag_log_prefix "$log_prefix THIS NET: " + $ipt -t mangle -A PREROUTING -i $_dev -s $class_e_reserved -j $LOG_TARGET $tag_log_prefix "$log_prefix Class E reserved: " + fi +done + +if $log_spoofed || $log_all ; then + $ipt -t mangle -A PREROUTING -s $loopback_ipv4 ! -i lo -j $LOG_TARGET $tag_log_prefix "$log_prefix (loopback): " +fi + +for _dev in ${ext_if_arr[@]} ; do + $ipt -t mangle -A PREROUTING -i $_dev -s $class_d_multicast -j DROP + $ipt -t mangle -A PREROUTING -i $_dev -s $link_local_rfc_5735 -j DROP + $ipt -t mangle -A PREROUTING -i $_dev -s $priv_class_b -j DROP + $ipt -t mangle -A PREROUTING -i $_dev -s $test_net_1_rfc_5735 -j DROP + $ipt -t mangle -A PREROUTING -i $_dev -s $priv_class_c -j DROP + $ipt -t mangle -A PREROUTING -i $_dev -s $priv_class_a -j DROP + $ipt -t mangle -A PREROUTING -i $_dev -s $this_net_rfc_5735 -j DROP + $ipt -t mangle -A PREROUTING -i $_dev -s $class_e_reserved -j DROP +done +$ipt -t mangle -A PREROUTING -s $loopback_ipv4 ! -i lo -j DROP +echo_done + + +# --- +# - Drop fragments in all chains +# --- + +echononl "\tDrop fragments in all chains" +if $log_fragments || $log_all ; then + /sbin/iptables -t mangle -A PREROUTING -f -j $LOG_TARGET $tag_log_prefix "$log_prefix IPTABLES FRAGMENTS:" +fi +/sbin/iptables -t mangle -A PREROUTING -f -j DROP +echo_done + + +# --- +# - Drop ICMP all ICMP traffic (you usually don't need this protocol) +# --- + +echononl "\tDrop all ICMP traffic.." +if [[ -n "$drop_icmp" ]] && $drop_icmp ; then + if $log_rejected || $log_all ; then + $ipt -t mangle -A PREROUTING -p icmp -j $LOG_TARGET $tag_log_prefix "$log_prefix Drop all ICMP traffic: " + fi + $ipt -t mangle -A PREROUTING -p icmp -j DROP + echo_done +else + echo_skipped +fi + + +# ------------- +# --- Drop Mikrotik RouterOS Neighbor Discovery Protocol (MNDP) Traffic +# --- Drop Tinc VPN Traffic +# ------------- + +[ "${drop_mndp,,}" == "yes" ] && drop_mndp=true +[ "${drop_mndp,,}" == "no" ] && drop_mndp=false + +echononl "\tDrop Tinc VPN / Mikrotik RouterOS Neighbor Discovery Traffic" +if [[ -n "$drop_mndp" ]] && ${drop_mndp} ; then + for _dev in ${ext_if_arr[@]} ; do + + if $log_mndp || $log_all ; then + $ipt -A OUTPUT -o $_dev -p udp --dport $standard_mndp_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MNDP Out: " + $ipt -A INPUT -i $_dev -p udp --sport $standard_mndp_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MNDP IN: " + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p udp --dport $standard_mndp_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MNDP fwd Out: " + $ipt -A FORWARD -i $_dev -p udp --dport $standard_mndp_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MNDP fwd In: " + fi + fi + $ipt -A OUTPUT -o $_dev -p udp --dport $standard_mndp_port -j DROP + $ipt -A INPUT -i $_dev -p udp --sport $standard_mndp_port -j DROP + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p udp --dport $standard_mndp_port -j DROP + $ipt -A FORWARD -i $_dev -p udp --dport $standard_mndp_port -j DROP + fi + + done + echo_done +else + echo_skipped +fi + + +# ------------- +# --- Drop Multicast DNS Traffic +# ------------- + +[ "${drop_mdns,,}" == "yes" ] && drop_mdns=true +[ "${drop_mdns,,}" == "no" ] && drop_mdns=false + +echononl "\tDrop Multicast DNS Traffic" +if [[ -n "$drop_mdns" ]] && ${drop_mdns} ; then + for _dev in ${ext_if_arr[@]} ; do + if $log_mdns || $log_all ; then + $ipt -A OUTPUT -o $_dev -p udp --dport $standard_mdns_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MDNS Out: " + $ipt -A INPUT -i $_dev -p udp --sport $standard_mdns_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MDNS IN: " + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p udp --dport $standard_mdns_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MDNS fwd Out: " + $ipt -A FORWARD -i $_dev -p udp --dport $standard_mdns_port -j $LOG_TARGET $tag_log_prefix "$log_prefix MDNS fwd In: " + fi + fi + $ipt -A OUTPUT -o $_dev -p udp --dport $standard_mdns_port -j DROP + $ipt -A INPUT -i $_dev -p udp --dport $standard_mdns_port -j DROP + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p udp --dport $standard_mdns_port -j DROP + $ipt -A FORWARD -i $_dev -p udp --dport $standard_mdns_port -j DROP + fi + done + echo_done +else + echo_skipped +fi + + +# --- +# - Don't allow spoofing from that server +# --- + +echo "" +echononl "\tDon't allow spoofing out from this server" +for _dev in ${ext_if_arr[@]} ; do + if $log_spoofed_out || $log_all ; then + $ipt -A OUTPUT -o $_dev -s $priv_class_a -j $LOG_TARGET $tag_log_prefix "$log_prefix out Class A:" + $ipt -A OUTPUT -o $_dev -s $priv_class_b -j $LOG_TARGET $tag_log_prefix "$log_prefix out Class B:" + $ipt -A OUTPUT -o $_dev -s $priv_class_c -j $LOG_TARGET $tag_log_prefix "$log_prefix out Class C:" + $ipt -A OUTPUT -o $_dev -s $link_local_rfc_5735 -j $LOG_TARGET $tag_log_prefix "$log_prefix out link local block:" + $ipt -A OUTPUT -o $_dev -s $test_net_1_rfc_5735 -j $LOG_TARGET $tag_log_prefix "$log_prefix out TEST-NET-1:" + $ipt -A OUTPUT -o $_dev -s $this_net_rfc_5735 -j $LOG_TARGET $tag_log_prefix "$log_prefix out THIS NET:" + $ipt -A OUTPUT -o $_dev -s $loopback_ipv4 -j $LOG_TARGET $tag_log_prefix "$log_prefix out Loopback:" + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -s $priv_class_a -j $LOG_TARGET $tag_log_prefix "$log_prefix out Class A:" + $ipt -A FORWARD -o $_dev -s $priv_class_b -j $LOG_TARGET $tag_log_prefix "$log_prefix out Class B:" + $ipt -A FORWARD -o $_dev -s $priv_class_c -j $LOG_TARGET $tag_log_prefix "$log_prefix out Class C:" + $ipt -A FORWARD -o $_dev -s $link_local_rfc_5735 -j $LOG_TARGET $tag_log_prefix "$log_prefix out link local block:" + $ipt -A FORWARD -o $_dev -s $test_net_1_rfc_5735 -j $LOG_TARGET $tag_log_prefix "$log_prefix out TEST-NET-1:" + $ipt -A FORWARD -o $_dev -s $this_net_rfc_5735 -j $LOG_TARGET $tag_log_prefix "$log_prefix out THIS NET:" + $ipt -A FORWARD -o $_dev -s $loopback_ipv4 -j $LOG_TARGET $tag_log_prefix "$log_prefix out Loopback:" + fi + fi + $ipt -A OUTPUT -o $_dev -s $priv_class_a -j DROP + $ipt -A OUTPUT -o $_dev -s $priv_class_b -j DROP + $ipt -A OUTPUT -o $_dev -s $priv_class_c -j DROP + $ipt -A OUTPUT -o $_dev -s $link_local_rfc_5735 -j DROP + $ipt -A OUTPUT -o $_dev -s $test_net_1_rfc_5735 -j DROP + $ipt -A OUTPUT -o $_dev -s $this_net_rfc_5735 -j DROP + $ipt -A OUTPUT -o $_dev -s $loopback_ipv4 -j DROP + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -s $priv_class_a -j DROP + $ipt -A FORWARD -o $_dev -s $priv_class_b -j DROP + $ipt -A FORWARD -o $_dev -s $priv_class_c -j DROP + $ipt -A FORWARD -o $_dev -s $link_local_rfc_5735 -j DROP + $ipt -A FORWARD -o $_dev -s $test_net_1_rfc_5735 -j DROP + $ipt -A FORWARD -o $_dev -s $this_net_rfc_5735 -j DROP + $ipt -A FORWARD -o $_dev -s $loopback_ipv4 -j DROP + fi +done +echo_done + + +# ------------- +# --- Traffic generally allowed +# ------------- + +echo +echononl "\tLoopback device generally allowed.." + +# --- +# - Loopback device +# --- + +$ipt -A INPUT -i lo -j ACCEPT +$ipt -A OUTPUT -o lo -j ACCEPT + +echo_done + + +# --- +# - Already established connections +# --- + +echononl "\tAccept already established connections.." + +$ipt -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT + $ipt -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT + +$ipt -A INPUT -m conntrack --ctstate INVALID -j DROP + +if $kernel_activate_forwarding ; then + $ipt -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT +fi + +echo_done + + +# --- +# - Protection against syn-flooding +# --- + +echo +echononl "\tProtection against syn-flooding" +if $protection_against_syn_flooding ; then + $ipt -N syn-flood + $ipt -A syn-flood -m limit --limit 1/second --limit-burst 3 -j RETURN + if $log_syn_flood || $log_all ; then + $ipt -A syn-flood -j $LOG_TARGET $tag_log_prefix "$log_prefix SYN flood:" + fi + $ipt -A syn-flood -j DROP + echo_done +else + echo_skipped +fi + + +# --- +# - Protection against port scanning +# --- + +echononl "\tProtection against port scanning" +if $protection_against_port_scanning ; then + $ipt -N port-scanning + $ipt -A port-scanning -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j RETURN + if $log_port_scanning || $log_all ; then + $ipt -A port-scanning -j $LOG_TARGET $tag_log_prefix "$log_prefix Port Scan:" + fi + $ipt -A port-scanning -j DROP + echo_done +else + echo_skipped +fi + + +# --- +# - Protection against SSH brute-force attacks +# --- + +echononl "\tProtection against SSH brute-force attacks" +if $protection_against_ssh_brute_force_attacks ; then + if can_use_recent ; then + $ipt -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --set + if $log_ssh_brute_force || $log_all ; then + $ipt -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j $LOG_TARGET $tag_log_prefix "$log_prefix SSH brute-force:" + fi + $ipt -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j DROP + else + if can_use_hashlimit ; then + warn "xt_recent not available; using hashlimit fallback for SSH brute-force protection." + if $log_ssh_brute_force || $log_all ; then + $ipt -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW \ + -m hashlimit --hashlimit-above 10/min --hashlimit-burst 10 --hashlimit-mode srcip \ + --hashlimit-name sshbf --hashlimit-htable-expire 60000 \ + -j $LOG_TARGET $tag_log_prefix "$log_prefix SSH brute-force:" + fi + $ipt -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW \ + -m hashlimit --hashlimit-above 10/min --hashlimit-burst 10 --hashlimit-mode srcip \ + --hashlimit-name sshbf --hashlimit-htable-expire 60000 \ + -j DROP + else + warn "Neither xt_recent nor xt_hashlimit available; using simple global limit fallback for SSH brute-force protection." + if $log_ssh_brute_force || $log_all ; then + $ipt -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW \ + -m limit --limit 10/min --limit-burst 10 \ + -j $LOG_TARGET $tag_log_prefix "$log_prefix SSH brute-force (limit fallback):" + fi + $ipt -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW \ + -m limit --limit 10/min --limit-burst 10 \ + -j DROP + fi + fi + +echo_done +else + echo_skipped +fi + + +# --- +# - Limit connections per source IP +# --- + +echononl "\tLimit connections per source IP" +if $limit_connections_per_source_IP ; then + + if ! is_number $per_IP_connection_limit ; then + per_IP_connection_limit=$default_per_IP_connection_limit + fi + + if can_use_connlimit ; then + + if $log_rejected || $log_all ; then + + $ipt -A INPUT -p tcp --syn \ + -m connlimit --connlimit-above $per_IP_connection_limit --connlimit-mask 32 --connlimit-saddr \ + -j $LOG_TARGET $tag_log_prefix "$log_prefix CONN limit per IP:" + + fi + + $ipt -A INPUT -p tcp --syn \ + -m connlimit --connlimit-above $per_IP_connection_limit --connlimit-mask 32 --connlimit-saddr \ + -j REJECT --reject-with tcp-reset + + else + warn "xt_connlimit not available; using fallback for per-source limiting (approximate)." + + if can_use_hashlimit ; then + # Fallback: rate-limit new SYNs per source IP (not the same as concurrent connlimit, but protective) + if $log_rejected || $log_all ; then + $ipt -A INPUT -p tcp --syn \ + -m hashlimit --hashlimit-above ${per_IP_connection_limit}/min --hashlimit-burst ${per_IP_connection_limit} --hashlimit-mode srcip \ + --hashlimit-name connlimit_fallback --hashlimit-htable-expire 60000 \ + -j $LOG_TARGET $tag_log_prefix "$log_prefix CONN limit per IP (hashlimit fallback):" + fi + + $ipt -A INPUT -p tcp --syn \ + -m hashlimit --hashlimit-above ${per_IP_connection_limit}/min --hashlimit-burst ${per_IP_connection_limit} --hashlimit-mode srcip \ + --hashlimit-name connlimit_fallback --hashlimit-htable-expire 60000 \ + -j REJECT --reject-with tcp-reset + else + warn "No xt_connlimit and no xt_hashlimit available; skipping per-source connection limiting." + fi + fi + + echo_done +else + echo_skipped +fi +# +# +# --- +# - Limit RST packets +# --- + +echononl "\tLimit RST packets" + +# --- +# Ersatzlos gestrichen +# --- +echo_skipped + + +#if $limit_rst_packets ; then +# +# $ipt -A INPUT -p tcp --tcp-flags RST RST \ +# -m limit --limit 2/s --limit-burst 2 -j ACCEPT +# +# if $log_rejected || $log_all ; then +# $ipt -A INPUT -p tcp --tcp-flags RST RST \ +# -m limit --limit 2/s --limit-burst 2 \ +# -j $LOG_TARGET $tag_log_prefix "$log_prefix Limit RST packets: " +# fi +# $ipt -A INPUT -p tcp --tcp-flags RST RST -j DROP +# echo_done +#else +# echo_skipped +#fi + + +# --- +# - Limit new TCP connections per second per source IP +# --- + +echononl "\tLimit new (syn) TCP connections per second per source IP (multiport)" + +if $limit_new_tcp_connections_per_seconds_per_source_IP \ + && [[ ${#limit_new_tcp_connections_per_seconds_ports} -gt 0 ]]; then + + #$ipt -A INPUT -p tcp -m conntrack --ctstate NEW -m limit --limit 60/s --limit-burst 20 -j ACCEPT + + # Rate-Limit für neue SYNs auf 443 pro IP + if can_use_hashlimit ; then + $ipt -A INPUT -p tcp --syn \ + -m multiport --dports $limit_new_tcp_connections_per_seconds_ports \ + -m hashlimit --hashlimit-name syn_multi_v4 \ + --hashlimit 30/second --hashlimit-burst 60 \ + --hashlimit-mode srcip --hashlimit-srcmask 32 \ + -j ACCEPT + + if $log_rejected || $log_all ; then + + # rate-limited logging für Überschreiter + $ipt -A INPUT -p tcp --syn \ + -m multiport --dports $limit_new_tcp_connections_per_seconds_ports \ + -m hashlimit --hashlimit-name syn_multi_v4_log \ + --hashlimit 2/second --hashlimit-burst 10 \ + --hashlimit-mode srcip --hashlimit-srcmask 32 \ + -j $LOG_TARGET $tag_log_prefix "$log_prefix SYN over limit (multiport):" + + fi +else + warn "xt_hashlimit not available; using simple global limit fallback for SYN rate limiting (multiport)." + $ipt -A INPUT -p tcp --syn \ + -m multiport --dports $limit_new_tcp_connections_per_seconds_ports \ + -m limit --limit 30/second --limit-burst 60 \ + -j ACCEPT +fi + + + #$ipt -A INPUT -p tcp -m conntrack --ctstate NEW -j DROP + + $ipt -A INPUT -p tcp --syn -m multiport --dports $limit_new_tcp_connections_per_seconds_ports -j DROP + + + echo_done +else + echo_skipped +fi + + +# --- +# - Use SYNPROXY on all ports (disables connection limiting rule) +# --- + +#echononl "\tUse SYNPROXY on all ports (disables connection limiting rule)" +#$ipt -t raw -A PREROUTING -p tcp -m tcp --syn -j CT --notrack +#$ipt -A INPUT -p tcp -m tcp -m conntrack --ctstate INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460 +#$ipt -A INPUT -m conntrack --ctstate INVALID -j DROP +#echo_done + + + +# ------------- +# ------------- Stopping firewall here if requested (parameter stop) +# ------------- + +case $1 in + sto*) + #echononl "Stopping firewall iptable (IPv4).." + echo + echo -e "\t\033[37m\033[1mStop was requested. No more rules..\033[m" + echo + exit 0;; +esac + + +echo + +# ------------- +# --- Traffic Counter (used by munin) +# ------------- + +echononl "\tCreate Traffic Counter (used by munin)" +if $create_traffic_counter ; then + for _ip in ${ext_ip_arr[@]} ; do + $ipt -A INPUT -d $_ip + $ipt -A INPUT -s $_ip + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -d $_ip + $ipt -A FORWARD -s $_ip + fi + done + echo_done +else + echo_skipped +fi + + +# ------------- +# --- iPerf +# ------------- + +# iPerf is a tool for active measurements of the maximum achievable bandwidth on IP networks. +# It supports tuning of various parameters related to timing, buffers and protocols (TCP, UDP, +# SCTP with IPv4 and IPv6). For each test it reports the bandwidth, loss, and other parameters. + +echononl "\tCreate \"iPerf\" rules.." +if $create_iperf_rules ; then + $ipt -A INPUT -p tcp --dport 5001 -j ACCEPT + $ipt -A INPUT -p tcp --sport 5001 -j ACCEPT + # + $ipt -A OUTPUT -p tcp --dport 5001 -j ACCEPT + $ipt -A OUTPUT -p tcp --sport 5001 -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -p tcp --dport 5001 -j ACCEPT + $ipt -A FORWARD -p tcp --sport 5001 -j ACCEPT + fi + echo_done +else + echo_skipped +fi + + +# ------------- +# --- Generally prohibited +# ------------- + +echononl "\tGenerally prohibited traffic.." + +for _dev in ${ext_if_arr[@]} ; do + if $log_prohibited || $log_all ; then + for _port in ${block_tcp_port_arr[@]} ; do + $ipt -A INPUT -p tcp -i $_dev --dport $_port -j $LOG_TARGET $tag_log_prefix "$log_prefix prohibited traffic:" + done + for _port in ${block_udp_port_arr[@]} ; do + $ipt -A INPUT -p udp -i $_dev --dport $_port -j $LOG_TARGET $tag_log_prefix "$log_prefix prohibited traffic:" + done + if $kernel_activate_forwarding ; then + for _port in ${block_tcp_port_arr[@]} ; do + $ipt -A FORWARD -p tcp -i $_dev --dport $_port -j $LOG_TARGET $tag_log_prefix "$log_prefix prohibited traffic:" + done + for _port in ${block_udp_port_arr[@]} ; do + $ipt -A FORWARD -p udp -i $_dev --dport $_port -j $LOG_TARGET $tag_log_prefix "$log_prefix prohibited traffic:" + done + fi + fi + for _port in ${block_tcp_port_arr[@]} ; do + $ipt -A INPUT -p tcp -i $_dev --dport $_port -j DROP + done + for _port in ${block_udp_port_arr[@]} ; do + $ipt -A INPUT -p udp -i $_dev --dport $_port -j DROP + done + if $kernel_activate_forwarding ; then + for _port in ${block_tcp_port_arr[@]} ; do + $ipt -A FORWARD -p tcp -i $_dev --dport $_port -j DROP + done + for _port in ${block_udp_port_arr[@]} ; do + $ipt -A FORWARD -p udp -i $_dev --dport $_port -j DROP + done + fi +done + +echo_done +echo + +# ------------- +# ---- Restrict local Servive to given (extern) IP-Address/Network +# ------------- + +echononl "\tRestrict local Service to given (extern) IP-Address/Network" +if [[ ${#restrict_local_service_to_net_arr[@]} -gt 0 ]] ; then + + _deny_service_arr=() + + for _val in "${restrict_local_service_to_net_arr[@]}" ; do + IFS=':' read -a _val_arr <<< "${_val}" + + for _dev in ${ext_if_arr[@]} ; do + $ipt -A INPUT -i $_dev -p ${_val_arr[3]} -s ${_val_arr[0]} -d ${_val_arr[1]} --dport ${_val_arr[2]} -j ACCEPT + + if ! containsElement "${_dev}:${_val_arr[1]}:${_val_arr[2]}:${_val_arr[3]}" "${_deny_service_arr[@]}" ; then + _deny_service_arr+=("${_dev}:${_val_arr[1]}:${_val_arr[2]}:${_val_arr[3]}") + fi + + done + + done + + for _val in "${_deny_service_arr[@]}" ; do + IFS=':' read -a _val_arr <<< "${_val}" + $ipt -A INPUT -i ${_val_arr[0]} -p ${_val_arr[3]} -d ${_val_arr[1]} --dport ${_val_arr[2]} -j DROP + done + + echo_done +else + echo_skipped +fi + + +# ------------- +# ---- Restrict local Network to given extern IP-Address/Network +# ------------- + +echononl "\tRestrict local Address/Network to given extern Address/Network" +if [[ ${#restrict_local_net_to_net_arr[@]} -gt 0 ]] ; then + + _deny_net_arr=() + + for _val in "${restrict_local_net_to_net_arr[@]}" ; do + IFS=':' read -a _val_arr <<< "${_val}" + for _dev in ${ext_if_arr[@]} ; do + $ipt -A INPUT -i $_dev -s ${_val_arr[0]} -d ${_val_arr[1]} -m conntrack --ctstate NEW -j ACCEPT + + if ! containsElement "${_dev}:${_val_arr[1]}" "${_deny_net_arr[@]}" ; then + _deny_net_arr+=("${_dev}:${_val_arr[1]}") + fi + + done + + done + + for _val in "${_deny_net_arr[@]}" ; do + IFS=':' read -a _val_arr <<< "${_val}" + $ipt -A INPUT -i ${_val_arr[0]} -d ${_val_arr[1]} -j DROP + done + + echo_done +else + echo_skipped +fi + +echo + + +# --- +# - LOG CGI script Traffic out +# --- + +echo +echononl "\tLOG CGI/PHP traffic out." + +if $log_cgi_traffic_out && [[ ${#cgi_script_user_arr[@]} -gt 0 ]] ; then + if can_use_owner ; then + for _dev in ${ext_if_arr[@]} ; do + for _user in ${cgi_script_user_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -m owner --uid-owner $_user -j $LOG_TARGET $tag_log_prefix "$log_prefix $_user PHP-OUT: " + done + done + echo_done + else + warn "owner/xt_owner match not available; skipping CGI/PHP uid-based OUTPUT logging." + echo_skipped + fi +else + echo_skipped +fi +echo + + +# ------------- +# --- Allow all outgoing traffic +# ------------- +echononl "\tAllow all outgoing traffic.." +if [[ -n "$allow_all_outgoing_traffic" ]] && $allow_all_outgoing_traffic ; then + for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p ALL -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p ALL -m conntrack --ctstate NEW -j ACCEPT + fi + done + echo_done +else + echo_skipped +fi + + +# --- +# - Don't allow traffic into private networks +# --- + +echo "" +echononl "\tDon't allow traffic into private anetworks" +for _dev in ${ext_if_arr[@]} ; do + if $log_private_network_out || $log_all ; then + $ipt -A OUTPUT -o $_dev -d $priv_class_a -j $LOG_TARGET $tag_log_prefix "$log_prefix out to priv Class A:" + $ipt -A OUTPUT -o $_dev -d $priv_class_b -j $LOG_TARGET $tag_log_prefix "$log_prefix out to priv Class B:" + $ipt -A OUTPUT -o $_dev -d $priv_class_c -j $LOG_TARGET $tag_log_prefix "$log_prefix out to priv Class C:" + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -d $priv_class_a -j $LOG_TARGET $tag_log_prefix "$log_prefix out to priv Class A:" + $ipt -A FORWARD -o $_dev -d $priv_class_b -j $LOG_TARGET $tag_log_prefix "$log_prefix out to priv Class B:" + $ipt -A FORWARD -o $_dev -d $priv_class_c -j $LOG_TARGET $tag_log_prefix "$log_prefix out to priv Class C:" + fi + fi + $ipt -A OUTPUT -o $_dev -d $priv_class_a -j DROP + $ipt -A OUTPUT -o $_dev -d $priv_class_b -j DROP + $ipt -A OUTPUT -o $_dev -d $priv_class_c -j DROP + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -d $priv_class_a -j DROP + $ipt -A FORWARD -o $_dev -d $priv_class_b -j DROP + $ipt -A FORWARD -o $_dev -d $priv_class_c -j DROP + fi +done +echo_done + + +# ------------- +# --- Services +# ------------- + +echo +echo -e "\t\033[37m\033[1mAdd Rules for Services..\033[m" + + +# ------------- +# ---- Allow extern Service +# ------------- + +echononl "\t\tAllow extern Service" + +if [[ ${#allow_ext_service_arr[@]} -gt 0 ]] ; then + for _dev in "${ext_if_arr[@]}" ; do + for _val in "${allow_ext_service_arr[@]}" ; do + IFS=':' read -a _val_arr <<< "${_val}" + $ipt -A OUTPUT -o $_dev -p ${_val_arr[2]} -d ${_val_arr[0]} --dport ${_val_arr[1]} -m conntrack --ctstate NEW -j ACCEPT + done + done + echo_done +else + echo_skipped +fi + + +# ------------- +# ---- Allow extern IP-Address/Network +# ------------- + +echononl "\t\tAllow extern IP-Address/Network" + +if [[ ${#allow_ext_net_arr[@]} -gt 0 ]] ; then + for _dev in "${ext_if_arr[@]}" ; do + for _net in "${allow_ext_net_arr[@]}" ; do + $ipt -A OUTPUT -o $_dev -p all -d $_net -m conntrack --ctstate NEW -j ACCEPT + done + done + echo_done +else + echo_skipped +fi + +echo + + +# ------------- +# ---- Allow (non-standard) local Services +# ------------- + +echononl "\t\tAllow (non-standard) local Services" + +if [[ ${#allow_local_service_arr[@]} -gt 0 ]] ; then + for _dev in "${ext_if_arr[@]}" ; do + for _val in "${allow_local_service_arr[@]}" ; do + IFS=':' read -a _val_arr <<< "${_val}" + $ipt -A INPUT -i $_dev -p ${_val_arr[1]} --dport ${_val_arr[0]} -m conntrack --ctstate NEW -j ACCEPT + done + done + echo_done +else + echo_skipped +fi + + +# ------------- +# ---- Allow local Services from given (extern) network +# ------------- + +echononl "\t\tAllow local Services from given (extern) network" + +if [[ ${#allow_local_service_from_network_arr[@]} -gt 0 ]] ; then + for _dev in "${ext_if_arr[@]}" ; do + for _val in "${allow_local_service_from_network_arr[@]}" ; do + IFS=':' read -a _val_arr <<< "${_val}" + $ipt -A INPUT -i $_dev -p ${_val_arr[2]} -s ${_val_arr[0]} --dport ${_val_arr[1]} -m conntrack --ctstate NEW -j ACCEPT + done + done + echo_done +else + echo_skipped +fi + +echo + +echo + + +# --- +# - DHCP +# --- + +echononl "\t\tDHCP Clients" + +if [[ ${#dhcp_client_if_arr[@]} -gt 0 ]] ; then + for _dev in ${dhcp_if_arr[@]} ; do + # - out + $ipt -A OUTPUT -p udp -o $_dev --dport 67 -d 0/0 --sport 1024:65535 -j ACCEPT + # - in + $ipt -A INPUT -p udp -i $_dev --sport 67 -d 0/0 --dport 68 -j ACCEPT + done + echo_done +else + echo_skipped +fi + +echononl "\t\tDHCP Server" + +if [[ ${#dhcp_server_if_arr[@]} -gt 0 ]] ; then + for _dev in ${dhcp_server_if_arr[@]} ; do + # - in + $ipt -A INPUT -p udp -i $_dev -s 0/0 --sport 68 -d 255.255.255.255 --dport 67 -j ACCEPT + # - out + $ipt -A OUTPUT -p udp -o $_dev --sport 67 -d 0/0 --dport 68 -j ACCEPT + done + echo_done +else + echo_skipped +fi + + + +# --- +# - DNS out only +# --- + +echononl "\t\tDNS out only" + +# - Nameservers on the INET must be reachable for the local recursiv nameserver +# - but also for all others +# - +for _dev in ${ext_if_arr[@]} ; do + # - out from local and virtual mashine(s) + $ipt -A OUTPUT -o $_dev -p udp --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + + # - Only useful (needed) if kernel forwarding is activated (kernel_activate_forwarding=true) + if $kernel_activate_forwarding ; then + # - forward from virtual mashine(s) + $ipt -A FORWARD -o $_dev -p udp --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + $ipt -A FORWARD -o $_dev -p tcp --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + + +# --- +# - DNS Service +# --- + +echononl "\t\tDNS Service" + +if [[ ${#dns_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_dns_server_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#dns_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${dns_server_ips[@]} ; do + # dns requests + # + # Note: + # If the total size of the DNS record is larger than 512 bytes, + # it will be sent over TCP, not UDP. + # + $ipt -A INPUT -p udp -d $_ip --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + $ipt -A INPUT -p tcp -d $_ip --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + # Zonetransfer + $ipt -A OUTPUT -p tcp -s $_ip --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + done + fi + + if [[ ${#forward_dns_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_dns_server_ip_arr[@]} ; do + # dns requests + # + # Note: + # If the total size of the DNS record is larger than 512 bytes, + # it will be sent over TCP, not UDP. + # + $ipt -A FORWARD -p udp -d $_ip --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + $ipt -A FORWARD -p tcp -d $_ip --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + # Zonetransfer + $ipt -A FORWARD -p tcp -s $_ip --dport $standard_dns_port -m conntrack --ctstate NEW -j ACCEPT + done + fi + echo_done +else + echo_skipped +fi + + +# --- +# - local Resolver" +# --- + +echononl "\t\tlocal Resolver" +if [[ -n "$local_resolver_service" ]] && $local_resolver_service ; then + if [[ ${#resolver_allowed_network_arr[@]} -gt 0 ]] ; then + for _net in ${resolver_allowed_network_arr[@]} ; do + $ipt -A INPUT -p udp -s $_net --dport $resolver_port -m conntrack --ctstate NEW -j ACCEPT + $ipt -A INPUT -p tcp -s $_net --dport $resolver_port -m conntrack --ctstate NEW -j ACCEPT + done + echo_done + else + echo_failed + fi +else + echo_skipped +fi + + +# --- +# - SSH out only +# --- + +echononl "\t\tSSH out only" + +# ausgehende Anfragen +for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_ssh_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p tcp --dport $standard_ssh_port -m conntrack --ctstate NEW -j ACCEPT + fi + + if [[ ${#ssh_port_arr[@]} -gt 0 ]] ; then + for _port in ${ssh_port_arr[@]} ; do + + [[ "$_port" = "$standard_ssh_port" ]] && continue + $ipt -A OUTPUT -o $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + fi + + done + fi + +done + +if [[ ${#local_if_arr[@]} -gt 0 ]] ; then + for _dev in ${local_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_ssh_port -m conntrack --ctstate NEW -j ACCEPT + + if [[ ${#ssh_port_arr[@]} -gt 0 ]] ; then + for _port in ${ssh_port_arr[@]} ; do + + [[ "$_port" = "$standard_ssh_port" ]] && continue + $ipt -A OUTPUT -o $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -i $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + fi + done + fi + + done +fi + +echo_done + + +# --- +# - SSH Service +# --- + +echononl "\t\tSSH Service" + +if [[ ${#ssh_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_ssh_server_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#ssh_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${ssh_server_ip_arr[@]} ; do + for _port in ${ssh_port_arr[@]} ; do + $ipt -A INPUT -p tcp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + if [[ ${#forward_ssh_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_ssh_server_ip_arr[@]} ; do + for _port in ${ssh_port_arr[@]} ; do + $ipt -A FORWARD -p tcp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - VPN +# --- + +echononl "\t\tVPN Service only out" +if [[ ${#vpn_port_arr[@]} -gt 0 ]] ; then + + for _dev in ${ext_if_arr[@]} ; do + for _port in ${vpn_port_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p udp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + + echo_done +else + echo_skipped +fi + +echononl "\t\tVPN Services.." +if [[ ${#vpn_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_vpn_server_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#vpn_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${vpn_server_ip_arr[@]} ; do + for _port in ${vpn_port_arr[@]} ; do + $ipt -A INPUT -p udp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + if [[ ${#forward_vpn_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_vpn_server_ip_arr[@]} ; do + for _port in ${vpn_port_arr[@]} ; do + $ipt -A FORWARD -p udp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Wireguard +# --- + +echononl "\t\tWireGuard Service only out" +if [[ ${#wireguard_out_port_port_arr[@]} -gt 0 ]] ; then + + for _dev in ${ext_if_arr[@]} ; do + for _port in ${wireguard_out_port_port_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p udp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + + echo_done +else + echo_skipped +fi + +echononl "\t\tWireGuard Services.." +if [[ ${#wireguard_server_ip_arr[@]} -gt 0 ]] || [[ ${forward_wireguard_server_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#wireguard_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${wireguard_server_ip_arr[@]} ; do + for _port in ${wireguard_server_ports[@]} ; do + $ipt -A INPUT -p udp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + if [[ ${forward_wireguard_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_wireguard_server_ip_arr[@]} ; do + for _port in ${wireguard_server_ports[@]} ; do + $ipt -A FORWARD -p udp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Rsync Out +# --- + +echononl "\t\tRsync (only OUT)" + +if [[ ${#rsync_out_ip_arr[@]} -gt 0 ]] || [[ ${#forward_rsync_out_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#rsync_out_ip_arr[@]} -gt 0 ]] ; then + for _port in ${rsync_port_arr[@]} ; do + + for _ip in ${rsync_out_ip_arr[@]} ; do + $ipt -A OUTPUT -p tcp -s $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + + done + fi + + if [[ ${#forward_rsync_out_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _port in ${rsync_port_arr[@]} ; do + + for _ip in ${forward_rsync_out_ip_arr[@]} ; do + $ipt -A FORWARD -p tcp -s $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Telnet +# --- + +echononl "\t\tTelnet (only OUT)" + +for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_telnet_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p tcp --dport $standard_telnet_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - MySQL +# --- + +echononl "\t\tMySQL (only OUT)" + +for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_mysql_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p tcp --dport $standard_mysql_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - Prometheus Monitoring - local Server +# --- + +echononl "\t\tLocal Prometheus Service" + +if [[ ${#prometheus_local_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${prometheus_local_server_ip_arr[@]} ; do + $ipt -A OUTPUT -p tcp -s $_ip -m multiport --dports $prometheus_remote_client_ports -m conntrack --ctstate NEW -j ACCEPT + done + echo_done +else + echo_skipped +fi + + +# --- +# - Prometheus Monitoring - local client +# --- + +echononl "\t\tLocal Prometheus Client" + +if [[ ${#prometheus_local_client_ip_arr[@]} -gt 0 ]] && [[ ${#prometheus_remote_server_ip_arr[@]} -gt 0 ]]; then + for _ip in ${prometheus_local_client_ip_arr[@]} ; do + for _ip in ${prometheus_remote_server_ip_arr[@]} ; do + $ipt -A INPUT -p tcp -d $_ip -m multiport --dports $prometheus_local_client_ports -m conntrack --ctstate NEW -j ACCEPT + done + done + echo_done +else + echo_skipped +fi + + +# --- +# - Munin remote service +# --- + +echononl "\t\tMunin remote service" + +if [ "X$munin_remote_ip" != "X" ]; then + for _dev in ${ext_if_arr[@]} ; do + $ipt -A INPUT -i $_dev -p tcp -s $munin_remote_ip --dport $munin_local_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -i $_dev -p tcp -s $munin_remote_ip --dport $munin_local_port -m conntrack --ctstate NEW -j ACCEPT + fi + done + echo_done +else + echo_skipped +fi + + +# --- +# - Munin local service +# --- + +echononl "\t\tMunin local service" + + +if [[ ${#munin_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_munin_server_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#munin_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${munin_server_ip_arr[@]} ; do + $ipt -A OUTPUT -p tcp --syn -s $_ip --dport $munin_remote_port -m conntrack --ctstate NEW -j ACCEPT + done + fi + + if [[ ${#forward_munin_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_munin_server_ip_arr[@]} ; do + $ipt -A FORWARD -p tcp --syn -s $_ip --dport $munin_remote_port -m conntrack --ctstate NEW -j ACCEPT + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Mail (SMTP OUT) +# --- + +echononl "\t\tMail (SMTP OUT)" + +for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_smtp_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p tcp --dport $standard_smtp_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - Mail (additional smtp ports OUT) +# --- + +echononl "\t\tMail (additional smtp ports OUT)" + +if [[ ${#smtpd_additional_outgoung_port_arr[@]} -gt 0 ]] ; then + + for _port in ${smtpd_additional_outgoung_port_arr[@]} ; do + for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + fi + done + done + + echo_done +else + echo_skipped +fi + + +# --- +# - Mail SMTP Server (Port 25) including Spam Control +# --- + +echononl "\t\tMail SMTP Server (Port 25) including Spam Control" + +if [[ ${#smtpd_ips_arr[@]} -gt 0 ]] || [[ ${#forward_smtpd_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#smtpd_ips_arr[@]} > 0 ]] ; then + + for _ip in ${smtpd_ips_arr[@]} ; do + $ipt -A INPUT -p tcp -d $_ip --dport $standard_smtp_port -m conntrack --ctstate NEW -j ACCEPT + # + # Razor2 (TCP Port 2703) + $ipt -A OUTPUT -p tcp -s $_ip --dport 2703 -m conntrack --ctstate NEW -j ACCEPT + # DEPRECATED: TCP Port 7 (echo) + $ipt -A OUTPUT -p tcp -s $_ip --dport 7 -m conntrack --ctstate NEW -j ACCEPT + # + # Pyzor (UDP Port 24441 or TCP Port 24441 or both ?) + $ipt -A OUTPUT -p udp -s $_ip --dport 24441 -m conntrack --ctstate NEW -j ACCEPT + $ipt -A OUTPUT -p tcp -s $_ip --dport 24441 -m conntrack --ctstate NEW -j ACCEPT + # + # - DCC (port udp:6277) + $ipt -A OUTPUT -s $_ip -p udp -m udp --dport 6277 -m conntrack --ctstate NEW -j ACCEPT + # if DCC Server is running (port tcp:6277) + $ipt -A INPUT -p tcp -d $_ip --dport 6277 -j ACCEPT + $ipt -A OUTPUT -p tcp -s $_ip --dport 6277 -j ACCEPT + done + fi + + if [[ ${#forward_smtpd_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_smtpd_ip_arr[@]} ; do + $ipt -A FORWARD -p tcp -d $_ip --dport $standard_smtp_port -m conntrack --ctstate NEW -j ACCEPT + # + # Razor2 (TCP Port 2703) + $ipt -A FORWARD -p tcp -s $_ip --dport 2703 -m conntrack --ctstate NEW -j ACCEPT + # DEPRECATED: TCP Port 7 (echo) + $ipt -A FORWARD -p tcp -s $_ip --dport 7 -m conntrack --ctstate NEW -j ACCEPT + # + # Pyzor (UDP Port 24441 or TCP Port 24441 or both ?) + $ipt -A FORWARD -p udp -s $_ip --dport 24441 -m conntrack --ctstate NEW -j ACCEPT + $ipt -A FORWARD -p tcp -s $_ip --dport 24441 -m conntrack --ctstate NEW -j ACCEPT + # + # DCC (port udp:6277) + $ipt -A FORWARD -s $_ip -p udp -m udp --dport 6277 -m conntrack --ctstate NEW -j ACCEPT + # if DCC Server is running (port tcp:6277) + $ipt -A FORWARD -p tcp -d $_ip --dport 6277 -j ACCEPT + $ipt -A FORWARD -p tcp -s $_ip --dport 6277 -j ACCEPT + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Mail (additional smtp ports IN) +# --- + +echononl "\t\tMail (additional smtp ports IN)" + +if [[ ${#smtpd_additional_listen_port_arr[@]} -gt 0 ]] ; then + + for _port in ${smtpd_additional_listen_port_arr[@]} ; do + for _dev in ${ext_if_arr[@]} ; do + $ipt -A INPUT -i $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -i $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + fi + done + done + + echo_done +else + echo_skipped +fi + + +# --- +# - Mailservice (Submission/SMTPS/POP/IMAP Server) +# --- + +echononl "\t\tMailservice (Submission/SMTPS/POP/IMAP Server)" + +if [[ ${#mail_server_ips_arr[@]} -gt 0 ]] || [[ ${#forward_mail_server_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#mail_server_ips_arr[@]} -gt 0 ]] ; then + for _ip in ${mail_server_ips_arr[@]} ; do + # mail ports + # + $ipt -A INPUT -p tcp -d $_ip -m multiport --dports $mail_user_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi # if [[ ${#mail_server_ips_arr[@]} -gt 0 ]] + + if [[ ${#forward_mail_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_mail_server_ip_arr[@]} ; do + # mail ports + # + $ipt -A FORWARD -p tcp -d $_ip -m multiport --dports $mail_user_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi # if [[ ${#forward_mail_server_ip_arr[@]} -gt 0 ]] ; then + + echo_done +else + echo_skipped +fi + + +# --- +# - Mail Client (Submission/SMTPS/POPS/IMAPS) out only +# --- + +echononl "\t\tMail Client (Submission/SMTPS/POPS/IMAPS) out only" + +if [[ ${#mail_client_ips_arr[@]} -gt 0 ]] || [[ ${#forward_mail_client_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#mail_client_ips_arr[@]} -gt 0 ]] ; then + for _ip in ${mail_client_ips_arr[@]} ; do + # mail ports + # + $ipt -A OUTPUT -p tcp -s $_ip -m multiport --dports $mail_user_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi # if [[ ${#mail_client_ips_arr[@]} -gt 0 ]] + + if [[ ${#forward_mail_client_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_mail_client_ip_arr[@]} ; do + # mail ports + # + $ipt -A FORWARD -p tcp -s $_ip -m multiport --dports $mail_user_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi # if [[ ${#forward_mail_client_ip_arr[@]} -gt 0 ]] ; then + + echo_done +else + echo_skipped +fi + + +# --- +# - (local) Dovecot auth service +# --- + +echononl "\t\t(local) Dovecot auth service" + +if [[ -n "$dovecot_auth_service" ]] && $dovecot_auth_service ; then + + if [[ ${#dovecot_auth_allowed_network_arr[@]} -gt 0 ]] && [[ -n "$dovecot_auth_port" ]]; then + for _ip in ${dovecot_auth_allowed_network_arr[@]} ; do + $ipt -A INPUT -p tcp -s $_ip --dport $dovecot_auth_port -m conntrack --ctstate NEW -j ACCEPT + done + echo_done + else + echo_failed + fi +else + echo_skipped +fi + + +# --- +# - HTTP(S) OUT +# --- + +echononl "\t\tHTTP(S) out only" + +for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp -m multiport --dports $standard_http_ports -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p tcp -m multiport --dports $standard_http_ports -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - HTTP(S) (local) Webserver +# --- + +echononl "\t\tHTTP(S) (local) Webserver" + +if [[ ${#http_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_http_server_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#http_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${http_server_ip_arr[@]} ; do + $ipt -A INPUT -p tcp -d $_ip -m multiport --dports $http_ports -m conntrack --ctstate NEW -j ACCEPT + done + + if [[ ${#forward_http_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_http_server_ip_arr[@]} ; do + $ipt -A FORWARD -p tcp -d $_ip -m multiport --dports $http_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Mattermost Service +# --- + +echononl "\t\tMattermost (MM) Service" +if [[ ${#mm_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_mm_server_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#mm_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${mm_server_ip_arr[@]} ; do + $ipt -A INPUT -p udp -d $_ip -m multiport --dports $mm_udp_ports_in -m conntrack --ctstate NEW -j ACCEPT + $ipt -A OUTPUT -p udp -s $_ip -m multiport --dports $mm_udp_ports_out -m conntrack --ctstate NEW -j ACCEPT + done + + if [[ ${#forward_mm_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_mm_server_ip_arr[@]} ; do + $ipt -A FORWARD -p udp -d $_ip -m multiport --dports $mm_udp_ports_in -m conntrack --ctstate NEW -j ACCEPT + $ipt -A FORWARD -p udp -s $_ip -m multiport --dports $mm_udp_ports_out -m conntrack --ctstate NEW -j ACCEPT + done + fi + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - FTP out only" +# --- + +echononl "\t\tFTP out only (using CT target)" + +# - (Re)define helper +# - +setup_ftp_conntrack_helper_output + +# - Used for different ftpdata recent lists 'ftpdata_out_$j' +# - +declare -i j=1 + +for _dev in ${ext_if_arr[@]} ; do + + # - (1) + # - + # - Open FTP connection and add the destination ip (--rdest) to ftpdata recent list 'ftpdata_out_$j'. + # - + if can_use_recent ; then + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_ftp_port -m conntrack --ctstate NEW \ + -m recent --name ftpdata_out_$j --rdest --set -j ACCEPT + $ipt -A OUTPUT -o $_dev -p tcp -m conntrack --ctstate NEW --dport 1024: \ + -m recent --name ftpdata_out_$j --rdest --update --seconds 1800 --reap -j ACCEPT +else + warn "xt_recent not available; FTP out-only FTPS workaround disabled (data connections may fail)." + # Allow control connection; non-TLS data connections may still work via helper/RELATED + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_ftp_port -m conntrack --ctstate NEW -j ACCEPT +fi + + + ((i++)) + + # - Accept (helper ftp) related connections + # - + if can_use_helper_match; then + $ipt -A OUTPUT -m conntrack --ctstate RELATED -m helper --helper ftp -o $_dev -p tcp --dport 1024: -j ACCEPT +else + warn "helper match not available; allowing RELATED ftp data without helper restriction" + $ipt -A OUTPUT -m conntrack --ctstate RELATED -o $_dev -p tcp --dport 1024: -j ACCEPT +fi + +done + +echo_done + + +#echononl "\t\tFTP out only" +# +#for _dev in ${ext_if_arr[@]} ; do +# # (Datenkanal aktiv) +# $ipt -A INPUT -i $_dev -p tcp --sport $standard_ftp_data_port -m conntrack --ctstate NEW -j ACCEPT +# # (Datenkanal passiv) +# $ipt -A OUTPUT -o $_dev -p tcp --sport $unprivports --dport $unprivports -m conntrack --ctstate NEW -j ACCEPT +# # (Kontrollverbindung) +# $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_ftp_port -m conntrack --ctstate NEW -j ACCEPT +# if $kernel_activate_forwarding ; then +# # (Datenkanal aktiv) +# $ipt -A FORWARD -i $_dev -p tcp --sport $standard_ftp_data_port -m conntrack --ctstate NEW -j ACCEPT +# # (Datenkanal passiv) +# $ipt -A FORWARD -o $_dev -p tcp --sport $unprivports --dport $unprivports -m conntrack --ctstate NEW -j ACCEPT +# # (Kontrollverbindung) +# $ipt -A FORWARD -o $_dev -p tcp --dport $standard_ftp_port -m conntrack --ctstate NEW -j ACCEPT +# fi +#done +# +#echo_done + + +# --- +# - FTP Server" +# --- + +echononl "\t\tFTP Server (using CT target)" + +if [[ ${#ftp_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_ftp_server_ip_arr[@]} -gt 0 ]] ; then + + # - Used for different ftpdata recent lists 'ftpdata_$i' + declare -i i=1 + + # - (Re)define helper + # - + # - !! Note: !! + # - for both, local FTP server (ftp_server_ip_arr) + # - and forward to FTP server (forward_ftp_server_ip_arr) + # - + setup_ftp_conntrack_helper_prerouting + + if [[ ${#ftp_server_ip_arr[@]} -gt 0 ]] ; then + + for _ip in ${ftp_server_ip_arr[@]} ; do + + # ===== + # - + # - ip_conntrack_ftp cannot see the TLS-encrypted traffic + # - ====================================================== + # - + # - Workaround: + # - (1) add source ip to a 'recent list' named 'ftpdata_$i! if ftp control connections appear + # - (2) accept packets of the formaly created recent list 'ftpdata_$i! + # - + # ===== + + # - (1) + # - + # - Accept initial FTP connection and add the source ip to ftpdata recent list 'ftpdata_$i'. + # - + if can_use_recent ; then + $ipt -A INPUT -p tcp -m conntrack --ctstate NEW -d $_ip --dport $standard_ftp_port \ + -m recent --name ftpdata_$i --set -j ACCEPT + + $ipt -A INPUT -p tcp -m conntrack --ctstate NEW --sport 1024: -d $_ip --dport $ftp_passive_port_range \ + -m recent --name ftpdata_$i --update --seconds 1800 --reap -j ACCEPT + else + + warn "xt_recent not available; relaxing FTPS workaround for FTP server $_ip (opening passive range)." + # Control connection + $ipt -A INPUT -p tcp -m conntrack --ctstate NEW -d $_ip --dport $standard_ftp_port -j ACCEPT + # Passive data ports (less strict without xt_recent) + $ipt -A INPUT -p tcp -m conntrack --ctstate NEW -d $_ip --dport $ftp_passive_port_range -j ACCEPT + fi + + # - Accept (helper ftp) related connections + # - + $ipt -A INPUT -m conntrack --ctstate RELATED -m helper --helper ftp -d $_ip -p tcp --dport 1024: -j ACCEPT + + ((i++)) + + done + fi + + if [[ ${#forward_ftp_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + + for _ip in ${forward_ftp_server_ip_arr[@]} ; do + + # ===== + # - + # - ip_conntrack_ftp cannot see the TLS-encrypted traffic + # - ====================================================== + # - + # - Workaround: + # - (1) add source ip to a 'recent list' named 'ftpdata_$i! if ftp control connections appear + # - (2) accept packets of the formaly created recent list 'ftpdata_$i! + # - + # ===== + + # - (1) + # - + # - Accept initial FTP connection and add the source ip to ftpdata recent list 'ftpdata_$i'. + # - + if can_use_recent ; then + $ipt -A FORWARD -p tcp -m conntrack --ctstate NEW -d $_ip --dport $standard_ftp_port \ + -m recent --name ftpdata_$i --set -j ACCEPT + + $ipt -A FORWARD -p tcp -m conntrack --ctstate NEW --sport 1024: -d $_ip --dport $ftp_passive_port_range \ + -m recent --name ftpdata_$i --update --seconds 1800 --reap -j ACCEPT + $ipt -A FORWARD -p tcp -m conntrack --ctstate NEW --dport 1024: -s $_ip --sport $ftp_passive_port_range \ + -m recent --name ftpdata_$i --update --seconds 1800 --reap -j ACCEPT + else + warn "xt_recent not available; relaxing FTPS workaround for forwarded FTP server $_ip (opening passive range)." + # Control connection to forwarded server + $ipt -A FORWARD -p tcp -m conntrack --ctstate NEW -d $_ip --dport $standard_ftp_port -j ACCEPT + + # Passive data ports to server (less strict without xt_recent) + $ipt -A FORWARD -p tcp -m conntrack --ctstate NEW -d $_ip --dport $ftp_passive_port_range -j ACCEPT + + # Return traffic from server passive ports + $ipt -A FORWARD -p tcp -m conntrack --ctstate NEW -s $_ip --sport $ftp_passive_port_range \ + --dport 1024: -j ACCEPT + fi + + # - Accept (helper ftp) related connections + # - + if can_use_helper_match; then + $ipt -A FORWARD -m conntrack --ctstate RELATED -m helper --helper ftp -d $_ip -p tcp --dport 1024: -j ACCEPT + else + warn "helper match not available; allowing RELATED ftp data without helper restriction" + $ipt -A FORWARD -m conntrack --ctstate RELATED -d $_ip -p tcp --dport 1024: -j ACCEPT + fi + if can_use_helper_match; then + $ipt -A FORWARD -m conntrack --ctstate RELATED -m helper --helper ftp -s $_ip -p tcp --sport 1024: -j ACCEPT + else + warn "helper match not available; allowing RELATED ftp data without helper restriction" + $ipt -A FORWARD -m conntrack --ctstate RELATED -s $_ip -p tcp --sport 1024: -j ACCEPT + fi + + ((i++)) + + done + fi + + echo_done +else + echo_skipped +fi + +#echononl "\t\tFTP Server" +# +#if [[ ${#ftp_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_ftp_server_ip_arr[@]} -gt 0 ]] ; then +# if [[ ${#ftp_server_ip_arr[@]} -gt 0 ]] ; then +# for _ip in ${ftp_server_ip_arr[@]} ; do +# # (Datenkanal aktiv) +# $ipt -A OUTPUT -p tcp -s $_ip --sport $standard_ftp_data_port20 -m conntrack --ctstate NEW -j ACCEPT +# # Datenkanal (passiver modus) +# $ipt -A INPUT -p tcp -d $_ip --dport $unprivports --sport $unprivports -m conntrack --ctstate NEW -j ACCEPT +# # - Kontrollverbindung +# $ipt -A INPUT -p tcp -d $_ip --dport $standard_ftp_port --sport $unprivports -m conntrack --ctstate NEW -j ACCEPT +# done +# fi +# +# if [[ ${#forward_ftp_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then +# for _ip in ${forward_ftp_server_ip_arr[@]} ; do +# # (Datenkanal aktiv) +# $ipt -A FORWARD -p tcp -s $_ip --sport $standard_ftp_data_port -m conntrack --ctstate NEW -j ACCEPT +# # Datenkanal (passiver modus) +# $ipt -A FORWARD -p tcp -d $_ip --dport $unprivports --sport $unprivports -m conntrack --ctstate NEW -j ACCEPT +# # - Kontrollverbindung +# $ipt -A FORWARD -p tcp -d $_ip --dport $standard_ftp_port --sport $unprivports -m conntrack --ctstate NEW -j ACCEPT +# done +# fi +# +# echo_done +#else +# echo_skipped +#fi + + +# --- +# - XMPP Service (Jabber) +# --- + +echononl "\t\tXMPP Service" + +if [[ ${#xmpp_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_xmpp_server_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#xmpp_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${xmpp_server_ip_arr[@]} ; do + for _port in ${xmmp_tcp_in_port_arr[@]} ; do + $ipt -A INPUT -p tcp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + + for _port in ${xmmp_tcp_out_port_arr[@]} ; do + $ipt -A OUTPUT -p tcp -s $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + + if [[ ${#forward_xmpp_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_xmpp_server_ip_arr[@]} ; do + for _port in ${xmmp_tcp_in_port_arr[@]} ; do + $ipt -A FORWARD -p tcp -d $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + + for _port in ${xmmp_tcp_out_port_arr[@]} ; do + $ipt -A FORWARD -p tcp -s $_ip --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - XMPP Remote Dovecote Out Service +# --- + +echononl "\t\tXMPP Remote Dovecote Out Service" + +if [[ ${#xmmp_remote_out_service_arr[@]} -gt 0 ]] ; then + for _dev in "${ext_if_arr[@]}" ; do + for _val in "${xmmp_remote_out_service_arr[@]}" ; do + IFS=':' read -a _val_arr <<< "${_val}" + $ipt -A OUTPUT -o $_dev -p tcp -d ${_val_arr[0]} --dport ${_val_arr[1]} -m conntrack --ctstate NEW -j ACCEPT + done + done + echo_done +else + echo_skipped +fi + + +# --- +# - Mumble Service +# --- + +echononl "\t\tMumble Service" + + +if [[ ${#mumble_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_mumble_server_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#mumble_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${mumble_server_ip_arr[@]} ; do + $ipt -A INPUT -p tcp -d $_ip -m multiport --dports $mumble_ports -m conntrack --ctstate NEW -j ACCEPT + $ipt -A INPUT -p udp -d $_ip -m multiport --dports $mumble_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi + + if [[ ${#forward_mumble_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_mumble_server_ip_arr[@]} ; do + $ipt -A FORWARD -p tcp -d $_ip -m multiport --dports $mumble_ports -m conntrack --ctstate NEW -j ACCEPT + $ipt -A FORWARD -p udp -d $_ip -m multiport --dports $mumble_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Jitsi Video Conferencing Service +# --- + +echononl "\t\tJitsi Meet Video Conferencing Service Incomming Ports" + + +if [[ ${#jitsi_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_jitsi_server_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#jitsi_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${jitsi_server_ip_arr[@]} ; do + if ! containsElement "$_ip" "${http_server_ip_arr[@]}" || [[ "$jitsi_tcp_ports" != "$standard_http_ports" ]] ; then + $ipt -A INPUT -p tcp -d $_ip -m multiport --dports $jitsi_tcp_ports -m conntrack --ctstate NEW -j ACCEPT + fi + $ipt -A INPUT -p udp -d $_ip -m multiport --dports $jitsi_udp_port_range -m conntrack --ctstate NEW -j ACCEPT + done + fi + + if [[ ${#forward_jitsi_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_jitsi_server_ip_arr[@]} ; do + if ! containsElement "$_ip" "${http_server_ip_arr[@]}" || [[ "$jitsi_tcp_ports" != "$standard_http_ports" ]] ; then + $ipt -A FORWARD -p tcp -d $_ip -m multiport --dports $jitsi_tcp_ports -m conntrack --ctstate NEW -j ACCEPT + fi + $ipt -A FORWARD -p udp -d $_ip -m multiport --dports $jitsi_udp_port_range -m conntrack --ctstate NEW -j ACCEPT + done + fi + + echo_done +else + echo_skipped +fi + +echononl "\t\tJitsi Meet Video Conferencing Service Outgoing Ports" +if [[ ${#jitsi_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_jitsi_server_ip_arr[@]} -gt 0 ]] ; then + if [[ ${#jitsi_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${jitsi_server_ip_arr[@]} ; do + $ipt -A OUTPUT -p tcp -s $_ip -m multiport --dports $jitsi_tcp_ports_out -m conntrack --ctstate NEW -j ACCEPT + $ipt -A OUTPUT -p udp -s $_ip -m multiport --dports $jitsi_udp_ports_out -m conntrack --ctstate NEW -j ACCEPT + done + fi + + if [[ ${#forward_jitsi_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_jitsi_server_ip_arr[@]} ; do + $ipt -A FORWARD -p tcp -s $_ip -m multiport --dports $jitsi_tcp_ports_out -m conntrack --ctstate NEW -j ACCEPT + $ipt -A FORWARD -p udp -s $_ip -m multiport --dports $jitsi_udp_ports_out -m conntrack --ctstate NEW -j ACCEPT + done + fi + echo_done +else + echo_skipped +fi + +echononl "\t\tJitsi Meet Dovecot Authentication" +if [[ ${#jitsi_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_jitsi_server_ip_arr[@]} -gt 0 ]] ; then + if $jitsi_dovecot_auth && [[ -n "$jitsi_dovecot_host" ]] && [[ -n "$jitsi_dovecot_port" ]] ; then + if [[ ${#jitsi_server_ip_arr[@]} -gt 0 ]] ; then + $ipt -A OUTPUT -p tcp -d $jitsi_dovecot_host --dport $jitsi_dovecot_port -m conntrack --ctstate NEW -j ACCEPT + fi + + if [[ ${#forward_jitsi_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + $ipt -A FORWARD -p tcp -d $jitsi_dovecot_host --dport $jitsi_dovecot_port -m conntrack --ctstate NEW -j ACCEPT + fi + echo_done + else + echo_skipped + fi +else + echo_skipped +fi + +echononl "\t\tJitsi Remote Jibri Client" +if [[ ${#jitsi_server_ip_arr[@]} -gt 0 ]] \ + && $jitsi_jibri_remote_auth \ + && [[ ${#jitsi_jibri_remote_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${jitsi_jibri_remote_ip_arr[@]} ; do + $ipt -A INPUT -p tcp -s $_ip --dport $jitsi_jibri_remote_auth_port -m conntrack --ctstate NEW -j ACCEPT + done + + echo_done +else + echo_skipped +fi + + +# --- +# - Jibri Recording / Streaming Service +# --- + +echononl "\t\tJibri Recording / Streaming Service" +if [[ ${#jibri_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_jibri_server_ip_arr[@]} -gt 0 ]]; then + + if [[ -z "$jibri_remote_jitsi_server" ]]; then + echo_skipped + else + if [[ ${#jibri_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${jibri_server_ip_arr[@]} ; do + $ipt -A OUTPUT -p tcp -s $_ip -d $jibri_remote_jitsi_server --dport $jibri_remote_auth_port -m conntrack --ctstate NEW -j ACCEPT + $ipt -A OUTPUT -p udp -s $_ip -d $jibri_remote_jitsi_server -m multiport --dports $standard_jitsi_udp_port_range -m conntrack --ctstate NEW -j ACCEPT + $ipt -A OUTPUT -p tcp -s $_ip -m multiport --dports $default_outbound_streaming_tcp_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi + + if [[ ${#forward_jibri_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_jibri_server_ip_arr[@]} ; do + $ipt -A FORWARD -p tcp -d $jibri_remote_jitsi_server --dport $jibri_remote_auth_port -m conntrack --ctstate NEW -j ACCEPT + $ipt -A FORWARD -p udp -s $_ip -d $jibri_remote_jitsi_server -m multiport --dports $standard_jitsi_udp_port_range -m conntrack --ctstate NEW -j ACCEPT + $ipt -A FORWARD -p tcp -s $_ip -m multiport --dports $default_outbound_streaming_tcp_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi + + echo_done + fi +else + echo_skipped +fi + + +# --- +# - TURN Service (for NC Talk App) +# --- + +echononl "\t\tTURN Service (for NC Talk App) both: udp and tcp" + +if [[ ${#nc_turn_server_ip_arr[@]} -gt 0 ]] || [[ ${#forward_nc_turn_server_ip_arr[@]} -gt 0 ]] ; then + + if [[ ${#nc_turn_server_ip_arr[@]} -gt 0 ]] ; then + for _ip in ${nc_turn_server_ip_arr[@]} ; do + $ipt -A INPUT -p tcp -d $_ip -m multiport --dports $nc_turn_ports -m conntrack --ctstate NEW -j ACCEPT + $ipt -A INPUT -p udp -d $_ip -m multiport --dports $nc_turn_ports -m conntrack --ctstate NEW -j ACCEPT + $ipt -A INPUT -p udp -d $_ip -m multiport --dports $nc_turn_udp_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi + + if [[ ${#forward_nc_turn_server_ip_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _ip in ${forward_nc_turn_server_ip_arr[@]} ; do + $ipt -A FORWARD -p tcp -d $_ip -m multiport --dports $nc_turn_ports -m conntrack --ctstate NEW -j ACCEPT + $ipt -A FORWARD -p udp -d $_ip -m multiport --dports $nc_turn_ports -m conntrack --ctstate NEW -j ACCEPT + $ipt -A FORWARD -p udp -d $_ip -m multiport --dports $nc_turn_udp_ports -m conntrack --ctstate NEW -j ACCEPT + done + fi + + + echo_done +else + echo_skipped +fi + + +# --- +# - Timeserver (Port 37 NOT NTP!)" +# --- + +echononl "\t\tTimeserver (Port 37 NOT NTP!) out only" + +for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_timeserver_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p tcp --dport $standard_timeserver_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - NTP out only" +# --- + +echononl "\t\tNTP out only" + +for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_ntp_port -m conntrack --ctstate NEW -j ACCEPT + $ipt -A OUTPUT -o $_dev -p udp --dport $standard_ntp_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p tcp --dport $standard_ntp_port -m conntrack --ctstate NEW -j ACCEPT + $ipt -A FORWARD -o $_dev -p udp --dport $standard_ntp_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - NTP local Service" +# --- + +echononl "\t\tNTP local Service" +if [[ -n "$local_ntp_service" ]] && $local_ntp_service ; then + if [[ -z "$ntp_allowed_net" ]] ; then + echo_failed + else + $ipt -A OUTPUT -p udp -d $ntp_allowed_net --dport $ntp_port -m conntrack --ctstate NEW -j ACCEPT + $ipt -A INPUT -p udp -s $ntp_allowed_net --dport $ntp_port -m conntrack --ctstate NEW -j ACCEPT + echo_done + fi +else + echo_skipped +fi + + +# --- +# - LDAP out only +# --- + +echononl "\t\tLDAP out only" + +for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_ldap_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p tcp --dport $standard_ldap_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - LDAPS out only +# --- + +echononl "\t\tLDAPS out only" + +for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_ldaps_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p tcp --dport $standard_ldaps_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + + + +# --- +# - Whois out only +# --- + +echononl "\t\tWhois out only" + +for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_whois_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p tcp --dport $standard_whois_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - PGP Keyserver out only +# --- + +echononl "\t\tPGP/GPG Key server - out only" + +for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_pgp_keyserver_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p tcp --dport $standard_pgp_keyserver_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done + + +# --- +# - GIT out only +# --- + +echononl "\t\tGIT out only" + +for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp --dport $standard_git_port -m conntrack --ctstate NEW -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p tcp --dport $standard_git_port -m conntrack --ctstate NEW -j ACCEPT + fi +done + +echo_done +echo + + +# --- +# - Special TCP Ports OUT +# --- + +echononl "\t\tSpecial TCP Ports OUT" + +if [[ ${#tcp_out_port_arr[@]} -gt 0 ]] || [[ ${#forward_tcp_out_port_arr[@]} -gt 0 ]] ; then + + if [[ ${#tcp_out_port_arr[@]} -gt 0 ]] ; then + + for _dev in ${ext_if_arr[@]} ; do + for _port in ${tcp_out_port_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + if [[ ${#forward_tcp_out_port_arr[@]} -gt 0 ]] && $kernel_activate_forwarding ; then + for _dev in ${ext_if_arr[@]} ; do + for _port in ${tcp_out_port_arr[@]} ; do + $ipt -A FORWARD -o $_dev -p tcp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Special UDP Ports OUT +# --- + +echononl "\t\tSpecial UDP Ports OUT" + +if [[ ${#udp_out_port_arr[@]} -gt 0 ]] || [[ ${#forward_udp_out_port_arr[@]} -gt 0 ]] ; then + if [[ ${#udp_out_port_arr[@]} -gt 0 ]] ; then + for _dev in ${ext_if_arr[@]} ; do + for _port in ${udp_out_port_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p udp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + if [[ ${#forward_udp_out_port_arr[@]} -gt 0 ]] ; then + for _dev in ${ext_if_arr[@]} ; do + for _port in ${forward_udp_out_port_arr[@]} ; do + $ipt -A FORWARD -o $_dev -p udp --dport $_port -m conntrack --ctstate NEW -j ACCEPT + done + done + fi + + echo_done +else + echo_skipped +fi + +echo + +# ------------- +# --- Portforwarding +# ------------- + +# --- +# - Portforwarding TCP +# --- + +echononl "\t\tPortforwarding TCP" + +if [[ ${#portforward_tcp_arr[@]} -gt 0 ]] ; then + for _val in "${portforward_tcp_arr[@]}" ; do + + # - Split value + # - + IFS=':' read -a _val_arr <<< "${_val}" + + # - Allow Packets IN + # - + $ipt -A INPUT -i ${_val_arr[0]} -p tcp -d ${_val_arr[1]} --dport ${_val_arr[2]} -m conntrack --ctstate NEW -j ACCEPT + + # - Allow Packets FORWARD + # - + $ipt -A FORWARD -i ${_val_arr[0]} -p tcp -d ${_val_arr[3]} --dport ${_val_arr[4]} -m conntrack --ctstate NEW -j ACCEPT + + _job_id="$(ps ax | grep "TCP4-LISTEN:${_val_arr[2]},fork,bind=${_val_arr[1]}" | grep -v grep | awk '{print$1}')" + if [[ -n "$_job_id" ]]; then + kill ${_job_id} > /dev/null 2>&1 + fi + + socat TCP4-LISTEN:${_val_arr[2]},fork,bind=${_val_arr[1]} TCP:${_val_arr[3]}:${_val_arr[4]} & + + done + echo_done +else + echo_skipped +fi + +echononl "\t\tPortforwarding UDP" + +if [[ ${#portforward_udp_arr[@]} -gt 0 ]] ; then + for _val in "${portforward_udp_arr[@]}" ; do + + # - Split value + # - + IFS=':' read -a _val_arr <<< "${_val}" + + # - Allow Packets IN + # - + $ipt -A INPUT -i ${_val_arr[0]} -p udp -d ${_val_arr[1]} --dport ${_val_arr[2]} -m conntrack --ctstate NEW -j ACCEPT + + # - Allow Packets FORWARD + # - + $ipt -A FORWARD -i ${_val_arr[0]} -p udp -d ${_val_arr[3]} --dport ${_val_arr[4]} -m conntrack --ctstate NEW -j ACCEPT + + _job_id="$(ps ax | grep "UDP4-LISTEN:${_val_arr[2]},fork,bind=${_val_arr[1]}" | grep -v grep | awk '{print$1}')" + if [[ -n "$_job_id" ]]; then + kill ${_job_id} > /dev/null 2>&1 + fi + + socat UDP4-LISTEN:${_val_arr[2]},fork,bind=${_val_arr[1]} UDP:${_val_arr[3]}:${_val_arr[4]} & + + done + echo_done +else + echo_skipped +fi + + +echo + +# --- +# - UNIX Traceroute +# --- + +echononl "\t\tUNIX Traceroute" + +# versendet udp packete im gegensatz zu tracert von windows +# der icmp-echo-request pakete versendet +# einige implementierungen von traceroute (linux) erm�lichens +# die option -I und versenden dann ebenfalls icmp-echo-request pakete + +for _dev in ${ext_if_arr[@]} ; do + $ipt -A OUTPUT -o $_dev -p udp -m conntrack --ctstate NEW --dport 33434:33530 -j ACCEPT + $ipt -A INPUT -i $_dev -p udp -m conntrack --ctstate NEW --dport 33434:33530 -j ACCEPT + if $kernel_activate_forwarding ; then + $ipt -A FORWARD -o $_dev -p udp -m conntrack --ctstate NEW --dport 33434:33530 -j ACCEPT + $ipt -A FORWARD -i $_dev -p udp -m conntrack --ctstate NEW --dport 33434:33530 -j ACCEPT + fi +done + +echo_done + + +# --- +# - Ping +# --- + +echononl "\t\tPing" + +$ipt -A INPUT -p icmp -j ACCEPT + $ipt -A OUTPUT -p icmp -j ACCEPT +if $kernel_activate_forwarding ; then + $ipt -A FORWARD -p icmp -j ACCEPT +fi + +#for _dev in ${ext_if_arr[@]} ; do +# $ipt -A INPUT -i $_dev -p icmp -j ACCEPT +# $ipt -A OUTPUT -o $_dev -p icmp -j ACCEPT +# if $kernel_activate_forwarding ; then +# $ipt -A FORWARD -i $_dev -p icmp -j ACCEPT +# $ipt -A FORWARD -o $_dev -p icmp -j ACCEPT +# fi +#done +#for _dev in ${local_if_arr[@]} ; do +# $ipt -A INPUT -i $_dev -p icmp -j ACCEPT +# $ipt -A OUTPUT -o $_dev -p icmp -j ACCEPT +# if $kernel_activate_forwarding ; then +# $ipt -A FORWARD -i $_dev -p icmp -j ACCEPT +# $ipt -A FORWARD -o $_dev -p icmp -j ACCEPT +# fi +#done + +echo_done + + +# --- +# - log all rejected traffic +# --- + +echo +echononl "\tLogging all rejected traffic" + +if $log_rejected || $log_all ; then + $ipt -A OUTPUT -m limit --limit-burst 5 -p tcp ! --tcp-flags ACK,FIN ACK,FIN -j $LOG_TARGET $tag_log_prefix "$log_prefix Rejected (end of firewall):" + $ipt -A OUTPUT -m limit --limit-burst 5 -p udp -j $LOG_TARGET $tag_log_prefix "$log_prefix Rejected (end of firewall):" + $ipt -A INPUT -m limit --limit-burst 5 -j $LOG_TARGET $tag_log_prefix "$log_prefix Rejected (end of firewall):" + + if $kernel_activate_forwarding ; then + #$ipt -A FORWARD -j $LOG_TARGET $tag_log_prefix "$log_prefix Rejected:" + $ipt -A FORWARD -m limit --limit-burst 5 -j $LOG_TARGET $tag_log_prefix "$log_prefix Rejected (end of firewall):" + fi + + echo_done +else + echo_skipped +fi + + +# --- +# - Drop all other +# --- + +echo +echononl "\tDrop all other on all interfaces" + +$ipt -A INPUT -j DROP + $ipt -A OUTPUT -j DROP +$ipt -A FORWARD -j DROP + +echo_done + + + +# ------------- +# ------------- Reload Fail2Ban if installed +# ------------- + +if ${FAIL2BAN_WAS_RUNNING}; then + echo + echononl "\tReloading fail2ban.." + $fail2ban_client reload > /dev/null 2>&1 + if [ "$?" = "0" ]; then + echo_done + else + # Fallback: reload + restart jails if needed + $fail2ban_client reload --restart > /dev/null 2>&1 + if [ "$?" = "0" ]; then + echo_done + else + echo_skipped + warn "Fail2ban reload failed. Leaving fail2ban unchanged. Check: fail2ban-client -d and /var/log/fail2ban.log" + fi + fi +else + # fail2ban not running before; do not start it here + : +fi + +echo +exit 0 + + + +# ------------ Portforwarding ------------- # +# - +# - !! NOTICE: +# - you need also portforwarding enabled at the kernel +# - echo 1 >/proc/sys/net/ipv4/ip_forward +# +# +# ---------------------------------------------- +# : --> ::80 +# ---------------------------------------------- +# +#$ipt -A FORWARD [-i ] -p tcp --dport -d -j ACCEPT +#$ipt -A FORWARD [-o ] -p tcp --sport -s -j ACCEPT +# +#$ipt -t nat -A PREROUTING [-i ] -p tcp --dport [-d ] -j DNAT --to-destination : +#$ipt -t nat -A POSTROUTING -d -j MASQUERADE +# +# +# ----------------------------------------------- +# www-alt.oopen.de --> www-neu.oopen.de +# +# 46.4.129.3:80 --> 83.223.86.130:80 +# 46.4.129.3:443 --> 83.223.86.130:443 +# ----------------------------------------------- +# +#$ipt -A FORWARD -p tcp -m multiport --dports 80,443 -d 83.223.86.130 -j ACCEPT +#$ipt -A FORWARD -p tcp -m multiport --sports 80,443 -s 83.223.86.130 -j ACCEPT +# +#$ipt -t nat -A PREROUTING -p tcp --dport 80 -d 46.4.129.3 -j DNAT --to-destination 83.223.86.130:80 +#$ipt -t nat -A PREROUTING -p tcp --dport 443 -d 46.4.129.3 -j DNAT --to-destination 83.223.86.130:443 +#$ipt -t nat -A POSTROUTING -d 83.223.86.130 -j MASQUERADE +# +# - +# ---------- Ende Portforwarding ---------- # + diff --git a/roles/ipt-server/handlers/main.yml b/roles/ipt-server/handlers/main.yml new file mode 100644 index 0000000..6395812 --- /dev/null +++ b/roles/ipt-server/handlers/main.yml @@ -0,0 +1,15 @@ +--- + +- name: Reload systemd daemon + systemd: + daemon_reload: true + +- name: Restart IPv4 Firewall + service: + name: ipt-firewall + state: restarted + +- name: Restart IPv6 Firewall + service: + name: ip6t-firewall + state: restarted diff --git a/roles/ipt-server/tasks/main.yml b/roles/ipt-server/tasks/main.yml new file mode 100644 index 0000000..1b9fafb --- /dev/null +++ b/roles/ipt-server/tasks/main.yml @@ -0,0 +1,215 @@ +--- + +# === +# Ensure /etc/ipt-firewall directory exists +# === + +- name: Create /etc/ipt-firewall if not present + file: + path: /etc/ipt-firewall + state: directory + owner: root + group: root + mode: "0750" + + +# === +# Check presence of host-specific config files +# === + +- name: Check if interfaces_ipv4.conf exists + stat: + path: /etc/ipt-firewall/interfaces_ipv4.conf + register: interfaces_ipv4_exists + +- name: Check if interfaces_ipv6.conf exists + stat: + path: /etc/ipt-firewall/interfaces_ipv6.conf + register: interfaces_ipv6_exists + +- name: Check if main_ipv4.conf exists + stat: + path: /etc/ipt-firewall/main_ipv4.conf + register: main_ipv4_exists + +- name: Check if main_ipv6.conf exists + stat: + path: /etc/ipt-firewall/main_ipv6.conf + register: main_ipv6_exists + + +# === +# Deploy host-specific config files from templates. +# +# Safety guard: by default (fw_manage_config: false) a file is only written +# when it does not yet exist on the host — so existing hosts are never touched +# accidentally. +# +# Once a host has been migrated (host_vars populated and diff verified), set +# fw_manage_config: true +# in its host_vars. From that point on Ansible is the authoritative source and +# will update the config on every run, triggering a firewall restart on changes. +# === + +- name: Deploy interfaces_ipv4.conf from template + template: + src: etc/ipt-firewall/interfaces_ipv4.conf.j2 + dest: /etc/ipt-firewall/interfaces_ipv4.conf + owner: root + group: root + mode: "0640" + when: fw_manage_config or not interfaces_ipv4_exists.stat.exists + notify: + - Restart IPv4 Firewall + +- name: Deploy interfaces_ipv6.conf from template + template: + src: etc/ipt-firewall/interfaces_ipv6.conf.j2 + dest: /etc/ipt-firewall/interfaces_ipv6.conf + owner: root + group: root + mode: "0640" + when: fw_manage_config or not interfaces_ipv6_exists.stat.exists + notify: + - Restart IPv6 Firewall + +- name: Deploy main_ipv4.conf from template + template: + src: etc/ipt-firewall/main_ipv4.conf.j2 + dest: /etc/ipt-firewall/main_ipv4.conf + owner: root + group: root + mode: "0640" + when: fw_manage_config or not main_ipv4_exists.stat.exists + notify: + - Restart IPv4 Firewall + +- name: Deploy main_ipv6.conf from template + template: + src: etc/ipt-firewall/main_ipv6.conf.j2 + dest: /etc/ipt-firewall/main_ipv6.conf + owner: root + group: root + mode: "0640" + when: fw_manage_config or not main_ipv6_exists.stat.exists + notify: + - Restart IPv6 Firewall + + +# === +# Firewall scripts +# === + +- name: Deploy ipt-firewall-server + copy: + src: usr/local/sbin/ipt-firewall-server + dest: /usr/local/sbin/ipt-firewall-server + owner: root + group: root + mode: "0750" + +- name: Deploy ip6t-firewall-server + copy: + src: usr/local/sbin/ip6t-firewall-server + dest: /usr/local/sbin/ip6t-firewall-server + owner: root + group: root + mode: "0750" + + +# === +# Shared conf files (not host-specific — always kept in sync with the role) +# === + +- name: Deploy shared conf files + copy: + src: "etc/ipt-firewall/{{ item }}" + dest: "/etc/ipt-firewall/{{ item }}" + owner: root + group: root + mode: "0640" + loop: + - default_settings.conf + - include_functions.conf + - logging_ipv4.conf + - logging_ipv6.conf + - post_declarations.conf + + +# === +# Ban lists — copy from sample once; the file can be customised per host. +# === + +- name: Check if ban_ipv4.list exists + stat: + path: /etc/ipt-firewall/ban_ipv4.list + register: ban_ipv4_exists + +- name: Copy ban_ipv4.list from sample (first install only) + copy: + src: etc/ipt-firewall/ban_ipv4.list.sample + dest: /etc/ipt-firewall/ban_ipv4.list + owner: root + group: root + mode: "0640" + when: not ban_ipv4_exists.stat.exists + +- name: Check if ban_ipv6.list exists + stat: + path: /etc/ipt-firewall/ban_ipv6.list + register: ban_ipv6_exists + +- name: Copy ban_ipv6.list from sample (first install only) + copy: + src: etc/ipt-firewall/ban_ipv6.list.sample + dest: /etc/ipt-firewall/ban_ipv6.list + owner: root + group: root + mode: "0640" + when: not ban_ipv6_exists.stat.exists + + +# === +# Systemd service units +# === + +- name: Deploy ipt-firewall.service + copy: + src: etc/systemd/system/ipt-firewall.service + dest: /etc/systemd/system/ipt-firewall.service + owner: root + group: root + mode: "0644" + notify: + - Reload systemd daemon + - Restart IPv4 Firewall + +- name: Deploy ip6t-firewall.service + copy: + src: etc/systemd/system/ip6t-firewall.service + dest: /etc/systemd/system/ip6t-firewall.service + owner: root + group: root + mode: "0644" + notify: + - Reload systemd daemon + - Restart IPv6 Firewall + + +# === +# Enable and start services +# === + +- name: Enable and start ipt-firewall + systemd: + name: ipt-firewall + enabled: true + state: started + daemon_reload: true + +- name: Enable and start ip6t-firewall + systemd: + name: ip6t-firewall + enabled: true + state: started + daemon_reload: true diff --git a/roles/ipt-server/templates/etc/ipt-firewall/interfaces_ipv4.conf.j2 b/roles/ipt-server/templates/etc/ipt-firewall/interfaces_ipv4.conf.j2 new file mode 100644 index 0000000..1790122 --- /dev/null +++ b/roles/ipt-server/templates/etc/ipt-firewall/interfaces_ipv4.conf.j2 @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# {{ ansible_managed }} + + +# ------------- +# --- Network Interfaces +# ------------- + +# - External interface(s) +# +ext_if_1="{{ fw_ext_interfaces[0] if fw_ext_interfaces | length >= 1 else '' }}" +ext_if_2="{{ fw_ext_interfaces[1] if fw_ext_interfaces | length >= 2 else '' }}" +ext_if_3="{{ fw_ext_interfaces[2] if fw_ext_interfaces | length >= 3 else '' }}" + +ext_ifs="{{ fw_ext_interfaces | join(' ') }}" + + +# - VPN Interfaces +# - (comma separated list) +vpn_ifs="{{ fw_vpn_ifs }}" + + +# - Wireguard Interfaces +# - (comma separated list) +wg_ifs="{{ fw_wg_ifs }}" + + +# - Local Interfaces +local_if_1="{{ fw_local_interfaces[0] if fw_local_interfaces | length >= 1 else '' }}" +local_if_2="{{ fw_local_interfaces[1] if fw_local_interfaces | length >= 2 else '' }}" +local_if_3="{{ fw_local_interfaces[2] if fw_local_interfaces | length >= 3 else '' }}" + +local_ifs="{{ fw_local_interfaces | join(' ') }}" + + +# ------------- +# --- IP-Addresses +# ------------- + +# - Extern IP Addresses on this Host +# +ext_1_ip="{{ fw_ext_ips_v4[0] if fw_ext_ips_v4 | length >= 1 else '' }}" +ext_2_ip="{{ fw_ext_ips_v4[1] if fw_ext_ips_v4 | length >= 2 else '' }}" +ext_3_ip="{{ fw_ext_ips_v4[2] if fw_ext_ips_v4 | length >= 3 else '' }}" + +ext_ips="{{ fw_ext_ips_v4 | join(' ') }}" + +local_1_ip="{{ fw_local_ips_v4[0] if fw_local_ips_v4 | length >= 1 else '' }}" +local_2_ip="{{ fw_local_ips_v4[1] if fw_local_ips_v4 | length >= 2 else '' }}" +local_3_ip="{{ fw_local_ips_v4[2] if fw_local_ips_v4 | length >= 3 else '' }}" + +local_ips="{{ fw_local_ips_v4 | join(' ') }}" + + +# ------------- +# --- IP-Addresses LXC Guest Systems +# ------------- + +lxc_guest_1_ip="{{ fw_lxc_guest_ips_v4[0] if fw_lxc_guest_ips_v4 | length >= 1 else '' }}" +lxc_guest_2_ip="{{ fw_lxc_guest_ips_v4[1] if fw_lxc_guest_ips_v4 | length >= 2 else '' }}" +lxc_guest_3_ip="{{ fw_lxc_guest_ips_v4[2] if fw_lxc_guest_ips_v4 | length >= 3 else '' }}" +lxc_guest_4_ip="{{ fw_lxc_guest_ips_v4[3] if fw_lxc_guest_ips_v4 | length >= 4 else '' }}" +lxc_guest_5_ip="{{ fw_lxc_guest_ips_v4[4] if fw_lxc_guest_ips_v4 | length >= 5 else '' }}" +lxc_guest_6_ip="{{ fw_lxc_guest_ips_v4[5] if fw_lxc_guest_ips_v4 | length >= 6 else '' }}" +lxc_guest_7_ip="{{ fw_lxc_guest_ips_v4[6] if fw_lxc_guest_ips_v4 | length >= 7 else '' }}" + +lxc_guest_ips="{{ fw_lxc_guest_ips_v4 | join(' ') }}" + + +# - Devices given in list "nat_devices" will be natted +# - +# - Blank separated list +# - +nat_devices="{{ fw_nat_devices }}" diff --git a/roles/ipt-server/templates/etc/ipt-firewall/interfaces_ipv6.conf.j2 b/roles/ipt-server/templates/etc/ipt-firewall/interfaces_ipv6.conf.j2 new file mode 100644 index 0000000..f695a08 --- /dev/null +++ b/roles/ipt-server/templates/etc/ipt-firewall/interfaces_ipv6.conf.j2 @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# {{ ansible_managed }} + + +# ------------- +# --- Network Interfaces +# ------------- + +# - External interface(s) +# +ext_if_1="{{ fw_ext_interfaces[0] if fw_ext_interfaces | length >= 1 else '' }}" +ext_if_2="{{ fw_ext_interfaces[1] if fw_ext_interfaces | length >= 2 else '' }}" +ext_if_3="{{ fw_ext_interfaces[2] if fw_ext_interfaces | length >= 3 else '' }}" + +ext_ifs="{{ fw_ext_interfaces | join(' ') }}" + + +# - VPN Interfaces +# - (comma separated list) +vpn_ifs="{{ fw_vpn_ifs }}" + + +# - Wireguard Interfaces +# - (comma separated list) +wg_ifs="{{ fw_wg_ifs }}" + + +# - Local Interfaces +local_if_1="{{ fw_local_interfaces[0] if fw_local_interfaces | length >= 1 else '' }}" +local_if_2="{{ fw_local_interfaces[1] if fw_local_interfaces | length >= 2 else '' }}" +local_if_3="{{ fw_local_interfaces[2] if fw_local_interfaces | length >= 3 else '' }}" + +local_ifs="{{ fw_local_interfaces | join(' ') }}" + + +# ------------- +# --- IP-Addresses +# ------------- + +# - Extern IP Addresses on this Host +# +ext_1_ip="{{ fw_ext_ips_v6[0] if fw_ext_ips_v6 | length >= 1 else '' }}" +ext_2_ip="{{ fw_ext_ips_v6[1] if fw_ext_ips_v6 | length >= 2 else '' }}" +ext_3_ip="{{ fw_ext_ips_v6[2] if fw_ext_ips_v6 | length >= 3 else '' }}" + +ext_ips="{{ fw_ext_ips_v6 | join(' ') }}" + +local_1_ip="{{ fw_local_ips_v6[0] if fw_local_ips_v6 | length >= 1 else '' }}" +local_2_ip="{{ fw_local_ips_v6[1] if fw_local_ips_v6 | length >= 2 else '' }}" +local_3_ip="{{ fw_local_ips_v6[2] if fw_local_ips_v6 | length >= 3 else '' }}" + +local_ips="{{ fw_local_ips_v6 | join(' ') }}" + + +# ------------- +# --- IP-Addresses LXC Guest Systems +# ------------- + +lxc_guest_1_ip="{{ fw_lxc_guest_ips_v6[0] if fw_lxc_guest_ips_v6 | length >= 1 else '' }}" +lxc_guest_2_ip="{{ fw_lxc_guest_ips_v6[1] if fw_lxc_guest_ips_v6 | length >= 2 else '' }}" +lxc_guest_3_ip="{{ fw_lxc_guest_ips_v6[2] if fw_lxc_guest_ips_v6 | length >= 3 else '' }}" +lxc_guest_4_ip="{{ fw_lxc_guest_ips_v6[3] if fw_lxc_guest_ips_v6 | length >= 4 else '' }}" +lxc_guest_5_ip="{{ fw_lxc_guest_ips_v6[4] if fw_lxc_guest_ips_v6 | length >= 5 else '' }}" +lxc_guest_6_ip="{{ fw_lxc_guest_ips_v6[5] if fw_lxc_guest_ips_v6 | length >= 6 else '' }}" +lxc_guest_7_ip="{{ fw_lxc_guest_ips_v6[6] if fw_lxc_guest_ips_v6 | length >= 7 else '' }}" + +lxc_guest_ips="{{ fw_lxc_guest_ips_v6 | join(' ') }}" diff --git a/roles/ipt-server/templates/etc/ipt-firewall/main_ipv4.conf.j2 b/roles/ipt-server/templates/etc/ipt-firewall/main_ipv4.conf.j2 new file mode 100644 index 0000000..d14be6c --- /dev/null +++ b/roles/ipt-server/templates/etc/ipt-firewall/main_ipv4.conf.j2 @@ -0,0 +1,357 @@ +#!/usr/bin/env bash +# {{ ansible_managed }} + + +## ---------------------------------------------------------------- +## --- Main Configurations IPv4 Firewall +## ---------------------------------------------------------------- + + +# ------------- +# --- Bridged / LXC traffic +# ------------- + +do_not_firewall_bridged_traffic={{ fw_do_not_firewall_bridged_traffic | lower }} +do_not_firewall_lx_guest_systems={{ fw_do_not_firewall_lx_guest_systems | lower }} + + +# ------------- +# --- Drop ICMP / MNDP / mDNS +# ------------- + +drop_icmp={{ fw_drop_icmp | lower }} +drop_mndp={{ fw_drop_mndp | lower }} +drop_mdns={{ fw_drop_mdns | lower }} + + +# ------------- +# --- Outgoing traffic +# ------------- + +allow_all_outgoing_traffic={{ fw_allow_all_outgoing_traffic | lower }} + + +# ------------- +# --- Interface policy +# ------------- + +blocked_ifs="{{ fw_blocked_ifs }}" +unprotected_ifs="{{ fw_unprotected_ifs }}" + + +# ------------- +# --- Forwarding / Routing +# ------------- + +# Private IPs to forward (CIDR notation, blank separated) +forward_private_ips="{{ fw_forward_private_ips_v4 }}" + + +# ------------- +# --- Access control (source-based) +# ------------- + +# restrict_local_service_to_net="ext-net:local-address:port:protocol" +restrict_local_service_to_net="{{ fw_restrict_local_service_to_net_v4 }}" + +# restrict_local_net_to_net=":" +restrict_local_net_to_net="{{ fw_restrict_local_net_to_net_v4 }}" + +# allow_ext_service="::" +allow_ext_service="{{ fw_allow_ext_service_v4 }}" + +# allow_ext_net="" (blank separated) +allow_ext_net="{{ fw_allow_ext_net_v4 }}" + +# allow_local_service=":" (blank separated) +allow_local_service="{{ fw_allow_local_service_v4 }}" + +# allow_local_service_from_networks="::" +allow_local_service_from_networks="{{ fw_allow_local_service_from_networks_v4 }}" + + +# ------------- +# --- Services: VPN / WireGuard +# ------------- + +vpn_server_ips="{{ fw_vpn_server_ips }}" +forward_vpn_server_ips="{{ fw_forward_vpn_server_ips }}" +vpn_ports="{{ fw_vpn_ports }}" + +wireguard_server_ips="{{ fw_wireguard_server_ips }}" +forward_wireguard_server_ips="{{ fw_forward_wireguard_server_ips }}" +wireguard_server_ports="{{ fw_wireguard_server_ports }}" +wireguard_out_ports="{{ fw_wireguard_out_ports }}" + + +# ------------- +# --- Services: NTP +# ------------- + +local_ntp_service={{ fw_local_ntp_service | lower }} +ntp_port="{{ fw_ntp_port }}" +ntp_allowed_net="{{ fw_ntp_allowed_net }}" + + +# ------------- +# --- Services: DHCP (IPv4 only) +# ------------- + +# Comma separated list of interfaces providing DHCP +dhcp_server_ifs="{{ fw_dhcp_server_ifs }}" + +# Comma separated list of interfaces acting as DHCP clients +dhcp_client_ifs="{{ fw_dhcp_client_ifs }}" + + +# ------------- +# --- Services: DNS +# ------------- + +dns_server_ips="{{ fw_dns_server_ips }}" +forward_dns_server_ips="{{ fw_forward_dns_server_ips }}" + +local_resolver_service={{ fw_local_resolver_service | lower }} +resolver_port="{{ fw_resolver_port }}" +# resolver_allowed_networks="192.68.11.64/27 194.150.169.139" +resolver_allowed_networks="{{ fw_resolver_allowed_networks_v4 }}" + + +# ------------- +# --- Services: SSH +# ------------- + +ssh_server_ips="{{ fw_ssh_server_ips }}" +forward_ssh_server_ips="{{ fw_forward_ssh_server_ips }}" +ssh_ports="{{ fw_ssh_ports }}" + + +# ------------- +# --- Services: HTTP(S) +# ------------- + +http_server_ips="{{ fw_http_server_ips }}" +forward_http_server_ips="{{ fw_forward_http_server_ips }}" +http_ports="{{ fw_http_ports }}" + +log_cgi_traffic_out={{ fw_log_cgi_traffic_out | lower }} +cgi_script_users="{{ fw_cgi_script_users }}" + + +# ------------- +# --- Services: Mattermost +# ------------- + +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_udp_ports_out="{{ fw_mm_udp_ports_out }}" + + +# ------------- +# --- Services: Mail (SMTP / IMAP / POP) +# ------------- + +smtpd_ips="{{ fw_smtpd_ips }}" +forward_smtpd_ips="{{ fw_forward_smtpd_ips }}" +smtpd_additional_listen_ports="{{ fw_smtpd_additional_listen_ports }}" +smtpd_additional_outgoung_ports="{{ fw_smtpd_additional_outgoing_ports }}" + +mail_server_ips="{{ fw_mail_server_ips }}" +forward_mail_server_ips="{{ fw_forward_mail_server_ips }}" +mail_user_ports="{{ fw_mail_user_ports }}" + +mail_client_ips="{{ fw_mail_client_ips }}" +forward_mail_client_ips="{{ fw_forward_mail_client_ips }}" + +dovecot_auth_service={{ fw_dovecot_auth_service | lower }} +dovecot_auth_port="{{ fw_dovecot_auth_port }}" +# dovecot_auth_allowed_networks="192.68.11.64/27 194.150.169.139" +dovecot_auth_allowed_networks="{{ fw_dovecot_auth_allowed_networks_v4 }}" + + +# ------------- +# --- Services: FTP +# ------------- + +ftp_server_ips="{{ fw_ftp_server_ips }}" +forward_ftp_server_ips="{{ fw_forward_ftp_server_ips }}" +ftp_passive_port_range="{{ fw_ftp_passive_port_range }}" + + +# ------------- +# --- Services: XMPP (Jabber / Prosody) +# ------------- + +xmpp_server_ips="{{ fw_xmpp_server_ips }}" +forward_xmpp_server_ips="{{ fw_forward_xmpp_server_ips }}" +xmmp_tcp_in_ports="{{ fw_xmmp_tcp_in_ports }}" +xmmp_tcp_out_ports="{{ fw_xmmp_tcp_out_ports }}" +# xmmp_remote_out_services="192.68.11.81:44444 83.223.86.91:44444" +xmmp_remote_out_services="{{ fw_xmmp_remote_out_services_v4 }}" + + +# ------------- +# --- Services: Mumble +# ------------- + +mumble_server_ips="{{ fw_mumble_server_ips }}" +forward_mumble_server_ips="{{ fw_forward_mumble_server_ips }}" +mumble_ports="{{ fw_mumble_ports }}" + + +# ------------- +# --- Services: Jitsi / Jibri +# ------------- + +jitsi_server_ips="{{ fw_jitsi_server_ips }}" +forward_jitsi_server_ips="{{ fw_forward_jitsi_server_ips }}" +jitsi_tcp_ports="{{ fw_jitsi_tcp_ports }}" +jitsi_udp_port_range="{{ fw_jitsi_udp_port_range }}" +jitsi_tcp_ports_out="{{ fw_jitsi_tcp_ports_out }}" +jitsi_udp_ports_out="{{ fw_jitsi_udp_ports_out }}" +jitsi_dovecot_auth={{ fw_jitsi_dovecot_auth | lower }} +jitsi_dovecot_host="{{ fw_jitsi_dovecot_host }}" +jitsi_dovecot_port="{{ fw_jitsi_dovecot_port }}" +jitsi_jibri_remote_auth={{ fw_jitsi_jibri_remote_auth | lower }} +jitsi_jibri_remote_ips="{{ fw_jitsi_jibri_remote_ips }}" +jitsi_jibri_remote_auth_port="{{ fw_jitsi_jibri_remote_auth_port }}" + +jibri_server_ips="{{ fw_jibri_server_ips }}" +forward_jibri_server_ips="{{ fw_forward_jibri_server_ips }}" +jibri_remote_jitsi_server="{{ fw_jibri_remote_jitsi_server }}" +jibri_remote_auth_port="{{ fw_jibri_remote_auth_port }}" + + +# ------------- +# --- Services: TURN / STUN (Nextcloud Talk) +# ------------- + +nc_turn_server_ips="{{ fw_nc_turn_server_ips }}" +forward_nc_turn_server_ips="{{ fw_forward_nc_turn_server_ips }}" +nc_turn_ports="{{ fw_nc_turn_ports }}" +nc_turn_udp_ports="{{ fw_nc_turn_udp_ports }}" + + +# ------------- +# --- Services: TFTP (not yet implemented) +# ------------- + +tftp_server_ips="{{ fw_tftp_server_ips }}" + + +# ------------- +# --- Services: Prometheus +# ------------- + +prometheus_local_server_ips="{{ fw_prometheus_local_server_ips }}" +prometheus_remote_client_ports="{{ fw_prometheus_remote_client_ports }}" + +prometheus_local_client_ips="{{ fw_prometheus_local_client_ips }}" +prometheus_local_client_ports="{{ fw_prometheus_local_client_ports }}" +prometheus_remote_server_ips="{{ fw_prometheus_remote_server_ips }}" + + +# ------------- +# --- Services: Munin +# ------------- + +munin_server_ips="{{ fw_munin_server_ips }}" +forward_munin_server_ips="{{ fw_forward_munin_server_ips }}" +munin_remote_port="{{ fw_munin_remote_port }}" + +munin_remote_ip="{{ munin_remote_ipv4 }}" +munin_local_port="{{ fw_munin_local_port }}" + + +# ------------- +# --- Services: Xymon (not yet implemented) +# ------------- + +xymon_server_ips="{{ fw_xymon_server_ips }}" +local_xymon_client={{ fw_local_xymon_client | lower }} +xymon_port="{{ fw_xymon_port }}" + + +# ------------- +# --- Protocols out: Rsync +# ------------- + +rsync_out_ips="{{ fw_rsync_out_ips }}" +forward_rsync_out_ips="{{ fw_forward_rsync_out_ips }}" +rsync_ports="{{ fw_rsync_ports }}" + + +# ------------- +# --- Special ports (OUT) +# ------------- + +tcp_out_ports="{{ fw_tcp_out_ports }}" +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 }}" + + +# ============= +# --- Portforwarding (IPv4) +# --- Format: "::::" +# ============= + +portforward_tcp="{{ fw_portforward_tcp_v4 }}" +portforward_udp="{{ fw_portforward_udp_v4 }}" + + +# ------------- +# --- Blocked IPs / Ports +# ------------- + +blocked_ips="{{ fw_blocked_ips }}" +block_tcp_ports="{{ fw_block_tcp_ports }}" +block_udp_ports="{{ fw_block_udp_ports }}" + + +# ------------- +# --- Special / Counters +# ------------- + +create_traffic_counter={{ fw_create_traffic_counter | lower }} +create_iperf_rules={{ fw_create_iperf_rules | lower }} + + +# ------------- +# --- Protection +# ------------- + +protection_against_syn_flooding={{ fw_protection_against_syn_flooding | lower }} +protection_against_port_scanning={{ fw_protection_against_port_scanning | lower }} +protection_against_ssh_brute_force_attacks={{ fw_protection_against_ssh_brute_force_attacks | lower }} + + +# ------------- +# --- Connection limits +# ------------- + +limit_connections_per_source_IP={{ fw_limit_connections_per_source_IP | lower }} +per_IP_connection_limit={{ fw_per_IP_connection_limit }} + +limit_new_tcp_connections_per_seconds_per_source_IP={{ fw_limit_new_tcp_connections_per_seconds_per_source_IP | lower }} +limit_new_tcp_connections_per_seconds_ports="{{ fw_limit_new_tcp_connections_per_seconds_ports }}" + + +# ------------- +# --- Kernel parameters (IPv4) +# ------------- + +kernel_activate_forwarding={{ fw_kernel_activate_forwarding | lower }} + +kernel_support_dynaddr={{ fw_kernel_support_dynaddr | lower }} +dynaddr_flag="{{ fw_dynaddr_flag }}" + +kernel_reduce_timeouts={{ fw_kernel_reduce_timeouts | lower }} +kernel_tcp_syncookies={{ fw_kernel_tcp_syncookies | lower }} +kernel_protect_against_icmp_bogus_messages={{ fw_kernel_protect_against_icmp_bogus_messages | lower }} +kernel_ignore_broadcast_ping={{ fw_kernel_ignore_broadcast_ping | lower }} +kernel_deactivate_source_route={{ fw_kernel_deactivate_source_route | lower }} +kernel_dont_accept_redirects={{ fw_kernel_dont_accept_redirects | lower }} +kernel_activate_rp_filter={{ fw_kernel_activate_rp_filter | lower }} +kernel_log_martians={{ fw_kernel_log_martians | lower }} diff --git a/roles/ipt-server/templates/etc/ipt-firewall/main_ipv6.conf.j2 b/roles/ipt-server/templates/etc/ipt-firewall/main_ipv6.conf.j2 new file mode 100644 index 0000000..9ad08ba --- /dev/null +++ b/roles/ipt-server/templates/etc/ipt-firewall/main_ipv6.conf.j2 @@ -0,0 +1,337 @@ +#!/usr/bin/env bash +# {{ ansible_managed }} + + +## ---------------------------------------------------------------- +## --- Main Configurations IPv6 Firewall +## ---------------------------------------------------------------- + + +# ------------- +# --- Bridged / LXC traffic +# ------------- + +do_not_firewall_bridged_traffic={{ fw_do_not_firewall_bridged_traffic | lower }} +do_not_firewall_lx_guest_systems={{ fw_do_not_firewall_lx_guest_systems | lower }} + + +# ------------- +# --- Drop ICMP / MNDP / mDNS +# ------------- + +drop_icmp={{ fw_drop_icmp | lower }} +drop_mndp={{ fw_drop_mndp | lower }} +drop_mdns={{ fw_drop_mdns | lower }} + + +# ------------- +# --- Outgoing traffic +# ------------- + +allow_all_outgoing_traffic={{ fw_allow_all_outgoing_traffic | lower }} + + +# ------------- +# --- Interface policy +# ------------- + +blocked_ifs="{{ fw_blocked_ifs }}" +unprotected_ifs="{{ fw_unprotected_ifs }}" + + +# ------------- +# --- Forwarding / Routing +# ------------- + +# Private IPs to forward (CIDR notation, blank separated) +forward_private_ips="{{ fw_forward_private_ips_v6 }}" + + +# ------------- +# --- Access control (source-based) +# --- Note: IPv6 uses comma as field separator (not colon) +# ------------- + +# restrict_local_service_to_net="ext-net,local-address,port,protocol" +restrict_local_service_to_net="{{ fw_restrict_local_service_to_net_v6 }}" + +# restrict_local_net_to_net="," +restrict_local_net_to_net="{{ fw_restrict_local_net_to_net_v6 }}" + +# allow_ext_service=",," +allow_ext_service="{{ fw_allow_ext_service_v6 }}" + +# allow_ext_net="" (blank separated) +allow_ext_net="{{ fw_allow_ext_net_v6 }}" + +# allow_local_service="," (blank separated) +allow_local_service="{{ fw_allow_local_service_v6 }}" + +# allow_local_service_from_networks=",," +allow_local_service_from_networks="{{ fw_allow_local_service_from_networks_v6 }}" + + +# ------------- +# --- Services: VPN / WireGuard +# ------------- + +vpn_server_ips="{{ fw_vpn_server_ips }}" +forward_vpn_server_ips="{{ fw_forward_vpn_server_ips }}" +vpn_ports="{{ fw_vpn_ports }}" + +wireguard_server_ips="{{ fw_wireguard_server_ips }}" +forward_wireguard_server_ips="{{ fw_forward_wireguard_server_ips }}" +wireguard_server_ports="{{ fw_wireguard_server_ports }}" +wireguard_out_ports="{{ fw_wireguard_out_ports }}" + + +# ------------- +# --- Services: NTP +# ------------- + +local_ntp_service={{ fw_local_ntp_service | lower }} +ntp_port="{{ fw_ntp_port }}" +ntp_allowed_net="{{ fw_ntp_allowed_net }}" + + +# ------------- +# --- Services: DNS +# ------------- + +dns_server_ips="{{ fw_dns_server_ips }}" +forward_dns_server_ips="{{ fw_forward_dns_server_ips }}" + +local_resolver_service={{ fw_local_resolver_service | lower }} +resolver_port="{{ fw_resolver_port }}" +# resolver_allowed_networks="2001:678:a40:3000::/64" +resolver_allowed_networks="{{ fw_resolver_allowed_networks_v6 }}" + + +# ------------- +# --- Services: SSH +# ------------- + +ssh_server_ips="{{ fw_ssh_server_ips }}" +forward_ssh_server_ips="{{ fw_forward_ssh_server_ips }}" +ssh_ports="{{ fw_ssh_ports }}" + + +# ------------- +# --- Services: HTTP(S) +# ------------- + +http_server_ips="{{ fw_http_server_ips }}" +forward_http_server_ips="{{ fw_forward_http_server_ips }}" +http_ports="{{ fw_http_ports }}" + +log_cgi_traffic_out={{ fw_log_cgi_traffic_out | lower }} +cgi_script_users="{{ fw_cgi_script_users }}" + + +# ------------- +# --- Services: Mattermost +# ------------- + +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_udp_ports_out="{{ fw_mm_udp_ports_out }}" + + +# ------------- +# --- Services: Mail (SMTP / IMAP / POP) +# ------------- + +smtpd_ips="{{ fw_smtpd_ips }}" +forward_smtpd_ips="{{ fw_forward_smtpd_ips }}" +smtpd_additional_listen_ports="{{ fw_smtpd_additional_listen_ports }}" +smtpd_additional_outgoung_ports="{{ fw_smtpd_additional_outgoing_ports }}" + +mail_server_ips="{{ fw_mail_server_ips }}" +forward_mail_server_ips="{{ fw_forward_mail_server_ips }}" +mail_user_ports="{{ fw_mail_user_ports }}" + +mail_client_ips="{{ fw_mail_client_ips }}" +forward_mail_client_ips="{{ fw_forward_mail_client_ips }}" + +dovecot_auth_service={{ fw_dovecot_auth_service | lower }} +dovecot_auth_port="{{ fw_dovecot_auth_port }}" +# dovecot_auth_allowed_networks="2001:678:a40:3000::/64 2a01:30:0:13:2f7:50ff:fed2:cef7" +dovecot_auth_allowed_networks="{{ fw_dovecot_auth_allowed_networks_v6 }}" + + +# ------------- +# --- Services: FTP +# ------------- + +ftp_server_ips="{{ fw_ftp_server_ips }}" +forward_ftp_server_ips="{{ fw_forward_ftp_server_ips }}" +ftp_passive_port_range="{{ fw_ftp_passive_port_range }}" + + +# ------------- +# --- Services: XMPP (Jabber / Prosody) +# ------------- + +xmpp_server_ips="{{ fw_xmpp_server_ips }}" +forward_xmpp_server_ips="{{ fw_forward_xmpp_server_ips }}" +xmmp_tcp_in_ports="{{ fw_xmmp_tcp_in_ports }}" +xmmp_tcp_out_ports="{{ fw_xmmp_tcp_out_ports }}" +# xmmp_remote_out_services="2a01:4f8:221:3b4e::247,44444" +xmmp_remote_out_services="{{ fw_xmmp_remote_out_services_v6 }}" + + +# ------------- +# --- Services: Mumble +# ------------- + +mumble_server_ips="{{ fw_mumble_server_ips }}" +forward_mumble_server_ips="{{ fw_forward_mumble_server_ips }}" +mumble_ports="{{ fw_mumble_ports }}" + + +# ------------- +# --- Services: Jitsi / Jibri +# ------------- + +jitsi_server_ips="{{ fw_jitsi_server_ips }}" +forward_jitsi_server_ips="{{ fw_forward_jitsi_server_ips }}" +jitsi_tcp_ports="{{ fw_jitsi_tcp_ports }}" +jitsi_udp_port_range="{{ fw_jitsi_udp_port_range }}" +jitsi_tcp_ports_out="{{ fw_jitsi_tcp_ports_out }}" +jitsi_udp_ports_out="{{ fw_jitsi_udp_ports_out }}" +jitsi_dovecot_auth={{ fw_jitsi_dovecot_auth | lower }} +jitsi_dovecot_host="{{ fw_jitsi_dovecot_host }}" +jitsi_dovecot_port="{{ fw_jitsi_dovecot_port }}" +jitsi_jibri_remote_auth={{ fw_jitsi_jibri_remote_auth | lower }} +jitsi_jibri_remote_ips="{{ fw_jitsi_jibri_remote_ips }}" +jitsi_jibri_remote_auth_port="{{ fw_jitsi_jibri_remote_auth_port }}" + +jibri_server_ips="{{ fw_jibri_server_ips }}" +forward_jibri_server_ips="{{ fw_forward_jibri_server_ips }}" +jibri_remote_jitsi_server="{{ fw_jibri_remote_jitsi_server }}" +jibri_remote_auth_port="{{ fw_jibri_remote_auth_port }}" + + +# ------------- +# --- Services: TURN / STUN (Nextcloud Talk) +# ------------- + +nc_turn_server_ips="{{ fw_nc_turn_server_ips }}" +forward_nc_turn_server_ips="{{ fw_forward_nc_turn_server_ips }}" +nc_turn_ports="{{ fw_nc_turn_ports }}" +nc_turn_udp_ports="{{ fw_nc_turn_udp_ports }}" + + +# ------------- +# --- Services: TFTP (not yet implemented) +# ------------- + +tftp_server_ips="{{ fw_tftp_server_ips }}" + + +# ------------- +# --- Services: Prometheus +# ------------- + +prometheus_local_server_ips="{{ fw_prometheus_local_server_ips }}" +prometheus_remote_client_ports="{{ fw_prometheus_remote_client_ports }}" + +prometheus_local_client_ips="{{ fw_prometheus_local_client_ips }}" +prometheus_local_client_ports="{{ fw_prometheus_local_client_ports }}" +prometheus_remote_server_ips="{{ fw_prometheus_remote_server_ips }}" + + +# ------------- +# --- Services: Munin +# ------------- + +munin_server_ips="{{ fw_munin_server_ips }}" +forward_munin_server_ips="{{ fw_forward_munin_server_ips }}" +munin_remote_port="{{ fw_munin_remote_port }}" + +munin_remote_ip="{{ munin_remote_ipv6 }}" +munin_local_port="{{ fw_munin_local_port }}" + + +# ------------- +# --- Services: Xymon (not yet implemented) +# ------------- + +xymon_server_ips="{{ fw_xymon_server_ips }}" +local_xymon_client={{ fw_local_xymon_client | lower }} +xymon_port="{{ fw_xymon_port }}" + + +# ------------- +# --- Protocols out: Rsync +# ------------- + +rsync_out_ips="{{ fw_rsync_out_ips }}" +forward_rsync_out_ips="{{ fw_forward_rsync_out_ips }}" +rsync_ports="{{ fw_rsync_ports }}" + + +# ------------- +# --- Special ports (OUT) +# ------------- + +tcp_out_ports="{{ fw_tcp_out_ports }}" +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 }}" + + +# ============= +# --- Portforwarding (IPv6) +# --- Format: ",,,," +# ============= + +portforward_tcp="{{ fw_portforward_tcp_v6 }}" +portforward_udp="{{ fw_portforward_udp_v6 }}" + + +# ------------- +# --- Blocked IPs / Ports +# ------------- + +blocked_ips="{{ fw_blocked_ips }}" +block_tcp_ports="{{ fw_block_tcp_ports }}" +block_udp_ports="{{ fw_block_udp_ports }}" + + +# ------------- +# --- Special / Counters +# ------------- + +create_traffic_counter={{ fw_create_traffic_counter | lower }} +create_iperf_rules={{ fw_create_iperf_rules | lower }} + + +# ------------- +# --- Protection +# ------------- + +protection_against_syn_flooding={{ fw_protection_against_syn_flooding | lower }} +protection_against_port_scanning={{ fw_protection_against_port_scanning | lower }} +protection_against_ssh_brute_force_attacks={{ fw_protection_against_ssh_brute_force_attacks | lower }} + + +# ------------- +# --- Connection limits +# ------------- + +limit_connections_per_source_IP={{ fw_limit_connections_per_source_IP | lower }} +per_IP_connection_limit={{ fw_per_IP_connection_limit }} + +limit_new_tcp_connections_per_seconds_per_source_IP={{ fw_limit_new_tcp_connections_per_seconds_per_source_IP | lower }} +limit_new_tcp_connections_per_seconds_ports="{{ fw_limit_new_tcp_connections_per_seconds_ports }}" + + +# ------------- +# --- Kernel parameters (IPv6) +# ------------- + +kernel_forward_between_interfaces={{ fw_kernel_forward_between_interfaces | lower }} +kernel_deactivate_source_route={{ fw_kernel_deactivate_source_route | lower }} +kernel_dont_accept_redirects={{ fw_kernel_dont_accept_redirects | lower }}