diff --git a/Shorewall2/changelog.txt b/Shorewall2/changelog.txt index e980997ee..aea828089 100644 --- a/Shorewall2/changelog.txt +++ b/Shorewall2/changelog.txt @@ -36,4 +36,6 @@ Changes since 2.0.1 17) Lots of fixes to 'save' -18) 'shorewall forget' \ No newline at end of file +18) 'shorewall forget' + +19) SNAT/MASQUERADE by proto/port(s) diff --git a/Shorewall2/firewall b/Shorewall2/firewall index 69122fb3c..c5cd245b5 100755 --- a/Shorewall2/firewall +++ b/Shorewall2/firewall @@ -4121,6 +4121,8 @@ setup_masq() ;; esac + [ "x$addresses" = x- ] && addresses= + if [ -n "$addresses" -a -n "$ADD_SNAT_ALIASES" ]; then for address in $(separate_list $addresses); do for addr in $(ip_range_explicit $address) ; do @@ -4137,6 +4139,47 @@ setup_masq() done fi + [ "x$proto" = x- ] && proto= + [ "x$ports" = x- ] && ports= + + if [ -n "$proto" ]; then + + displayproto="($proto)" + + case $proto in + tcp|TCP|udp|UDP|6|17) + if [ -n "$ports" ]; then + displayproto="($proto $ports)" + + if [ $(list_count $ports) -gt 1 ]; then + case $ports in + *:*) + fatal_error "Port Range not allowed in list ($ports)" + ;; + *) + if [ -n "$MULTIPORT" ]; then + ports="-m multiport --dports $ports" + else + fatal_error "Port Ranges require multiport match support in your kernel ($ports)" + fi + ;; + esac + else + ports="--dport $ports" + fi + fi + ;; + *) + [ -n "$ports" ] && fatal_error "Ports only allowed with UDP or TCP ($ports)" + ;; + esac + + proto="-p $proto" + else + displayproto="(all)" + [ -n "$ports" ] && fatal_error "Ports only allowed with UDP or TCP ($ports)" + fi + destination=$destnets chain=$(masq_chain $interface) @@ -4153,7 +4196,7 @@ setup_masq() if [ -n "$networks" ]; then for s in $networks; do - addnatrule $chain -s $s -j $newchain + addnatrule $chain -s $s $proto $ports -j $newchain done networks= else @@ -4163,6 +4206,8 @@ setup_masq() masq_seq=$(($masq_seq + 1)) chain=$newchain destnets=0.0.0.0/0 + proto= + ports= if [ -n "$nomasq" ]; then for addr in $(separate_list $nomasq); do @@ -4179,12 +4224,12 @@ setup_masq() if [ -n "$networks" ]; then for s in $networks; do for destnet in $(separate_list $destnets); do - addnatrule $chain -d $destnet -s $s -j $newchain + addnatrule $chain -d $destnet -s $s $proto $ports -j $newchain done done else for destnet in $(separate_list $destnets); do - addnatrule $chain -d $destnet -j $newchain + addnatrule $chain -d $destnet $proto $ports -j $newchain done fi @@ -4192,6 +4237,8 @@ setup_masq() chain=$newchain networks= destnets=0.0.0.0/0 + proto= + ports= for addr in $(separate_list $nomasq); do addnatrule $chain -s $addr -j RETURN @@ -4203,6 +4250,7 @@ setup_masq() esac addrlist= + if [ -n "$addresses" ]; then for address in $(separate_list $addresses); do addrlist="$addrlist --to-source $address" @@ -4213,26 +4261,26 @@ setup_masq() for s in $networks; do if [ -n "$addresses" ]; then for destnet in $(separate_list $destnets); do - addnatrule $chain -s $s -d $destnet -j SNAT $addrlist + addnatrule $chain -s $s -d $destnet $proto $ports -j SNAT $addrlist done - progress_message " To $destination from $s through ${interface} using $addresses" + progress_message " To $destination $displayproto from $s through ${interface} using $addresses" else for destnet in $(separate_list $destnets); do - addnatrule $chain -s $s -d $destnet -j MASQUERADE + addnatrule $chain -s $s -d $destnet $proto $ports -j MASQUERADE done - progress_message " To $destination from $s through ${interface}" + progress_message " To $destination $displayproto from $s through ${interface}" fi done elif [ -n "$addresses" ]; then for destnet in $(separate_list $destnets); do - addnatrule $chain -d $destnet -j SNAT $addrlist + addnatrule $chain -d $destnet $proto $ports -j SNAT $addrlist done - echo " To $destination from $source through ${interface} using $addresses" + echo " To $destination $displayproto from $source through ${interface} using $addresses" else for destnet in $(separate_list $destnets); do - addnatrule $chain -d $destnet -j MASQUERADE + addnatrule $chain -d $destnet $proto $ports -j MASQUERADE done - progress_message " To $destination from $source through ${interface}" + progress_message " To $destination $displayproto from $source through ${interface}" fi } @@ -4241,8 +4289,8 @@ setup_masq() [ -n "$NAT_ENABLED" ] && echo "Masqueraded Networks and Hosts:" - while read fullinterface networks addresses; do - expandv fullinterface networks addresses + while read fullinterface networks addresses proto ports; do + expandv fullinterface networks addresses proto ports [ -n "$NAT_ENABLED" ] && setup_one || \ error_message "Warning: NAT disabled; masq rule ignored" done < $TMP_DIR/masq diff --git a/Shorewall2/masq b/Shorewall2/masq index 4a548a866..19f5aaf92 100755 --- a/Shorewall2/masq +++ b/Shorewall2/masq @@ -55,6 +55,26 @@ # # This column may not contain DNS Names. # +# If you want to leave this column empty +# but you need to specify the next column then +# place a hyphen ("-") here. +# +# PROTO -- (Optional) If you wish to restrict this entry to a +# particular protocol then enter the protocol +# name (from /etc/protocols) or number here. +# +# PORT(S) -- (Optional) If the PROTO column specifies TCP (protocol 6) +# or UDP (protocol 17) then you may list one +# or more port numbers (or names from +# /etc/services) separated by commas or you +# may list a single port range +# (:). +# +# Where a comma-separated list is given, your +# kernel and iptables must have multiport match +# support. +# +# # Example 1: # # You have a simple masquerading setup where eth0 connects to @@ -94,6 +114,19 @@ # # eth0:0 192.168.1.0/24 206.124.146.176 # +# Example 5: +# +# You want all outgoing SMTP traffic entering the firewall +# on eth1 to be sent from eth0 with source IP address +# 206.124.146.177. You want all other outgoing traffic +# from eth1 to be sent from eth0 with source IP address +# 206.124.146.176. +# +# eth0 eth1 206.124.146.177 tcp smtp +# eth0 eth1 206.124.146.176 +# +# THE ORDER OF THE ABOVE TWO RULES IS SIGNIFICANT!!!!! +# ############################################################################### -#INTERFACE SUBNET ADDRESS +#INTERFACE SUBNET ADDRESS PROTO PORT(S) #LAST LINE -- ADD YOUR ENTRIES ABOVE THIS LINE -- DO NOT REMOVE diff --git a/Shorewall2/releasenotes.txt b/Shorewall2/releasenotes.txt index 49e19faca..11a909d95 100755 --- a/Shorewall2/releasenotes.txt +++ b/Shorewall2/releasenotes.txt @@ -174,5 +174,28 @@ New Features: 9) Shorewall now used 'modprobe' to load kernel modules if that utility is available in the PATH; otherwise, 'insmod' is used. +10) It is now possible to restrict entries in the /etc/shorewall/masq + file to particular protocols and destination port(s). Two new + columns (PROTO and PORT(S)) have been added to the file. + + Example: + + You want all outgoing SMTP traffic entering the firewall + on eth1 to be sent from eth0 with source IP address + 206.124.146.177. You want all other outgoing traffic + from eth1 to be sent from eth0 with source IP address + 206.124.146.176. + + eth0 eth1 206.124.146.177 tcp 25 + eth0 eth1 206.124.146.176 + + THE ORDER OF THE ABOVE TWO RULES IS SIGNIFICANT!!!!! + + Assuming that 10.0.0.0/8 is the only host/network connected + to eth1, the progress message at "shorewall start" would be: + + Masqueraded Networks and Hosts: + To 0.0.0.0/0 (tcp 25) from 10.0.0.0/8 through eth0 using 206.124.146.176 + To 0.0.0.0/0 (all) from 10.0.0.0/8 through eth0 using 206.124.146.179