adds a new uci firewall - iptbales and netfilter packages need to be rewrapped when we switch to this firewall as default - there are some examples in the file /etc/config/firewall - iptables-save/restore are still missing - hotplug takes care of adding/removing netdevs during runtime - misisng features ? wishes ? let me know ...

SVN-Revision: 12089
This commit is contained in:
John Crispin 2008-08-04 11:51:58 +00:00
parent e4a0bfec3c
commit 21bbdc24c3
12 changed files with 513 additions and 13 deletions

View file

@ -14,7 +14,7 @@ DEVICE_TYPE?=router
# Default packages - the really basic set
DEFAULT_PACKAGES:=base-files libgcc uclibc busybox dropbear mtd uci
# For router targets
DEFAULT_PACKAGES.router:=dnsmasq iptables ppp ppp-mod-pppoe kmod-ipt-nathelper bridge
DEFAULT_PACKAGES.router:=dnsmasq iptables ppp ppp-mod-pppoe kmod-ipt-nathelper bridge firewall
# Additional packages for Linux 2.6
ifneq ($(KERNEL),2.4)

View file

@ -0,0 +1,17 @@
choice
prompt "Choose firewall"
default FIREWALL_OLD
depends PACKAGE_firewall
config FIREWALL_OLD
bool "old firewall"
config FIREWALL_NEW
bool "new uci firewall"
select PACKAGE_iptables-mod-conntrack
select PACKAGE_iptables-mod-extra
select PACKAGE_iptables-mod-ipopt
select PACKAGE_iptables-mod-ulog
select PACKAGE_kmod-ipt-nathelper
endchoice

69
package/firewall/Makefile Normal file
View file

@ -0,0 +1,69 @@
#
# Copyright (C) 2008 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
include $(TOPDIR)/rules.mk
PKG_NAME:=firewall
PKG_VERSION:=1
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define Package/firewall
SECTION:=net
CATEGORY:=Base system
URL:=http://openwrt.org/
TITLE:=OpenWrt firewall
DEPENDS:=+iptables
endef
define Package/firewall/description
firewall for openwrt, you can select if you want to use the old version or the new uci based script
endef
define Package/firewall/config
source "$(SOURCE)/Config.in"
endef
define Build/Compile
true
endef
ifeq ($(CONFIG_FIREWALL_NEW),y)
define Package/firewall/conffiles
/etc/config/firewall
endef
define Package/firewall/install
$(INSTALL_DIR) $(1)/lib/firewall
$(INSTALL_DATA) ./files/new/uci_firewall.sh $(1)/lib/firewall
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DATA) ./files/new/firewall.config $(1)/etc/config/firewall
$(INSTALL_DIR) $(1)/etc/init.d/
$(INSTALL_BIN) ./files/new/firewall.init $(1)/etc/init.d/firewall
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
$(INSTALL_DATA) ./files/new/20-firewall $(1)/etc/hotplug.d/iface
endef
else
define Package/firewall/conffiles
/etc/firewall.config
/etc/firewall.user
endef
define Package/firewall/install
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DATA) ./files/old/firewall.config $(1)/etc/
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/old/firewall.init $(1)/etc/init.d/firewall
$(INSTALL_BIN) ./files/old/firewall.user $(1)/etc/
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DATA) ./files/old/firewall.awk $(1)/usr/lib
endef
endif
$(eval $(call BuildPackage,firewall))

View file

@ -0,0 +1,41 @@
. /lib/firewall/uci_firewall.sh
unset ZONE
config_get ifname $INTERFACE ifname
INTERFACE=$ifname
[ "$INTERFACE" == "lo" ] && exit 0
load_zones() {
local name
local network
config_get name $1 name
config_get network $1 network
[ -z "$network" ] && return
for n in $network; do
local ifname
config_get ifname $n ifname
list_contains ifname $INTERFACE && {
list_contains ZONE $name || ZONE="$ZONE $name"
}
done
}
config_foreach load_zones zone
IFACE=$(find_config $INTERFACE)
[ -n "$IFACE" ] &&
list_contains ZONE $IFACE || ZONE="$ZONE $IFACE"
[ ifup = "$ACTION" ] && {
for z in $ZONE; do
local loaded
config_get loaded core loaded
[ -n "$loaded" ] && addif $INTERFACE $z
done
}
[ ifdown = "$ACTION" ] && {
for z in $ZONE; do
local up
config_get up $z up
[ "$up" == "1" ] && delif $INTERFACE $z
done
}

View file

@ -0,0 +1,80 @@
config defaults
option syn_flood 1
option input DROP
option output ACCEPT
option forward DROP
config zone
option name lan
option input ACCEPT
option output ACCEPT
option forward DROP
config zone
option name wan
option input DROP
option output ACCEPT
option forward DROP
option masq 1
config forwarding
option src lan
option dest wan
### EXAMPLE CONFIG SECTIONS
# do not allow a specific ip to access wan
#config rule
# option src lan
# option src_ip 192.168.45.2
# option dest wan
# option proto tcp
# option target REJECT
# block a specific mac on wan
#config rule
# option dest wan
# option src_mac 00:11:22:33:44:66
# option target REJECT
# block incoming ICMP traffic on a zone
#config rule
# option src lan
# option proto ICMP
# option target DROP
# port redirect port coming in on wan to lan
#config redirect
# option src wan
# option src_dport 80
# option dest lan
# option dest_ip 192.168.16.235
# option dest_port 80
# option protocol tcp
# include a file with users custom iptables rules
#config include
# option path /etc/firewall.user
### FULL CONFIG SECTIONS
#config rule
# option src lan
# option src_ip 192.168.45.2
# option src_mac 00:11:22:33:44:55
# option src_port 80
# option dest wan
# option dest_ip 194.25.2.129
# option dest_port 120
# option proto tcp
# option target REJECT
#config redirect
# option src lan
# option src_ip 192.168.45.2
# option src_mac 00:11:22:33:44:55
# option src_port 1024
# option src_dport 80
# option dest_ip 194.25.2.129
# option dest_port 120
# option proto tcp

View file

@ -0,0 +1,14 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2008 OpenWrt.org
START=45
start() {
. /lib/firewall/uci_firewall.sh
fw_init
}
stop() {
. /lib/firewall/uci_firewall.sh
fw_stop
}

View file

@ -0,0 +1,291 @@
#!/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
DEF_INPUT=DROP
DEF_OUTPUT=DROP
DEF_FORWARD=DROP
load_policy() {
config_get input $1 input
config_get output $1 output
config_get forward $1 forward
[ -z "$input" ] && input=$DEF_INPUT
[ -z "$output" ] && output=$DEF_OUTPUT
[ -z "$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_ACCEPT
$IPTABLES -N zone_$1_DROP
$IPTABLES -N zone_$1_REJECT
$IPTABLES -N zone_$1_forward
$IPTABLES -A zone_$1_forward -j zone_$1_$5
$IPTABLES -A zone_$1 -j zone_$1_$3
$IPTABLES -A OUTPUT -j zone_$1_$4
$IPTABLES -N zone_$1_nat -t nat
$IPTABLES -N zone_$1_prerouting -t nat
[ "$6" == "1" ] && $IPTABLES -t nat -A POSTROUTING -j zone_$2_nat
}
addif() {
logger "adding $1 to firewall zone $2"
$IPTABLES -A INPUT -i $1 -j zone_$2
$IPTABLES -I zone_$2_ACCEPT 1 -o $1 -j ACCEPT
$IPTABLES -I zone_$2_DROP 1 -o $1 -j DROP
$IPTABLES -I zone_$2_REJECT 1 -o $1 -j REJECT
$IPTABLES -I zone_$2_ACCEPT 1 -i $1 -j ACCEPT
$IPTABLES -I zone_$2_DROP 1 -i $1 -j DROP
$IPTABLES -I zone_$2_REJECT 1 -i $1 -j REJECT
$IPTABLES -I zone_$2_nat 1 -t nat -o $1 -j MASQUERADE
$IPTABLES -I PREROUTING 1 -t nat -i $1 -j zone_$2_prerouting
$IPTABLES -A FORWARD -i $1 -j zone_$2_forward
}
delif() {
logger "removing $1 from firewall zone $2"
$IPTABLES -D INPUT -i $1 -j zone_$2
$IPTABLES -D zone_$2_ACCEPT -o $1 -j ACCEPT
$IPTABLES -D zone_$2_DROP -o $1 -j DROP
$IPTABLES -D zone_$2_REJECT -o $1 -j REJECT
$IPTABLES -D zone_$2_ACCEPT -i $1 -j ACCEPT
$IPTABLES -D zone_$2_DROP -i $1 -j DROP
$IPTABLES -D zone_$2_REJECT -i $1 -j REJECT
$IPTABLES -D zone_$2_nat -t nat -o $1 -j MASQUERADE
$IPTABLES -D PREROUTING -t nat -i $1 -j zone_$2_prerouting
$IPTABLES -D FORWARD -i $1 -j zone_$2_forward
}
load_synflood() {
echo "Loading synflood protection"
$IPTABLES -N SYN_FLOOD
$IPTABLES -A SYN_FLOOD -p tcp --syn -m limit --limit ${1}/second --limit-burst $2 -j RETURN
$IPTABLES -A SYN_FLOOD -p ! tcp -j RETURN
$IPTABLES -A SYN_FLOOD -p tcp ! --syn -j RETURN
$IPTABLES -A SYN_FLOOD -j LOG --log-prefix "syn_flood: "
$IPTABLES -A SYN_FLOOD -j DROP
$IPTABLES -A INPUT -p tcp --syn -j SYN_FLOOD
}
create_network_zone() {
create_zone "$1" "$1"
}
fw_defaults() {
load_policy $1
DEF_INPUT=$input
DEF_OUTPUT=$output
DEF_FORWARD=$forward
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
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -t mangle -F
$IPTABLES -X -t nat
$IPTABLES -X
$IPTABLES -P INPUT $input
$IPTABLES -A INPUT -m state --state INVALID -j DROP
$IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPTABLES -P OUTPUT $output
$IPTABLES -A OUTPUT -m state --state INVALID -j DROP
$IPTABLES -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPTABLES -P FORWARD $forward
$IPTABLES -A FORWARD -m state --state INVALID -j DROP
$IPTABLES -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
$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
[ -z "$syn_rate" ] && syn_rate=25
[ -z "$syn_burst" ] && syn_burst=50
[ "$syn_flood" == "1" ] && load_synflood $syn_rate $syn_burst
}
fw_zone() {
local name
local network
local masq
config_get name $1 name
config_get network $1 network
config_get masq $1 masq
load_policy $1
[ -z "$network" ] && network=$name
create_zone "$name" "$network" "$input" "$output" "$forward" "$masq"
}
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 target
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 target $1 target
config_get ruleset $1 ruleset
[ -z "$target" ] && target=DROP
[ -n "$src" ] && ZONE=zone_$src || ZONE=INPUT
[ -n "$dest" ] && TARGET=zone_${dest}_$target || TARGET=$target
$IPTABLES -I $ZONE 1 \
${proto:+-p $proto} \
${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
}
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
}
fw_redirect() {
local src
local src_ip
local src_port
local src_dport
local src_mac
local dest_ip
local dest_port
local protocol
config_get src $1 src
config_get src_ip $1 src_ip
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 protocol $1 protocol
[ -z "$src" -o -z "$dest_ip" ] && { \
echo "redirect needs src and dest_ip"; return ; }
$IPTABLES -A zone_${src}_prerouting -t nat \
${protocol:+-p $protocol} \
${src_ip:+-s $srcdip} \
${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 \
${protocol:+-p $protocol} \
-d $dest_ip \
${src_ip:+-s $srcdip} \
${src_port:+--sport $src_port} \
${dest_port:+--dport $dest_port} \
${src_mac:+-m mac --mac-source $src_mac} \
-j ACCEPT
}
fw_include() {
local path
config_get path $1 path
[ -e $path ] && . $path
}
fw_addif() {
local up
local ifname
config_get up $1 up
config_get ifname $1 ifname
[ -n "$up" ] || return 0
(ACTION="ifup" INTERFACE="$1" . /etc/hotplug.d/iface/20-firewall)
}
fw_init() {
echo "Loading defaults"
config_foreach fw_defaults defaults
echo "Loading zones"
config_foreach fw_zone zone
echo "Loading interfaces"
config_foreach create_network_zone interface
echo "Loading rules"
config_foreach fw_rule rule
echo "Loading forwarding"
config_foreach fw_forwarding forwarding
echo "Loading redirects"
config_foreach fw_redirect redirect
echo "Loading includes"
config_foreach fw_include include
uci_set_state firewall core "" firewall_state
uci_set_state firewall core loaded 1
unset CONFIG_APPEND
config_load network
config_foreach fw_addif interface
}
fw_stop() {
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -t mangle -F
$IPTABLES -X -t nat
$IPTABLES -X
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
}

View file

@ -58,11 +58,6 @@ $(call Package/iptables/Default)
MENU:=1
endef
define Package/iptables/conffiles
/etc/firewall.config
/etc/firewall.user
endef
define Package/iptables-mod-conntrack
$(call Package/iptables/Module, +kmod-ipt-conntrack)
TITLE:=connection tracking modules
@ -247,13 +242,6 @@ define Build/InstallDev
endef
define Package/iptables/install
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DATA) ./files/firewall.config $(1)/etc/
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/firewall.init $(1)/etc/init.d/firewall
$(INSTALL_BIN) ./files/firewall.user $(1)/etc/
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DATA) ./files/firewall.awk $(1)/usr/lib
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/iptables $(1)/usr/sbin/
$(INSTALL_DIR) $(1)/usr/lib/iptables