diff --git a/bin/srfirewall b/bin/srfirewall index 5033c39..fa780b0 100755 --- a/bin/srfirewall +++ b/bin/srfirewall @@ -172,6 +172,8 @@ if [ "${EnableIPv4}" == "yes" ]; then [ "${DNSClientManualv4Servers}" ] && allow_dnsclient_manual ipv4 "${DNSClientManualv4Servers}" [ "${Enablev4EasyBlock}" == "yes" ] && enable_easyblock ipv4 [ "${Enablev4Filtering}" == "yes" ] && enable_filtering ipv4 + #[ "${Enablev4Forwarding}" == "yes" ] && enable_forwarding ipv4 + [ "${Enablev4NAT}" == "yes" ] && enable_nat ipv4 fi @@ -191,5 +193,7 @@ if [ "${EnableIPv6}" == "yes" ]; then [ "${DNSClientManualv6Servers}" ] && allow_dnsclient_manual ipv6 "${DNSClientManualv6Servers}" [ "${Enablev6EasyBlock}" == "yes" ] && enable_easyblock ipv6 [ "${Enablev6Filtering}" == "yes" ] && enable_filtering ipv6 + #[ "${Enablev6Forwarding}" == "yes" ] && enable_forwarding ipv6 + [ "${Enablev6NAT}" == "yes" ] && enable_nat ipv6 fi diff --git a/etc/ipv4.conf b/etc/ipv4.conf index 2578dde..9ea5a98 100644 --- a/etc/ipv4.conf +++ b/etc/ipv4.conf @@ -51,4 +51,10 @@ Enablev4EasyBlock="yes" # filtering rules. # Config file: ipv4/acl.conf # Values: no | yes (default) -Enablev4Filtering="yes" \ No newline at end of file +Enablev4Filtering="yes" + +# Enable IPv4 NAT/NETMAP rules +# This allows you to set up NAT rules, SNAT, MASQ, and NETMAP +# Config file: ipv4/nat.conf +# Values: no | yes (default) +Enablev4NAT="yes" \ No newline at end of file diff --git a/etc/ipv4/nat.conf b/etc/ipv4/nat.conf new file mode 100644 index 0000000..c50aa3a --- /dev/null +++ b/etc/ipv4/nat.conf @@ -0,0 +1,18 @@ +# Network Address Translation Rules +# Use this file to set up network address translation rules +# Use tabs or single space to separate +# +# +# +# Type: Required ( SNAT | MASQ | NETMAP ) +# Source Interface: Optional ( interface name, aka eth0 ) +# Source Address: Optional ( IP address with optional netmask ) +# Destination Interface: Optional for all but MASQ ( interface name, aka eth0 ) +# Destination Address: Required for all but MASQ ( IP address with optional netmask ) +# You can use '-' for optional fields +#============================================================ +# +SNAT eth1 10.0.0.0/24 eth0 172.16.1.1 +MASQ - - eth0 - +NETMAP eth1 192.168.0.0/24 vpn0 172.16.10.0/24 + diff --git a/etc/ipv6.conf b/etc/ipv6.conf index bc9ad6c..4fe0378 100644 --- a/etc/ipv6.conf +++ b/etc/ipv6.conf @@ -51,4 +51,10 @@ Enablev6EasyBlock="yes" # filtering rules. # Config file: ipv6/acl.conf # Values: no | yes (default) -Enablev6Filtering="yes" \ No newline at end of file +Enablev6Filtering="yes" + +# Enable IPv6 NAT/NETMAP rules +# This allows you to set up NAT rules, SNAT, MASQ, and NETMAP +# Config file: ipv4/nat.conf +# Values: no | yes (default) +Enablev6NAT="yes" \ No newline at end of file diff --git a/lib/iptables.inc b/lib/iptables.inc index 698973a..259415e 100644 --- a/lib/iptables.inc +++ b/lib/iptables.inc @@ -318,4 +318,54 @@ function enable_filtering { done < "${FWCONFIGDIR}/ipv${IPVER}/acl.conf" ${debug} ${DebugColor} "${FUNCNAME}:${DEFAULT_COLOR} done" fi +} + +function enable_nat { + IP_VERSION=$1 + case $IP_VERSION in + ipv6) VER_IPTABLES=${IP6TABLES}; + IPVER="6" ;; + ipv4|*) VER_IPTABLES=${IPTABLES} + IPVER="4" ;; + esac + ${debug} ${DebugColor} "${FUNCNAME}:${DEFAULT_COLOR} loading" + if [ -e "${FWCONFIGDIR}/ipv${IPVER}/nat.conf" ]; then + ${debug} ${DebugColor} "${FUNCNAME}:${DEFAULT_COLOR} read ${FWCONFIGDIR}/ipv${IPVER}/nat.conf successful" + while read -r type srcinterface srcaddress dstinterface dstaddress; do + [[ ${type} = \#* ]] && continue + [[ ${type} = "" ]] && continue + ([[ ${type} != "SNAT" ]] && [[ ${type} != "MASQ" ]] && [[ ${type} != "NETMAP" ]]) \ + && ${display} RED "nat.conf: Error - must begin with SNAT/MASQ/NETMAP: ${DEFAULT_COLOR}${type} ${srcinterface} ${srcaddress} ${dstinterface} ${dstaddress}" && continue + + # Do some creative work with variables to make building the iptables rules fairly painless + [[ ${srcinterface} != "-" ]] && srcinterface="-i ${srcinterface}" + [[ ${dstinterface} != "-" ]] && dstinterface="-o ${dstinterface}" + ([[ ${srcaddresss} != "-" ]] && [[ ${type} != "NETMAP" ]]) && srcaddress="-s ${srcaddress}" + + ([[ ${dstinterface} != "-" ]] && [[ ${type} == "MASQ" ]]) && action="-j MASQUERADE" + ([[ ${dstinterface} == "-" ]] && [[ ${type} == "MASQ" ]]) && \ + ${display} RED "nat.conf: Error - MASQ rule can not have empty destination interface: ${DEFAULT_COLOR}${type} ${srcinterface} ${srcaddress} ${dstinterface} ${dstaddress}" \ + && continue + + ([[ ${dstaddress} != "-" ]] && [[ ${type} == "SNAT" ]]) && action="-j SNAT" && dstaddress="--to-source ${dstaddress}" + ([[ ${dstaddress} == "-" ]] && [[ ${type} == "SNAT" ]]) && \ + ${display} RED "nat.conf: Error - SNAT rule can not have empty destination address: ${DEFAULT_COLOR}${type} ${srcinterface} ${srcaddress} ${dstinterface} ${dstaddress}" \ + && continue + + ([[ ${srcaddress} != "-" ]] && [[ ${dstaddress} != "-" ]] && [[ ${type} == "NETMAP" ]]) && action="-j NETMAP" && srcaddress="-d ${srcaddress}" && dstaddress="--to ${dstaddress}" + + + ${debug} ${DebugColor} "${FUNCNAME}:${DEFAULT_COLOR}${direction} ${action} ${interface} ${srcaddress} ${srcport} ${dstaddress} ${dstport} ${protocol}" + + # Blank variables that we're not going to use. + [[ ${srcinterface} == "-" ]] && srcinterface="" + [[ ${dstinterface} == "-" ]] && dstinterface="" + [[ ${dstaddress} == "-" ]] && dstaddress="" + [[ ${srcaddress} == "-" ]] && srcaddress="" + + ${VER_IPTABLES} -A ${NAT} ${srcinterface} ${srcaddress} ${dstinterface} ${dstaddress} ${action} + ${VER_IPTABLES} -A ${FwdFilter} ${M_STATE} ${C_STATE} RELATED,ESTABLISHED ${srcinterface} ${srcaddress} ${dstinterface} -j ACCEPT + done < "${FWCONFIGDIR}/ipv${IPVER}/nat.conf" + ${debug} ${DebugColor} "${FUNCNAME}:${DEFAULT_COLOR} done" + fi } \ No newline at end of file