firewall: - replace uci firewall with a modular dual stack implementation developed by Malte S. Stretz - bump version to 2
SVN-Revision: 21286
This commit is contained in:
parent
085b2b9ad6
commit
c284cb51c0
15 changed files with 1023 additions and 544 deletions
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (C) 2008-2009 OpenWrt.org
|
||||
# Copyright (C) 2008-2010 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
|
@ -8,8 +8,8 @@ include $(TOPDIR)/rules.mk
|
|||
|
||||
PKG_NAME:=firewall
|
||||
|
||||
PKG_VERSION:=1
|
||||
PKG_RELEASE:=10
|
||||
PKG_VERSION:=2
|
||||
PKG_RELEASE:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
|
@ -36,13 +36,15 @@ endef
|
|||
|
||||
define Package/firewall/install
|
||||
$(INSTALL_DIR) $(1)/lib/firewall
|
||||
$(INSTALL_DATA) ./files/uci_firewall.sh $(1)/lib/firewall
|
||||
$(INSTALL_DATA) ./files/lib/*.sh $(1)/lib/firewall
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(INSTALL_BIN) ./files/bin/fw $(1)/sbin
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_DATA) ./files/firewall.config $(1)/etc/config/firewall
|
||||
$(INSTALL_DIR) $(1)/etc/init.d/
|
||||
$(INSTALL_BIN) ./files/firewall.init $(1)/etc/init.d/firewall
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
|
||||
$(INSTALL_DATA) ./files/20-firewall $(1)/etc/hotplug.d/iface
|
||||
$(INSTALL_DATA) ./files/firewall.hotplug $(1)/etc/hotplug.d/iface/20-firewall
|
||||
$(INSTALL_DIR) $(1)/etc
|
||||
$(INSTALL_DATA) ./files/firewall.user $(1)/etc
|
||||
endef
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
. /lib/firewall/uci_firewall.sh
|
||||
unset ZONE
|
||||
config_get ifname $INTERFACE ifname
|
||||
[ "$ifname" == "lo" ] && exit 0
|
||||
fw_event "$ACTION" "$INTERFACE"
|
49
package/firewall/files/bin/fw
Normal file
49
package/firewall/files/bin/fw
Normal file
|
@ -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 $?
|
19
package/firewall/files/firewall.hotplug
Normal file
19
package/firewall/files/firewall.hotplug
Normal file
|
@ -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
|
|
@ -3,12 +3,25 @@
|
|||
|
||||
START=45
|
||||
|
||||
FW_LIBDIR=/lib/firewall
|
||||
|
||||
fw() {
|
||||
. $FW_LIBDIR/core.sh
|
||||
fw_$1
|
||||
}
|
||||
|
||||
start() {
|
||||
. /lib/firewall/uci_firewall.sh
|
||||
fw_init
|
||||
fw start
|
||||
}
|
||||
|
||||
stop() {
|
||||
. /lib/firewall/uci_firewall.sh
|
||||
fw_stop
|
||||
fw stop
|
||||
}
|
||||
|
||||
restart() {
|
||||
fw restart
|
||||
}
|
||||
|
||||
reload() {
|
||||
fw reload
|
||||
}
|
||||
|
|
97
package/firewall/files/lib/config.sh
Normal file
97
package/firewall/files/lib/config.sh
Normal file
|
@ -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}"
|
||||
}
|
136
package/firewall/files/lib/core.sh
Normal file
136
package/firewall/files/lib/core.sh
Normal file
|
@ -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
|
||||
}
|
40
package/firewall/files/lib/core_forwarding.sh
Normal file
40
package/firewall/files/lib/core_forwarding.sh
Normal file
|
@ -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
|
||||
}
|
258
package/firewall/files/lib/core_init.sh
Normal file
258
package/firewall/files/lib/core_init.sh
Normal file
|
@ -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
|
||||
}
|
86
package/firewall/files/lib/core_interface.sh
Normal file
86
package/firewall/files/lib/core_interface.sh
Normal file
|
@ -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
|
||||
}
|
||||
|
61
package/firewall/files/lib/core_redirect.sh
Normal file
61
package/firewall/files/lib/core_redirect.sh
Normal file
|
@ -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
|
||||
}
|
66
package/firewall/files/lib/core_rule.sh
Normal file
66
package/firewall/files/lib/core_rule.sh
Normal file
|
@ -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
|
||||
}
|
182
package/firewall/files/lib/fw.sh
Normal file
182
package/firewall/files/lib/fw.sh
Normal file
|
@ -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
|
||||
}
|
||||
|
5
package/firewall/files/lib/uci_firewall.sh
Normal file
5
package/firewall/files/lib/uci_firewall.sh
Normal file
|
@ -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 a new issue