diff --git a/Shorewall2/accounting b/Shorewall2/accounting index 33564fcda..499dbf24d 100644 --- a/Shorewall2/accounting +++ b/Shorewall2/accounting @@ -61,13 +61,33 @@ # only be specified if the protocol is TCP or UDP (6 # or 17). # +# USER/GROUP This column may only be non-empty if the CHAIN is +# OUTPUT. +# +# The column may contain: +# +# [!][][:] +# +# When this column is non-empty, the rule applies only +# if the program generating the output is running under +# the effective and/or specified (or is +# NOT running under that id if "!" is given). +# +# Examples: +# +# joe #program must be run by joe +# :kids #program must be run by a member of +# #the 'kids' group +# !:kids #program must not be run by a member +# #of the 'kids' group +# # In all of the above columns except ACTION and CHAIN, the values "-", # "any" and "all" may be used as wildcards # # Please see http://shorewall.net/Accounting.html for examples and # additional information about how to use this file. # -#ACTION CHAIN SOURCE DESTINATION PROTO DEST SOURCE -# PORT PORT +#ACTION CHAIN SOURCE DESTINATION PROTO DEST SOURCE USER/ +# PORT PORT GROUP # #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE diff --git a/Shorewall2/changelog.txt b/Shorewall2/changelog.txt index 787758980..4c394f3a1 100644 --- a/Shorewall2/changelog.txt +++ b/Shorewall2/changelog.txt @@ -52,3 +52,5 @@ Changes since 2.0.3 24) Deprecate the -c option in /sbin/shorewall. 25) Allow distinct input and output IPSEC parameters. + +26) Allow source port remapping in /etc/shorewall/masq. diff --git a/Shorewall2/firewall b/Shorewall2/firewall index 0fd2124fd..30b5ef58d 100755 --- a/Shorewall2/firewall +++ b/Shorewall2/firewall @@ -2324,11 +2324,11 @@ process_accounting_rule() { jumpchain= accounting_error() { - error_message "Warning: Invalid Accounting rule" $action $chain $source $dest $proto $port $sport + error_message "Warning: Invalid Accounting rule" $action $chain $source $dest $proto $port $sport $user } accounting_interface_error() { - error_message "Warning: Unknown interface $1 in " $action $chain $source $dest $proto $port $sport + error_message "Warning: Unknown interface $1 in " $action $chain $source $dest $proto $port $sport $user } accounting_interface_verify() { @@ -2404,6 +2404,25 @@ process_accounting_rule() { ;; esac + [ -n "$user" ] && case $user in + -|any|all) + ;; + *:*) + [ "$chain" != OUTPUT ] && \ + fatal_error "Invalid use of a user/group: chain is not OUTPUT but $chain" + rule="$rule -m owner" + temp="${user%:*}" + [ -n "$temp" ] && rule="$rule --uid-owner $temp " + temp="${user#*:}" + [ -n "$temp" ] && rule="$rule --gid-owner $temp " + ;; + *) + [ "$chain" != OUTPUT ] && \ + fatal_error "Invalid use of a user/group: chain is not OUTPUT but $chain" + rule="$rule -m owner --uid-owner $user " + ;; + esac + case $action in COUNT) ;; @@ -2432,7 +2451,7 @@ process_accounting_rule() { if iptables -A $chain $(fix_bang $rule) ; then [ -n "$rule2" ] && run_iptables2 -A $jumpchain $rule2 - progress_message " Accounting rule" $action $chain $source $dest $proto $port $sport Added + progress_message " Accounting rule" $action $chain $source $dest $proto $port $sport $user Added else accounting_error fi @@ -2448,8 +2467,8 @@ setup_accounting() # $1 = Name of accounting file strip_file accounting $1 - while read action chain source dest proto port sport ; do - expandv action chain source dest proto port sport + while read action chain source dest proto port sport user ; do + expandv action chain source dest proto port sport user process_accounting_rule done < $TMP_DIR/accounting @@ -4687,17 +4706,20 @@ setup_masq() if [ -n "$addresses" -a -n "$add_snat_aliases" ]; then for address in $(separate_list $addresses); do - for addr in $(ip_range_explicit $address) ; do - if ! list_search $addr $aliases_to_add; then - save_command qt ip addr del $addr dev $interface - aliases_to_add="$aliases_to_add $addr $fullinterface" - case $fullinterface in - *:*) - fullinterface=${fullinterface%:*}:$((${fullinterface#*:} + 1 )) - ;; - esac - fi - done + address=${address%:)} + if [ -n "$address" ]; then + for addr in $(ip_range_explicit ${address%:*}) ; do + if ! list_search $addr $aliases_to_add; then + save_command qt ip addr del $addr dev $interface + aliases_to_add="$aliases_to_add $addr $fullinterface" + case $fullinterface in + *:*) + fullinterface=${fullinterface%:*}:$((${fullinterface#*:} + 1 )) + ;; + esac + fi + done + fi done fi @@ -4817,37 +4839,44 @@ setup_masq() esac addrlist= + target=MASQUERADE if [ -n "$addresses" ]; then for address in $(separate_list $addresses); do - addrlist="$addrlist --to-source $address" + case $address in + *.*.*.*) + target=SNAT + addrlist="$addrlist --to-source $address" + ;; + *) + addrlist="$addrlist --to-ports ${address#:}" + ;; + esac done fi if [ -n "$networks" ]; then - for s in $networks; do + for network in $networks; do + for destnet in $(separate_list $destnets); do + addnatrule $chain -s $network -d $destnet $proto $ports $policy -j $target $addrlist + done + if [ -n "$addresses" ]; then - for destnet in $(separate_list $destnets); do - addnatrule $chain -s $s -d $destnet $proto $ports $policy -j SNAT $addrlist - done - progress_message " To $destination $displayproto from $s through ${interface} using $addresses" + progress_message " To $destination $displayproto from $network through ${interface} using $addresses" else - for destnet in $(separate_list $destnets); do - addnatrule $chain -s $s -d $destnet $proto $ports $policy -j MASQUERADE - done - progress_message " To $destination $displayproto from $s through ${interface}" + progress_message " To $destination $displayproto from $network through ${interface}" fi done - elif [ -n "$addresses" ]; then - for destnet in $(separate_list $destnets); do - addnatrule $chain -d $destnet $proto $ports $policy -j SNAT $addrlist - done - echo " To $destination $displayproto from $source through ${interface} using $addresses" else for destnet in $(separate_list $destnets); do - addnatrule $chain -d $destnet $proto $ports $policy -j MASQUERADE + addnatrule $chain -d $destnet $proto $ports $policy -j $target $addrlist done - progress_message " To $destination $displayproto from $source through ${interface}" + + if [ -n "$addresses" ]; then + progress_message " To $destination $displayproto from $source through ${interface} using $addresses" + else + progress_message " To $destination $displayproto from $source through ${interface}" + fi fi } @@ -5266,6 +5295,9 @@ initialize_netfilter () { echo "Deleting user chains..." + exists_INPUT=Yes + exists_OUTPUT=Yes + exists_FORWARD=Yes setpolicy INPUT DROP setpolicy OUTPUT DROP setpolicy FORWARD DROP diff --git a/Shorewall2/masq b/Shorewall2/masq index 7c6dd1ae8..f5f2f46a4 100755 --- a/Shorewall2/masq +++ b/Shorewall2/masq @@ -73,6 +73,19 @@ # # This column may not contain DNS Names. # +# Normally, Netfilter will attempt to retain +# the source port number. You may cause +# netfilter to remap the source port by following +# an address or range (if any) by ":" and +# a port range with the format - +# . If this is done, you must +# specify "tcp" or "udp" in the PROTO column. +# +# Examples: +# +# 192.0.2.4:5000-6000 +# :4000-5000 +# # If you want to leave this column empty # but you need to specify the next column then # place a hyphen ("-") here. diff --git a/Shorewall2/releasenotes.txt b/Shorewall2/releasenotes.txt index 3ca33d838..54cb06cb5 100755 --- a/Shorewall2/releasenotes.txt +++ b/Shorewall2/releasenotes.txt @@ -381,3 +381,26 @@ New Features: shorewall restart [ ] shorewall start [ ] +11) Normally, when SNAT or MASQUERADE is applied to a tcp or udp + connection, Netfilter attempts to retain the source port + number. If it has to change to port number to avoid + , conflicts, it tries to do so + within port ranges ( < 512, 512-1023, and > 1023). You may + now specify an explicit range of source ports to be used + by following the address or address range (if any) in the + ADDRESS column with ":" and a port range in the format + -. You must specify either "tcp" or + "udp" in the PROTO column. + + Examples 1 -- MASQUERADE with tcp source ports 4000-5000: + + #INTERFACE SUBNET ADDRESS PROTO + eth0 192.168.1.0/24 :4000-5000 tcp + + Example 2 -- SNAT with udp source ports 7000-8000: + + #INTERFACE SUBNET ADDRESS PROTO + eth0 10.0.0.0/8 192.0.2.44:7000-8000 udp + + +