just wondering if all the gurus could comment on this script (below) before we move it into production. seems to work nicely on test box. thanks.
*-*-*-*-* #!/bin/bash # set to location of iptables IPTABLES="/sbin/iptables" # TCP ports to allow TCP_ALLOW="22 25 53 79 80 113 119 617 873" # UDP ports to allow (ports 6112, 6119, and 4000?) UDP_ALLOW="53 68 79 113 617 873" # Internet interface INET_IFACE="eth0" # LAN interface LAN_IFACE="eth1" # LAN Addresses INTERNAL_LAN="192.168.1.0/24" # Addresses to be MASQ'd (overridden by MAC_MASQ) MASQ_LAN="192.168.1.0/24" # Addresses that need static NAT SNAT_LAN="" # Default action of packets we don't want # DROP # REJECT # TREJECT (Reject with tcp-reset for TCP) # LDROP (log and drop) # LREJECT (log and reject) # LTREJECT (log and reject with tcp-reset) # ULDROP (ULOG and DROP) DROP="TREJECT" # Internet hosts that should be completely denied (inbound) DENY_ALL="" # Host/Port to deny TCP (format is IP>PORT) DENY_HOSTWISE_TCP="" # Host/Port to deny UDP (format is IP>PORT) DENY_HOSTWISE_UDP="" # People you dont want *any* communiction with (in or out) BLACKHOLE="" # What to do for the blackholed people BLACKHOLE_DROP="DROP" # Internet hosts that should have full access (inbound) ALLOW_ALL="" # Host/Port to allow TCP (format it IP>PORT) ALLOW_HOSTWISE_TCP="192.168.1.11>110" # Host/Port to allow UDP (format is IP/PORT) ALLOW_HOSTWISE_UDP="" # TCP ports to forward (format is SPORT:DPORT>IP) TCP_FW="" # UDP ports to forward (format is SPORT:DPORT>IP) UDP_FW="" # TOS optimizations on or off MANGLE_TOS_OPTIMIZE="TRUE" # Enable the firewall ? (Y/N) ENABLE="Y" # Flooding control # Logging limit LOG_FLOOD="2/s" # Global SYN packet limit SYN_FLOOD="20/s" # Global ICMP echo-reply limit PING_FLOOD="1/s" # Flooding control end # LAN hosts to be forwarded out on TCP ALLOW_OUT_TCP="" # Below here is experimental # Mac addresses of those permitted to do MASQ (blank turns off) MAC_MASQ="" # Mac addresses of those permitted to do SNAT (format MAC:external IP) MAC_SNAT="" # number of hops on LAN (needs netfilter patch) TTL_SAFE="" # Use TCP Syncookies USE_SYNCOOKIES="TRUE" # Use rp_filter on interfaces RP_FILTER="TRUE" # Use source-routing ACCEPT_SOURCE_ROUTE="FALSE" # Proxy address (format host:port) PROXY="" # Running a DHCP server for LAN? (if so, needs LAN_IFACE) DHCP_SERVER="TRUE" # ICMP message types to disallow from Internet BAD_ICMP="5 9 10 15 16 17 18" # ALPHA code .. don't use DMZ_IFACE="" # ----------------------------------------------------------------------| # These control basic script behavior, there should be no need to | # change any of these settings for normal use. | # ----------------------------------------------------------------------| FILTER_CHAINS="INETIN INETOUT DMZIN DMZOUT TCPACCEPT UDPACCEPT LDROP LREJECT TREJECT LTREJECT" UL_FILTER_CHAINS="ULDROP ULREJECT ULTREJECT" LOOP_IFACE="lo" # ----------------------------------------------------------------------| # Main Script Starts | # ----------------------------------------------------------------------| case $1 in start) # Let's load it! echo "Loading iptables firewall:" # Configuration Sanity Checks echo -n "Checking configuration..." # It's hard to run an iptables script without iptables... if ! [ -x $IPTABLES ] ; then echo echo "ERROR IN CONFIGURATION: ${IPTABLES} doesn't exist or isn't executable!" exit 1 fi # Basic interface sanity if [ "$DMZ_IFACE" = "$LAN_IFACE" ] && [ "$LAN_IFACE" != "" ]; then echo echo "ERROR IN CONFIGURATION: DMZ_IFACE and LAN_IFACE can't be the same!" exit 1 fi # Create a test chain to work with for system ablilities testing ${IPTABLES} -N SYSTEST # Check for ULOG support ${IPTABLES} -A SYSTEST -j ULOG > /dev/null 2>&1 if [ "$?" = "0" ] ; then HAVE_ULOG="true" else HAVE_ULOG="false" fi # Check for stateful matching ${IPTABLES} -A SYSTEST -m state --state ESTABLISHED -j ACCEPT > /dev/null 2>&1 if [ "$?" != "0" ] ; then echo echo "Your kernel lacks stateful matching, this would break this script. Aborting." exit 3 fi # Check DROP sanity if [ "$DROP" = "" ] ; then echo echo "There needs to be a DROP policy (try TREJECT)!" exit 1 fi if [ "$DROP" = "ACCEPT" ] ; then echo echo "The DROP policy is set to ACCEPT; there is no point in loading the firewall as there wouldn't be one." exit 2 fi if [ "$DROP" = "ULDROP" ] || [ "$DROP" = "ULREJECT" ] || [ "$DROP" = "ULTREJECT" ] ; then if [ "$HAVE_ULOG" != "true" ] ; then echo echo "You have selected a ULOG policy, but your system lacks ULOG support." echo "Please choose a policy that your system has support for." exit 3 fi fi # Problems with blackholes? if [ "$BLACKHOLE" != "" ] && [ "$BLACKHOLE_DROP" = "" ] ; then echo echo "You can't use blackholes and not have a policy for them!" exit 1 fi # Has it been configured? if ! [ "$ENABLE" = "Y" ] ; then echo echo "You need to edit your configuration and set ENABLE to Y!" exit 99 fi # Flush and remove the chain SYSTEST ${IPTABLES} -F SYSTEST ${IPTABLES} -X SYSTEST # Seems ok... echo "passed" # =============================================== # -------Set some Kernel stuff via SysCTL-------- # =============================================== # Turn on IP forwarding if [ "$INTERNAL_LAN" != "" ] ; then echo -n "Checking IP Forwarding..." if [ -e /proc/sys/net/ipv4/ip_forward ] ; then echo 1 > /proc/sys/net/ipv4/ip_forward echo "enabled." else echo "support not found! This will cause problems if you need to do any routing." fi fi # Enable TCP Syncookies echo -n "Checking IP SynCookies..." if [ -e /proc/sys/net/ipv4/tcp_syncookies ] ; then if [ "$USE_SYNCOOKIES" = "TRUE" ] ; then echo 1 > /proc/sys/net/ipv4/tcp_syncookies echo "enabled." else echo 0 > /proc/sys/net/ipv4/tcp_syncookies echo "disabled." fi else echo "support not found, but that's OK." fi # Enable Route Verification to prevent martians and other such crud that # seems to be commonplace on the internet today echo -n "Checking Route Verification..." if [ "$INET_IFACE" != "" ] ; then if [ -e /proc/sys/net/ipv4/conf/$INET_IFACE/rp_filter ] ; then if [ "$RP_FILTER" = "TRUE" ] ; then echo 1 > /proc/sys/net/ipv4/conf/$INET_IFACE/rp_filter echo -n "activated:${INET_IFACE} " else echo 0 > /proc/sys/net/ipv4/conf/$INET_IFACE/rp_filter echo -n "disabled:${INET_IFACE} " fi else echo "not found:${INET_IFACE} " fi fi if [ "$LAN_IFACE" != "" ] ; then if [ -e /proc/sys/net/ipv4/conf/$LAN_IFACE/rp_filter ] ; then if [ "$RP_FILTER" = "TRUE" ] ; then echo 1 > /proc/sys/net/ipv4/conf/$LAN_IFACE/rp_filter echo -n "activated:${LAN_IFACE} " else echo 0 > /proc/sys/net/ipv4/conf/$LAN_IFACE/rp_filter echo -n "disabled:${LAN_IFACE} " fi else echo "not found:${LAN_IFACE} " fi fi if [ "$DMZ_IFACE" != "" ] ; then if [ -e /proc/sys/net/ipv4/conf/$DMZ_IFACE/rp_filter ] ; then if [ "$RP_FILTER" = "TRUE" ] ; then echo 1 > /proc/sys/net/ipv4/conf/$DMZ_IFACE/rp_filter echo -n "activated:${DMZ_IFACE} " else echo 0 > /proc/sys/net/ipv4/conf/$DMZ_IFACE/rp_filter echo -n "disabled:${DMZ_IFACE} " fi else echo "not found:${DMZ_IFACE} " fi fi echo # Tell the Kernel to Ignore Source Routed Packets echo -n "Refusing SSR Packets via SysCtl..." if [ "$INET_IFACE" != "" ] ; then if [ -e /proc/sys/net/ipv4/conf/$INET_IFACE/accept_source_route ] ; then if [ "$ACCEPT_SOURCE_ROUTE" = "TRUE" ] ; then echo "1" > /proc/sys/net/ipv4/conf/$INET_IFACE/accept_source_route echo -n "disabled:${INET_IFACE} " else echo "0" > /proc/sys/net/ipv4/conf/$INET_IFACE/accept_source_route echo -n "activated:${INET_IFACE} " fi else echo "not found:${INET_IFACE} " fi fi if [ "$LAN_IFACE" != "" ] ; then if [ -e /proc/sys/net/ipv4/conf/$LAN_IFACE/accept_source_route ] ; then if [ "$ACCEPT_SOURCE_ROUTE" = "TRUE" ] ; then echo "1" > /proc/sys/net/ipv4/conf/$LAN_IFACE/accept_source_route echo -n "disabled:${LAN_IFACE} " else echo "0" > /proc/sys/net/ipv4/conf/$LAN_IFACE/accept_source_route echo -n "activated:${LAN_IFACE} " fi else echo "not found:${LAN_IFACE} " fi fi if [ "$DMZ_IFACE" != "" ] ; then if [ -e /proc/sys/net/ipv4/conf/$DMZ_IFACE/accept_source_route ] ; then if [ "$ACCEPT_SOURCE_ROUTE" = "TRUE" ] ; then echo "1" > /proc/sys/net/ipv4/conf/$DMZ_IFACE/accept_source_route echo -n "disabled:${DMZ_IFACE} " else echo "0" > /proc/sys/net/ipv4/conf/$DMZ_IFACE/accept_source_route echo -n "activated:${DMZ_IFACE} " fi else echo "not found:${DMZ_IFACE} " fi fi echo # =============================================== # --------Actual NetFilter Stuff Follows--------- # =============================================== # Flush everything # If you need compatability, you can comment some or all of these out, # but remember, if you re-run it, it'll just add the new rules in, it # won't remove the old ones for you then, this is how it removes them. echo -n "Flush: " ${IPTABLES} -t filter -F INPUT echo -n "INPUT " ${IPTABLES} -t filter -F OUTPUT echo -n "OUTPUT1 " ${IPTABLES} -t filter -F FORWARD echo -n "FORWARD " ${IPTABLES} -t nat -F PREROUTING echo -n "PREROUTING1 " ${IPTABLES} -t nat -F OUTPUT echo -n "OUTPUT2 " ${IPTABLES} -t nat -F POSTROUTING echo -n "POSTROUTING " ${IPTABLES} -t mangle -F PREROUTING echo -n "PREROUTING2 " ${IPTABLES} -t mangle -F OUTPUT echo -n "OUTPUT3" echo # Create new chains # Output to /dev/null in case they don't exist from a previous invocation echo -n "Creating chains: " for chain in ${FILTER_CHAINS} ; do ${IPTABLES} -t filter -F ${chain} > /dev/null 2>&1 ${IPTABLES} -t filter -X ${chain} > /dev/null 2>&1 ${IPTABLES} -t filter -N ${chain} echo -n "${chain} " done if [ ${HAVE_ULOG} = "true" ] ; then for chain in ${UL_FILTER_CHAINS} ; do ${IPTABLES} -t filter -F ${chain} > /dev/null 2>&1 ${IPTABLES} -t filter -X ${chain} > /dev/null 2>&1 ${IPTABLES} -t filter -N ${chain} echo -n "${chain} " done fi echo # Default Policies # INPUT policy is drop # Policy can't be reject because of kernel limitations echo -n "Default Policies: " ${IPTABLES} -t filter -P INPUT DROP echo -n "INPUT:DROP " ${IPTABLES} -t filter -P OUTPUT ACCEPT echo -n "OUTPUT:ACCEPT " ${IPTABLES} -t filter -P FORWARD DROP echo -n "FORWARD:DROP " echo # =============================================== # -------Chain setup before jumping to them------ # =============================================== #These logging chains are valid to specify in DROP= above #Set up LDROP echo -n "Setting up drop chains chains: " ${IPTABLES} -t filter -A LDROP -p tcp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "TCP Dropped " ${IPTABLES} -t filter -A LDROP -p udp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "UDP Dropped " ${IPTABLES} -t filter -A LDROP -p icmp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "ICMP Dropped " ${IPTABLES} -t filter -A LDROP -f -m limit --limit ${LOG_FLOOD} -j LOG --log-level 4 --log-prefix "FRAGMENT Dropped " ${IPTABLES} -t filter -A LDROP -j DROP echo -n "LDROP " #And LREJECT too ${IPTABLES} -t filter -A LREJECT -p tcp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "TCP Rejected " ${IPTABLES} -t filter -A LREJECT -p udp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "UDP Rejected " ${IPTABLES} -t filter -A LREJECT -p icmp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "ICMP Rejected " ${IPTABLES} -t filter -A LREJECT -f -m limit --limit ${LOG_FLOOD} -j LOG --log-level 4 --log-prefix "FRAGMENT Rejected " ${IPTABLES} -t filter -A LREJECT -j REJECT echo -n "LREJECT " #Don't forget TREJECT ${IPTABLES} -t filter -A TREJECT -p tcp -j REJECT --reject-with tcp-reset ${IPTABLES} -t filter -A TREJECT -p udp -j REJECT --reject-with icmp-port-unreachable ${IPTABLES} -t filter -A TREJECT -p icmp -j DROP ${IPTABLES} -t filter -A TREJECT -j REJECT echo -n "TREJECT " #And LTREJECT ${IPTABLES} -t filter -A LTREJECT -p tcp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "TCP Rejected " ${IPTABLES} -t filter -A LTREJECT -p udp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "UDP Rejected " ${IPTABLES} -t filter -A LTREJECT -p icmp -m limit --limit ${LOG_FLOOD} -j LOG --log-level 6 --log-prefix "ICMP Rejected " ${IPTABLES} -t filter -A LTREJECT -f -m limit --limit ${LOG_FLOOD} -j LOG --log-level 4 --log-prefix "FRAGMENT Rejected " ${IPTABLES} -t filter -A LTREJECT -p tcp -j REJECT --reject-with tcp-reset ${IPTABLES} -t filter -A LTREJECT -p udp -j REJECT --reject-with icmp-port-unreachable ${IPTABLES} -t filter -A LTREJECT -p icmp -j DROP ${IPTABLES} -t filter -A LTREJECT -j REJECT echo -n "LTREJECT " #And ULOG stuff, same as above but ULOG instead of LOG if [ ${HAVE_ULOG} = "true" ] ; then ${IPTABLES} -t filter -A ULDROP -p tcp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LDROP_TCP ${IPTABLES} -t filter -A ULDROP -p udp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LDROP_UDP ${IPTABLES} -t filter -A ULDROP -p icmp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LDROP_ICMP ${IPTABLES} -t filter -A ULDROP -f -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LDROP_FRAG ${IPTABLES} -t filter -A ULDROP -j DROP echo -n "ULDROP " ${IPTABLES} -t filter -A ULREJECT -p tcp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LREJECT_TCP ${IPTABLES} -t filter -A ULREJECT -p udp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LREJECT_UDP ${IPTABLES} -t filter -A ULREJECT -p icmp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LREJECT_UDP ${IPTABLES} -t filter -A ULREJECT -f -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LREJECT_FRAG ${IPTABLES} -t filter -A ULREJECT -j REJECT echo -n "LREJECT " ${IPTABLES} -t filter -A ULTREJECT -p tcp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LTREJECT_TCP ${IPTABLES} -t filter -A ULTREJECT -p udp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LTREJECT_UDP ${IPTABLES} -t filter -A ULTREJECT -p icmp -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LTREJECT_ICMP ${IPTABLES} -t filter -A ULTREJECT -f -m limit --limit ${LOG_FLOOD} -j ULOG --ulog-nlgroup 1 --ulog-prefix LTREJECT_FRAG ${IPTABLES} -t filter -A ULTREJECT -p tcp -j REJECT --reject-with tcp-reset ${IPTABLES} -t filter -A ULTREJECT -p udp -j REJECT --reject-with icmp-port-unreachable ${IPTABLES} -t filter -A ULTREJECT -p icmp -j DROP ${IPTABLES} -t filter -A ULTREJECT -j REJECT echo -n "ULTREJECT " fi #newline echo # Set up the per-proto ACCEPT chains echo -n "Setting up per-proto ACCEPT: " # TCPACCEPT # SYN Flood "Protection" ${IPTABLES} -t filter -A TCPACCEPT -p tcp --syn -m limit --limit ${SYN_FLOOD} -j ACCEPT ${IPTABLES} -t filter -A TCPACCEPT -p tcp --syn -m limit --limit ${LOG_FLOOD} -j LOG --log-prefix "Possible SynFlood " ${IPTABLES} -t filter -A TCPACCEPT -p tcp --syn -j ${DROP} ${IPTABLES} -t filter -A TCPACCEPT -p tcp ! --syn -j ACCEPT # Log anything that hasn't matched yet and ${DROP} it since it isn't TCP and shouldn't be here ${IPTABLES} -t filter -A TCPACCEPT -m limit --limit ${LOG_FLOOD} -j LOG --log-prefix "Mismatch in TCPACCEPT " ${IPTABLES} -t filter -A TCPACCEPT -j ${DROP} echo -n "TCPACCEPT " #UDPACCEPT ${IPTABLES} -t filter -A UDPACCEPT -p udp -j ACCEPT # Log anything not UDP and ${DROP} it since it's not supposed to be here ${IPTABLES} -t filter -A UDPACCEPT -m limit --limit ${LOG_FLOOD} -j LOG --log-prefix "Mismatch on UDPACCEPT " ${IPTABLES} -t filter -A UDPACCEPT -j ${DROP} echo -n "UDPACCEPT " #Done echo # ================================================= # ----------------Explicit Denies------------------ # ================================================= #Blackholes will not be overridden by hostwise allows if [ "$BLACKHOLE" != "" ] ; then echo -n "Blackholes: " for host in ${BLACKHOLE} ; do ${IPTABLES} -t filter -A INPUT -s ${host} -j ${BLACKHOLE_DROP} ${IPTABLES} -t filter -A OUTPUT -d ${host} -j ${BLACKHOLE_DROP} ${IPTABLES} -t filter -A FORWARD -s ${host} -j ${BLACKHOLE_DROP} ${IPTABLES} -t filter -A FORWARD -d ${host} -j ${BLACKHOLE_DROP} echo -n "${host} " done echo fi if [ "$DENY_ALL" != "" ] ; then echo -n "Denying hosts: " for host in ${DENY_ALL} ; do ${IPTABLES} -t filter -A INPUT -s ${host} -j ${DROP} ${IPTABLES} -t filter -A FORWARD -s ${host} -j ${DROP} echo -n "${host}:${DROP}" done echo fi if [ "$DENY_HOSTWISE_TCP" != "" ] ; then echo -n "Hostwise TCP Denies: " for rule in ${DENY_HOSTWISE_TCP} ; do echo "$rule" | { IFS='>' read host port ${IPTABLES} -t filter -A INPUT -p tcp -s ${host} --dport ${port} -j ${DROP} ${IPTABLES} -t filter -A FORWARD -p tcp -s ${host} --dport ${port} -j ${DROP} echo -n "${rule} " } done echo fi if [ "$DENY_HOSTWISE_UDP" != "" ] ; then echo -n "Hostwise UDP Denies: " for rule in ${DENY_HOSTWISE_UDP} ; do echo "$rule" | { IFS='>' read host port ${IPTABLES} -t filter -A INPUT -p udp -s ${host} --dport ${port} -j ${DROP} ${IPTABLES} -t filter -A FORWARD -p udp -s ${host} --dport ${port} -j ${DROP} echo -n "${rule} " } done echo fi #Invalid packets are always annoying echo -n "${DROP}ing invalid packets..." ${IPTABLES} -t filter -A INETIN -m state --state INVALID -j ${DROP} echo "done" # ------------------------------------------------------------------------ # Internet jumps to INET chains and DMZ # Set up INET chains echo -n "Setting up INET chains: " ${IPTABLES} -t filter -A INPUT -i ${INET_IFACE} -j INETIN ${IPTABLES} -t filter -A FORWARD -i ${INET_IFACE} -o ${LAN_IFACE} -j INETIN echo -n "INETIN " ${IPTABLES} -t filter -A OUTPUT -o ${INET_IFACE} -j INETOUT ${IPTABLES} -t filter -A FORWARD -o ${INET_IFACE} -i ${LAN_IFACE} -j INETOUT echo -n "INETOUT " echo # For now we'll subject the DMZ to the same rules as the internet when going onto the trusted LAN # And we'll let it go anywhere on the internet if [ "$DMZ_IFACE" != "" ] ; then echo -n "Setting up DMZ Chains: " ${IPTABLES} -A OUTPUT -o ${DMZ_IFACE} -j DMZOUT ${IPTABLES} -A FORWARD -i ${LAN_IFACE} -o ${DMZ_IFACE} -j DMZOUT ${IPTABLES} -A FORWARD -i ${INET_IFACE} -o ${DMZ_IFACE} -j ACCEPT echo -n "DMZOUT " echo -n "DMZ for Internet Forwarding to INETOUT..." ${IPTABLES} -A DMZOUT -j INETOUT ${IPTABLES} -A INPUT -i ${DMZ_IFACE} -j DMZIN ${IPTABLES} -A FORWARD -i ${DMZ_IFACE} -o ${LAN_IFACE} -j DMZIN ${IPTABLES} -A FORWARD -i ${DMZ_IFACE} -o ${INET_IFACE} -j ACCEPT echo -n "DMZIN " echo echo -n "DMZ for LAN and localhost Forwarding to INETIN..." ${IPTABLES} -A DMZIN -j INETIN echo "done" echo -n "done" fi # ------------------------------------------------------------------------ # Local traffic to internet or crossing subnets # This should cover what we need if we don't use masquerading # Unfortunately, MAC address matching isn't bidirectional (for # obvious reasons), so IP based matching is done here echo -n "Local Traffic Rules: " if [ "$INTERNAL_LAN" != "" ] ; then for subnet in ${INTERNAL_LAN} ; do ${IPTABLES} -t filter -A INPUT -s ${subnet} -j ACCEPT echo -n "${subnet}:ACCEPT " done fi # 127.0.0.0/8 used to need an entry in INTERNAL_LAN, but routing of that isn't needed # so an allow is placed on INPUT so that the computer can talk to itself :) ${IPTABLES} -t filter -A INPUT -i ${LOOP_IFACE} -j ACCEPT echo -n "loopback:ACCEPT " # DHCP server magic # Allow broadcasts from LAN to UDP port 67 (DHCP server) if [ "$DHCP_SERVER" = "TRUE" ] ; then ${IPTABLES} -t filter -A INPUT -i ${LAN_IFACE} -p udp --dport 67 -j ACCEPT echo -n "dhcp:ACCEPT" fi echo if [ "$PROXY" != "" ] ; then echo -n "Setting up Transparent Proxy to ${PROXY}: " for subnet in ${INTERNAL_LAN} ; do echo "$PROXY" | { IFS=':' read host port if [ "$host" = "localhost" ] || [ "$host" = "127.0.0.1" ] ; then ${IPTABLES} -t nat -A PREROUTING -s ${subnet} -p tcp --dport 80 -j REDIRECT --to-port ${port} echo -n "${subnet}:PROXY " else ${IPTABLES} -t nat -A PREROUTING -s ${subnet} -p tcp --dport 80 -j DNAT --to ${host}:${port} echo -n "${subnet}:PROXY " fi } done echo fi if [ "$ALLOW_OUT_TCP" != "" ] ; then echo -n "Internet censorship TCP allows: " for rule in ${ALLOW_OUT_TCP} ; do echo "$rule" | { IFS=':' read intip destip dport ${IPTABLES} -t filter -A FORWARD -s ${intip} -d ${destip} --dport ${dport} -o ${INET_IFACE} -j ACCEPT ${IPTABLES} -t filter -A FORWARD -d ${intip} -s ${destip} -i ${INET_IFACE} -j ACCEPT echo -n "${intip}:${destip} " } done echo fi # Set up basic NAT if the user wants it if [ "$MASQ_LAN" != "" ] ; then echo -n "Setting up masquerading: " if [ "$MAC_MASQ" = "" ] ; then for subnet in ${MASQ_LAN} ; do ${IPTABLES} -t nat -A POSTROUTING -s ${subnet} -o ${INET_IFACE} -j MASQUERADE echo -n "${subnet}:MASQUERADE " done else for address in ${MAC_MASQ} ; do ${IPTABLES} -t nat -A POSTROUTING -m mac --mac-source ${address} -o ${INET_IFACE} -j MASQUERADE echo -n "${address}:MASQUERADE " done fi echo fi if [ "$SNAT_LAN" != "" ] ; then #Static NAT used echo -n "Setting up static NAT: " if [ "$MAC_SNAT" = "" ] ; then for rule in ${SNAT_LAN} ; do echo "$rule" | { IFS=':' read host destip ${IPTABLES} -t nat -A POSTROUTING -s ${host} -o ${INET_IFACE} -j SNAT --to-source ${destip} echo -n "${subnet}:SNAT " } done else for rule in ${MAC_SNAT} ; do echo "$rule" | { IFS=':' read address destip ${IPTABLES} -t nat -A POSTROUTING -m mac --mac-source ${address} -o ${INET_IFACE} -j SNAT --to-source ${destip} echo -n "${address}:SNAT " } done fi echo fi #TCP Port-Forwards if [ "$TCP_FW" != "" ] ; then echo -n "TCP Port Forwards: " for rule in ${TCP_FW} ; do echo "$rule" | { IFS=':>' read srcport destport host echo "$srcport" | { IFS='-' read fsp lsp if [ "$lsp" != "" ] ; then echo "$destport" | { IFS='-' read fdp ldp ${IPTABLES} -t nat -A PREROUTING -p tcp -i ${INET_IFACE} --dport ${fsp}:${lsp} -j DNAT --to-destination ${host}:${destport} ${IPTABLES} -t filter -A FORWARD -p tcp -d ${host} --dport ${fdp}:${ldp} -j ACCEPT } else ${IPTABLES} -t nat -A PREROUTING -p tcp -i ${INET_IFACE} --dport ${srcport} -j DNAT --to-destination ${host}:${destport} ${IPTABLES} -t filter -A FORWARD -p tcp -d ${host} --dport ${destport} -j ACCEPT fi echo -n "${rule} " } } done echo fi #UDP Port Forwards if [ "$UDP_FW" != "" ] ; then echo -n "UDP Port Forwards: " for rule in ${UDP_FW} ; do echo "$rule" | { IFS=':>' read srcport destport host echo "$srcport" | { IFS='-' read fsp lsp if [ "$lsp" != "" ] ; then echo "$destport" | { IFS='-' read fdp ldp ${IPTABLES} -t nat -A PREROUTING -p udp -i ${INET_IFACE} --dport ${fsp}:${lsp} -j DNAT --to-destination ${host}:${destport} ${IPTABLES} -t filter -A FORWARD -p udp -d ${host} --dport ${fdp}:${ldp} -j ACCEPT } else ${IPTABLES} -t nat -A PREROUTING -p udp -i ${INET_IFACE} --dport ${srcport} -j DNAT --to-destination ${host}:${destport} ${IPTABLES} -t filter -A FORWARD -p udp -d ${host} --dport ${destport} -j ACCEPT fi echo -n "${rule} " } } done echo fi # ================================================================ # ------------Allow stuff we have chosen to allow in-------------- # ================================================================ # Hostwise allows if [ "$ALLOW_ALL" != "" ] ; then echo -n "Hostwise Input Allow: " for host in ${ALLOW_ALL} ; do ${IPTABLES} -t filter -A INETIN -s ${host} -j ACCEPT echo -n "${host} " done echo fi if [ "$ALLOW_HOSTWISE_TCP" != "" ] ; then echo -n "Hostwise TCP Allows: " for rule in ${ALLOW_HOSTWISE_TCP} ; do echo "$rule" | { IFS='>' read host port ${IPTABLES} -t filter -A INETIN -p tcp -s ${host} --dport ${port} -j ACCEPT echo -n "${rule} " } done echo fi if [ "$ALLOW_HOSTWISE_UDP" != "" ] ; then echo -n "Hostwise UDP Allows: " for rule in ${ALLOW_HOSTWISE_UDP} ; do echo "$rule" | { IFS='>' read host port ${IPTABLES} -t filter -A INETIN -p udp -s ${host} --dport ${port} -j ACCEPT echo -n "${rule} " } done echo fi # Flood "security" # You'll still respond to these if they comply with the limits (set in config) # There is a more elegant way to set this using sysctl, however this has the # advantage that the kernel ICMP stack never has to process it, lessening # the chance of a very serious flood overloading your kernel. # This is just a packet limit, you still get the packets on the interface and # still may experience lag if the flood is heavy enough echo -n "Flood limiting: " # Ping Floods (ICMP echo-request) ${IPTABLES} -t filter -A INETIN -p icmp --icmp-type echo-request -m limit --limit ${PING_FLOOD} -j ACCEPT ${IPTABLES} -t filter -A INETIN -p icmp --icmp-type echo-request -j ${DROP} echo -n "ICMP-PING " echo if [ "$BAD_ICMP" != "" ] ; then echo -n "Dropping ICMP messages specified in BAD_ICMP..." for message in ${BAD_ICMP} ; do ${IPTABLES} -t filter -A INETIN -p icmp --icmp-type ${message} -j ${DROP} echo -n "${message} " done echo fi echo -n "Allowing the rest of the ICMP messages in..." ${IPTABLES} -t filter -A INETIN -p icmp --icmp-type ! echo-request -j ACCEPT echo "done" if [ "$TCP_ALLOW" != "" ] ; then echo -n "TCP Input Allow: " for port in ${TCP_ALLOW} ; do ${IPTABLES} -t filter -A INETIN -p tcp --dport ${port} -j TCPACCEPT echo -n "${port} " done echo fi if [ "$UDP_ALLOW" != "" ] ; then echo -n "UDP Input Allow: " for port in ${UDP_ALLOW} ; do ${IPTABLES} -t filter -A INETIN -p udp --dport ${port} -j UDPACCEPT echo -n "${port} " done echo fi echo -n "Allowing established outbound connections back in..." ${IPTABLES} -t filter -A INETIN -m state --state ESTABLISHED -j ACCEPT echo "done" # RELATED on high ports only for security echo -n "Allowing related inbound connections..." ${IPTABLES} -t filter -A INETIN -p tcp --dport 1024:65535 -m state --state RELATED -j TCPACCEPT ${IPTABLES} -t filter -A INETIN -p udp --dport 1024:65535 -m state --state RELATED -j UDPACCEPT echo "done" # ================================================= # ----------------Packet Mangling------------------ # ================================================= # TTL mangling # This is probably just for the paranoid, but hey, isn't that what # all security guys are? :) if [ "$TTL_SAFE" != "" ] ; then ${IPTABLES} -t mangle -A PREROUTING -i ${INET_IFACE} -j TTL --ttl-set ${TTL_SAFE} fi # Type of Service mangle optimizations (the ACTIVE FTP one will only work for uploads) if [ "$MANGLE_TOS_OPTIMIZE" = "TRUE" ] ; then echo -n "Optimizing traffic: " ${IPTABLES} -t mangle -A OUTPUT -p tcp --dport 22 -j TOS --set-tos Minimize-Delay echo -n "ssh " echo fi # What to do on those INET chains when we hit the end echo -n "Setting up INET policies: " # Drop if we cant find a valid inbound rule. ${IPTABLES} -t filter -A INETIN -j ${DROP} echo -n "INETIN:${DROP} " # We can send what we want to the internet ${IPTABLES} -t filter -A INETOUT -j ACCEPT echo -n "INETOUT:ACCEPT " echo # All done! echo "Done loading the firewall!" ;; stop) echo -n "Flush: " ${IPTABLES} -t filter -F INPUT echo -n "INPUT " ${IPTABLES} -t filter -F OUTPUT echo -n "OUTPUT1 " ${IPTABLES} -t filter -F FORWARD echo -n "FORWARD " ${IPTABLES} -t nat -F PREROUTING echo -n "PREROUTING1 " ${IPTABLES} -t nat -F OUTPUT echo -n "OUTPUT2 " ${IPTABLES} -t nat -F POSTROUTING echo -n "POSTROUTING " ${IPTABLES} -t mangle -F PREROUTING echo -n "PREROUTING2 " ${IPTABLES} -t mangle -F OUTPUT echo -n "OUTPUT3" echo ;; esac -- Douglas J Hunley (doug at hunley.homeip.net) - Linux User #174778 Admin: Linux StepByStep - http://linux.nf Alliance, n.: In international politics, the union of two thieves who have their hands so deeply inserted in each other's pocket that they cannot separately plunder a third. -- Ambrose Bierce, "The Devil's Dictionary" _______________________________________________ Linux-users mailing list Archives, Digests, etc at http://linux.nf/mailman/listinfo/linux-users