[package] firewall: relocate TCPMSS rules into mangle table, add code to selectively...
[openwrt/svn-archive/archive.git] / package / firewall / files / lib / core_init.sh
index 82939b941661c20e4d2b918771ab404e6970999c..e93de1613ff091f9236eecea61ad07b0016584bc 100644 (file)
@@ -1,9 +1,11 @@
-# Copyright (C) 2009-2010 OpenWrt.org
+# Copyright (C) 2009-2011 OpenWrt.org
 # Copyright (C) 2008 John Crispin <blogic@openwrt.org>
 
 FW_INITIALIZED=
 
 FW_ZONES=
+FW_ZONES4=
+FW_ZONES6=
 FW_CONNTRACK_ZONES=
 FW_NOTRACK_DISABLED=
 
@@ -16,6 +18,9 @@ FW_DEFAULT_INPUT_POLICY=REJECT
 FW_DEFAULT_OUTPUT_POLICY=REJECT
 FW_DEFAULT_FORWARD_POLICY=REJECT
 
+FW_DISABLE_IPV4=0
+FW_DISABLE_IPV6=0
+
 
 fw_load_defaults() {
        fw_config_get_section "$1" defaults { \
@@ -34,9 +39,10 @@ fw_load_defaults() {
                boolean accept_redirects 0 \
                boolean accept_source_route 0 \
                boolean custom_chains 1 \
+               boolean disable_ipv6 0 \
        } || return
        [ -n "$FW_DEFAULTS_APPLIED" ] && {
-               echo "Error: multiple defaults sections detected"
+               fw_log error "duplicate defaults section detected, skipping"
                return 1
        }
        FW_DEFAULTS_APPLIED=1
@@ -50,6 +56,8 @@ fw_load_defaults() {
        FW_ACCEPT_REDIRECTS=$defaults_accept_redirects
        FW_ACCEPT_SRC_ROUTE=$defaults_accept_source_route
 
+       FW_DISABLE_IPV6=$defaults_disable_ipv6
+
        fw_callback pre defaults
 
        # Seems like there are only one sysctl for both IP versions.
@@ -58,17 +66,17 @@ fw_load_defaults() {
        done
        fw_sysctl_interface all
 
+       fw add i f INPUT   ACCEPT { -m conntrack --ctstate RELATED,ESTABLISHED }
+       fw add i f OUTPUT  ACCEPT { -m conntrack --ctstate RELATED,ESTABLISHED }
+       fw add i f FORWARD ACCEPT { -m conntrack --ctstate RELATED,ESTABLISHED }
+
        [ $defaults_drop_invalid == 1 ] && {
-               fw add i f INPUT   DROP { -m state --state INVALID }
-               fw add i f OUTPUT  DROP { -m state --state INVALID }
-               fw add i f FORWARD DROP { -m state --state INVALID }
+               fw add i f INPUT   DROP { -m conntrack --ctstate INVALID }
+               fw add i f OUTPUT  DROP { -m conntrack --ctstate INVALID }
+               fw add i f FORWARD DROP { -m conntrack --ctstate INVALID }
                FW_NOTRACK_DISABLED=1
        }
 
-       fw add i f INPUT   ACCEPT { -m state --state RELATED,ESTABLISHED }
-       fw add i f OUTPUT  ACCEPT { -m state --state RELATED,ESTABLISHED }
-       fw add i f FORWARD ACCEPT { -m state --state RELATED,ESTABLISHED }
-
        fw add i f INPUT  ACCEPT { -i lo }
        fw add i f OUTPUT ACCEPT { -o lo }
 
@@ -76,13 +84,16 @@ fw_load_defaults() {
        [ $defaults_syn_flood == 1 ] && \
                defaults_synflood_protect=1
 
+       [ "${defaults_synflood_rate%/*}" == "$defaults_synflood_rate" ] && \
+               defaults_synflood_rate="$defaults_synflood_rate/second"
+
        [ $defaults_synflood_protect == 1 ] && {
                echo "Loading synflood protection"
                fw_callback pre synflood
                fw add i f syn_flood
                fw add i f syn_flood RETURN { \
                        -p tcp --syn \
-                       -m limit --limit "${defaults_synflood_rate}/second" --limit-burst "${defaults_synflood_burst}" \
+                       -m limit --limit "${defaults_synflood_rate}" --limit-burst "${defaults_synflood_burst}" \
                }
                fw add i f syn_flood DROP
                fw add i f INPUT syn_flood { -p tcp --syn }
@@ -96,7 +107,7 @@ fw_load_defaults() {
                fw add i f forwarding_rule
                fw add i n prerouting_rule
                fw add i n postrouting_rule
-                       
+
                fw add i f INPUT       input_rule
                fw add i f OUTPUT      output_rule
                fw add i f FORWARD     forwarding_rule
@@ -131,9 +142,14 @@ fw_config_get_zone() {
                string output "$FW_DEFAULT_OUTPUT_POLICY" \
                string forward "$FW_DEFAULT_FORWARD_POLICY" \
                boolean masq 0 \
+               string masq_src "" \
+               string masq_dest "" \
                boolean conntrack 0 \
                boolean mtu_fix 0 \
                boolean custom_chains "$FW_ADD_CUSTOM_CHAINS" \
+               boolean log 0 \
+               string log_limit 10 \
+               string family "" \
        } || return
        [ -n "$zone_name" ] || zone_name=$zone_NAME
        [ -n "$zone_network" ] || zone_network=$zone_name
@@ -143,68 +159,124 @@ fw_load_zone() {
        fw_config_get_zone "$1"
 
        list_contains FW_ZONES $zone_name && {
-               fw_die "zone ${zone_name}: duplicated zone"
+               fw_log error "zone ${zone_name}: duplicated zone, skipping"
+               return 0
        }
        append FW_ZONES $zone_name
 
        fw_callback pre zone
 
        [ $zone_conntrack = 1 -o $zone_masq = 1 ] && \
-               append FW_CONNTRACK_ZONES "$zone_NAME"
+               append FW_CONNTRACK_ZONES "$zone_name"
+
+       local mode
+       case "$zone_family" in
+               *4)
+                       mode=4
+                       append FW_ZONES4 $zone_name
+                       uci_set_state firewall core ${zone_name}_ipv4 1
+               ;;
+               *6)
+                       mode=6
+                       append FW_ZONES6 $zone_name
+                       uci_set_state firewall core ${zone_name}_ipv6 1
+               ;;
+               *)
+                       mode=i
+                       append FW_ZONES4 $zone_name
+                       append FW_ZONES6 $zone_name
+                       uci_set_state firewall core ${zone_name}_ipv4 1
+                       uci_set_state firewall core ${zone_name}_ipv6 1
+               ;;
+       esac
 
        local chain=zone_${zone_name}
 
-       fw add i f ${chain}_ACCEPT
-       fw add i f ${chain}_DROP
-       fw add i f ${chain}_REJECT
-       fw add i f ${chain}_MSSFIX
+       fw add $mode f ${chain}_ACCEPT
+       fw add $mode f ${chain}_DROP
+       fw add $mode f ${chain}_REJECT
 
        # TODO: Rename to ${chain}_input
-       fw add i f ${chain}
-       fw add i f ${chain} ${chain}_${zone_input} $
+       fw add $mode f ${chain}
+       fw add $mode f ${chain} ${chain}_${zone_input} $
 
-       fw add i f ${chain}_forward
-       fw add i f ${chain}_forward ${chain}_${zone_forward} $
+       fw add $mode f ${chain}_forward
+       fw add $mode f ${chain}_forward ${chain}_${zone_forward} $
 
        # TODO: add ${chain}_output
-       fw add i f output ${chain}_${zone_output} $
+       fw add $mode f output ${chain}_${zone_output} $
 
        # TODO: Rename to ${chain}_MASQUERADE
-       fw add i n ${chain}_nat
-       fw add i n ${chain}_prerouting
+       fw add $mode n ${chain}_nat
+       fw add $mode n ${chain}_prerouting
 
-       fw add i r ${chain}_notrack
-       [ $zone_masq == 1 ] && \
-               fw add i n POSTROUTING ${chain}_nat $
+       fw add $mode r ${chain}_notrack
 
-       [ $zone_mtu_fix == 1 ] && \
-               fw add i f FORWARD ${chain}_MSSFIX ^
+       [ $zone_mtu_fix == 1 ] && {
+               fw add $mode m ${chain}_MSSFIX
+               fw add $mode m FORWARD ${chain}_MSSFIX ^
+               uci_set_state firewall core ${zone_name}_tcpmss 1
+       }
 
        [ $zone_custom_chains == 1 ] && {
                [ $FW_ADD_CUSTOM_CHAINS == 1 ] || \
                        fw_die "zone ${zone_name}: custom_chains globally disabled"
 
-               fw add i f input_${zone_name}
-               fw add i f ${chain} input_${zone_name} ^
+               fw add $mode f input_${zone_name}
+               fw add $mode f ${chain} input_${zone_name} ^
 
-               fw add i f forwarding_${zone_name}
-               fw add i f ${chain}_forward forwarding_${zone_name} ^
+               fw add $mode f forwarding_${zone_name}
+               fw add $mode f ${chain}_forward forwarding_${zone_name} ^
 
-               fw add i n prerouting_${zone_name}
-               fw add i n ${chain}_prerouting prerouting_${zone_name} ^
+               fw add $mode n prerouting_${zone_name}
+               fw add $mode n ${chain}_prerouting prerouting_${zone_name} ^
        }
 
+       [ "$zone_log" == 1 ] && {
+               [ "${zone_log_limit%/*}" == "$zone_log_limit" ] && \
+                       zone_log_limit="$zone_log_limit/minute"
+
+               local t
+               for t in REJECT DROP; do
+                       fw add $mode f ${chain}_${t} LOG ^ \
+                               { -m limit --limit $zone_log_limit --log-prefix "$t($zone_name): " }
+               done
+
+               [ $zone_mtu_fix == 1 ] && \
+                       fw add $mode m ${chain}_MSSFIX LOG ^ \
+                               { -m limit --limit $zone_log_limit --log-prefix "MSSFIX($zone_name): " }
+       }
+
+       # NB: if MASQUERADING for IPv6 becomes available we'll need a family check here
+       if [ "$zone_masq" == 1 ]; then
+               local msrc mdst
+               for msrc in ${zone_masq_src:-0.0.0.0/0}; do
+                       case "$msrc" in
+                               *.*) fw_get_negation msrc '-s' "$msrc" ;;
+                               *)   fw_get_subnet4 msrc '-s' "$msrc" || break ;;
+                       esac
+
+                       for mdst in ${zone_masq_dest:-0.0.0.0/0}; do
+                               case "$mdst" in
+                                       *.*) fw_get_negation mdst '-d' "$mdst" ;;
+                                       *)   fw_get_subnet4 mdst '-d' "$mdst" || break ;;
+                               esac
+
+                               fw add $mode n ${chain}_nat MASQUERADE $ { $msrc $mdst }
+                       done
+               done
+       fi
+
        fw_callback post zone
 }
 
 fw_load_notrack_zone() {
-       list_contains FW_CONNTRACK_ZONES "$1" && return
-
        fw_config_get_zone "$1"
+       list_contains FW_CONNTRACK_ZONES "${zone_name}" && return
 
        fw_callback pre notrack
 
-       fw add i f zone_${zone_name}_notrack NOTRACK $
+       fw add i r zone_${zone_name}_notrack NOTRACK $
 
        fw_callback post notrack
 }
@@ -213,8 +285,10 @@ fw_load_notrack_zone() {
 fw_load_include() {
        local name="$1"
 
-       local path; config_get path ${name} path
-       [ -e $path ] && . $path
+       local path
+       config_get path ${name} path
+
+       [ -e $path ] && ( . $path )
 }