Implement support for ipsets

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@2085 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2005-05-05 20:37:31 +00:00
parent 5502bafc19
commit e085262d29
7 changed files with 187 additions and 32 deletions

View File

@ -72,6 +72,16 @@
# kernel and iptables must have
# iprange match support.
#
# +remote The name of an ipset prefaced
# by "+". Your kernel and
# iptables must have set match
# support
#
# +remote[4] The name of the ipset may
# followed by a number of
# levels of ipset bindings
# enclosed in square brackets.
#
# 192.168.1.1,192.168.1.2
# Hosts 192.168.1.1 and
# 192.168.1.2.
@ -85,8 +95,9 @@
# another colon (":") and an IP/MAC/subnet address
# as described above (e.g., eth1:192.168.1.5).
#
# DEST Location of Server. Same as above with the exception that
# MAC addresses are not allowed.
# DEST Location of destination host. Same as above with the exception that
# MAC addresses are not allowed and that you cannot specify
# an ipset name in both the SOURCE and DEST columns.
#
# PROTO Protocol - Must be "tcp", "udp", "icmp", a number, or
# "all".

View File

@ -7,9 +7,10 @@
#
# Columns are:
#
# ADDRESS/SUBNET - Host address, subnetwork, MAC address or IP address
# ADDRESS/SUBNET - Host address, subnetwork, MAC address, IP address
# range (if your kernel and iptables contain iprange
# match support).
# match support) or ipset name prefaced by "+" (if
# your kernel supports ipset match).
#
# MAC addresses must be prefixed with "~" and use "-"
# as a separator.
@ -38,6 +39,13 @@
# ADDRESS/SUBNET PROTOCOL PORT
# 192.0.2.126 udp 53
#
# Example:
#
# To block DNS queries from addresses in the ipset 'dnsblack':
#
# ADDRESS/SUBNET PROTOCOL PORT
# +dnsblack udp 53
#
# Please see http://shorewall.net/blacklisting_support.htm for additional
# information.
#

View File

@ -1,3 +1,5 @@
Changes in 2.3.0
1) Implement support for --cmd-owner
2) Implement support for ipsets.

View File

@ -218,6 +218,19 @@ run_tc() {
fi
}
#
# Run ipset and if an error occurs, stop the firewall and quit
#
run_ipset() {
if ! ipset $@ ; then
if [ -z "$stopping" ]; then
error_message "ERROR: Command \"ipset $@\" Failed"
stop_firewall
exit 2
fi
fi
}
#
# Create a filter chain
#
@ -541,6 +554,29 @@ iprange_echo()
fi
}
#
# Get set flags
#
get_set_flags() # $1 = set name and optional [levels], $2 = src or dst
{
local temp setname options=$2
case $1 in
*\[*[1-6]\])
temp=${1#*\[}
temp=${temp%\]}
setname=${1%\[*}
while [ $temp -gt 1 ]; do
options="$options,$2"
temp=$(($temp - 1))
done
echo "--set ${setname#+} $options"
;;
*)
echo "--set ${1#+} $2"
;;
esac
}
#
# Source IP range
@ -558,6 +594,12 @@ source_ip_range() # $1 = Address or Address Range
;;
esac
;;
!+*)
echo "-m set ! $(get_set_flags ${1#!} src)"
;;
+*)
echo "-m set $(get_set_flags $1 src)"
;;
*)
echo "-s $1"
;;
@ -580,6 +622,12 @@ dest_ip_range() # $1 = Address or Address Range
;;
esac
;;
!+*)
echo "-m set ! $(get_set_flags ${1#!} dst)"
;;
+*)
ipset_echo "-m set $(get_set_flags ${1#+} dst)"
;;
*)
echo "-d $1"
;;
@ -595,6 +643,10 @@ both_ip_ranges() # $1 = Source address or range, $2 = dest address or range
prefix="-m iprange"
match="--src-range $1"
;;
+*)
prefix="-m set"
match="--set ${1#+} src"
;;
*)
match="-s $1"
;;
@ -605,6 +657,18 @@ both_ip_ranges() # $1 = Source address or range, $2 = dest address or range
prefix="-m iprange"
match="$match --dst-range $2"
;;
+*)
case $1 in
*.*.*.*-*.*.*.*)
prefix="$iprange -m set"
;;
*)
prefix="-m set"
;;
esac
match="--set ${1#+} dst"
;;
*)
match="$match -d $2"
;;
@ -749,6 +813,22 @@ match_ipsec_out() # $1 = zone, $2 = host
fi
}
#
# Generate a match for packets whose source matches the passed IPSET
#
match_ipset_source()
{
echo "-m set --set ${1#+} src"
}
#
# Generate a match for packets whose destination matches the passed IPSET
#
match_ipset_dest()
{
echo "-m set --set ${1#+} dst"
}
#
# Jacket for ip_range() that takes care of iprange match
#
@ -1002,7 +1082,7 @@ validate_hosts_file() {
startup_error "Bridged interfaces may not be defined in /etc/shorewall/interfaces: $host"
check_bridge_port ${host%%:*}
;;
*.*.*.*)
*.*.*.*|+*)
;;
*)
known_interface $host && \
@ -2380,7 +2460,7 @@ process_tc_rule()
if [ "x$source" != "x-" ]; then
case $source in
*.*.*)
*.*.*|+*|!+*)
r="$(source_ip_range $source) "
;;
~*)
@ -2431,7 +2511,7 @@ process_tc_rule()
if [ "x$dest" != "x-" ]; then
case $dest in
*.*.*)
*.*.*|+*|!+*)
r="${r}$(dest_ip_range $dest) "
;;
*)
@ -2685,8 +2765,8 @@ process_accounting_rule() {
accounting_interface_verify ${source%:*}
rule="-s ${source#*:} $(match_source_dev ${source%:*})"
;;
*.*.*.*)
rule="-s $source"
*.*.*.*|+*|!+*)
rule="$(source_ip_range)"
;;
-|all|any)
;;
@ -2703,7 +2783,7 @@ process_accounting_rule() {
accounting_interface_verify ${dest%:*}
rule="$rule $(dest_ip_range ${dest#*:}) $(match_dest_dev ${dest%:*})"
;;
*.*.*.*)
*.*.*.*|+*|!*)
rule="$rule $(dest_ip_range $dest)"
;;
-|all|any)
@ -3036,8 +3116,8 @@ add_an_action()
action_interface_verify ${client%:*}
cli="$(match_source_dev ${client%:*}) $(source_ip_range ${client#*:})"
;;
*.*.*)
cli="-s $client"
*.*.*|+*|!+*)
cli="$(source_ip_range $client)"
;;
~*)
cli=$(mac_match $client)
@ -3058,7 +3138,7 @@ add_an_action()
case "$server" in
-)
;;
*.*.*)
*.*.*|+*|!+*)
serv=$server
;;
~*)
@ -3116,7 +3196,7 @@ add_an_action()
for srv in $(firewall_ip_range $serv1); do
if [ -n "$loglevel" ]; then
log_rule_limit $loglevel $chain $action $logtarget "$ratelimit" "$logtag" -A $userandgroup \
$(fix_bang $proto $sports $multiport $cli $(source_ip_range $srv) $dports)
$(fix_bang $proto $sports $multiport $cli $(dest_ip_range $srv) $dports)
fi
run_iptables2 -A $chain $proto $multiport $cli $sports \
@ -4082,7 +4162,7 @@ add_a_rule()
rule_interface_verify ${client%:*}
cli="$(match_source_dev ${client%:*}) $(source_ip_range ${client#*:})"
;;
*.*.*)
*.*.*|+*)
cli="$(source_ip_range $client)"
;;
~*)
@ -4104,7 +4184,7 @@ add_a_rule()
case "$server" in
-)
;;
*.*.*)
*.*.*|+*)
serv=$server
;;
~*)
@ -4763,7 +4843,7 @@ process_tos_rule() {
fi
[ -n "$src" ] && case "$src" in
*.*.*)
*.*.*|+*|!+*)
#
# IP Address or networks
#
@ -4811,7 +4891,7 @@ process_tos_rule() {
fi
[ -n "$dst" ] && case "$dst" in
*.*.*)
*.*.*|+*|!+*)
#
# IP Address or networks
#
@ -5245,7 +5325,7 @@ setup_masq()
source="$networks"
case $source in
*.*.*)
*.*.*|+*|!+*)
;;
*)
networks=$(get_routed_networks $networks)
@ -5256,8 +5336,6 @@ setup_masq()
[ "x$addresses" = x- ] && addresses=
if [ -n "$addresses" -a -n "$add_snat_aliases" ]; then
for address in $(separate_list $addresses); do
address=${address%:)}
@ -5502,6 +5580,8 @@ process_blacklist_rec() {
local addr
local proto
local dport
local temp
local setname
for addr in $(separate_list $networks); do
case $addr in
@ -5825,6 +5905,16 @@ report_capabilities() {
report_capability "Owner Match" $OWNER_MATCH
}
#
# Restore ipsets
#
restore_ipsets()
{
local restore_sets=/var/lib/shorewall/${RESTOREFILE:-restore}-ipsets
[ -x $restore_sets ] && $restore_sets
}
#
# Perform Initialization
# - Delete all old rules
@ -5918,6 +6008,7 @@ initialize_netfilter () {
deleteallchains
setcontinue FORWARD
setcontinue INPUT
setcontinue OUTPUT
@ -7469,6 +7560,7 @@ do_initialize() {
DROPINVALID=
RFC1918_STRICT=
MACLIST_TTL=
RESTOREFILE=
RESTOREBASE=
TMP_DIR=

View File

@ -55,7 +55,10 @@ address|host)
May be either a host IP address such as 192.168.1.4 or a network address in
CIDR format like 192.168.1.0/24. If your kernel and iptables contain iprange
match support then IP address ranges of the form <low address>-<high address>
are also permitted."
are also permitted. If your kernel and iptables contain ipset match support
then you may specify the name of an ipset prefaced by "+". The name of the
ipsec may be optionally followed by a number of levels of ipset bindings
(1 - 6) that are to be followed"
;;
allow)

View File

@ -36,4 +36,30 @@ New Features in version 2.3.0
symbolic links, it's easy to alias command names to be anything you
want.
2) Support has been added for ipsets
(see http://people.netfilter.org/kadlec/ipset/).
In most places where an host or network address may be used, you may
also use the name of an ipset prefaced by "+". The name of the set
may optionally followed by a number from 1 to 6 enclosed in square
brackets ([]) -- this number indicates the maximum number of ipset
binding levels that are to be matched. Depending on the context
where the ipset name is used, either all "src" or all "dst" matches
will be used.
Example 1: Blacklist all hosts in an ipset named "blacklist"
/etc/shorewall/blacklist
#ADDRESS/SUBNET PROTOCOL PORT
+blacklist
Example 2: Allow SSH from all hosts in an ipset named "sshok:
/etc/shorewall/rules
#ACTION SOURCE DEST PROTO DEST PORT(S)
ACCEPT +sshok fw tcp 22

View File

@ -134,6 +134,11 @@
# Hosts may be specified as an IP address range using the
# syntax <low address>-<high address>. This requires that
# your kernel and iptables contain iprange match support.
# If you kernel and iptables have ipset match support then
# you may give the name of an ipset prefaced by "+". The
# ipset name may be optionally followed by a number from
# 1 to 6 enclosed in square brackets ([]) to indicate the
# number of levels of source bindings to be matched.
#
# dmz:192.168.2.2 Host 192.168.2.2 in the DMZ
#
@ -189,6 +194,14 @@
# the connections will be assigned to addresses in the
# range in a round-robin fashion.
#
# If you kernel and iptables have ipset match support then
# you may give the name of an ipset prefaced by "+". The
# ipset name may be optionally followed by a number from
# 1 to 6 enclosed in square brackets ([]) to indicate the
# number of levels of destination bindings to be matched.
# Only one of the SOURCE and DEST columns may specify an
# ipset name.
#
# The port that the server is listening on may be
# included and separated from the server's IP address by
# ":". If omitted, the firewall will not modifiy the