firewall: - replace uci firewall with a modular dual stack implementation developed by Malte S. Stretz - bump version to 2
SVN-Revision: 21286master
parent
085b2b9ad6
commit
c284cb51c0
@ -1,5 +0,0 @@ |
|||||||
. /lib/firewall/uci_firewall.sh |
|
||||||
unset ZONE |
|
||||||
config_get ifname $INTERFACE ifname |
|
||||||
[ "$ifname" == "lo" ] && exit 0 |
|
||||||
fw_event "$ACTION" "$INTERFACE" |
|
@ -0,0 +1,49 @@ |
|||||||
|
#!/bin/sh |
||||||
|
FW_LIBDIR=/lib/firewall |
||||||
|
|
||||||
|
. /etc/functions.sh |
||||||
|
. ${FW_LIBDIR}/fw.sh |
||||||
|
|
||||||
|
case "$(type fw)" in |
||||||
|
*function) ;; |
||||||
|
*) exit 255;; |
||||||
|
esac |
||||||
|
|
||||||
|
usage() { |
||||||
|
echo $0 "<command>" "<family>" "<table>" "<chain>" "<target>" "{" "<rules>" "}" |
||||||
|
exit 0 |
||||||
|
} |
||||||
|
|
||||||
|
cmd=$1 |
||||||
|
shift |
||||||
|
case "$cmd" in |
||||||
|
--help|help) usage ;; |
||||||
|
start|stop|reload|restart) |
||||||
|
. ${FW_LIBDIR}/core.sh |
||||||
|
fw_$cmd |
||||||
|
exit $? |
||||||
|
;; |
||||||
|
esac |
||||||
|
|
||||||
|
fam=$1 |
||||||
|
shift |
||||||
|
case "$fam" in |
||||||
|
ip) |
||||||
|
fam=i |
||||||
|
if [ $# -gt 2 ]; then |
||||||
|
for p in $(seq 2 $(($# - 1))); do |
||||||
|
if eval "[ \$$p == '}' ]"; then |
||||||
|
fam=I |
||||||
|
break |
||||||
|
fi |
||||||
|
done |
||||||
|
fi ;; |
||||||
|
ip4) fam=4 ;; |
||||||
|
ip6) fam=6 ;; |
||||||
|
arp) fam=a ;; |
||||||
|
eth) fam=e ;; |
||||||
|
-*) exec $0 $cmd ${fam##*-} "$@" ;; |
||||||
|
esac |
||||||
|
|
||||||
|
fw "$cmd" "$fam" "$@" |
||||||
|
exit $? |
@ -0,0 +1,19 @@ |
|||||||
|
#!/bin/sh |
||||||
|
# This script is executed as part of the hotplug event with |
||||||
|
# HOTPLUG_TYPE=iface, triggered by various scripts when an interface |
||||||
|
# is configured (ACTION=ifup) or deconfigured (ACTION=ifdown). The |
||||||
|
# interface is available as INTERFACE, the real device as DEVICE. |
||||||
|
. /etc/functions.sh |
||||||
|
|
||||||
|
[ "$DEVICE" == "lo" ] && exit 0 |
||||||
|
|
||||||
|
. /lib/firewall/core.sh |
||||||
|
fw_is_loaded || exit 0 |
||||||
|
fw_init |
||||||
|
|
||||||
|
case "$ACTION" in |
||||||
|
ifup) |
||||||
|
fw_configure_interface "$INTERFACE" add "$DEVICE" ;; |
||||||
|
ifdown) |
||||||
|
fw_configure_interface "$INTERFACE" del "$DEVICE" ;; |
||||||
|
esac |
@ -0,0 +1,97 @@ |
|||||||
|
# Copyright (C) 2009-2010 OpenWrt.org |
||||||
|
# Copyright (C) 2009 Malte S. Stretz <http://msquadrat.de> |
||||||
|
# |
||||||
|
# This is a temporary file, I hope to have some of this stuff merged into |
||||||
|
# /lib/functions.sh (without the fw_ prefix of course) one day. |
||||||
|
|
||||||
|
fw_config_append() { # <package> |
||||||
|
CONFIG_APPEND=1 config_load "$@" |
||||||
|
unset CONFIG_APPEND |
||||||
|
} |
||||||
|
|
||||||
|
fw_config_once() { # <function> <type> |
||||||
|
local func=$1 |
||||||
|
local type=$2 |
||||||
|
shift 2 |
||||||
|
|
||||||
|
local config=cfg00nil |
||||||
|
fw_config__once() { |
||||||
|
config=$1 |
||||||
|
} |
||||||
|
config_foreach fw_config__once "$type" |
||||||
|
|
||||||
|
$func $config "$@" |
||||||
|
} |
||||||
|
|
||||||
|
fw_config_get_section() { # <config> <prefix> <type> <name> <default> ... |
||||||
|
local config=$1 |
||||||
|
local prefix=$2 |
||||||
|
shift 2 |
||||||
|
|
||||||
|
[ -n "$config" ] || return 1 |
||||||
|
[ -n "$prefix" ] && { |
||||||
|
prefix="${prefix}_" |
||||||
|
export ${NO_EXPORT:+-n} -- "${prefix}NAME"="${config}" |
||||||
|
config_get "${prefix}TYPE" "$config" TYPE |
||||||
|
} |
||||||
|
|
||||||
|
[ "$1" == '{' ] && shift |
||||||
|
while [ $# -ge 3 ]; do |
||||||
|
local type=$1 |
||||||
|
local name=$2 |
||||||
|
local dflt=$3 |
||||||
|
shift 3 |
||||||
|
# TODO: Move handling of defaults to /lib/functions.sh |
||||||
|
# and get replace the case block with the following |
||||||
|
# two lines: |
||||||
|
# type=${type#string} |
||||||
|
# config_get${type:+_${type}} "${prefix}${name}" "$config" "$name" "$dflt" || return |
||||||
|
case "$type" in |
||||||
|
string) |
||||||
|
local tmp |
||||||
|
config_get tmp "$config" "$name" || return |
||||||
|
[ -z "$tmp" ] && tmp=$dflt |
||||||
|
export ${NO_EXPORT:+-n} -- "${prefix}${name}=${tmp}" |
||||||
|
continue |
||||||
|
;; |
||||||
|
boolean) |
||||||
|
type=bool |
||||||
|
;; |
||||||
|
esac; |
||||||
|
|
||||||
|
local cmd=${prefix}config_get_${type} |
||||||
|
type $cmd > /dev/null || { |
||||||
|
cmd=config_get_${type} |
||||||
|
} |
||||||
|
type $cmd > /dev/null || { |
||||||
|
echo "config type $type (for $name) not supported" >&2 |
||||||
|
return 1 |
||||||
|
} |
||||||
|
$cmd "${prefix}${name}" "$config" "$name" "$dflt" || return |
||||||
|
done |
||||||
|
} |
||||||
|
|
||||||
|
config_get_ipaddr() { |
||||||
|
local varn=$1 |
||||||
|
local conf=$2 |
||||||
|
local name=$3 |
||||||
|
local dflt=$4 |
||||||
|
|
||||||
|
local addr |
||||||
|
config_get addr "$conf" "$name" || return |
||||||
|
[ -n "$addr" ] || addr=$dflt |
||||||
|
|
||||||
|
local mask=${addr#*/} |
||||||
|
[ "$mask" != "$addr" ] || mask= |
||||||
|
addr=${addr%/*} |
||||||
|
|
||||||
|
local vers= |
||||||
|
case "$addr" in |
||||||
|
*.*) vers=4 ;; |
||||||
|
*:*) vers=6 ;; |
||||||
|
esac |
||||||
|
|
||||||
|
export ${NO_EXPORT:+-n} -- "${varn}=${addr}" |
||||||
|
export ${NO_EXPORT:+-n} -- "${varn}_prefixlen=${mask}" |
||||||
|
export ${NO_EXPORT:+-n} -- "${varn}_version=${vers}" |
||||||
|
} |
@ -0,0 +1,136 @@ |
|||||||
|
# Copyright (C) 2009-2010 OpenWrt.org |
||||||
|
|
||||||
|
FW_LIBDIR=${FW_LIBDIR:-/lib/firewall} |
||||||
|
|
||||||
|
. $FW_LIBDIR/fw.sh |
||||||
|
include /lib/network |
||||||
|
|
||||||
|
fw_start() { |
||||||
|
fw_init |
||||||
|
|
||||||
|
FW_DEFAULTS_APPLIED= |
||||||
|
|
||||||
|
fw_is_loaded && { |
||||||
|
echo "firewall already loaded" >&2 |
||||||
|
exit 1 |
||||||
|
} |
||||||
|
uci_set_state firewall core "" firewall_state |
||||||
|
|
||||||
|
fw_clear DROP |
||||||
|
|
||||||
|
fw_callback pre core |
||||||
|
|
||||||
|
echo "Loading defaults" |
||||||
|
fw_config_once fw_load_defaults defaults |
||||||
|
|
||||||
|
echo "Loading zones" |
||||||
|
config_foreach fw_load_zone zone |
||||||
|
|
||||||
|
echo "Loading forwardings" |
||||||
|
config_foreach fw_load_forwarding forwarding |
||||||
|
|
||||||
|
echo "Loading redirects" |
||||||
|
config_foreach fw_load_redirect redirect |
||||||
|
|
||||||
|
echo "Loading rules" |
||||||
|
config_foreach fw_load_rule rule |
||||||
|
|
||||||
|
echo "Loading includes" |
||||||
|
config_foreach fw_load_include include |
||||||
|
|
||||||
|
[ -n "$FW_NOTRACK_DISABLED" ] && { |
||||||
|
echo "Optimizing conntrack" |
||||||
|
config_foreach fw_load_notrack_zone zone |
||||||
|
} |
||||||
|
|
||||||
|
echo "Loading interfaces" |
||||||
|
config_foreach fw_configure_interface interface add |
||||||
|
|
||||||
|
fw_callback post core |
||||||
|
|
||||||
|
uci_set_state firewall core loaded 1 |
||||||
|
} |
||||||
|
|
||||||
|
fw_stop() { |
||||||
|
fw_init |
||||||
|
|
||||||
|
fw_callback pre stop |
||||||
|
|
||||||
|
fw_clear ACCEPT |
||||||
|
|
||||||
|
fw_callback post stop |
||||||
|
|
||||||
|
uci_revert_state firewall |
||||||
|
config_clear |
||||||
|
unset FW_INITIALIZED |
||||||
|
} |
||||||
|
|
||||||
|
fw_restart() { |
||||||
|
fw_stop |
||||||
|
fw_start |
||||||
|
} |
||||||
|
|
||||||
|
fw_reload() { |
||||||
|
fw_restart |
||||||
|
} |
||||||
|
|
||||||
|
fw_is_loaded() { |
||||||
|
local bool |
||||||
|
config_get_bool bool core loaded 0 |
||||||
|
return $((! $bool)) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
fw_die() { |
||||||
|
echo "Error:" "$@" >&2 |
||||||
|
fw_log error "$@" |
||||||
|
fw_stop |
||||||
|
exit 1 |
||||||
|
} |
||||||
|
|
||||||
|
fw_log() { |
||||||
|
local level="$1" |
||||||
|
[ -n "$2" ] || { |
||||||
|
shift |
||||||
|
level=notice |
||||||
|
} |
||||||
|
logger -t firewall -p user.$level "$@" |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
fw_init() { |
||||||
|
[ -z "$FW_INITIALIZED" ] || return 0 |
||||||
|
|
||||||
|
. $FW_LIBDIR/config.sh |
||||||
|
|
||||||
|
scan_interfaces |
||||||
|
fw_config_append firewall |
||||||
|
|
||||||
|
local hooks="core stop defaults zone notrack synflood" |
||||||
|
local file lib hk pp |
||||||
|
for file in $FW_LIBDIR/core_*.sh; do |
||||||
|
. $file |
||||||
|
hk=$(basename $file .sh) |
||||||
|
hk=${hk#core_} |
||||||
|
append hooks $hk |
||||||
|
done |
||||||
|
for file in $FW_LIBDIR/*.sh; do |
||||||
|
lib=$(basename $file .sh) |
||||||
|
lib=${lib##[0-9][0-9]_} |
||||||
|
case $lib in |
||||||
|
core*|fw|config|uci_firewall) continue ;; |
||||||
|
esac |
||||||
|
. $file |
||||||
|
for hk in $hooks; do |
||||||
|
for pp in pre post; do |
||||||
|
type ${lib}_${pp}_${hk}_cb >/dev/null && |
||||||
|
append FW_CB_${pp}_${hk} ${lib} |
||||||
|
done |
||||||
|
done |
||||||
|
done |
||||||
|
|
||||||
|
fw_callback post init |
||||||
|
|
||||||
|
FW_INITIALIZED=1 |
||||||
|
return 0 |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
# Copyright (C) 2009-2010 OpenWrt.org |
||||||
|
|
||||||
|
fw_config_get_forwarding() { |
||||||
|
[ "${forwarding_NAME}" != "$1" ] || return |
||||||
|
fw_config_get_section "$1" forwarding { \ |
||||||
|
string _name "$1" \ |
||||||
|
string name "" \ |
||||||
|
string src "" \ |
||||||
|
string dest "" \ |
||||||
|
} || return |
||||||
|
[ -n "$forwarding_name" ] || forwarding_name=$forwarding__name |
||||||
|
} |
||||||
|
|
||||||
|
fw_load_forwarding() { |
||||||
|
fw_config_get_forwarding "$1" |
||||||
|
|
||||||
|
fw_callback pre forwarding |
||||||
|
|
||||||
|
local chain=forward |
||||||
|
[ -n "$forwarding_src" ] && { |
||||||
|
chain=zone_${forwarding_src}_forward |
||||||
|
} |
||||||
|
|
||||||
|
local target=ACCEPT |
||||||
|
[ -n "$forwarding_dest" ] && { |
||||||
|
target=zone_${forwarding_dest}_ACCEPT |
||||||
|
} |
||||||
|
|
||||||
|
fw add i f $chain $target ^ |
||||||
|
|
||||||
|
# propagate masq zone flag |
||||||
|
[ -n "$forwarding_src" ] && list_contains CONNTRACK_ZONES $forwarding_src && { |
||||||
|
append CONNTRACK_ZONES $forwarding_dest |
||||||
|
} |
||||||
|
[ -n "$forwarding_dest" ] && list_contains CONNTRACK_ZONES $forwarding_dest && { |
||||||
|
append CONNTRACK_ZONES $forwarding_src |
||||||
|
} |
||||||
|
|
||||||
|
fw_callback post forwarding |
||||||
|
} |
@ -0,0 +1,258 @@ |
|||||||
|
# Copyright (C) 2009-2010 OpenWrt.org |
||||||
|
# Copyright (C) 2008 John Crispin <blogic@openwrt.org> |
||||||
|
|
||||||
|
FW_INITIALIZED= |
||||||
|
|
||||||
|
FW_ZONES= |
||||||
|
FW_CONNTRACK_ZONES= |
||||||
|
FW_NOTRACK_DISABLED= |
||||||
|
|
||||||
|
FW_DEFAULTS_APPLIED= |
||||||
|
FW_ADD_CUSTOM_CHAINS= |
||||||
|
FW_ACCEPT_REDIRECTS= |
||||||
|
FW_ACCEPT_SRC_ROUTE= |
||||||
|
|
||||||
|
FW_DEFAULT_INPUT_POLICY=REJECT |
||||||
|
FW_DEFAULT_OUTPUT_POLICY=REJECT |
||||||
|
FW_DEFAULT_FORWARD_POLICY=REJECT |
||||||
|
|
||||||
|
|
||||||
|
fw_load_defaults() { |
||||||
|
fw_config_get_section "$1" defaults { \ |
||||||
|
string input $FW_DEFAULT_INPUT_POLICY \ |
||||||
|
string output $FW_DEFAULT_OUTPUT_POLICY \ |
||||||
|
string forward $FW_DEFAULT_FORWARD_POLICY \ |
||||||
|
boolean drop_invalid 0 \ |
||||||
|
boolean syn_flood 0 \ |
||||||
|
boolean synflood_protect 0 \ |
||||||
|
string synflood_rate 25 \ |
||||||
|
string synflood_burst 50 \ |
||||||
|
boolean tcp_syncookies 1 \ |
||||||
|
boolean tcp_ecn 0 \ |
||||||
|
boolean tcp_westwood 0 \ |
||||||
|
boolean tcp_window_scaling 1 \ |
||||||
|
boolean accept_redirects 0 \ |
||||||
|
boolean accept_source_route 0 \ |
||||||
|
boolean custom_chains 1 \ |
||||||
|
} || return |
||||||
|
[ -n "$FW_DEFAULTS_APPLIED" ] && { |
||||||
|
echo "Error: multiple defaults sections detected" |
||||||
|
return 1 |
||||||
|
} |
||||||
|
FW_DEFAULTS_APPLIED=1 |
||||||
|
|
||||||
|
FW_DEFAULT_INPUT_POLICY=$defaults_input |
||||||
|
FW_DEFAULT_OUTPUT_POLICY=$defaults_output |
||||||
|
FW_DEFAULT_FORWARD_POLICY=$defaults_forward |
||||||
|
|
||||||
|
FW_ADD_CUSTOM_CHAINS=$defaults_custom_chains |
||||||
|
|
||||||
|
FW_ACCEPT_REDIRECTS=$defaults_accept_redirects |
||||||
|
FW_ACCEPT_SRC_ROUTE=$defaults_accept_source_route |
||||||
|
|
||||||
|
fw_callback pre defaults |
||||||
|
|
||||||
|
# Seems like there are only one sysctl for both IP versions. |
||||||
|
for s in syncookies ecn westwood window_scaling; do |
||||||
|
eval "sysctl -e -w net.ipv4.tcp_${s}=\$defaults_tcp_${s}" >/dev/null |
||||||
|
done |
||||||
|
fw_sysctl_interface all |
||||||
|
|
||||||
|
[ $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_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 } |
||||||
|
|
||||||
|
# Compatibility to old 'syn_flood' parameter |
||||||
|
[ $defaults_syn_flood == 1 ] && \ |
||||||
|
defaults_synflood_protect=1 |
||||||
|
|
||||||
|
[ $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}" \ |
||||||
|
} |
||||||
|
fw add i f syn_flood DROP |
||||||
|
fw add i f INPUT syn_flood { -p tcp --syn } |
||||||
|
fw_callback post synflood |
||||||
|
} |
||||||
|
|
||||||
|
[ $defaults_custom_chains == 1 ] && { |
||||||
|
echo "Adding custom chains" |
||||||
|
fw add i f input_rule |
||||||
|
fw add i f output_rule |
||||||
|
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 |
||||||
|
fw add i n PREROUTING prerouting_rule |
||||||
|
fw add i n POSTROUTING postrouting_rule |
||||||
|
} |
||||||
|
|
||||||
|
fw add i f input |
||||||
|
fw add i f output |
||||||
|
fw add i f forward |
||||||
|
|
||||||
|
fw add i f INPUT input |
||||||
|
fw add i f OUTPUT output |
||||||
|
fw add i f FORWARD forward |
||||||
|
|
||||||
|
fw add i f reject |
||||||
|
fw add i f reject REJECT { --reject-with tcp-reset -p tcp } |
||||||
|
fw add i f reject REJECT { --reject-with port-unreach } |
||||||
|
|
||||||
|
fw_set_filter_policy |
||||||
|
|
||||||
|
fw_callback post defaults |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
fw_config_get_zone() { |
||||||
|
[ "${zone_NAME}" != "$1" ] || return |
||||||
|
fw_config_get_section "$1" zone { \ |
||||||
|
string name "$1" \ |
||||||
|
string network "" \ |
||||||
|
string input "$FW_DEFAULT_INPUT_POLICY" \ |
||||||
|
string output "$FW_DEFAULT_OUTPUT_POLICY" \ |
||||||
|
string forward "$FW_DEFAULT_FORWARD_POLICY" \ |
||||||
|
boolean masq 0 \ |
||||||
|
boolean conntrack 0 \ |
||||||
|
boolean mtu_fix 0 \ |
||||||
|
boolean custom_chains "$FW_ADD_CUSTOM_CHAINS" \ |
||||||
|
} || return |
||||||
|
[ -n "$zone_name" ] || zone_name=$zone_NAME |
||||||
|
[ -n "$zone_network" ] || zone_network=$zone_name |
||||||
|
} |
||||||
|
|
||||||
|
fw_load_zone() { |
||||||
|
fw_config_get_zone "$1" |
||||||
|
|
||||||
|
list_contains FW_ZONES $zone_name && { |
||||||
|
fw_die "zone ${zone_name}: duplicated zone" |
||||||
|
} |
||||||
|
append FW_ZONES $zone_name |
||||||
|
|
||||||
|
fw_callback pre zone |
||||||
|
|
||||||
|
[ $zone_conntrack = 1 -o $zone_masq = 1 ] && \ |
||||||
|
append FW_CONNTRACK_ZONES "$zone_NAME" |
||||||
|
|
||||||
|
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 |
||||||
|
|
||||||
|
# TODO: Rename to ${chain}_input |
||||||
|
fw add i f ${chain} |
||||||
|
fw add i f ${chain} ${chain}_${zone_input} $ |
||||||
|
|
||||||
|
fw add i f ${chain}_forward |
||||||
|
fw add i f ${chain}_forward ${chain}_${zone_forward} $ |
||||||
|
|
||||||
|
# TODO: add ${chain}_output |
||||||
|
fw add i f output ${chain}_${zone_output} $ |
||||||
|
|
||||||
|
# TODO: Rename to ${chain}_MASQUERADE |
||||||
|
fw add i n ${chain}_nat |
||||||
|
fw add i n ${chain}_prerouting |
||||||
|
|
||||||
|
fw add i r ${chain}_notrack |
||||||
|
[ $zone_masq == 1 ] && \ |
||||||
|
fw add i n POSTROUTING ${chain}_nat $ |
||||||
|
|
||||||
|
[ $zone_mtu_fix == 1 ] && \ |
||||||
|
fw add i f FORWARD ${chain}_MSSFIX ^ |
||||||
|
|
||||||
|
[ $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 i f forwarding_${zone_name} |
||||||
|
fw add i f ${chain}_forward forwarding_${zone_name} ^ |
||||||
|
|
||||||
|
fw add i n prerouting_${zone_name} |
||||||
|
fw add i n ${chain}_prerouting prerouting_${zone_name} ^ |
||||||
|
} |
||||||
|
|
||||||
|
fw_callback post zone |
||||||
|
} |
||||||
|
|
||||||
|
fw_load_notrack_zone() { |
||||||
|
list_contains FW_CONNTRACK_ZONES "$1" && return |
||||||
|
|
||||||
|
fw_config_get_zone "$1" |
||||||
|
|
||||||
|
fw_callback pre notrack |
||||||
|
|
||||||
|
fw add i f zone_${zone_name}_notrack NOTRACK $ |
||||||
|
|
||||||
|
fw_callback post notrack |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
fw_load_include() { |
||||||
|
local name="$1" |
||||||
|
|
||||||
|
local path; config_get path ${name} path |
||||||
|
[ -e $path ] && . $path |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
fw_clear() { |
||||||
|
local policy=$1 |
||||||
|
|
||||||
|
fw_set_filter_policy $policy |
||||||
|
|
||||||
|
local tab |
||||||
|
for tab in f n r; do |
||||||
|
fw del i $tab |
||||||
|
done |
||||||
|
} |
||||||
|
|
||||||
|
fw_set_filter_policy() { |
||||||
|
local policy=$1 |
||||||
|
|
||||||
|
local chn tgt |
||||||
|
for chn in INPUT OUTPUT FORWARD; do |
||||||
|
eval "tgt=\${policy:-\${FW_DEFAULT_${chn}_POLICY}}" |
||||||
|
[ $tgt == "REJECT" ] && tgt=reject |
||||||
|
[ $tgt == "ACCEPT" -o $tgt == "DROP" ] || { |
||||||
|
fw add i f $chn $tgt $ |
||||||
|
tgt=DROP |
||||||
|
} |
||||||
|
fw policy i f $chn $tgt |
||||||
|
done |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
fw_callback() { |
||||||
|
local pp=$1 |
||||||
|
local hk=$2 |
||||||
|
|
||||||
|
local libs lib |
||||||
|
eval "libs=\$FW_CB_${pp}_${hk}" |
||||||
|
[ -n "$libs" ] || return |
||||||
|
for lib in $libs; do |
||||||
|
${lib}_${pp}_${hk}_cb |
||||||
|
done |
||||||
|
} |
@ -0,0 +1,86 @@ |
|||||||
|
# Copyright (C) 2009-2010 OpenWrt.org |
||||||
|
|
||||||
|
fw_configure_interface() { |
||||||
|
local iface=$1 |
||||||
|
local action=$2 |
||||||
|
local ifname=$3 |
||||||
|
|
||||||
|
local status; |
||||||
|
config_get_bool status "$iface" up "0" |
||||||
|
[ "$status" == 1 ] || return 0 |
||||||
|
|
||||||
|
[ -n "$ifname" ] || { |
||||||
|
config_get ifname "$iface" ifname |
||||||
|
ifname=${ifname:-$iface} |
||||||
|
} |
||||||
|
[ "$ifname" == "lo" ] && return 0 |
||||||
|
|
||||||
|
fw_callback pre interface |
||||||
|
|
||||||
|
fw__do_rules() { |
||||||
|
local action=$1 |
||||||
|
local chain=$2 |
||||||
|
local ifname=$3 |
||||||
|
|
||||||
|
fw $action i f ${chain}_ACCEPT ACCEPT ^ { -o "$ifname" } |
||||||
|
fw $action i f ${chain}_ACCEPT ACCEPT ^ { -i "$ifname" } |
||||||
|
fw $action i f ${chain}_DROP DROP ^ { -o "$ifname" } |
||||||
|
fw $action i f ${chain}_DROP DROP ^ { -i "$ifname" } |
||||||
|
fw $action i f ${chain}_REJECT reject ^ { -o "$ifname" } |
||||||
|
fw $action i f ${chain}_REJECT reject ^ { -i "$ifname" } |
||||||
|
|
||||||
|
fw $action i n ${chain}_nat MASQUERADE ^ { -o "$ifname" } |
||||||
|
fw $action i f ${chain}_MSSFIX TCPMSS ^ { -o "$ifname" -p tcp --tcp-flags SYN,RST SYN --clamp-mss-to-pmtu } |
||||||
|
|
||||||
|
fw $action i f input ${chain} $ { -i "$ifname" } |
||||||
|
fw $action i f forward ${chain}_forward $ { -i "$ifname" } |
||||||
|
fw $action i n PREROUTING ${chain}_prerouting ^ { -i "$ifname" } |
||||||
|
fw $action i r PREROUTING ${chain}_notrack ^ { -i "$ifname" } |
||||||
|
} |
||||||
|
|
||||||
|
local old_zones old_ifname |
||||||
|
config_get old_zones core "${iface}_zone" |
||||||
|
[ -n "$old_zones" ] && { |
||||||
|
config_get old_ifname core "${iface}_ifname" |
||||||
|
for z in $old_zones; do |
||||||
|
fw_log info "removing $iface ($old_ifname) from zone $z" |
||||||
|
fw__do_rules del zone_$z $old_ifname |
||||||
|
|
||||||
|
ACTION=remove ZONE="$z" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall |
||||||
|
done |
||||||
|
uci_revert_state firewall core "${iface}_zone" |
||||||
|
uci_revert_state firewall core "${iface}_ifname" |
||||||
|
} |
||||||
|
[ "$action" == del ] && return |
||||||
|
|
||||||
|
local new_zones |
||||||
|
load_zone() { |
||||||
|
fw_config_get_zone "$1" |
||||||
|
list_contains zone_network "$iface" || return |
||||||
|
|
||||||
|
fw_log info "adding $iface ($ifname) to zone $zone_name" |
||||||
|
fw__do_rules add zone_${zone_name} "$ifname" |
||||||
|
append new_zones $zone_name |
||||||
|
|
||||||
|
ACTION=add ZONE="$zone_name" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall |
||||||
|
} |
||||||
|
config_foreach load_zone zone |
||||||
|
|
||||||
|
uci_set_state firewall core "${iface}_zone" "$new_zones" |
||||||
|
uci_set_state firewall core "${iface}_ifname" "$ifname" |
||||||
|
|
||||||
|
fw_sysctl_interface $ifname |
||||||
|
|
||||||
|
fw_callback post interface |
||||||
|
} |
||||||
|
|
||||||
|
fw_sysctl_interface() { |
||||||
|
local ifname=$1 |
||||||
|
{ |
||||||
|
sysctl -w net.ipv4.conf.${ifname}.accept_redirects=$FW_ACCEPT_REDIRECTS |
||||||
|
sysctl -w net.ipv6.conf.${ifname}.accept_redirects=$FW_ACCEPT_REDIRECTS |
||||||
|
sysctl -w net.ipv4.conf.${ifname}.accept_source_route=$FW_ACCEPT_SRC_ROUTE |
||||||
|
sysctl -w net.ipv6.conf.${ifname}.accept_source_route=$FW_ACCEPT_SRC_ROUTE |
||||||
|
} >/dev/null 2>/dev/null |
||||||
|
} |
||||||
|
|
@ -0,0 +1,61 @@ |
|||||||
|
# Copyright (C) 2009-2010 OpenWrt.org |
||||||
|
|
||||||
|
fw_config_get_redirect() { |
||||||
|
[ "${redirect_NAME}" != "$1" ] || return |
||||||
|
fw_config_get_section "$1" redirect { \ |
||||||
|
string _name "$1" \ |
||||||
|
string name "" \ |
||||||
|
string src "" \ |
||||||
|
ipaddr src_ip "" \ |
||||||
|
ipaddr src_dip "" \ |
||||||
|
string src_mac "" \ |
||||||
|
string src_port "" \ |
||||||
|
string src_dport "" \ |
||||||
|
string dest "" \ |
||||||
|
ipaddr dest_ip "" \ |
||||||
|
string dest_mac "" \ |
||||||
|
string dest_port "" \ |
||||||
|
string proto "tcpudp" \ |
||||||
|
} || return |
||||||
|
[ -n "$redirect_name" ] || redirect_name=$redirect__name |
||||||
|
} |
||||||
|
|
||||||
|
fw_load_redirect() { |
||||||
|
fw_config_get_redirect "$1" |
||||||
|
|
||||||
|
fw_callback pre redirect |
||||||
|
|
||||||
|
[ -n "$redirect_src" -a -n "$redirect_dest_ip" ] || { |
||||||
|
fw_die "redirect ${redirect_name}: needs src and dest_ip" |
||||||
|
} |
||||||
|
|
||||||
|
local nat_dest_port=$redirect_dest_port |
||||||
|
redirect_dest_port=$(fw_get_port_range $redirect_dest_port) |
||||||
|
redirect_src_port=$(fw_get_port_range $redirect_src_port) |
||||||
|
redirect_src_dport=$(fw_get_port_range $redirect_src_dport) |
||||||
|
local fwd_dest_port=${redirect_dest_port:-$redirect_src_dport} |
||||||
|
|
||||||
|
[ "$redirect_proto" == "tcpudp" ] && redirect_proto="tcp udp" |
||||||
|
for redirect_proto in $redirect_proto; do |
||||||
|
fw add I n zone_${redirect_src}_prerouting DNAT $ { $redirect_src_ip $redirect_dest_ip } { \ |
||||||
|
${redirect_proto:+-p $redirect_proto} \ |
||||||
|
${redirect_src_ip:+-s $redirect_src_ip} \ |
||||||
|
${redirect_src_dip:+-d $redirect_src_dip} \ |
||||||
|
${redirect_src_port:+--sport $redirect_src_port} \ |
||||||
|
${redirect_src_dport:+--dport $redirect_src_dport} \ |
||||||
|
${redirect_src_mac:+-m mac --mac-source $redirect_src_mac} \ |
||||||
|
--to-destination ${redirect_dest_ip}${redirect_dest_port:+:$nat_dest_port} \ |
||||||
|
} |
||||||
|
|
||||||
|
fw add I f zone_${redirect_src}_forward ACCEPT ^ { $redirect_src_ip $redirect_dest_ip } { \ |
||||||
|
-d $redirect_dest_ip \ |
||||||
|
${redirect_proto:+-p $redirect_proto} \ |
||||||
|
${redirect_src_ip:+-s $redirect_src_ip} \ |
||||||
|
${redirect_src_port:+--sport $redirect_src_port} \ |
||||||
|
${fwd_dest_port:+--dport $fwd_dest_port} \ |
||||||
|
${redirect_src_mac:+-m mac --mac-source $redirect_src_mac} \ |
||||||
|
} |
||||||
|
done |
||||||
|
|
||||||
|
fw_callback post redirect |
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
# Copyright (C) 2009-2010 OpenWrt.org |
||||||
|
|
||||||
|
fw_config_get_rule() { |
||||||
|
[ "${rule_NAME}" != "$1" ] || return |
||||||
|
fw_config_get_section "$1" rule { \ |
||||||
|
string _name "$1" \ |
||||||
|
string name "" \ |
||||||
|
string src "" \ |
||||||
|
ipaddr src_ip "" \ |
||||||
|
string src_mac "" \ |
||||||
|
string src_port "" \ |
||||||
|
string dest "" \ |
||||||
|
ipaddr dest_ip "" \ |
||||||
|
string dest_mac "" \ |
||||||
|
string dest_port "" \ |
||||||
|
string icmp_type "" \ |
||||||
|
string proto "tcpudp" \ |
||||||
|
string target "" \ |
||||||
|
} || return |
||||||
|
[ -n "$rule_name" ] || rule_name=$rule__name |
||||||
|
[ "$rule_proto" == "icmp" ] || rule_icmp_type= |
||||||
|
} |
||||||
|
|
||||||
|
fw_load_rule() { |
||||||
|
fw_config_get_rule "$1" |
||||||
|
|
||||||
|
fw_callback pre rule |
||||||
|
|
||||||
|
rule_src_port=$(fw_get_port_range $rule_src_port) |
||||||
|
rule_dest_port=$(fw_get_port_range $rule_dest_port) |
||||||
|
|
||||||
|
local chain=input |
||||||
|
[ -n "$rule_src" ] && { |
||||||
|
[ -z "$rule_dest" ] && { |
||||||
|
chain=zone_${rule_src} |
||||||
|
} || { |
||||||
|
chain=zone_${rule_src}_forward |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
local target=$rule_target |
||||||
|
[ -z "$target" ] && { |
||||||
|
target=REJECT |
||||||
|
} |
||||||
|
[ -n "$dest" ] && { |
||||||
|
target=zone_${rule_dest}_${target} |
||||||
|
} |
||||||
|
|
||||||
|
local rule_pos |
||||||
|
eval 'rule_pos=$((++FW__RULE_COUNT_'$chain'))' |
||||||
|
|
||||||
|
[ "$rule_proto" == "tcpudp" ] && rule_proto="tcp udp" |
||||||
|
for rule_proto in $rule_proto; do |
||||||
|
fw add I f $chain $target $rule_pos { $rule_src_ip $rule_dest_ip } { \ |
||||||
|
${rule_proto:+-p $rule_proto} \ |
||||||
|
${rule_src_ip:+-s $rule_src_ip} \ |
||||||
|
${rule_src_port:+--sport $rule_src_port} \ |
||||||
|
${rule_src_mac:+-m mac --mac-source $rule_src_mac} \ |
||||||
|
${rule_dest_ip:+-d $rule_dest_ip} \ |
||||||
|
${rule_dest_port:+--dport $rule_dest_port} \ |
||||||
|
${rule_icmp_type:+--icmp-type $rule_icmp_type} \ |
||||||
|
} |
||||||
|
done |
||||||
|
|
||||||
|
fw_callback post rule |
||||||
|
} |
@ -0,0 +1,182 @@ |
|||||||
|
# Copyright (C) 2009-2010 OpenWrt.org |
||||||
|
# Copyright (C) 2009 Malte S. Stretz |
||||||
|
|
||||||
|
export FW_4_ERROR=0 |
||||||
|
export FW_6_ERROR=0 |
||||||
|
export FW_i_ERROR=0 |
||||||
|
export FW_e_ERROR=0 |
||||||
|
export FW_a_ERROR=0 |
||||||
|
|
||||||
|
#TODO: remove this |
||||||
|
[ "${-#*x}" == "$-" ] && { |
||||||
|
fw() { |
||||||
|
fw__exec "$@" |
||||||
|
} |
||||||
|
} || { |
||||||
|
fw() { |
||||||
|
local os=$- |
||||||
|
set +x |
||||||
|
fw__exec "$@" |
||||||
|
local rc=$? |
||||||
|
set -$os |
||||||
|
return $rc |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fw__exec() { # <action> <family> <table> <chain> <target> <position> { <rules> } |
||||||
|
local cmd fam tab chn tgt pos |
||||||
|
local i |
||||||
|
for i in cmd fam tab chn tgt pos; do |
||||||
|
if [ "$1" -a "$1" != '{' ]; then |
||||||
|
eval "$i='$1'" |
||||||
|
shift |
||||||
|
else |
||||||
|
eval "$i=-" |
||||||
|
fi |
||||||
|
done |
||||||
|
|
||||||
|
fw__rc() { |
||||||
|
export FW_${fam}_ERROR=$1 |
||||||
|
return $1 |
||||||
|
} |
||||||
|
|
||||||
|
fw__dualip() { |
||||||
|
fw $cmd 4 $tab $chn $tgt $pos "$@" |
||||||
|
fw $cmd 6 $tab $chn $tgt $pos "$@" |
||||||
|
fw__rc $((FW_4_ERROR | FW_6_ERROR)) |
||||||
|
} |
||||||
|
|
||||||
|
fw__autoip() { |
||||||
|
local ip4 ip6 |
||||||
|
shift |
||||||
|
while [ "$1" != '}' ]; do |
||||||
|
case "$1" in |
||||||
|
*.*.*.*) ip4=1 ;; |
||||||
|
*:*) ip6=1 ;; |
||||||
|
esac |
||||||
|
shift |
||||||
|
done |
||||||
|
shift |
||||||
|
if [ "${ip4:-4}" == "${ip6:-6}" ]; then |
||||||
|
echo "fw: can't mix ip4 and ip6" >&2 |
||||||
|
return 1 |
||||||
|
fi |
||||||
|
local ver=${ip4:+4}${ip6:+6} |
||||||
|
fam=i |
||||||
|
fw $cmd ${ver:-i} $tab $chn $tgt $pos "$@" |
||||||
|
fw__rc $? |
||||||
|
} |
||||||
|
|
||||||
|
fw__has() { |
||||||
|
local tab=${1:-$tab} |
||||||
|
if [ $tab == '-' ]; then |
||||||
|
type $app > /dev/null 2> /dev/null |
||||||
|
fw__rc $(($? & 1)) |
||||||
|
return |
||||||
|
fi |
||||||
|
local mod |
||||||
|
eval "mod=\$FW_${fam}_${tab}" |
||||||
|
if [ "$mod" ]; then |
||||||
|
fw__rc $mod |
||||||
|
return |
||||||
|
fi |
||||||
|
case "$fam" in |
||||||
|
4) mod=iptable_${tab} ;; |
||||||
|
6) mod=ip6table_${tab} ;; |
||||||
|
*) mod=. ;; |
||||||
|
esac |
||||||
|
grep "^${mod} " /proc/modules > /dev/null |
||||||
|
mod=$? |
||||||
|
export FW_${fam}_${tab}=$mod |
||||||
|
fw__rc $mod |
||||||
|
} |
||||||
|
|
||||||
|
fw__err() { |
||||||
|
local err |
||||||
|
eval "err=\$FW_${fam}_ERROR" |
||||||
|
fw__rc $err |
||||||
|
} |
||||||
|
|
||||||
|
local app= |
||||||
|
local pol= |
||||||
|
case "$fam" in |
||||||
|
4) app=iptables ;; |
||||||
|
6) app=ip6tables ;; |
||||||
|
i) fw__dualip "$@"; return ;; |
||||||
|
I) fw__autoip "$@"; return ;; |
||||||
|
e) app=ebtables ;; |
||||||
|
a) app=arptables ;; |
||||||
|
-) fw $cmd i $tab $chn $tgt $pos "$@"; return ;; |
||||||
|
*) return 254 ;; |
||||||
|
esac |
||||||
|
case "$tab" in |
||||||
|
f) tab=filter ;; |
||||||
|
m) tab=mangle ;; |
||||||
|
n) tab=nat ;; |
||||||
|
r) tab=raw ;; |
||||||
|
-) tab=filter ;; |
||||||
|
esac |
||||||
|
case "$cmd:$chn:$tgt:$pos" in |
||||||
|
add:*:-:*) cmd=new-chain ;; |
||||||
|
add:*:*:-) cmd=append ;; |
||||||
|
add:*:*:$) cmd=append ;; |
||||||
|
add:*:*:*) cmd=insert ;; |
||||||
|
del:-:*:*) cmd=delete-chain; fw flush $fam $tab ;; |
||||||
|
del:*:-:*) cmd=delete-chain; fw flush $fam $tab $chn ;; |
||||||
|
del:*:*:*) cmd=delete ;; |
||||||
|
flush:*) ;; |
||||||
|
policy:*) pol=$tgt; tgt=- ;; |
||||||
|
has:*) fw__has; return ;; |
||||||
|
err:*) fw__err; return ;; |
||||||
|
list:*) cmd="numeric --verbose --$cmd" ;; |
||||||
|
*) return 254 ;; |
||||||
|
esac |
||||||
|
case "$chn" in |
||||||
|
-) chn= ;; |
||||||
|
esac |
||||||
|
case "$tgt" in |
||||||
|
-) tgt= ;; |
||||||
|
esac |
||||||
|
case "$pos" in |
||||||
|
^) pos=1 ;; |
||||||
|
$) pos= ;; |
||||||
|
-) pos= ;; |
||||||
|
esac |
||||||
|
|
||||||
|
if ! fw__has - family || ! fw__has $tab ; then |
||||||
|
export FW_${fam}_ERROR=0 |
||||||
|
return 0 |
||||||
|
fi |
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then |
||||||
|
shift |
||||||
|
if [ $cmd == del ]; then |
||||||
|
pos=- |
||||||
|
fi |
||||||
|
fi |
||||||
|
while [ $# -gt 1 ]; do |
||||||
|
echo -n "$1" |
||||||
|
echo -ne "\0" |
||||||
|
shift |
||||||
|
done | xargs -0 ${FW_TRACE:+-t} \ |
||||||
|
$app --table ${tab} --${cmd} ${chn} ${pol} ${pos} ${tgt:+--jump "$tgt"} |
||||||
|
fw__rc $? |
||||||
|
} |
||||||
|
|
||||||
|
fw_get_port_range() { |
||||||
|
local ports=$1 |
||||||
|
local delim=${2:-:} |
||||||
|
if [ "$3" ]; then |
||||||
|
fw_get_port_range "${ports}-${3}" $delim |
||||||
|
return |
||||||
|
fi |
||||||
|
|
||||||
|
local first=${ports%-*} |
||||||
|
local last=${ports#*-} |
||||||
|
if [ "$first" != "$last" ]; then |
||||||
|
echo "$first$delim$last" |
||||||
|
else |
||||||
|
echo "$first" |
||||||
|
fi |
||||||
|
} |
||||||
|
|
@ -0,0 +1,5 @@ |
|||||||
|
# This file is here for backwards compatibility and to override the |
||||||
|
# uci_firewall.sh from an earlier version. |
||||||
|
type fw_is_loaded >/dev/null || { |
||||||
|
. /lib/firewall/core.sh |
||||||
|
} |
@ -1,530 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
# Copyright (C) 2008 John Crispin <blogic@openwrt.org> |
|
||||||
|
|
||||||
. /etc/functions.sh |
|
||||||
|
|
||||||
IPTABLES="echo iptables" |
|
||||||
IPTABLES=iptables |
|
||||||
|
|
||||||
config_clear |
|
||||||
include /lib/network |
|
||||||
scan_interfaces |
|
||||||
|
|
||||||
CONFIG_APPEND=1 |
|
||||||
config_load firewall |
|
||||||
|
|
||||||
config fw_zones |
|
||||||
ZONE_LIST=$CONFIG_SECTION |
|
||||||
|
|
||||||
CUSTOM_CHAINS=1 |
|
||||||
DEF_INPUT=DROP |
|
||||||
DEF_OUTPUT=DROP |
|
||||||
DEF_FORWARD=DROP |
|
||||||
CONNTRACK_ZONES= |
|
||||||
NOTRACK_DISABLED= |
|
||||||
|
|
||||||
find_item() { |
|
||||||
local item="$1"; shift |
|
||||||
for i in "$@"; do |
|
||||||
[ "$i" = "$item" ] && return 0 |
|
||||||
done |
|
||||||
return 1 |
|
||||||
} |
|
||||||
|
|
||||||
load_policy() { |
|
||||||
config_get input $1 input |
|
||||||
config_get output $1 output |
|
||||||
config_get forward $1 forward |
|
||||||
|
|
||||||
DEF_INPUT="${input:-$DEF_INPUT}" |
|
||||||
DEF_OUTPUT="${output:-$DEF_OUTPUT}" |
|
||||||
DEF_FORWARD="${forward:-$DEF_FORWARD}" |
|
||||||
} |
|
||||||
|
|
||||||
create_zone() { |
|
||||||
local exists |
|
||||||
|
|
||||||
[ "$1" == "loopback" ] && return |
|
||||||
|
|
||||||
config_get exists $ZONE_LIST $1 |
|
||||||
[ -n "$exists" ] && return |
|
||||||
config_set $ZONE_LIST $1 1 |
|
||||||
|
|
||||||
$IPTABLES -N zone_$1 |
|
||||||
$IPTABLES -N zone_$1_MSSFIX |
|
||||||
$IPTABLES -N zone_$1_ACCEPT |
|
||||||
$IPTABLES -N zone_$1_DROP |
|
||||||
$IPTABLES -N zone_$1_REJECT |
|
||||||
$IPTABLES -N zone_$1_forward |
|
||||||
[ "$4" ] && $IPTABLES -A output -j zone_$1_$4 |
|
||||||
$IPTABLES -N zone_$1_nat -t nat |
|
||||||
$IPTABLES -N zone_$1_prerouting -t nat |
|
||||||
$IPTABLES -t raw -N zone_$1_notrack |
|
||||||
[ "$6" == "1" ] && $IPTABLES -t nat -A POSTROUTING -j zone_$1_nat |
|
||||||
[ "$7" == "1" ] && $IPTABLES -I FORWARD 1 -j zone_$1_MSSFIX |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
addif() { |
|
||||||
local network="$1" |
|
||||||
local ifname="$2" |
|
||||||
local zone="$3" |
|
||||||
|
|
||||||
local n_if n_zone |
|
||||||
config_get n_if core "${network}_ifname" |
|
||||||
config_get n_zone core "${network}_zone" |
|
||||||
[ -n "$n_zone" ] && { |
|
||||||
if [ "$n_zone" != "$zone" ]; then |
|
||||||
delif "$network" "$n_if" "$n_zone" |
|
||||||
else |
|
||||||
return |
|
||||||
fi |
|
||||||
} |
|
||||||
|
|
||||||
logger "adding $network ($ifname) to firewall zone $zone" |
|
||||||
$IPTABLES -A input -i "$ifname" -j zone_${zone} |
|
||||||
$IPTABLES -I zone_${zone}_MSSFIX 1 -o "$ifname" -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu |
|
||||||
$IPTABLES -I zone_${zone}_ACCEPT 1 -o "$ifname" -j ACCEPT |
|
||||||
$IPTABLES -I zone_${zone}_DROP 1 -o "$ifname" -j DROP |
|
||||||
$IPTABLES -I zone_${zone}_REJECT 1 -o "$ifname" -j reject |
|
||||||
$IPTABLES -I zone_${zone}_ACCEPT 1 -i "$ifname" -j ACCEPT |
|
||||||
$IPTABLES -I zone_${zone}_DROP 1 -i "$ifname" -j DROP |
|
||||||
$IPTABLES -I zone_${zone}_REJECT 1 -i "$ifname" -j reject |
|
||||||
$IPTABLES -I zone_${zone}_nat 1 -t nat -o "$ifname" -j MASQUERADE |
|
||||||
$IPTABLES -I PREROUTING 1 -t nat -i "$ifname" -j zone_${zone}_prerouting |
|
||||||
$IPTABLES -A forward -i "$ifname" -j zone_${zone}_forward |
|
||||||
$IPTABLES -t raw -I PREROUTING 1 -i "$ifname" -j zone_${zone}_notrack |
|
||||||
uci_set_state firewall core "${network}_ifname" "$ifname" |
|
||||||
uci_set_state firewall core "${network}_zone" "$zone" |
|
||||||
ACTION=add ZONE="$zone" INTERFACE="$network" DEVICE="$ifname" /sbin/hotplug-call firewall |
|
||||||
} |
|
||||||
|
|
||||||
delif() { |
|
||||||
local network="$1" |
|
||||||
local ifname="$2" |
|
||||||
local zone="$3" |
|
||||||
|
|
||||||
logger "removing $network ($ifname) from firewall zone $zone" |
|
||||||
$IPTABLES -D input -i "$ifname" -j zone_$zone |
|
||||||
$IPTABLES -D zone_${zone}_MSSFIX -o "$ifname" -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu |
|
||||||
$IPTABLES -D zone_${zone}_ACCEPT -o "$ifname" -j ACCEPT |
|
||||||
$IPTABLES -D zone_${zone}_DROP -o "$ifname" -j DROP |
|
||||||
$IPTABLES -D zone_${zone}_REJECT -o "$ifname" -j reject |
|
||||||
$IPTABLES -D zone_${zone}_ACCEPT -i "$ifname" -j ACCEPT |
|
||||||
$IPTABLES -D zone_${zone}_DROP -i "$ifname" -j DROP |
|
||||||
$IPTABLES -D zone_${zone}_REJECT -i "$ifname" -j reject |
|
||||||
$IPTABLES -D zone_${zone}_nat -t nat -o "$ifname" -j MASQUERADE |
|
||||||
$IPTABLES -D PREROUTING -t nat -i "$ifname" -j zone_${zone}_prerouting |
|
||||||
$IPTABLES -D forward -i "$ifname" -j zone_${zone}_forward |
|
||||||
uci_revert_state firewall core "${network}_ifname" |
|
||||||
uci_revert_state firewall core "${network}_zone" |
|
||||||
ACTION=remove ZONE="$zone" INTERFACE="$network" DEVICE="$ifname" /sbin/hotplug-call firewall |
|
||||||
} |
|
||||||
|
|
||||||
load_synflood() { |
|
||||||
local rate=${1:-25} |
|
||||||
local burst=${2:-50} |
|
||||||
echo "Loading synflood protection" |
|
||||||
$IPTABLES -N syn_flood |
|
||||||
$IPTABLES -A syn_flood -p tcp --syn -m limit --limit $rate/second --limit-burst $burst -j RETURN |
|
||||||
$IPTABLES -A syn_flood -j DROP |
|
||||||
$IPTABLES -A INPUT -p tcp --syn -j syn_flood |
|
||||||
} |
|
||||||
|
|
||||||
fw_set_chain_policy() { |
|
||||||
local chain=$1 |
|
||||||
local target=$2 |
|
||||||
[ "$target" == "REJECT" ] && { |
|
||||||
$IPTABLES -A $chain -j reject |
|
||||||
target=DROP |
|
||||||
} |
|
||||||
$IPTABLES -P $chain $target |
|
||||||
} |
|
||||||
|
|
||||||
fw_clear() { |
|
||||||
$IPTABLES -F |
|
||||||
$IPTABLES -t nat -F |
|
||||||
$IPTABLES -t nat -X |
|
||||||
$IPTABLES -t raw -F |
|
||||||
$IPTABLES -t raw -X |
|
||||||
$IPTABLES -X |
|
||||||
} |
|
||||||
|
|
||||||
fw_defaults() { |
|
||||||
[ -n "$DEFAULTS_APPLIED" ] && { |
|
||||||
echo "Error: multiple defaults sections detected" |
|
||||||
return; |
|
||||||
} |
|
||||||
DEFAULTS_APPLIED=1 |
|
||||||
|
|
||||||
load_policy "$1" |
|
||||||
|
|
||||||
echo 1 > /proc/sys/net/ipv4/tcp_syncookies |
|
||||||
for f in /proc/sys/net/ipv4/conf/*/accept_redirects |
|
||||||
do |
|
||||||
echo 0 > $f |
|
||||||
done |
|
||||||
for f in /proc/sys/net/ipv4/conf/*/accept_source_route |
|
||||||
do |
|
||||||
echo 0 > $f |
|
||||||
done |
|
||||||
|
|
||||||
uci_revert_state firewall core |
|
||||||
uci_set_state firewall core "" firewall_state |
|
||||||
|
|
||||||
$IPTABLES -P INPUT DROP |
|
||||||
$IPTABLES -P OUTPUT DROP |
|
||||||
$IPTABLES -P FORWARD DROP |
|
||||||
|
|
||||||
fw_clear |
|
||||||
config_get_bool drop_invalid $1 drop_invalid 0 |
|
||||||
|
|
||||||
[ "$drop_invalid" -gt 0 ] && { |
|
||||||
$IPTABLES -A INPUT -m state --state INVALID -j DROP |
|
||||||
$IPTABLES -A OUTPUT -m state --state INVALID -j DROP |
|
||||||
$IPTABLES -A FORWARD -m state --state INVALID -j DROP |
|
||||||
NOTRACK_DISABLED=1 |
|
||||||
} |
|
||||||
|
|
||||||
$IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT |
|
||||||
$IPTABLES -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT |
|
||||||
$IPTABLES -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT |
|
||||||
|
|
||||||
$IPTABLES -A INPUT -i lo -j ACCEPT |
|
||||||
$IPTABLES -A OUTPUT -o lo -j ACCEPT |
|
||||||
|
|
||||||
config_get syn_flood $1 syn_flood |
|
||||||
config_get syn_rate $1 syn_rate |
|
||||||
config_get syn_burst $1 syn_burst |
|
||||||
[ "$syn_flood" == "1" ] && load_synflood $syn_rate $syn_burst |
|
||||||
|
|
||||||
echo "Adding custom chains" |
|
||||||
fw_custom_chains |
|
||||||
|
|
||||||
$IPTABLES -N input |
|
||||||
$IPTABLES -N output |
|
||||||
$IPTABLES -N forward |
|
||||||
|
|
||||||
$IPTABLES -A INPUT -j input |
|
||||||
$IPTABLES -A OUTPUT -j output |
|
||||||
$IPTABLES -A FORWARD -j forward |
|
||||||
|
|
||||||
$IPTABLES -N reject |
|
||||||
$IPTABLES -A reject -p tcp -j REJECT --reject-with tcp-reset |
|
||||||
$IPTABLES -A reject -j REJECT --reject-with icmp-port-unreachable |
|
||||||
|
|
||||||
fw_set_chain_policy INPUT "$DEF_INPUT" |
|
||||||
fw_set_chain_policy OUTPUT "$DEF_OUTPUT" |
|
||||||
fw_set_chain_policy FORWARD "$DEF_FORWARD" |
|
||||||
} |
|
||||||
|
|
||||||
fw_zone_defaults() { |
|
||||||
local name |
|
||||||
local network |
|
||||||
local masq |
|
||||||
|
|
||||||
config_get name $1 name |
|
||||||
config_get network $1 network |
|
||||||
config_get_bool masq $1 masq "0" |
|
||||||
config_get_bool conntrack $1 conntrack "0" |
|
||||||
config_get_bool mtu_fix $1 mtu_fix 0 |
|
||||||
|
|
||||||
load_policy $1 |
|
||||||
[ "$forward" ] && $IPTABLES -A zone_${name}_forward -j zone_${name}_${forward} |
|
||||||
[ "$input" ] && $IPTABLES -A zone_${name} -j zone_${name}_${input} |
|
||||||
} |
|
||||||
|
|
||||||
fw_zone() { |
|
||||||
local name |
|
||||||
local network |
|
||||||
local masq |
|
||||||
|
|
||||||
config_get name $1 name |
|
||||||
config_get network $1 network |
|
||||||
config_get_bool masq $1 masq "0" |
|
||||||
config_get_bool conntrack $1 conntrack "0" |
|
||||||
config_get_bool mtu_fix $1 mtu_fix 0 |
|
||||||
|
|
||||||
load_policy $1 |
|
||||||
[ "$conntrack" = "1" -o "$masq" = "1" ] && append CONNTRACK_ZONES "$name" |
|
||||||
[ -z "$network" ] && network=$name |
|
||||||
create_zone "$name" "$network" "$input" "$output" "$forward" "$masq" "$mtu_fix" |
|
||||||
fw_custom_chains_zone "$name" |
|
||||||
} |
|
||||||
|
|
||||||
fw_rule() { |
|
||||||
local src |
|
||||||
local src_ip |
|
||||||
local src_mac |
|
||||||
local src_port |
|
||||||
local src_mac |
|
||||||
local dest |
|
||||||
local dest_ip |
|
||||||
local dest_port |
|
||||||
local proto |
|
||||||
local icmp_type |
|
||||||
local target |
|
||||||
local ruleset |
|
||||||
|
|
||||||
config_get src $1 src |
|
||||||
config_get src_ip $1 src_ip |
|
||||||
config_get src_mac $1 src_mac |
|
||||||
config_get src_port $1 src_port |
|
||||||
config_get dest $1 dest |
|
||||||
config_get dest_ip $1 dest_ip |
|
||||||
config_get dest_port $1 dest_port |
|
||||||
config_get proto $1 proto |
|
||||||
config_get icmp_type $1 icmp_type |
|
||||||
config_get target $1 target |
|
||||||
config_get ruleset $1 ruleset |
|
||||||
|
|
||||||
src_port_first=${src_port%-*} |
|
||||||
src_port_last=${src_port#*-} |
|
||||||
[ "$src_port_first" -ne "$src_port_last" ] && { \ |
|
||||||
src_port="$src_port_first:$src_port_last"; } |
|
||||||
|
|
||||||
dest_port_first=${dest_port%-*} |
|
||||||
dest_port_last=${dest_port#*-} |
|
||||||
[ "$dest_port_first" -ne "$dest_port_last" ] && { \ |
|
||||||
dest_port="$dest_port_first:$dest_port_last"; } |
|
||||||
|
|
||||||
ZONE=input |
|
||||||
TARGET=$target |
|
||||||
[ -z "$target" ] && target=DROP |
|
||||||
[ -n "$src" -a -z "$dest" ] && ZONE=zone_$src |
|
||||||
[ -n "$src" -a -n "$dest" ] && ZONE=zone_${src}_forward |
|
||||||
[ -n "$dest" ] && TARGET=zone_${dest}_$target |
|
||||||
|
|
||||||
eval 'RULE_COUNT=$((++RULE_COUNT_'$ZONE'))' |
|
||||||
|
|
||||||
add_rule() { |
|
||||||
$IPTABLES -I $ZONE $RULE_COUNT \ |
|
||||||
${proto:+-p $proto} \ |
|
||||||
${icmp_type:+--icmp-type $icmp_type} \ |
|
||||||
${src_ip:+-s $src_ip} \ |
|
||||||
${src_port:+--sport $src_port} \ |
|
||||||
${src_mac:+-m mac --mac-source $src_mac} \ |
|
||||||
${dest_ip:+-d $dest_ip} \ |
|
||||||
${dest_port:+--dport $dest_port} \ |
|
||||||
-j $TARGET |
|
||||||
} |
|
||||||
[ "$proto" == "tcpudp" -o -z "$proto" ] && { |
|
||||||
proto=tcp |
|
||||||
add_rule |
|
||||||
proto=udp |
|
||||||
add_rule |
|
||||||
return |
|
||||||
} |
|
||||||
add_rule |
|
||||||
} |
|
||||||
|
|
||||||
fw_forwarding() { |
|
||||||
local src |
|
||||||
local dest |
|
||||||
local masq |
|
||||||
|
|
||||||
config_get src $1 src |
|
||||||
config_get dest $1 dest |
|
||||||
[ -n "$src" ] && z_src=zone_${src}_forward || z_src=forward |
|
||||||
[ -n "$dest" ] && z_dest=zone_${dest}_ACCEPT || z_dest=ACCEPT |
|
||||||
$IPTABLES -I $z_src 1 -j $z_dest |
|
||||||
|
|
||||||
# propagate masq zone flag |
|
||||||
find_item "$src" $CONNTRACK_ZONES && append CONNTRACK_ZONES $dest |
|
||||||
find_item "$dest" $CONNTRACK_ZONES && append CONNTRACK_ZONES $src |
|
||||||
} |
|
||||||
|
|
||||||
fw_redirect() { |
|
||||||
local src |
|
||||||
local src_ip |
|
||||||
local src_port |
|
||||||
local src_dport |
|
||||||
local src_mac |
|
||||||
local dest_ip |
|
||||||
local dest_port dest_port2 |
|
||||||
local proto |
|
||||||
|
|
||||||
config_get src $1 src |
|
||||||
config_get src_ip $1 src_ip |
|
||||||
config_get src_dip $1 src_dip |
|
||||||
config_get src_port $1 src_port |
|
||||||
config_get src_dport $1 src_dport |
|
||||||
config_get src_mac $1 src_mac |
|
||||||
config_get dest_ip $1 dest_ip |
|
||||||
config_get dest_port $1 dest_port |
|
||||||
config_get proto $1 proto |
|
||||||
[ -z "$src" -o -z "$dest_ip" ] && { \ |
|
||||||
echo "redirect needs src and dest_ip"; return ; } |
|
||||||
|
|
||||||
src_port_first=${src_port%-*} |
|
||||||
src_port_last=${src_port#*-} |
|
||||||
[ "$src_port_first" != "$src_port_last" ] && { \ |
|
||||||
src_port="$src_port_first:$src_port_last"; } |
|
||||||
|
|
||||||
src_dport_first=${src_dport%-*} |
|
||||||
src_dport_last=${src_dport#*-} |
|
||||||
[ "$src_dport_first" != "$src_dport_last" ] && { \ |
|
||||||
src_dport="$src_dport_first:$src_dport_last"; } |
|
||||||
|
|
||||||
dest_port2=${dest_port:-$src_dport} |
|
||||||
dest_port_first=${dest_port2%-*} |
|
||||||
dest_port_last=${dest_port2#*-} |
|
||||||
[ "$dest_port_first" != "$dest_port_last" ] && { \ |
|
||||||
dest_port2="$dest_port_first:$dest_port_last"; } |
|
||||||
|
|
||||||
add_rule() { |
|
||||||
$IPTABLES -A zone_${src}_prerouting -t nat \ |
|
||||||
${proto:+-p $proto} \ |
|
||||||
${src_ip:+-s $src_ip} \ |
|
||||||
${src_dip:+-d $src_dip} \ |
|
||||||
${src_port:+--sport $src_port} \ |
|
||||||
${src_dport:+--dport $src_dport} \ |
|
||||||
${src_mac:+-m mac --mac-source $src_mac} \ |
|
||||||
-j DNAT --to-destination $dest_ip${dest_port:+:$dest_port} |
|
||||||
|
|
||||||
$IPTABLES -I zone_${src}_forward 1 \ |
|
||||||
${proto:+-p $proto} \ |
|
||||||
-d $dest_ip \ |
|
||||||
${src_ip:+-s $src_ip} \ |
|
||||||
${src_port:+--sport $src_port} \ |
|
||||||
${dest_port2:+--dport $dest_port2} \ |
|
||||||
${src_mac:+-m mac --mac-source $src_mac} \ |
|
||||||
-j ACCEPT |
|
||||||
} |
|
||||||
[ "$proto" == "tcpudp" -o -z "$proto" ] && { |
|
||||||
proto=tcp |
|
||||||
add_rule |
|
||||||
proto=udp |
|
||||||
add_rule |
|
||||||
return |
|
||||||
} |
|
||||||
add_rule |
|
||||||
} |
|
||||||
|
|
||||||
fw_include() { |
|
||||||
local path |
|
||||||
config_get path $1 path |
|
||||||
[ -e $path ] && . $path |
|
||||||
} |
|
||||||
|
|
||||||
get_interface_zones() { |
|
||||||
local interface="$2" |
|
||||||
local name |
|
||||||
local network |
|
||||||
config_get name $1 name |
|
||||||
config_get network $1 network |
|
||||||
[ -z "$network" ] && network=$name |
|
||||||
for n in $network; do |
|
||||||
[ "$n" = "$interface" ] && append add_zone "$name" |
|
||||||
done |
|
||||||
} |
|
||||||
|
|
||||||
fw_event() { |
|
||||||
local action="$1" |
|
||||||
local interface="$2" |
|
||||||
local ifname="$(sh -c ". /etc/functions.sh; include /lib/network; scan_interfaces; config_get "$interface" ifname")" |
|
||||||
add_zone= |
|
||||||
local up |
|
||||||
|
|
||||||
[ -z "$ifname" ] && return 0 |
|
||||||
config_foreach get_interface_zones zone "$interface" |
|
||||||
[ -z "$add_zone" ] && return 0 |
|
||||||
|
|
||||||
case "$action" in |
|
||||||
ifup) |
|
||||||
for z in $add_zone; do |
|
||||||
local loaded |
|
||||||
config_get loaded core loaded |
|
||||||
[ -n "$loaded" ] && addif "$interface" "$ifname" "$z" |
|
||||||
done |
|
||||||
;; |
|
||||||
ifdown) |
|
||||||
config_get up "$interface" up |
|
||||||
|
|
||||||
for z in $ZONE; do |
|
||||||
[ "$up" == "1" ] && delif "$interface" "$ifname" "$z" |
|
||||||
done |
|
||||||
;; |
|
||||||
esac |
|
||||||
} |
|
||||||
|
|
||||||
fw_addif() { |
|
||||||
local up |
|
||||||
local ifname |
|
||||||
config_get up $1 up |
|
||||||
[ -n "$up" ] || return 0 |
|
||||||
fw_event ifup "$1" |
|
||||||
} |
|
||||||
|
|
||||||
fw_custom_chains() { |
|
||||||
[ -n "$CUSTOM_CHAINS" ] || return 0 |
|
||||||
$IPTABLES -N input_rule |
|
||||||
$IPTABLES -N output_rule |
|
||||||
$IPTABLES -N forwarding_rule |
|
||||||
$IPTABLES -N prerouting_rule -t nat |
|
||||||
$IPTABLES -N postrouting_rule -t nat |
|
||||||
|
|
||||||
$IPTABLES -A INPUT -j input_rule |
|
||||||
$IPTABLES -A OUTPUT -j output_rule |
|
||||||
$IPTABLES -A FORWARD -j forwarding_rule |
|
||||||
$IPTABLES -A PREROUTING -t nat -j prerouting_rule |
|
||||||
$IPTABLES -A POSTROUTING -t nat -j postrouting_rule |
|
||||||
} |
|
||||||
|
|
||||||
fw_custom_chains_zone() { |
|
||||||
local zone="$1" |
|
||||||
|
|
||||||
[ -n "$CUSTOM_CHAINS" ] || return 0 |
|
||||||
$IPTABLES -N input_${zone} |
|
||||||
$IPTABLES -N forwarding_${zone} |
|
||||||
$IPTABLES -N prerouting_${zone} -t nat |
|
||||||
$IPTABLES -I zone_${zone} 1 -j input_${zone} |
|
||||||
$IPTABLES -I zone_${zone}_forward 1 -j forwarding_${zone} |
|
||||||
$IPTABLES -I zone_${zone}_prerouting 1 -t nat -j prerouting_${zone} |
|
||||||
} |
|
||||||
|
|
||||||
fw_check_notrack() { |
|
||||||
local zone="$1" |
|
||||||
config_get name "$zone" name |
|
||||||
[ -n "$NOTRACK_DISABLED" ] || \ |
|
||||||
find_item "$name" $CONNTRACK_ZONES || \ |
|
||||||
$IPTABLES -t raw -A zone_${name}_notrack -j NOTRACK |
|
||||||
} |
|
||||||
|
|
||||||
fw_init() { |
|
||||||
DEFAULTS_APPLIED= |
|
||||||
|
|
||||||
echo "Loading defaults" |
|
||||||
config_foreach fw_defaults defaults |
|
||||||
echo "Loading zones" |
|
||||||
config_foreach fw_zone zone |
|
||||||
echo "Loading forwarding" |
|
||||||
config_foreach fw_forwarding forwarding |
|
||||||
echo "Loading redirects" |
|
||||||
config_foreach fw_redirect redirect |
|
||||||
echo "Loading rules" |
|
||||||
config_foreach fw_rule rule |
|
||||||
echo "Loading includes" |
|
||||||
config_foreach fw_include include |
|
||||||
echo "Loading zone defaults" |
|
||||||
config_foreach fw_zone_defaults zone |
|
||||||
uci_set_state firewall core loaded 1 |
|
||||||
config_set core loaded 1 |
|
||||||
config_foreach fw_check_notrack zone |
|
||||||
INTERFACES="$(sh -c ' |
|
||||||
. /etc/functions.sh; config_load network |
|
||||||
echo_up() { local up; config_get_bool up "$1" up 0; [ $up = 1 ] && echo "$1"; } |
|
||||||
config_foreach echo_up interface |
|
||||||
')" |
|
||||||
for interface in $INTERFACES; do |
|
||||||
fw_event ifup "$interface" |
|
||||||
done |
|
||||||
} |
|
||||||
|
|
||||||
fw_stop() { |
|
||||||
fw_clear |
|
||||||
$IPTABLES -P INPUT ACCEPT |
|
||||||
$IPTABLES -P OUTPUT ACCEPT |
|
||||||
$IPTABLES -P FORWARD ACCEPT |
|
||||||
uci_revert_state firewall |
|
||||||
} |
|
Loading…
Reference in new issue