]> git.ipfire.org Git - people/stevee/network.git/blobdiff - functions.firewall
firewall: ipv6: Discard all packets with rounting header of type zero.
[people/stevee/network.git] / functions.firewall
index ba57943975e8d5d25d9029a74127413fd3de52cd..faeb5949d5c91275245fc6d31b8ed6b9f485cedc 100644 (file)
 # High-level function which will create a ruleset for the current firewall
 # configuration and load it into the kernel.
 function firewall_start() {
+       local protocol="${1}"
+       assert isset protocol
+       shift
+
        # Test mode.
        local test="false"
 
@@ -30,6 +34,10 @@ function firewall_start() {
                        --test)
                                test="true"
                                ;;
+                       *)
+                               error "Unrecognized argument: ${1}"
+                               return ${EXIT_ERROR}
+                               ;;
                esac
                shift
        done
@@ -42,74 +50,88 @@ function firewall_start() {
        firewall_lock_acquire
 
        # Initialize an empty iptables ruleset.
-       iptables_init DROP
+       iptables_init "${protocol}" "DROP"
 
        # Add default chains.
-       firewall_tcp_state_flags
-       firewall_custom_chains
-       firewall_connection_tracking
-       firewall_tcp_clamp_mss
+       firewall_filter_rh0_headers "${protocol}"
+       firewall_tcp_state_flags "${protocol}"
+       firewall_custom_chains "${protocol}"
+       firewall_connection_tracking "${protocol}"
+       firewall_tcp_clamp_mss "${protocol}"
 
        # Add policies for every zone.
-       firewall_localhost_create_chains
+       firewall_localhost_create_chains "${protocol}"
 
        local zone
        for zone in $(zones_get_all); do
                # Create all needed chains for the zone.
-               firewall_zone_create_chains ${zone}
+               firewall_zone_create_chains "${protocol}" "${zone}"
 
                # After the chains that are always available have been
                # created, we will add a custom policy to every single
                # zone.
 
-               # XXX TODO
-               #policy_zone_add ${zone}
+               policy_zone_add "${protocol}" "${zone}"
        done
 
        # Load the new ruleset.
-       iptables_load ${test}
+       local args
+       if enabled testmode; then
+               list_append args "--test"
+       fi
+       iptables_commit "${protocol}" ${args}
 
        firewall_lock_release
 }
 
 function firewall_stop() {
+       local protocol="${1}"
+       assert isset protocol
+
        firewall_lock_acquire
 
        # Initialize an empty firewall ruleset
        # with default policy ACCEPT.
-       iptables_init ACCEPT
+       iptables_init "${protocol}" ACCEPT
 
        # Load it.
-       iptables_load
+       ipables_load "${protocol}"
 
        firewall_lock_release
 }
 
 function firewall_show() {
+       local protocol="${1}"
+       assert isset protocol
+
        # Shows the ruleset that is currently loaded.
-       iptables_status
+       iptables_status "${protocol}"
 
        return ${EXIT_OK}
 }
 
 function firewall_panic() {
+       local protocol="${1}"
+       assert isset protocol
+       shift
+
        local admin_hosts="$@"
 
-       firewall_lock_acquire
+       firewall_lock_acquire "${protocol}"
 
        # Drop all communications.
-       iptables_init DROP
+       iptables_init "${protocol}" DROP
 
        # If an admin host is provided, some administrative
        # things will be allowed from there.
        local admin_host
        for admin_host in ${admin_hosts}; do
-               iptables -A INPUT -s ${admin_host} -j ACCEPT
-               iptables -A OUTPUT -d ${admin_host} -j ACCEPT
+               iptables "${protocol}" -A INPUT  -s "${admin_host}" -j ACCEPT
+               iptables "${protocol}" -A OUTPUT -d "${admin_host}" -j ACCEPT
        done
 
        # Load it.
-       iptables_load
+       iptables_commit "${protocol}"
 
        firewall_lock_release
 }
@@ -142,82 +164,120 @@ function firewall_lock_release() {
 }
 
 function firewall_custom_chains() {
+       local protocol="${1}"
+       assert isset protocol
+
        log INFO "Creating CUSTOM* chains..."
 
        # These chains are intened to be filled with
        # rules by the user. They are processed at the very
        # beginning so it is possible to overwrite everything.
 
-       iptables_chain_create CUSTOMINPUT
-       iptables -A INPUT -j CUSTOMINPUT
+       iptables_chain_create "${protocol}" CUSTOMINPUT
+       iptables "${protocol}" -A INPUT -j CUSTOMINPUT
 
-       iptables_chain_create CUSTOMFORWARD
-       iptables -A FORWARD -j CUSTOMFORWARD
+       iptables_chain_create "${protocol}" CUSTOMFORWARD
+       iptables "${protocol}" -A FORWARD -j CUSTOMFORWARD
 
-       iptables_chain_create CUSTOMOUTPUT
-       iptables -A OUTPUT -j CUSTOMOUTPUT
+       iptables_chain_create "${protocol}" CUSTOMOUTPUT
+       iptables "${protocol}" -A OUTPUT -j CUSTOMOUTPUT
 
-       iptables_chain_create -4 -t nat CUSTOMPREROUTING
-       iptables -4 -t nat -A PREROUTING -j CUSTOMPREROUTING
+       iptables_chain_create "${protocol}" -t nat CUSTOMPREROUTING
+       iptables "${protocol}" -t nat -A PREROUTING -j CUSTOMPREROUTING
 
-       iptables_chain_create -4 -t nat CUSTOMPOSTROUTING
-       iptables -4 -t nat -A POSTROUTING -j CUSTOMPOSTROUTING
+       iptables_chain_create "${protocol}" -t nat CUSTOMPOSTROUTING
+       iptables "${protocol}" -t nat -A POSTROUTING -j CUSTOMPOSTROUTING
 
-       iptables_chain_create -4 -t nat CUSTOMOUTPUT
-       iptables -4 -t nat -A OUTPUT -j CUSTOMOUTPUT
+       iptables_chain_create "${protocol}" -t nat CUSTOMOUTPUT
+       iptables "${protocol}" -t nat -A OUTPUT -j CUSTOMOUTPUT
 }
 
 function firewall_tcp_state_flags() {
+       local protocol="${1}"
+       assert isset protocol
+
        log INFO "Creating TCP State Flags chain..."
-       iptables_chain_create BADTCP_LOG
-       iptables -A BADTCP_LOG -p tcp -j $(iptables_LOG "Illegal TCP state: ")
-       iptables -A BADTCP_LOG -j DROP
-
-       iptables_chain_create BADTCP
-       iptables -A BADTCP -p tcp --tcp-flags ALL NONE -j BADTCP_LOG
-       iptables -A BADTCP -p tcp --tcp-flags SYN,FIN SYN,FIN -j BADTCP_LOG
-       iptables -A BADTCP -p tcp --tcp-flags SYN,RST SYN,RST -j BADTCP_LOG
-       iptables -A BADTCP -p tcp --tcp-flags FIN,RST FIN,RST -j BADTCP_LOG
-       iptables -A BADTCP -p tcp --tcp-flags ACK,FIN FIN     -j BADTCP_LOG
-       iptables -A BADTCP -p tcp --tcp-flags ACK,PSH PSH     -j BADTCP_LOG
-       iptables -A BADTCP -p tcp --tcp-flags ACK,URG URG     -j BADTCP_LOG
-
-       iptables -A INPUT   -p tcp -j BADTCP
-       iptables -A OUTPUT  -p tcp -j BADTCP
-       iptables -A FORWARD -p tcp -j BADTCP
+
+       iptables_chain_create "${protocol}" BADTCP_LOG
+       iptables "${protocol}" -A BADTCP_LOG -p tcp -j "$(iptables_LOG "Illegal TCP state: ")"
+       iptables "${protocol}" -A BADTCP_LOG -j DROP
+
+       iptables_chain_create "${protocol}" BADTCP
+       iptables "${protocol}" -A BADTCP -p tcp --tcp-flags ALL NONE        -j BADTCP_LOG
+       iptables "${protocol}" -A BADTCP -p tcp --tcp-flags SYN,FIN SYN,FIN -j BADTCP_LOG
+       iptables "${protocol}" -A BADTCP -p tcp --tcp-flags SYN,RST SYN,RST -j BADTCP_LOG
+       iptables "${protocol}" -A BADTCP -p tcp --tcp-flags FIN,RST FIN,RST -j BADTCP_LOG
+       iptables "${protocol}" -A BADTCP -p tcp --tcp-flags ACK,FIN FIN     -j BADTCP_LOG
+       iptables "${protocol}" -A BADTCP -p tcp --tcp-flags ACK,PSH PSH     -j BADTCP_LOG
+       iptables "${protocol}" -A BADTCP -p tcp --tcp-flags ACK,URG URG     -j BADTCP_LOG
+
+       iptables "${protocol}" -A INPUT   -p tcp -j BADTCP
+       iptables "${protocol}" -A OUTPUT  -p tcp -j BADTCP
+       iptables "${protocol}" -A FORWARD -p tcp -j BADTCP
 }
 
 function firewall_tcp_clamp_mss() {
        # Do nothing if this has been disabled.
        enabled FIREWALL_CLAMP_PATH_MTU || return ${EXIT_OK}
 
+       local protocol="${1}"
+       assert isset protocol
+
        log DEBUG "Adding rules to clamp MSS to path MTU..."
-       iptables -t mangle -A FORWARD \
+
+       iptables "${protocol}" -t mangle -A FORWARD \
                -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
 }
 
 function firewall_connection_tracking() {
+       local protocol="${1}"
+       assert isset protocol
+
        log INFO "Creating Connection Tracking chain..."
-       iptables_chain_create CONNTRACK
-       iptables -A CONNTRACK -m state --state ESTABLISHED,RELATED -j ACCEPT
-       iptables -A CONNTRACK -m state --state INVALID -j $(iptables_LOG "INVALID packet: ")
-       iptables -A CONNTRACK -m state --state INVALID -j DROP
-
-       iptables -A INPUT   -j CONNTRACK
-       iptables -A OUTPUT  -j CONNTRACK
-       iptables -A FORWARD -j CONNTRACK
+
+       iptables_chain_create "${protocol}" CONNTRACK
+       iptables "${protocol}" -A CONNTRACK -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
+       iptables "${protocol}" -A CONNTRACK -m conntrack --ctstate INVALID -j "$(iptables_LOG "INVALID packet: ")"
+       iptables "${protocol}" -A CONNTRACK -m conntrack --ctstate INVALID -j DROP
+
+       iptables "${protocol}" -A INPUT   -j CONNTRACK
+       iptables "${protocol}" -A OUTPUT  -j CONNTRACK
+       iptables "${protocol}" -A FORWARD -j CONNTRACK
 }
 
 function firewall_localhost_create_chains() {
+       local protocol="${1}"
+       assert isset protocol
+
        log DEBUG "Creating firewall chains for localhost..."
 
        # Accept everything on lo
-       iptables -A INPUT  -i lo -m state --state NEW -j ACCEPT
-       iptables -A OUTPUT -o lo -m state --state NEW -j ACCEPT
+       iptables "${protocol}" -A INPUT  -i lo -j ACCEPT
+       iptables "${protocol}" -A OUTPUT -o lo -j ACCEPT
+}
+
+function firewall_filter_rh0_headers() {
+       local protocol="${1}"
+       assert isset protocol
+
+       # Only IPv6.
+       [ "${protocol}" = "ipv6" ] || return ${EXIT_OK}
+
+       # Filter all packets that have RH0 headers
+       # http://www.ietf.org/rfc/rfc5095.txt
+       iptables_chain_create "${protocol}" FILTER_RH0
+       iptables "${protocol}" -A FILTER_RH0 -m rt --rt-type 0 -j DROP
+
+       iptables "${protocol}" -A INPUT   -j FILTER_RH0
+       iptables "${protocol}" -A FORWARD -j FILTER_RH0
+       iptables "${protocol}" -A OUTPUT  -j FILTER_RH0
 }
 
 function firewall_zone_create_chains() {
-       local zone=${1}
+       local protocol="${1}"
+       assert isset protocol
+
+       local zone="${2}"
        assert isset zone
 
        log DEBUG "Creating firewall chains for zone '${zone}'."
@@ -225,17 +285,17 @@ function firewall_zone_create_chains() {
        local chain_prefix="ZONE_${zone^^}"
 
        # Create filter chains.
-       iptables_chain_create "${chain_prefix}_INPUT"
-       iptables -A INPUT   -i ${zone} -j "${chain_prefix}_INPUT"
+       iptables_chain_create "${protocol}" "${chain_prefix}_INPUT"
+       iptables "${protocol}" -A INPUT   -i ${zone} -j "${chain_prefix}_INPUT"
 
-       iptables_chain_create "${chain_prefix}_OUTPUT"
-       iptables -A OUTPUT  -o ${zone} -j "${chain_prefix}_OUTPUT"
+       iptables_chain_create "${protocol}" "${chain_prefix}_OUTPUT"
+       iptables "${protocol}" -A OUTPUT  -o ${zone} -j "${chain_prefix}_OUTPUT"
 
        # Custom rules.
-       iptables_chain_create "${chain_prefix}_CUSTOM"
+       iptables_chain_create "${protocol}" "${chain_prefix}_CUSTOM"
 
        # Intrusion Prevention System.
-       iptables_chain_create "${chain_prefix}_IPS"
+       iptables_chain_create "${protocol}" "${chain_prefix}_IPS"
 
        # Create a chain for each other zone.
        # This leaves us with n^2 chains. Duh.
@@ -243,52 +303,52 @@ function firewall_zone_create_chains() {
        local other_zone other_chain_prefix
        for other_zone in $(zones_get_all); do
                other_chain_prefix="${chain_prefix}_${other_zone^^}"
-               iptables_chain_create ${other_chain_prefix}
+               iptables_chain_create "${protocol}" "${other_chain_prefix}"
 
                # Connect the chain with the FORWARD chain.
-               iptables -A FORWARD -i ${zone} -o ${other_zone} \
+               iptables "${protocol}" -A FORWARD -i "${zone}" -o "${other_zone}" \
                        -j "${other_chain_prefix}"
 
                # Handle custom rules.
-               iptables -A ${other_chain_prefix} -j "${chain_prefix}_CUSTOM"
+               iptables "${protocol}" -A "${other_chain_prefix}" -j "${chain_prefix}_CUSTOM"
 
                # Link IPS.
-               iptables -A ${other_chain_prefix} -j "${chain_prefix}_IPS"
+               iptables "${protocol}" -A "${other_chain_prefix}" -j "${chain_prefix}_IPS"
 
                # Rules.
-               iptables_chain_create "${other_chain_prefix}_RULES"
-               iptables -A ${other_chain_prefix} -j "${other_chain_prefix}_RULES"
+               iptables_chain_create "${protocol}" "${other_chain_prefix}_RULES"
+               iptables "${protocol}" -A "${other_chain_prefix}" -j "${other_chain_prefix}_RULES"
 
                # Policy.
-               iptables_chain_create "${other_chain_prefix}_POLICY"
-               iptables -A ${other_chain_prefix} -j "${other_chain_prefix}_POLICY"
+               iptables_chain_create "${protocol}" "${other_chain_prefix}_POLICY"
+               iptables "${protocol}" -A "${other_chain_prefix}" -j "${other_chain_prefix}_POLICY"
        done
 
        ## Create mangle chain.
-       #iptables_chain_create -t mangle ${chain_prefix}
-       #iptables -t mangle -A PREROUTING  -i ${zone} -j ${chain_prefix}
-       #iptables -t mangle -A POSTROUTING -o ${zone} -j ${chain_prefix}
+       #iptables_chain_create "${protocol}" -t mangle "${chain_prefix}"
+       #iptables "${protocol}" -t mangle -A PREROUTING  -i "${zone}" -j "${chain_prefix}"
+       #iptables "${protocol}" -t mangle -A POSTROUTING -o "${zone}" -j "${chain_prefix}"
 
        ## Quality of Service
-       #iptables_chain_create -t mangle "${chain_prefix}_QOS_INC"
-       #iptables -t mangle -A ${chain_prefix} -i ${zone} -j "${chain_prefix}_QOS_INC"
-       #iptables_chain_create -t mangle "${chain_prefix}_QOS_OUT"
-       #iptables -t mangle -A ${chain_prefix} -o ${zone} -j "${chain_prefix}_QOS_OUT"
+       #iptables_chain_create "${protocol}" -t mangle "${chain_prefix}_QOS_INC"
+       #iptables "${protocol}" -t mangle -A "${chain_prefix}" -i "${zone}" -j "${chain_prefix}_QOS_INC"
+       #iptables_chain_create "${protocol}" -t mangle "${chain_prefix}_QOS_OUT"
+       #iptables "${protocol}" -t mangle -A "${chain_prefix}" -o "${zone}" -j "${chain_prefix}_QOS_OUT"
 
        # Create NAT chain.
-       iptables_chain_create -4 -t nat ${chain_prefix}
-       iptables -4 -t nat -A PREROUTING  -i ${zone} -j ${chain_prefix}
-       iptables -4 -t nat -A POSTROUTING -o ${zone} -j ${chain_prefix}
+       iptables_chain_create "${protocol}" -t nat "${chain_prefix}"
+       iptables "${protocol}" -t nat -A PREROUTING  -i "${zone}" -j "${chain_prefix}"
+       iptables "${protocol}" -t nat -A POSTROUTING -o "${zone}" -j "${chain_prefix}"
 
        # Network Address Translation
-       iptables_chain_create -4 -t nat "${chain_prefix}_DNAT"
-       iptables -4 -t nat -A PREROUTING  -i ${zone} -j "${chain_prefix}_DNAT"
-       iptables_chain_create -4 -t nat "${chain_prefix}_SNAT"
-       iptables -4 -t nat -A POSTROUTING -o ${zone} -j "${chain_prefix}_SNAT"
+       iptables_chain_create "${protocol}" -t nat "${chain_prefix}_DNAT"
+       iptables "${protocol}" -t nat -A PREROUTING  -i "${zone}" -j "${chain_prefix}_DNAT"
+       iptables_chain_create "${protocol}" -t nat "${chain_prefix}_SNAT"
+       iptables "${protocol}" -t nat -A POSTROUTING -o "${zone}" -j "${chain_prefix}_SNAT"
 
        # UPnP
-       iptables_chain_create -4 -t nat "${chain_prefix}_UPNP"
-       iptables -4 -t nat -A ${chain_prefix} -j "${chain_prefix}_UPNP"
+       iptables_chain_create "${protocol}" -t nat "${chain_prefix}_UPNP"
+       iptables "${protocol}" -t nat -A "${chain_prefix}" -j "${chain_prefix}_UPNP"
 
        return ${EXIT_OK}
 }