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

@ -70,7 +70,17 @@
# #
# 10.0.0.4-10.0.0.9 Range of IP addresses; your # 10.0.0.4-10.0.0.9 Range of IP addresses; your
# kernel and iptables must have # kernel and iptables must have
# iprange match support. # 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 # 192.168.1.1,192.168.1.2
# Hosts 192.168.1.1 and # Hosts 192.168.1.1 and
@ -85,8 +95,9 @@
# another colon (":") and an IP/MAC/subnet address # another colon (":") and an IP/MAC/subnet address
# as described above (e.g., eth1:192.168.1.5). # as described above (e.g., eth1:192.168.1.5).
# #
# DEST Location of Server. Same as above with the exception that # DEST Location of destination host. Same as above with the exception that
# MAC addresses are not allowed. # 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 # PROTO Protocol - Must be "tcp", "udp", "icmp", a number, or
# "all". # "all".

View File

@ -7,9 +7,10 @@
# #
# Columns are: # 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 # 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 "-" # MAC addresses must be prefixed with "~" and use "-"
# as a separator. # as a separator.
@ -38,6 +39,13 @@
# ADDRESS/SUBNET PROTOCOL PORT # ADDRESS/SUBNET PROTOCOL PORT
# 192.0.2.126 udp 53 # 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 # Please see http://shorewall.net/blacklisting_support.htm for additional
# information. # information.
# #

View File

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

View File

@ -218,6 +218,19 @@ run_tc() {
fi 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 # Create a filter chain
# #
@ -541,6 +554,29 @@ iprange_echo()
fi 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 # Source IP range
@ -558,6 +594,12 @@ source_ip_range() # $1 = Address or Address Range
;; ;;
esac esac
;; ;;
!+*)
echo "-m set ! $(get_set_flags ${1#!} src)"
;;
+*)
echo "-m set $(get_set_flags $1 src)"
;;
*) *)
echo "-s $1" echo "-s $1"
;; ;;
@ -580,6 +622,12 @@ dest_ip_range() # $1 = Address or Address Range
;; ;;
esac esac
;; ;;
!+*)
echo "-m set ! $(get_set_flags ${1#!} dst)"
;;
+*)
ipset_echo "-m set $(get_set_flags ${1#+} dst)"
;;
*) *)
echo "-d $1" echo "-d $1"
;; ;;
@ -595,6 +643,10 @@ both_ip_ranges() # $1 = Source address or range, $2 = dest address or range
prefix="-m iprange" prefix="-m iprange"
match="--src-range $1" match="--src-range $1"
;; ;;
+*)
prefix="-m set"
match="--set ${1#+} src"
;;
*) *)
match="-s $1" match="-s $1"
;; ;;
@ -605,6 +657,18 @@ both_ip_ranges() # $1 = Source address or range, $2 = dest address or range
prefix="-m iprange" prefix="-m iprange"
match="$match --dst-range $2" match="$match --dst-range $2"
;; ;;
+*)
case $1 in
*.*.*.*-*.*.*.*)
prefix="$iprange -m set"
;;
*)
prefix="-m set"
;;
esac
match="--set ${1#+} dst"
;;
*) *)
match="$match -d $2" match="$match -d $2"
;; ;;
@ -749,6 +813,22 @@ match_ipsec_out() # $1 = zone, $2 = host
fi 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 # 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" startup_error "Bridged interfaces may not be defined in /etc/shorewall/interfaces: $host"
check_bridge_port ${host%%:*} check_bridge_port ${host%%:*}
;; ;;
*.*.*.*) *.*.*.*|+*)
;; ;;
*) *)
known_interface $host && \ known_interface $host && \
@ -2380,7 +2460,7 @@ process_tc_rule()
if [ "x$source" != "x-" ]; then if [ "x$source" != "x-" ]; then
case $source in case $source in
*.*.*) *.*.*|+*|!+*)
r="$(source_ip_range $source) " r="$(source_ip_range $source) "
;; ;;
~*) ~*)
@ -2431,7 +2511,7 @@ process_tc_rule()
if [ "x$dest" != "x-" ]; then if [ "x$dest" != "x-" ]; then
case $dest in case $dest in
*.*.*) *.*.*|+*|!+*)
r="${r}$(dest_ip_range $dest) " r="${r}$(dest_ip_range $dest) "
;; ;;
*) *)
@ -2685,8 +2765,8 @@ process_accounting_rule() {
accounting_interface_verify ${source%:*} accounting_interface_verify ${source%:*}
rule="-s ${source#*:} $(match_source_dev ${source%:*})" rule="-s ${source#*:} $(match_source_dev ${source%:*})"
;; ;;
*.*.*.*) *.*.*.*|+*|!+*)
rule="-s $source" rule="$(source_ip_range)"
;; ;;
-|all|any) -|all|any)
;; ;;
@ -2703,7 +2783,7 @@ process_accounting_rule() {
accounting_interface_verify ${dest%:*} accounting_interface_verify ${dest%:*}
rule="$rule $(dest_ip_range ${dest#*:}) $(match_dest_dev ${dest%:*})" rule="$rule $(dest_ip_range ${dest#*:}) $(match_dest_dev ${dest%:*})"
;; ;;
*.*.*.*) *.*.*.*|+*|!*)
rule="$rule $(dest_ip_range $dest)" rule="$rule $(dest_ip_range $dest)"
;; ;;
-|all|any) -|all|any)
@ -3036,8 +3116,8 @@ add_an_action()
action_interface_verify ${client%:*} action_interface_verify ${client%:*}
cli="$(match_source_dev ${client%:*}) $(source_ip_range ${client#*:})" cli="$(match_source_dev ${client%:*}) $(source_ip_range ${client#*:})"
;; ;;
*.*.*) *.*.*|+*|!+*)
cli="-s $client" cli="$(source_ip_range $client)"
;; ;;
~*) ~*)
cli=$(mac_match $client) cli=$(mac_match $client)
@ -3058,7 +3138,7 @@ add_an_action()
case "$server" in case "$server" in
-) -)
;; ;;
*.*.*) *.*.*|+*|!+*)
serv=$server serv=$server
;; ;;
~*) ~*)
@ -3116,7 +3196,7 @@ add_an_action()
for srv in $(firewall_ip_range $serv1); do for srv in $(firewall_ip_range $serv1); do
if [ -n "$loglevel" ]; then if [ -n "$loglevel" ]; then
log_rule_limit $loglevel $chain $action $logtarget "$ratelimit" "$logtag" -A $userandgroup \ 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 fi
run_iptables2 -A $chain $proto $multiport $cli $sports \ run_iptables2 -A $chain $proto $multiport $cli $sports \
@ -4082,7 +4162,7 @@ add_a_rule()
rule_interface_verify ${client%:*} rule_interface_verify ${client%:*}
cli="$(match_source_dev ${client%:*}) $(source_ip_range ${client#*:})" cli="$(match_source_dev ${client%:*}) $(source_ip_range ${client#*:})"
;; ;;
*.*.*) *.*.*|+*)
cli="$(source_ip_range $client)" cli="$(source_ip_range $client)"
;; ;;
~*) ~*)
@ -4104,7 +4184,7 @@ add_a_rule()
case "$server" in case "$server" in
-) -)
;; ;;
*.*.*) *.*.*|+*)
serv=$server serv=$server
;; ;;
~*) ~*)
@ -4763,7 +4843,7 @@ process_tos_rule() {
fi fi
[ -n "$src" ] && case "$src" in [ -n "$src" ] && case "$src" in
*.*.*) *.*.*|+*|!+*)
# #
# IP Address or networks # IP Address or networks
# #
@ -4811,7 +4891,7 @@ process_tos_rule() {
fi fi
[ -n "$dst" ] && case "$dst" in [ -n "$dst" ] && case "$dst" in
*.*.*) *.*.*|+*|!+*)
# #
# IP Address or networks # IP Address or networks
# #
@ -5245,7 +5325,7 @@ setup_masq()
source="$networks" source="$networks"
case $source in case $source in
*.*.*) *.*.*|+*|!+*)
;; ;;
*) *)
networks=$(get_routed_networks $networks) networks=$(get_routed_networks $networks)
@ -5254,9 +5334,7 @@ setup_masq()
;; ;;
esac esac
[ "x$addresses" = x- ] && addresses= [ "x$addresses" = x- ] && addresses=
if [ -n "$addresses" -a -n "$add_snat_aliases" ]; then if [ -n "$addresses" -a -n "$add_snat_aliases" ]; then
for address in $(separate_list $addresses); do for address in $(separate_list $addresses); do
@ -5502,16 +5580,18 @@ process_blacklist_rec() {
local addr local addr
local proto local proto
local dport local dport
local temp
local setname
for addr in $(separate_list $networks); do for addr in $(separate_list $networks); do
case $addr in case $addr in
~*) ~*)
addr=$(echo $addr | sed 's/~//;s/-/:/g') addr=$(echo $addr | sed 's/~//;s/-/:/g')
source="--match mac --mac-source $addr" source="--match mac --mac-source $addr"
;; ;;
*) *)
source="$(source_ip_range $addr)" source="$(source_ip_range $addr)"
;; ;;
esac esac
if [ -n "$protocol" ]; then if [ -n "$protocol" ]; then
@ -5825,6 +5905,16 @@ report_capabilities() {
report_capability "Owner Match" $OWNER_MATCH 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 # Perform Initialization
# - Delete all old rules # - Delete all old rules
@ -5918,6 +6008,7 @@ initialize_netfilter () {
deleteallchains deleteallchains
setcontinue FORWARD setcontinue FORWARD
setcontinue INPUT setcontinue INPUT
setcontinue OUTPUT setcontinue OUTPUT
@ -6918,7 +7009,7 @@ define_firewall() # $1 = Command (Start or Restart)
for file in chains nat proxyarp zones; do for file in chains nat proxyarp zones; do
append_file $file append_file $file
done done
save_progress_message "Restoring Netfilter Configuration..." save_progress_message "Restoring Netfilter Configuration..."
save_command 'iptables-restore << __EOF__' save_command 'iptables-restore << __EOF__'
@ -7469,6 +7560,7 @@ do_initialize() {
DROPINVALID= DROPINVALID=
RFC1918_STRICT= RFC1918_STRICT=
MACLIST_TTL= MACLIST_TTL=
RESTOREFILE=
RESTOREBASE= RESTOREBASE=
TMP_DIR= 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 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 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> 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) 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 symbolic links, it's easy to alias command names to be anything you
want. 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 # Hosts may be specified as an IP address range using the
# syntax <low address>-<high address>. This requires that # syntax <low address>-<high address>. This requires that
# your kernel and iptables contain iprange match support. # 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 # 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 # the connections will be assigned to addresses in the
# range in a round-robin fashion. # 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 # The port that the server is listening on may be
# included and separated from the server's IP address by # included and separated from the server's IP address by
# ":". If omitted, the firewall will not modifiy the # ":". If omitted, the firewall will not modifiy the