/** Initialize the firewall rules. */ int iptables_fw_init(void) { s_config *config; char * gw_interface = NULL; char * gw_address = NULL; char * gw_iprange = NULL; int gw_port = 0; int traffic_control; int set_mss, mss_value; t_MAC *pt; t_MAC *pb; t_MAC *pa; int rc = 0, mmask = 0, macmechanism; LOCK_CONFIG(); config = config_get_config(); gw_interface = safe_strdup(config->gw_interface); /* must free */ gw_address = safe_strdup(config->gw_address); /* must free */ gw_iprange = safe_strdup(config->gw_iprange); /* must free */ gw_port = config->gw_port; pt = config->trustedmaclist; pb = config->blockedmaclist; pa = config->allowedmaclist; macmechanism = config->macmechanism; set_mss = config->set_mss; mss_value = config->mss_value; traffic_control = config->traffic_control; FW_MARK_BLOCKED = config->FW_MARK_BLOCKED; FW_MARK_TRUSTED = config->FW_MARK_TRUSTED; FW_MARK_AUTHENTICATED = config->FW_MARK_AUTHENTICATED; UNLOCK_CONFIG(); /* Set up packet marking methods */ rc |= _iptables_init_marks(); rc |= _iptables_check_mark_masking(); /* * ************************************** * Set up mangle table chains and rules * */ /* Create new chains in the mangle table */ rc |= iptables_do_command("-t mangle -N " CHAIN_TRUSTED); /* for marking trusted packets */ rc |= iptables_do_command("-t mangle -N " CHAIN_BLOCKED); /* for marking blocked packets */ rc |= iptables_do_command("-t mangle -N " CHAIN_INCOMING); /* for counting incoming packets */ rc |= iptables_do_command("-t mangle -N " CHAIN_OUTGOING); /* for marking authenticated packets, and for counting outgoing packets */ /* Assign jumps to these new chains */ rc |= iptables_do_command("-t mangle -I PREROUTING 1 -i %s -s %s -j " CHAIN_OUTGOING, gw_interface, gw_iprange); rc |= iptables_do_command("-t mangle -I PREROUTING 2 -i %s -s %s -j " CHAIN_BLOCKED, gw_interface, gw_iprange); rc |= iptables_do_command("-t mangle -I PREROUTING 3 -i %s -s %s -j " CHAIN_TRUSTED, gw_interface, gw_iprange); rc |= iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -d %s -j " CHAIN_INCOMING, gw_interface, gw_iprange); /* Rules to mark as trusted MAC address packets in mangle PREROUTING */ for (; pt != NULL; pt = pt->next) { rc |= iptables_trust_mac(pt->mac); } /* Rules to mark as blocked MAC address packets in mangle PREROUTING */ if(MAC_BLOCK == macmechanism) { /* with the MAC_BLOCK mechanism, * MAC's on the block list are marked as blocked; * everything else passes */ for (; pb != NULL; pb = pb->next) { rc |= iptables_block_mac(pb->mac); } } else if(MAC_ALLOW == macmechanism) { /* with the MAC_ALLOW mechanism, * MAC's on the allow list pass; * everything else is to be marked as blocked */ /* So, append at end of chain a rule to mark everything blocked */ rc |= iptables_do_command("-t mangle -A " CHAIN_BLOCKED " -j MARK %s 0x%x", markop, FW_MARK_BLOCKED); /* But insert at beginning of chain rules to pass allowed MAC's */ for (; pa != NULL; pa = pa->next) { rc |= iptables_allow_mac(pa->mac); } } else { debug(LOG_ERR, "Unknown MAC mechanism: %d", macmechanism); rc = -1; } /* Set up for traffic control */ if(traffic_control) { rc |= tc_init_tc(); } /* * End of mangle table chains and rules ************************************** */ /* * ************************************** * Set up nat table chains and rules * */ /* Create new chains in nat table */ rc |= iptables_do_command("-t nat -N " CHAIN_OUTGOING); /* * nat PREROUTING chain */ /* packets coming in on gw_interface jump to CHAIN_OUTGOING */ rc |= iptables_do_command("-t nat -A PREROUTING -i %s -s %s -j " CHAIN_OUTGOING, gw_interface, gw_iprange); /* CHAIN_OUTGOING, packets marked TRUSTED ACCEPT */ rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -m mark --mark 0x%x%s -j ACCEPT", FW_MARK_TRUSTED, markmask); /* CHAIN_OUTGOING, packets marked AUTHENTICATED ACCEPT */ rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -m mark --mark 0x%x%s -j ACCEPT",FW_MARK_AUTHENTICATED, markmask); /* CHAIN_OUTGOING, append the "preauthenticated-users" ruleset */ rc |= _iptables_append_ruleset("nat", "preauthenticated-users", CHAIN_OUTGOING); /* CHAIN_OUTGOING, packets for tcp port 80, redirect to gw_port on primary address for the iface */ rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -p tcp --dport 80 -j DNAT --to-destination %s:%d", gw_address, gw_port); /* CHAIN_OUTGOING, other packets ACCEPT */ rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -j ACCEPT"); /* * End of nat table chains and rules ************************************** */ /* * ************************************** * Set up filter table chains and rules * */ /* Create new chains in the filter table */ rc |= iptables_do_command("-t filter -N " CHAIN_TO_INTERNET); rc |= iptables_do_command("-t filter -N " CHAIN_TO_ROUTER); rc |= iptables_do_command("-t filter -N " CHAIN_AUTHENTICATED); rc |= iptables_do_command("-t filter -N " CHAIN_TRUSTED); rc |= iptables_do_command("-t filter -N " CHAIN_TRUSTED_TO_ROUTER); /* * filter INPUT chain */ /* packets coming in on gw_interface jump to CHAIN_TO_ROUTER */ rc |= iptables_do_command("-t filter -I INPUT -i %s -s %s -j " CHAIN_TO_ROUTER, gw_interface, gw_iprange); /* CHAIN_TO_ROUTER packets marked BLOCKED DROP */ rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m mark --mark 0x%x%s -j DROP", FW_MARK_BLOCKED, markmask); /* CHAIN_TO_ROUTER, invalid packets DROP */ rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m state --state INVALID -j DROP"); /* CHAIN_TO_ROUTER, related and established packets ACCEPT */ rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m state --state RELATED,ESTABLISHED -j ACCEPT"); /* CHAIN_TO_ROUTER, bogus SYN packets DROP */ rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -p tcp --tcp-flags SYN SYN \\! --tcp-option 2 -j DROP"); /* CHAIN_TO_ROUTER, packets to HTTP listening on gw_port on router ACCEPT */ rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -p tcp --dport %d -j ACCEPT", gw_port); /* CHAIN_TO_ROUTER, packets marked TRUSTED: */ /* if trusted-users-to-router ruleset is empty: * use empty ruleset policy * else: * jump to CHAIN_TRUSTED_TO_ROUTER, and load and use users-to-router ruleset */ if(is_empty_ruleset("trusted-users-to-router")) { rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m mark --mark 0x%x%s -j %s", FW_MARK_TRUSTED, markmask, get_empty_ruleset_policy("trusted-users-to-router")); } else { rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m mark --mark 0x%x%s -j " CHAIN_TRUSTED_TO_ROUTER, FW_MARK_TRUSTED, markmask); /* CHAIN_TRUSTED_TO_ROUTER, related and established packets ACCEPT */ rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED_TO_ROUTER " -m state --state RELATED,ESTABLISHED -j ACCEPT"); /* CHAIN_TRUSTED_TO_ROUTER, append the "trusted-users-to-router" ruleset */ rc |= _iptables_append_ruleset("filter", "trusted-users-to-router", CHAIN_TRUSTED_TO_ROUTER); /* CHAIN_TRUSTED_TO_ROUTER, any packets not matching that ruleset REJECT */ rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED_TO_ROUTER " -j REJECT --reject-with icmp-port-unreachable"); } /* CHAIN_TO_ROUTER, other packets: */ /* if users-to-router ruleset is empty: * use empty ruleset policy * else: * load and use users-to-router ruleset */ if(is_empty_ruleset("users-to-router")) { rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -j %s", get_empty_ruleset_policy("users-to-router")); } else { /* CHAIN_TO_ROUTER, append the "users-to-router" ruleset */ rc |= _iptables_append_ruleset("filter", "users-to-router", CHAIN_TO_ROUTER); /* everything else, REJECT */ rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -j REJECT --reject-with icmp-port-unreachable"); } /* * filter FORWARD chain */ /* packets coming in on gw_interface jump to CHAIN_TO_INTERNET */ rc |= iptables_do_command("-t filter -A FORWARD -i %s -s %s -j " CHAIN_TO_INTERNET, gw_interface, gw_iprange); /* CHAIN_TO_INTERNET packets marked BLOCKED DROP */ rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j DROP", FW_MARK_BLOCKED, markmask); /* CHAIN_TO_INTERNET, invalid packets DROP */ rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m state --state INVALID -j DROP"); /* CHAIN_TO_INTERNET, deal with MSS */ if (set_mss) { /* XXX this mangles, so 'should' be done in the mangle POSTROUTING chain. * However OpenWRT standard S35firewall does it in filter FORWARD, * and since we are pre-empting that chain here, we put it in */ if (mss_value > 0) { /* set specific MSS value */ rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss %d", mss_value); } else { /* allow MSS as large as possible */ rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu"); } } /* CHAIN_TO_INTERNET, packets marked TRUSTED: */ /* if trusted-users ruleset is empty: * use empty ruleset policy * else: * jump to CHAIN_TRUSTED, and load and use trusted-users ruleset */ if(is_empty_ruleset("trusted-users")) { rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j %s", FW_MARK_TRUSTED, markmask, get_empty_ruleset_policy("trusted-users")); } else { rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j " CHAIN_TRUSTED, FW_MARK_TRUSTED, markmask); /* CHAIN_TRUSTED, related and established packets ACCEPT */ rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED " -m state --state RELATED,ESTABLISHED -j ACCEPT"); /* CHAIN_TRUSTED, append the "trusted-users" ruleset */ rc |= _iptables_append_ruleset("filter", "trusted-users", CHAIN_TRUSTED); /* CHAIN_TRUSTED, any packets not matching that ruleset REJECT */ rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED " -j REJECT --reject-with icmp-port-unreachable"); } /* CHAIN_TO_INTERNET, packets marked AUTHENTICATED: */ /* if authenticated-users ruleset is empty: * use empty ruleset policy * else: * jump to CHAIN_AUTHENTICATED, and load and use authenticated-users ruleset */ if(is_empty_ruleset("authenticated-users")) { rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j %s", FW_MARK_AUTHENTICATED, markmask, get_empty_ruleset_policy("authenticated-users")); } else { rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j " CHAIN_AUTHENTICATED, FW_MARK_AUTHENTICATED, markmask); /* CHAIN_AUTHENTICATED, related and established packets ACCEPT */ rc |= iptables_do_command("-t filter -A " CHAIN_AUTHENTICATED " -m state --state RELATED,ESTABLISHED -j ACCEPT"); /* CHAIN_AUTHENTICATED, append the "authenticated-users" ruleset */ rc |= _iptables_append_ruleset("filter", "authenticated-users", CHAIN_AUTHENTICATED); /* CHAIN_AUTHENTICATED, any packets not matching that ruleset REJECT */ rc |= iptables_do_command("-t filter -A " CHAIN_AUTHENTICATED " -j REJECT --reject-with icmp-port-unreachable"); } /* CHAIN_TO_INTERNET, other packets: */ /* if preauthenticated-users ruleset is empty: * use empty ruleset policy * else: * load and use authenticated-users ruleset */ if(is_empty_ruleset("preauthenticated-users")) { rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j %s ", get_empty_ruleset_policy("preauthenticated-users")); } else { rc |= _iptables_append_ruleset("filter", "preauthenticated-users", CHAIN_TO_INTERNET); } /* CHAIN_TO_INTERNET, all other packets REJECT */ rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j REJECT --reject-with icmp-port-unreachable"); /* * End of filter table chains and rules ************************************** */ free(gw_interface); free(gw_iprange); free(gw_address); return rc; }
/** Initialize the firewall rules. */ int iptables_fw_init(void) { s_config *config; int iptables_version; char *gw_interface = NULL; char *gw_ip = NULL; char *gw_address = NULL; char *gw_iprange = NULL; int gw_port = 0; char *fas_remoteip; int fas_port; int traffic_control; int set_mss, mss_value; t_MAC *pt; t_MAC *pb; t_MAC *pa; int rc = 0; int macmechanism; LOCK_CONFIG(); config = config_get_config(); gw_interface = safe_strdup(config->gw_interface); /* must free */ /* ip4 vs ip6 differences */ const char *ICMP_TYPE; if (config->ip6) { /* ip6 addresses must be in square brackets like [ffcc:e08::1] */ safe_asprintf(&gw_ip, "[%s]", config->gw_ip); /* must free */ ICMP_TYPE = "icmp6"; } else { gw_ip = safe_strdup(config->gw_ip); /* must free */ ICMP_TYPE = "icmp"; } gw_address = safe_strdup(config->gw_address); /* must free */ gw_iprange = safe_strdup(config->gw_iprange); /* must free */ gw_port = config->gw_port; fas_remoteip = safe_strdup(config->fas_remoteip); /* must free */ fas_port = config->fas_port; pt = config->trustedmaclist; pb = config->blockedmaclist; pa = config->allowedmaclist; macmechanism = config->macmechanism; set_mss = config->set_mss; mss_value = config->mss_value; traffic_control = config->traffic_control; FW_MARK_BLOCKED = config->fw_mark_blocked; FW_MARK_TRUSTED = config->fw_mark_trusted; FW_MARK_AUTHENTICATED = config->fw_mark_authenticated; UNLOCK_CONFIG(); iptables_version = get_iptables_version(); if (iptables_version < 0) { debug(LOG_ERR, "Cannot get iptables version."); return -1; } if (iptables_version < MIN_IPTABLES_VERSION) { debug(LOG_ERR, "Unsupported iptables version v%d.%d.%d, needs at least v%d.%d.%d.", (iptables_version / 10000), (iptables_version % 10000) / 100, (iptables_version % 100), (MIN_IPTABLES_VERSION / 10000), (MIN_IPTABLES_VERSION % 10000) / 100, (MIN_IPTABLES_VERSION % 100) ); return -1; } /* Set up packet marking methods */ rc |= _iptables_init_marks(); rc |= _iptables_check_mark_masking(); /* * ************************************** * Set up mangle table chains and rules * */ /* Create new chains in the mangle table */ rc |= iptables_do_command("-t mangle -N " CHAIN_TRUSTED); /* for marking trusted packets */ rc |= iptables_do_command("-t mangle -N " CHAIN_BLOCKED); /* for marking blocked packets */ rc |= iptables_do_command("-t mangle -N " CHAIN_ALLOWED); /* for marking allowed packets */ rc |= iptables_do_command("-t mangle -N " CHAIN_INCOMING); /* for counting incoming packets */ rc |= iptables_do_command("-t mangle -N " CHAIN_OUTGOING); /* for marking authenticated packets, and for counting outgoing packets */ /* Assign jumps to these new chains */ rc |= iptables_do_command("-t mangle -I PREROUTING 1 -i %s -s %s -j " CHAIN_OUTGOING, gw_interface, gw_iprange); rc |= iptables_do_command("-t mangle -I PREROUTING 2 -i %s -s %s -j " CHAIN_BLOCKED, gw_interface, gw_iprange); rc |= iptables_do_command("-t mangle -I PREROUTING 3 -i %s -s %s -j " CHAIN_TRUSTED, gw_interface, gw_iprange); rc |= iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -d %s -j " CHAIN_INCOMING, gw_interface, gw_iprange); /* Rules to mark as trusted MAC address packets in mangle PREROUTING */ for (; pt != NULL; pt = pt->next) { rc |= iptables_trust_mac(pt->mac); } /* Rules to mark as blocked MAC address packets in mangle PREROUTING */ if (MAC_BLOCK == macmechanism) { /* with the MAC_BLOCK mechanism, * MAC's on the block list are marked as blocked; * everything else passes */ for (; pb != NULL; pb = pb->next) { rc |= iptables_block_mac(pb->mac); } } else if (MAC_ALLOW == macmechanism) { /* with the MAC_ALLOW mechanism, * MAC's on the allow list pass; * everything else is to be marked as blocked */ // So, append at end of chain a rule to mark everything blocked rc |= iptables_do_command("-t mangle -A " CHAIN_BLOCKED " -j MARK %s 0x%x", markop, FW_MARK_BLOCKED); // But insert at beginning of chain rules to pass allowed MAC's for (; pa != NULL; pa = pa->next) { rc |= iptables_allow_mac(pa->mac); } } else { debug(LOG_ERR, "Unknown MAC mechanism: %d", macmechanism); rc = -1; } /* Set up for traffic control */ if (traffic_control) { rc |= tc_init_tc(); } /* * End of mangle table chains and rules ************************************** */ /* * ************************************** * Set up nat table chains and rules (ip4 only) * */ if (!config->ip6) { /* Create new chains in nat table */ rc |= iptables_do_command("-t nat -N " CHAIN_OUTGOING); /* * nat PREROUTING chain */ // packets coming in on gw_interface jump to CHAIN_OUTGOING rc |= iptables_do_command("-t nat -I PREROUTING -i %s -s %s -j " CHAIN_OUTGOING, gw_interface, gw_iprange); // CHAIN_OUTGOING, packets marked TRUSTED ACCEPT rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -m mark --mark 0x%x%s -j RETURN", FW_MARK_TRUSTED, markmask); // CHAIN_OUTGOING, packets marked AUTHENTICATED ACCEPT rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -m mark --mark 0x%x%s -j RETURN", FW_MARK_AUTHENTICATED, markmask); // CHAIN_OUTGOING, append the "preauthenticated-users" ruleset rc |= _iptables_append_ruleset("nat", "preauthenticated-users", CHAIN_OUTGOING); // Allow access to remote FAS - CHAIN_OUTGOING and CHAIN_TO_INTERNET packets for remote FAS, ACCEPT if (fas_port && strcmp(fas_remoteip, gw_ip)) { rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -p tcp --destination %s --dport %d -j ACCEPT", fas_remoteip, fas_port); } // CHAIN_OUTGOING, packets for tcp port 80, redirect to gw_port on primary address for the iface rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -p tcp --dport 80 -j DNAT --to-destination %s", gw_address); // CHAIN_OUTGOING, other packets ACCEPT rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -j ACCEPT"); } /* * End of nat table chains and rules (ip4 only) ************************************** */ /* * ************************************** * Set up filter table chains and rules * */ // Create new chains in the filter table rc |= iptables_do_command("-t filter -N " CHAIN_TO_INTERNET); rc |= iptables_do_command("-t filter -N " CHAIN_TO_ROUTER); rc |= iptables_do_command("-t filter -N " CHAIN_AUTHENTICATED); rc |= iptables_do_command("-t filter -N " CHAIN_TRUSTED); rc |= iptables_do_command("-t filter -N " CHAIN_TRUSTED_TO_ROUTER); /* * filter INPUT chain */ // packets coming in on gw_interface jump to CHAIN_TO_ROUTER rc |= iptables_do_command("-t filter -I INPUT -i %s -s %s -j " CHAIN_TO_ROUTER, gw_interface, gw_iprange); // CHAIN_TO_ROUTER packets marked BLOCKED DROP rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m mark --mark 0x%x%s -j DROP", FW_MARK_BLOCKED, markmask); // CHAIN_TO_ROUTER, invalid packets DROP rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m conntrack --ctstate INVALID -j DROP"); // CHAIN_TO_ROUTER, related and established packets ACCEPT rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT"); // CHAIN_TO_ROUTER, bogus SYN packets DROP rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -p tcp --tcp-flags SYN SYN \\! --tcp-option 2 -j DROP"); // CHAIN_TO_ROUTER, packets to HTTP listening on gw_port on router ACCEPT rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -p tcp --dport %d -j ACCEPT", gw_port); // CHAIN_TO_ROUTER, packets to HTTP listening on fas_port on router ACCEPT if (fas_port && !strcmp(fas_remoteip, gw_ip)) { rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -p tcp --dport %d -j ACCEPT", fas_port); } // CHAIN_TO_ROUTER, packets marked TRUSTED: /* if trusted-users-to-router ruleset is empty: * use empty ruleset policy * else: * jump to CHAIN_TRUSTED_TO_ROUTER, and load and use users-to-router ruleset */ if (is_empty_ruleset("trusted-users-to-router")) { rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m mark --mark 0x%x%s -j %s", FW_MARK_TRUSTED, markmask, get_empty_ruleset_policy("trusted-users-to-router")); } else { rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m mark --mark 0x%x%s -j " CHAIN_TRUSTED_TO_ROUTER, FW_MARK_TRUSTED, markmask); // CHAIN_TRUSTED_TO_ROUTER, related and established packets ACCEPT rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED_TO_ROUTER " -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT"); // CHAIN_TRUSTED_TO_ROUTER, append the "trusted-users-to-router" ruleset rc |= _iptables_append_ruleset("filter", "trusted-users-to-router", CHAIN_TRUSTED_TO_ROUTER); // CHAIN_TRUSTED_TO_ROUTER, any packets not matching that ruleset REJECT rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED_TO_ROUTER " -j REJECT --reject-with %s-port-unreachable", ICMP_TYPE); } // CHAIN_TO_ROUTER, other packets: /* if users-to-router ruleset is empty: * use empty ruleset policy * else: * load and use users-to-router ruleset */ if (is_empty_ruleset("users-to-router")) { rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -j %s", get_empty_ruleset_policy("users-to-router")); } else { /* CHAIN_TO_ROUTER, append the "users-to-router" ruleset */ rc |= _iptables_append_ruleset("filter", "users-to-router", CHAIN_TO_ROUTER); /* everything else, REJECT */ rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -j REJECT --reject-with %s-port-unreachable", ICMP_TYPE); } /* * filter FORWARD chain */ // packets coming in on gw_interface jump to CHAIN_TO_INTERNET rc |= iptables_do_command("-t filter -I FORWARD -i %s -s %s -j " CHAIN_TO_INTERNET, gw_interface, gw_iprange); // CHAIN_TO_INTERNET packets marked BLOCKED DROP rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j DROP", FW_MARK_BLOCKED, markmask); // CHAIN_TO_INTERNET, invalid packets DROP rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m conntrack --ctstate INVALID -j DROP"); // CHAIN_TO_INTERNET, deal with MSS if (set_mss) { /* XXX this mangles, so 'should' be done in the mangle POSTROUTING chain. * However OpenWRT standard S35firewall does it in filter FORWARD, * and since we are pre-empting that chain here, we put it in */ if (mss_value > 0) { /* set specific MSS value */ rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss %d", mss_value); } else { /* allow MSS as large as possible */ rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu"); } } // Allow access to remote FAS - CHAIN_OUTGOING and CHAIN_TO_INTERNET packets for remote FAS, ACCEPT if (fas_port && strcmp(fas_remoteip, gw_ip)) { rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -p tcp --destination %s --dport %d -j ACCEPT", fas_remoteip, fas_port); } /* CHAIN_TO_INTERNET, packets marked TRUSTED: */ /* if trusted-users ruleset is empty: * use empty ruleset policy * else: * jump to CHAIN_TRUSTED, and load and use trusted-users ruleset */ if (is_empty_ruleset("trusted-users")) { rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j %s", FW_MARK_TRUSTED, markmask, get_empty_ruleset_policy("trusted-users")); } else { rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j " CHAIN_TRUSTED, FW_MARK_TRUSTED, markmask); // CHAIN_TRUSTED, related and established packets ACCEPT rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED " -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT"); // CHAIN_TRUSTED, append the "trusted-users" ruleset rc |= _iptables_append_ruleset("filter", "trusted-users", CHAIN_TRUSTED); // CHAIN_TRUSTED, any packets not matching that ruleset REJECT rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED " -j REJECT --reject-with %s-port-unreachable", ICMP_TYPE); } /* CHAIN_TO_INTERNET, packets marked AUTHENTICATED: */ /* if authenticated-users ruleset is empty: * use empty ruleset policy * else: * jump to CHAIN_AUTHENTICATED, and load and use authenticated-users ruleset */ if (is_empty_ruleset("authenticated-users")) { rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j %s", FW_MARK_AUTHENTICATED, markmask, get_empty_ruleset_policy("authenticated-users")); } else { rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j " CHAIN_AUTHENTICATED, FW_MARK_AUTHENTICATED, markmask); // CHAIN_AUTHENTICATED, related and established packets ACCEPT rc |= iptables_do_command("-t filter -A " CHAIN_AUTHENTICATED " -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT"); // CHAIN_AUTHENTICATED, append the "authenticated-users" ruleset rc |= _iptables_append_ruleset("filter", "authenticated-users", CHAIN_AUTHENTICATED); // CHAIN_AUTHENTICATED, any packets not matching that ruleset REJECT rc |= iptables_do_command("-t filter -A " CHAIN_AUTHENTICATED " -j REJECT --reject-with %s-port-unreachable", ICMP_TYPE); } /* CHAIN_TO_INTERNET, other packets: */ /* if preauthenticated-users ruleset is empty: * use empty ruleset policy * else: * load and use authenticated-users ruleset */ if (is_empty_ruleset("preauthenticated-users")) { rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j %s ", get_empty_ruleset_policy("preauthenticated-users")); } else { rc |= _iptables_append_ruleset("filter", "preauthenticated-users", CHAIN_TO_INTERNET); } // CHAIN_TO_INTERNET, all other packets REJECT rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j REJECT --reject-with %s-port-unreachable", ICMP_TYPE); /* * End of filter table chains and rules ************************************** */ free(gw_interface); free(gw_iprange); free(gw_ip); free(gw_address); free(fas_remoteip); return rc; }