#!/bin/sh ################################################################################# # # IPTABLES Masquerading Firewall v 0.97 # by Thomas Stangner (thomas at shadowweb.org) # # See http://www.shadowweb.org/fwscript for updated versions # # Small parts from http://members.optusnet.com.au/~technion/ # and some tutorials # # This script is intended to setup a masquerading firewall based on # the IPTABLES (Net)filter-mechanism of Linux 2.3.15+ # Syslogging matches fireparse for graphical output (see http://www.fireparse.com) # # Probably this script will work 'out-of-the-box', but keep in mind that it's an # EXAMPLE, so you should adapt it to your own needs (At least you should set the # correct default interfaces --> see BASIC PARAMETERS/Default-Interfaces section) # # Comments, suggestions, etc. are welcome # # USAGE ON YOUR OWN RISK # # Syntax to invoke script: firewall (start|stop|restart|status) EXTIF INTIF # Example: "firewall start ppp0 eth0" # ################################################################################# # # Version History: # # 0.97: Fixed a typo in dynamic generation of UDP-forwarding-entries # # 0.96: Integrated additional ideas and code to the script from Eryk L. Rathman (erath at elk.com.pl): # - Dynamic generation of masquerading entries (so that single subnets/hosts may be masqueraded only) # - Changed some sysctl options # Shortened code for dynamic generation of portforwarding-entries # # 0.95: Fixed an issue with kernel rp_filter (routes once established in the route-cache will be forwarded, # regardless of spoof-protection) # Thx to Roger Standridge ! # # 0.94: Removed silent external SMB-filtering # Moved Badflag-Filtering in FORWARD-chain to "FROM EXTERNAL NET"-section (so that you can use nmap or other tools from inside) # Added comments # Changed detection of default GW to explicitly use external interface (Thx to erath@elk.com.pl) # # 0.93: Changed Port-Forwarding-Section, so that affected chains are generated dynamically # (Makes it more independent and faster to change) # # 0.92: Additions by Kai Thiele (mail@kai-thiele.de): ICQ-Forwarding example # NTPD-Server entry # Outsourced several sections from built-in chains to user-chains for simplified # maintenance and better readability # Re-organized main chains # Added several comments # # 0.91: Removed double "-i $EXTIF" from Battlecom-Forwarding (Thx to sneaker@bnmsp.de ;) ) # # 0.90: Removed detection of INTLAN since it was only used to prevent IP-spoofing and rp_filter is # enabled # # 0.89: Slightly changed port-forwarding section # Added port-forwarding example for FTP-forwarding (active + passive) # # 0.88: Made loglevel variable to avoid logging to the console (changed default-loglevel from 'warn' # to 'info') # # 0.87: Fixed problem with rejecting ident / blocking own reply # (Thx to Simon Vandemoortele) # # 0.86: Added a few comments # # 0.85: Various re-arrangements # Added TCP-SYN-flood protection # Added separate logging of pingfloods # Added automatic detection of parameters on internal interface # Made flooding-parameters variable # # 0.84: Added special ICMP-Filtering # # [...] # ######################################################################################## # This is the location of the iptables executable IPTABLES="/usr/sbin/iptables" #Check for presence of iptables if ! [ -x $IPTABLES ]; then echo "Could not find iptables executable. Please edit script !" if which iptables 2> /dev/null 1> /dev/null; then echo "According to which, the iptables executable is located here: `which iptables`" fi exit 1 fi case "$1" in stop) echo "Shutting down firewall..." $IPTABLES -F $IPTABLES -F -t mangle $IPTABLES -F -t nat $IPTABLES -X $IPTABLES -X -t mangle $IPTABLES -X -t nat $IPTABLES -P INPUT ACCEPT $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P FORWARD ACCEPT echo "...done" ;; status) echo $"Table: filter" $IPTABLES --list --numeric --verbose echo $"Table: nat" $IPTABLES -t nat --list --numeric --verbose echo $"Table: mangle" $IPTABLES -t mangle --list --numeric --verbose ;; restart|reload) $0 stop $0 start ;; start) echo "Starting Firewall..." echo "" ####------------------------------START FIREWALL---------------------------------#### # ...well, it seems we've chosen to start the script...so let's do it ;) ###-------------------START BASIC PARAMETERS--------------------### # We'll begin with the basic parameters for our firewall #----Default-Interfaces-----# ## Default external interface (used, if EXTIF isn't specified on command line) DEFAULT_EXTIF="ppp0" ## Default internal interface (used, if INTIF isn't specified on command line) DEFAULT_INTIF="eth0" #----Special Variables-----# # IP Mask for all IP addresses UNIVERSE="0.0.0.0/0" # Specification of the high unprivileged IP ports. UNPRIVPORTS="1024:65535" # Specification of X Window System (TCP) ports. XWINPORTS="6000:6063" # Ports for IRC-Connection-Tracking IRCPORTS="6665,6666,6667,6668,6669,7000" #-----Masquerading Variables-----# # If you want to masquerade connections from your internal network to the external net, # you will have to specify it here (The Entries must be space-separated (IN ONE LINE !) : # MASQ_ADDR="SINGLE_ADDRESS1 NETWORK_ADDRESS2", etc. # Examples: MASQ_ADDR="192.168.0.5 192.168.0.12" --> This will masquerade two hosts 192.168.0.5 and 192.168.0.12 from internal network # MASQ_ADDR="192.168.1.0/24 192.168.0.5" --> This will masquerade single network 192.168.1.0/24 and single address 192.168.0.5 # MASQ_ADDR="ALL" --> This will masquerade for all adresses from internel interface [default] # MASQ_ADDR="" --> This will disable masquerading MASQ_ADDR="ALL" #-----Port-Forwarding Variables-----# # If you want to port-forward connections from the internet to hosts on your internal network, # you will have to specify it here (The Entries must be space-separated (IN ONE LINE !) : # PORTFW_XXX="Port>Host:Destinationport Port2>Host2:Destinationport", etc. Destinationport may be omitted) # Examples: PORTFW_TCP="80>192.168.0.5:9000" --> This will forward all HTTP-Traffic to Port 9000 on host 192.168.0.5 # PORTFW_UDP="123>192.168.0.10" --> This will forward all NTP-Traffic to Port 123 on host 192.168.0.10 # PORTFW_TCP="5010-5030>192.168.0.8" --> This will forward TCP-Portrange 5010-5030 to 192.168.0.8 PORTFW_TCP="" PORTFW_UDP="" #----Flood Variables-----# # Overall Limit for TCP-SYN-Flood detection TCPSYNLIMIT="5/s" # Burst Limit for TCP-SYN-Flood detection TCPSYNLIMITBURST="10" # Overall Limit for Loggging in Logging-Chains LOGLIMIT="2/s" # Burst Limit for Logging in Logging-Chains LOGLIMITBURST="10" # Overall Limit for Ping-Flood-Detection PINGLIMIT="5/s" # Burst Limit for Ping-Flood-Detection PINGLIMITBURST="10" #----Log-Level----# # Set the log-level for the logging-chains. Defaults to "info" to avoid logging to the console LOGLEVEL="info" ###-------------------END BASIC PARAMETERS--------------------### ###---------------------START PREPARATION---------------------### # Now we'll determine the interfaces/IPs involved, load the needed iptables modules # and set some kernel-parameters to secure our firewall-box #----Automatically determine info about involved interfaces-----# ### External Interface: ## Get external interface from command-line ## If no interface is specified then set $DEFAULT_EXTIF as EXTIF if [ "x$2" != "x" ]; then EXTIF=$2 else EXTIF=$DEFAULT_EXTIF fi echo External Interface: $EXTIF ## Determine external IP EXTIP="`ifconfig $EXTIF | grep inet | cut -d : -f 2 | cut -d \ -f 1`" if [ "$EXTIP" = '' ]; then echo "Aborting: Unable to determine the IP-address of $EXTIF !" exit 1 fi echo External IP: $EXTIP ## Determine external gateway EXTGW=`route -n | grep -A 4 UG | grep $EXTIF | awk '{ print $2}'` echo Default GW: $EXTGW echo "" ### Internal Interface: ## Get internal interface from command-line ## If no interface is specified then set $DEFAULT_INTIF as INTIF if [ "x$3" != "x" ]; then INTIF=$3 else INTIF=$DEFAULT_INTIF fi echo Internal Interface: $INTIF ## Determine internal IP INTIP="`ifconfig $INTIF | grep inet | cut -d : -f 2 | cut -d \ -f 1`" if [ "$INTIP" = '' ]; then echo "Aborting: Unable to determine the IP-address of $INTIF !" exit 1 fi echo Internal IP: $INTIP echo " ---" #----Load IPTABLES-modules-----# #Insert modules- should be done automatically if needed #If the IRC-modules are available, uncomment them below. # #ATTENTION: From linux kernel 2.4.14 up to 2.4.18-pre8 there exists a bug in the ip_conntrack_irc module, which, under certain circumstances, #may lead to insecurities in the firewall during DCC-transfers. See http://lwn.net/2002/0228/a/netfilter-irc.php3 for details echo "Loading IPTABLES modules" dmesg -n 1 #Kill copyright display on module load /sbin/modprobe ip_tables /sbin/modprobe iptable_filter /sbin/modprobe ip_conntrack /sbin/modprobe ip_conntrack_ftp /sbin/modprobe ip_nat_ftp #/sbin/modprobe ip_conntrack_irc ports=$IRCPORTS #/sbin/modprobe ip_nat_irc ports=$IRCPORTS dmesg -n 6 echo " --- " #----Clear/Reset all chains-----# #Clear all IPTABLES-chains #Flush everything, start from scratch $IPTABLES -F $IPTABLES -F -t mangle $IPTABLES -F -t nat $IPTABLES -X $IPTABLES -X -t mangle $IPTABLES -X -t nat #Set default policies to DROP $IPTABLES -P INPUT DROP $IPTABLES -P OUTPUT DROP $IPTABLES -P FORWARD DROP #----Set network sysctl options-----# echo "Setting sysctl options" #Disable forwarding in kernel until all rules have been set echo "0" > /proc/sys/net/ipv4/ip_forward #Disable IP Spoofing attacks echo "2" > /proc/sys/net/ipv4/conf/all/rp_filter #Kill redirects echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects #Block source routing echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route #Log martians (packets with impossible addresses) echo "1" > /proc/sys/net/ipv4/conf/all/log_martians #Enable TCP SYN-Cookies [if available] if [ -r /proc/sys/net/ipv4/conf/all/tcp_syncookies ]; then echo "1" > /proc/sys/net/ipv4/tcp_syncookies fi #Disable Explicit Congestion Notification (Some routers may have problems with it) [if available] if [ -r /proc/sys/net/ipv4/conf/all/tcp_ecn ]; then echo "0" > /proc/sys/net/ipv4/tcp_ecn fi #Flush route cache echo "1" > /proc/sys/net/ipv4/route/flush #Enable bad error message protection echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses #Don't respond to broadcast pings (Smurf-Amplifier-Protection) echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts #Optional: Ignore all ICMP echo packets (e.g. to avoid ping-scans) #echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all #Optional: Explicitly set local port range #echo "32768 61000" > /proc/sys/net/ipv4/ip_local_port_range #Reduce DoS'ing ability by reducing timeouts echo "20" > /proc/sys/net/ipv4/tcp_fin_timeout echo "2400" > /proc/sys/net/ipv4/tcp_keepalive_time echo "20" > /proc/sys/net/ipv4/ipfrag_time #Additional TCP-settings echo "0" > /proc/sys/net/ipv4/tcp_window_scaling echo "0" > /proc/sys/net/ipv4/tcp_sack echo "0" > /proc/sys/net/ipv4/tcp_timestamps echo " --- " echo "Creating user-chains" ###----------------------END PREPARATION---------------------### ###------------------------START STATIC USER-CHAINS--------------------------### # We will first create some user-chains (non-builtin chains) to deal with logging and to simplify organization. # Later we will jump from the main chains (in the RULESET-section) to these user-chains. #----Create logging chains-----# ##These are the logging-chains. They all have a certain limit of log-entries/sec to prevent log-flooding ##The syslog-entries will be fireparse-compatible (see http://www.fireparse.com) #Invalid packets (not ESTABLISHED,RELATED or NEW) $IPTABLES -N LINVALID $IPTABLES -A LINVALID -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-level $LOGLEVEL --log-prefix "fp=INVALID:1 a=DROP " $IPTABLES -A LINVALID -j DROP #TCP-Packets with one ore more bad flags $IPTABLES -N LBADFLAG $IPTABLES -A LBADFLAG -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-level $LOGLEVEL --log-prefix "fp=BADFLAG:1 a=DROP " $IPTABLES -A LBADFLAG -j DROP #Logging of connection attempts on special ports (Trojan portscans, special services, etc.) $IPTABLES -N LSPECIALPORT $IPTABLES -A LSPECIALPORT -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-level $LOGLEVEL --log-prefix "fp=SPECIALPORT:1 a=DROP " $IPTABLES -A LSPECIALPORT -j DROP #Logging of possible TCP-SYN-Floods $IPTABLES -N LSYNFLOOD $IPTABLES -A LSYNFLOOD -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-level $LOGLEVEL --log-prefix "fp=SYNFLOOD:1 a=DROP " $IPTABLES -A LSYNFLOOD -j DROP #Logging of possible Ping-Floods $IPTABLES -N LPINGFLOOD $IPTABLES -A LPINGFLOOD -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-level $LOGLEVEL --log-prefix "fp=PINGFLOOD:1 a=DROP " $IPTABLES -A LPINGFLOOD -j DROP #All other dropped packets $IPTABLES -N LDROP $IPTABLES -A LDROP -p tcp -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-level $LOGLEVEL --log-prefix "fp=TCP:1 a=DROP " $IPTABLES -A LDROP -p udp -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-level $LOGLEVEL --log-prefix "fp=UDP:2 a=DROP " $IPTABLES -A LDROP -p icmp -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-level $LOGLEVEL --log-prefix "fp=ICMP:3 a=DROP " $IPTABLES -A LDROP -f -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-level $LOGLEVEL --log-prefix "fp=FRAGMENT:4 a=DROP " $IPTABLES -A LDROP -j DROP #All other rejected packets $IPTABLES -N LREJECT $IPTABLES -A LREJECT -p tcp -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-level $LOGLEVEL --log-prefix "fp=TCP:1 a=REJECT " $IPTABLES -A LREJECT -p udp -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-level $LOGLEVEL --log-prefix "fp=UDP:2 a=REJECT " $IPTABLES -A LREJECT -p icmp -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-level $LOGLEVEL --log-prefix "fp=ICMP:3 a=REJECT " $IPTABLES -A LREJECT -f -m limit --limit $LOGLIMIT --limit-burst $LOGLIMITBURST -j LOG --log-level $LOGLEVEL --log-prefix "fp=FRAGMENT:4 a=REJECT " $IPTABLES -A LREJECT -p tcp -j REJECT --reject-with tcp-reset $IPTABLES -A LREJECT -p udp -j REJECT --reject-with icmp-port-unreachable $IPTABLES -A LREJECT -j REJECT #----Create Accept-Chains-----# #TCPACCEPT - Check for SYN-Floods before letting TCP-Packets in $IPTABLES -N TCPACCEPT $IPTABLES -A TCPACCEPT -p tcp --syn -m limit --limit $TCPSYNLIMIT --limit-burst $TCPSYNLIMITBURST -j ACCEPT $IPTABLES -A TCPACCEPT -p tcp --syn -j LSYNFLOOD $IPTABLES -A TCPACCEPT -p tcp ! --syn -j ACCEPT #----Create special User-Chains-----# #CHECKBADFLAG - Kill any TCP-Packets with impossible flag-combinations (Some port-scanners use these, eg. nmap Xmas,Null,etc.-scan) $IPTABLES -N CHECKBADFLAG $IPTABLES -A CHECKBADFLAG -p tcp --tcp-flags ALL FIN,URG,PSH -j LBADFLAG $IPTABLES -A CHECKBADFLAG -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LBADFLAG $IPTABLES -A CHECKBADFLAG -p tcp --tcp-flags ALL ALL -j LBADFLAG $IPTABLES -A CHECKBADFLAG -p tcp --tcp-flags ALL NONE -j LBADFLAG $IPTABLES -A CHECKBADFLAG -p tcp --tcp-flags SYN,RST SYN,RST -j LBADFLAG $IPTABLES -A CHECKBADFLAG -p tcp --tcp-flags SYN,FIN SYN,FIN -j LBADFLAG #FILTERING FOR SPECIAL PORTS #Outbound SILENTDROPS/REJECTS (Things we don't want in our Logs) #SMB-Traffic $IPTABLES -N SMBOUTBOUND $IPTABLES -A SMBOUTBOUND -p tcp --sport 137 -j DROP $IPTABLES -A SMBOUTBOUND -p tcp --sport 138 -j DROP $IPTABLES -A SMBOUTBOUND -p tcp --sport 139 -j DROP $IPTABLES -A SMBOUTBOUND -p tcp --sport 445 -j DROP $IPTABLES -A SMBOUTBOUND -p udp --sport 137 -j DROP $IPTABLES -A SMBOUTBOUND -p udp --sport 138 -j DROP $IPTABLES -A SMBOUTBOUND -p udp --sport 139 -j DROP $IPTABLES -A SMBOUTBOUND -p udp --sport 445 -j DROP #Inbound SILENTDROPS/REJECTS (Things we don't want in our Logs) #SMB-Traffic $IPTABLES -N SMBINBOUND $IPTABLES -A SMBINBOUND -p tcp --dport 137 -j DROP $IPTABLES -A SMBINBOUND -p tcp --dport 138 -j DROP $IPTABLES -A SMBINBOUND -p tcp --dport 139 -j DROP $IPTABLES -A SMBINBOUND -p tcp --dport 445 -j DROP $IPTABLES -A SMBINBOUND -p udp --dport 137 -j DROP $IPTABLES -A SMBINBOUND -p udp --dport 138 -j DROP $IPTABLES -A SMBINBOUND -p udp --dport 139 -j DROP $IPTABLES -A SMBINBOUND -p udp --dport 445 -j DROP #Inbound Special Ports (Scans for Trojans, etc.) $IPTABLES -N SPECIALPORTS #Deepthroat Scan $IPTABLES -A SPECIALPORTS -p tcp --dport 6670 -j LSPECIALPORT #Subseven Scan $IPTABLES -A SPECIALPORTS -p tcp --dport 1243 -j LSPECIALPORT $IPTABLES -A SPECIALPORTS -p udp --dport 1243 -j LSPECIALPORT $IPTABLES -A SPECIALPORTS -p tcp --dport 27374 -j LSPECIALPORT $IPTABLES -A SPECIALPORTS -p udp --dport 27374 -j LSPECIALPORT $IPTABLES -A SPECIALPORTS -p tcp --dport 6711:6713 -j LSPECIALPORT #Netbus Scan $IPTABLES -A SPECIALPORTS -p tcp --dport 12345:12346 -j LSPECIALPORT $IPTABLES -A SPECIALPORTS -p tcp --dport 20034 -j LSPECIALPORT #Back Orifice scan $IPTABLES -A SPECIALPORTS -p udp --dport 31337:31338 -j LSPECIALPORT #X-Win $IPTABLES -A SPECIALPORTS -p tcp --dport $XWINPORTS -j LSPECIALPORT #Hack'a'Tack 2000 $IPTABLES -A SPECIALPORTS -p udp --dport 28431 -j LSPECIALPORT #ICMP/TRACEROUTE FILTERING # These chains filter all icmp-traffic coming in/going out #Inbound ICMP/Traceroute $IPTABLES -N ICMPINBOUND #Ping Flood protection. Accept $PINGLIMIT echo-requests/sec, rest will be logged/dropped $IPTABLES -A ICMPINBOUND -p icmp --icmp-type echo-request -m limit --limit $PINGLIMIT --limit-burst $PINGLIMITBURST -j ACCEPT # $IPTABLES -A ICMPINBOUND -p icmp --icmp-type echo-request -j LPINGFLOOD #Block ICMP-Redirects (Should already be catched by sysctl-options, if enabled) $IPTABLES -A ICMPINBOUND -p icmp --icmp-type redirect -j LDROP #Block ICMP-Timestamp (Should already be catched by sysctl-options, if enabled) $IPTABLES -A ICMPINBOUND -p icmp --icmp-type timestamp-request -j LDROP $IPTABLES -A ICMPINBOUND -p icmp --icmp-type timestamp-reply -j LDROP #Block ICMP-address-mask (can help to prevent OS-fingerprinting) $IPTABLES -A ICMPINBOUND -p icmp --icmp-type address-mask-request -j LDROP $IPTABLES -A ICMPINBOUND -p icmp --icmp-type address-mask-reply -j LDROP #Allow all other ICMP in $IPTABLES -A ICMPINBOUND -p icmp -j ACCEPT #Outbound ICMP/Traceroute $IPTABLES -N ICMPOUTBOUND #Block ICMP-Redirects (Should already be catched by sysctl-options, if enabled) $IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type redirect -j LDROP #Block ICMP-TTL-Expired #MS Traceroute (MS uses ICMP instead of UDp for tracert) $IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type ttl-zero-during-transit -j LDROP $IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type ttl-zero-during-reassembly -j LDROP #Block ICMP-Parameter-Problem $IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type parameter-problem -j LDROP #Block ICMP-Timestamp (Should already be catched by sysctl-options, if enabled) $IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type timestamp-request -j LDROP $IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type timestamp-reply -j LDROP #Block ICMP-address-mask (can help to prevent OS-fingerprinting) $IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type address-mask-request -j LDROP $IPTABLES -A ICMPOUTBOUND -p icmp --icmp-type address-mask-reply -j LDROP ##Accept all other ICMP going out $IPTABLES -A ICMPOUTBOUND -p icmp -j ACCEPT #PUBLIC SERVICES RUNNING ON FIREWALL # If you have public services running DIRECTLY ON YOUR FIREWALL-BOX (available to the internet), uncomment the # according lines below or add new entries (Inbound + Outbound) # ATTENTION: Running public services directly on your firewallbox is a major security-risk, so avoid it, if possible #Inbound $IPTABLES -N FWSERVICESINBOUND # ftp-data (for active FTP) #$IPTABLES -A FWSERVICESINBOUND -p tcp --dport 20 -j TCPACCEPT # ftp (for passive FTP you will need an additional portrange) #$IPTABLES -A FWSERVICESINBOUND -p tcp --dport 21 -j TCPACCEPT # ssh #$IPTABLES -A FWSERVICESINBOUND -p tcp --dport 22 -j TCPACCEPT # telnet #$IPTABLES -A FWSERVICESINBOUND -p tcp --dport 23 -j TCPACCEPT # smtp #$IPTABLES -A FWSERVICESINBOUND -p tcp --dport 25 -j TCPACCEPT # DNS #$IPTABLES -A FWSERVICESINBOUND -p tcp --dport 53 -j TCPACCEPT #$IPTABLES -A FWSERVICESINBOUND -p udp --dport 53 -j ACCEPT # http #$IPTABLES -A FWSERVICESINBOUND -p tcp --dport 80 -j TCPACCEPT # POP-3 #$IPTABLES -A FWSERVICESINBOUND -p tcp --dport 110 -j TCPACCEPT # ntp #$IPTABLES -A FWSERVICESINBOUND -p udp --sport 123 --dport 123 -j ACCEPT # https #$IPTABLES -A FWSERVICESINBOUND -p tcp --dport 443 -j TCPACCEPT # IPsec # # IKE negotiations #iptables -A FWSERVICESINBOUND -p udp --sport 500 --dport 500 -j ACCEPT # ESP encryption and authentication #iptables -A FWSERVICESINBOUND -p 50 -j ACCEPT #Outbound $IPTABLES -N FWSERVICESOUTBOUND # ftp-data (for active FTP) #$IPTABLES -A FWSERVICESOUTBOUND -p tcp --sport 20 -j ACCEPT # ftp (for passive FTP you will need an additional portrange) #$IPTABLES -A FWSERVICESOUTBOUND -p tcp --sport 21 -j ACCEPT # ssh #$IPTABLES -A FWSERVICESOUTBOUND -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT # telnet #$IPTABLES -A FWSERVICESOUTBOUND -p tcp --sport 23 -m state --state ESTABLISHED -j ACCEPT # smtp #$IPTABLES -A FWSERVICESOUTBOUND -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT # DNS #$IPTABLES -A FWSERVICESOUTBOUND -p tcp --sport 53 -j ACCEPT #$IPTABLES -A FWSERVICESOUTBOUND -p udp --sport 53 -j ACCEPT # http #$IPTABLES -A FWSERVICESOUTBOUND -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT # POP-3 #$IPTABLES -A FWSERVICESOUTBOUND -p tcp --sport 110 -m state --state ESTABLISHED -j ACCEPT # ntp #$IPTABLES -A FWSERVICESOUTBOUND -p udp --sport 123 --dport 123 -j ACCEPT # https #$IPTABLES -A FWSERVICESOUTBOUND -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT # IPsec # # IKE negotiations #iptables -A FWSERVICESOUTBOUND -p udp --sport 500 --dport 500 -j ACCEPT # ESP encryption and authentication #iptables -A FWSERVICESOUTBOUND -p 50 -j ACCEPT ###-------------------------END STATIC USER-CHAINS--------------------------### ###-----------------------START DYNAMIC USER-CHAINS-------------------------### # These user-chains will be generated dynamically on runtime to simplify maintenance #DYNAMIC GENERATION OF PORT-FORWARDING ENTRIES # This will allow port-forwarded packets to flow in/out and put an entry in the PREROUTING-chain to do the actual forwarding $IPTABLES -N PORTFWALLOWSINBOUND $IPTABLES -N PORTFWALLOWSOUTBOUND if [ "$PORTFW_TCP" != "" ] ; then echo "" echo "Port-Forwarding following TCP connections: " for ENTRY in $PORTFW_TCP ; do echo "$ENTRY" | { IFS='>:' read SRCPORT DESTHOST DESTPORT echo "$SRCPORT" | { IFS='-' read SPSTART SPEND if [ "$SPEND" != "" ] ; then $IPTABLES -A PORTFWALLOWSINBOUND -i $EXTIF -p tcp -d $DESTHOST --dport $SPSTART:$SPEND -j TCPACCEPT $IPTABLES -A PORTFWALLOWSOUTBOUND -o $EXTIF -p tcp -s $DESTHOST --sport $SPSTART:$SPEND -j ACCEPT $IPTABLES -t nat -A PREROUTING -i $EXTIF -d $EXTIP -p tcp --dport $SPSTART:$SPEND -j DNAT --to $DESTHOST echo "$EXTIP:$SRCPORT --> $DESTHOST" else if [ "$DESTPORT" = "" ]; then DESTPORT=$SRCPORT fi $IPTABLES -A PORTFWALLOWSINBOUND -i $EXTIF -p tcp -d $DESTHOST --dport $DESTPORT -j TCPACCEPT $IPTABLES -A PORTFWALLOWSOUTBOUND -o $EXTIF -p tcp -s $DESTHOST --sport $DESTPORT -j ACCEPT $IPTABLES -t nat -A PREROUTING -i $EXTIF -d $EXTIP -p tcp --dport $SRCPORT -j DNAT --to $DESTHOST:$DESTPORT echo "$EXTIP:$SRCPORT --> $DESTHOST:$DESTPORT" fi } } done fi if [ "$PORTFW_UDP" != "" ] ; then echo "" echo "Port-Forwarding following UDP connections: " for ENTRY in $PORTFW_UDP ; do echo "$ENTRY" | { IFS='>:' read SRCPORT DESTHOST DESTPORT echo "$SRCPORT" | { IFS='-' read SPSTART SPEND if [ "$SPEND" != "" ] ; then $IPTABLES -A PORTFWALLOWSINBOUND -i $EXTIF -p udp -d $DESTHOST --dport $SPSTART:$SPEND -j ACCEPT $IPTABLES -A PORTFWALLOWSOUTBOUND -o $EXTIF -p udp -s $DESTHOST --sport $SPSTART:$SPEND -j ACCEPT $IPTABLES -t nat -A PREROUTING -i $EXTIF -d $EXTIP -p udp --dport $SPSTART:$SPEND -j DNAT --to $DESTHOST echo "$EXTIP:$SRCPORT --> $DESTHOST" else if [ "$DESTPORT" = "" ]; then DESTPORT=$SRCPORT fi $IPTABLES -A PORTFWALLOWSINBOUND -i $EXTIF -p udp -d $DESTHOST --dport $DESTPORT -j ACCEPT $IPTABLES -A PORTFWALLOWSOUTBOUND -o $EXTIF -p udp -s $DESTHOST --sport $DESTPORT -j ACCEPT $IPTABLES -t nat -A PREROUTING -i $EXTIF -d $EXTIP -p udp --dport $SRCPORT -j DNAT --to $DESTHOST:$DESTPORT echo "$EXTIP:$SRCPORT --> $DESTHOST:$DESTPORT" fi } } done fi #DYNAMIC GENERATION OF MASQUERADING ENTRIES # This will setup the masquerading for the specified nets if [ "$MASQ_ADDR" = "ALL" ] ; then echo "" echo "Masquerading ALL internal hosts and networks" $IPTABLES -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE elif [ "$MASQ_ADDR" != "" ] ; then echo "" echo "Masquerading following host or networks: " for ENTRY in $MASQ_ADDR ; do $IPTABLES -t nat -A POSTROUTING -s $ENTRY -o $EXTIF -j MASQUERADE echo "$ENTRY --> $EXTIP" done else echo "" echo "Masquerading disabled !" fi ###------------------------END DYNAMIC USER-CHAINS--------------------------### echo " --- " ###------------------------------START RULESET------------------------------### # We will now implement the actual firewall to the main builtin chains echo "Implementing firewall rules..." ################# ## INPUT-Chain ## (everything that is addressed to the firewall itself) ################# ##GENERAL Filtering # Kill INVALID packets (not ESTABLISHED, RELATED or NEW) $IPTABLES -A INPUT -m state --state INVALID -j LINVALID # Check TCP-Packets for Bad Flags $IPTABLES -A INPUT -p tcp -j CHECKBADFLAG ##Packets FROM FIREWALL-BOX ITSELF #Accept Loopback $IPTABLES -A INPUT -i lo -j ACCEPT #Kill connections to the local interface from the outside world (--> Should be already catched by kernel/rp_filter) $IPTABLES -A INPUT -d 127.0.0.0/8 -j LREJECT ##Packets FROM INTERNAL NET ##Allow unlimited traffic from internal network to firewall-box ##If protection from the internal interface is needed, alter it $IPTABLES -A INPUT -i $INTIF -j ACCEPT ##Packets FROM EXTERNAL NET ##Explicit DROPS/REJECTS #Logged DROPS/REJECTS # - None - #Silent DROPS/REJECTS (Things we don't want in our logs) #Silently drop all SMB-Traffic (if it keeps filling up your logs) #$IPTABLES -A INPUT -i $EXTIF -j SMBINBOUND #Silently reject Ident (Don't DROP ident, because of possible delays when establishing an outbound connection to a server checking the auth-port (e.g. IRC)) $IPTABLES -A INPUT -i $EXTIF -p tcp --dport 113 -j REJECT --reject-with tcp-reset ##Explicit ALLOWS #Public services running ON FIREWALL-BOX $IPTABLES -A INPUT -i $EXTIF -j FWSERVICESINBOUND #Other ALLOWS go here ##ICMP & Traceroute filtering #Filter ICMP $IPTABLES -A INPUT -i $EXTIF -p icmp -j ICMPINBOUND #Block UDP-Traceroute $IPTABLES -A INPUT -p udp --dport 33434:33523 -j LDROP ##Separate logging of special portscans/connection attempts $IPTABLES -A INPUT -i $EXTIF -j SPECIALPORTS ##Allow all ESTABLISHED/RELATED connections (to unprivileged Ports) in $IPTABLES -A INPUT -i $EXTIF -m state --state ESTABLISHED -j ACCEPT $IPTABLES -A INPUT -i $EXTIF -p tcp --dport $UNPRIVPORTS -m state --state RELATED -j TCPACCEPT $IPTABLES -A INPUT -i $EXTIF -p udp --dport $UNPRIVPORTS -m state --state RELATED -j ACCEPT ##Discard all other packets $IPTABLES -A INPUT -j LDROP ################## ## Output-Chain ## (everything that originates from the Firewall-Box) ################## ##Packets TO FIREWALL-BOX ITSELF #Accept Loopback $IPTABLES -A OUTPUT -o lo -j ACCEPT ##Packets TO INTERNAL NET #Allow unlimited traffic to internal network $IPTABLES -A OUTPUT -o $INTIF -j ACCEPT ##Packets TO EXTERNAL NET ##Explicit DROPS/REJECTS #Logged DROPS/REJECTS # - None - #Silent DROPS/REJECTS (Things we don't want in our logs) #SMB $IPTABLES -A OUTPUT -o $EXTIF -j SMBOUTBOUND ##Explicit ALLOWS #Public services running ON FIREWALL-BOX $IPTABLES -A OUTPUT -o $EXTIF -j FWSERVICESOUTBOUND #Ident (Leave this enabled for reply traffic from silent reject in INPUT-chain !) $IPTABLES -A OUTPUT -o $EXTIF -p tcp --sport 113 -m state --state ESTABLISHED,RELATED -j ACCEPT ##ICMP & Traceroute filtering $IPTABLES -A OUTPUT -o $EXTIF -p icmp -j ICMPOUTBOUND ##Accept all tcp/udp traffic on unprivileged ports going out $IPTABLES -A OUTPUT -o $EXTIF -p tcp --sport $UNPRIVPORTS -j ACCEPT $IPTABLES -A OUTPUT -o $EXTIF -p udp --sport $UNPRIVPORTS -j ACCEPT ##Discard all other packets $IPTABLES -A OUTPUT -j LDROP #################### ## FORWARD-Chain ## (everything that passes the firewall) #################### ##GENERAL Filtering #No entries ##Packets FROM INTERNAL NET ##Explicit DROPS/REJECTS #Logged DROPS/REJECTS #Filter for some Trojans communicating to outside # - To be done - #Silent DROPS/REJECTS (Things we don't want in our logs) #SMB $IPTABLES -A FORWARD -i $INTIF -o $EXTIF -j SMBOUTBOUND ##Explicit ALLOWS #PORT-FORWARDING allows $IPTABLES -A FORWARD -i $INTIF -o $EXTIF -j PORTFWALLOWSOUTBOUND ##Allow all other forwarding (from Ports > 1024) from Internal Net to External Net $IPTABLES -A FORWARD -i $INTIF -o $EXTIF -p tcp --sport $UNPRIVPORTS -j ACCEPT $IPTABLES -A FORWARD -i $INTIF -o $EXTIF -p udp --sport $UNPRIVPORTS -j ACCEPT $IPTABLES -A FORWARD -i $INTIF -o $EXTIF -p icmp -j ACCEPT ##Packets FROM EXTERNAL NET ##Explicit DROPS/REJECTS #Logged DROPS/REJECTS #Kill invalid packets (not ESTABLISHED, RELATED or NEW) $IPTABLES -A FORWARD -i $EXTIF -m state --state INVALID -j LINVALID #Check TCP-Packets for Bad Flags $IPTABLES -A FORWARD -i $EXTIF -p tcp -j CHECKBADFLAG #Silent DROPS/REJECTS (Things we don't want in our logs) #No entries ##Explicit ALLOWS #PORT-FORWARDING allows $IPTABLES -A FORWARD -i $EXTIF -o $INTIF -j PORTFWALLOWSINBOUND ##Allow replies coming in $IPTABLES -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED -j ACCEPT $IPTABLES -A FORWARD -i $EXTIF -o $INTIF -p tcp --dport $UNPRIVPORTS -m state --state RELATED -j TCPACCEPT $IPTABLES -A FORWARD -i $EXTIF -o $INTIF -p udp --dport $UNPRIVPORTS -m state --state RELATED -j ACCEPT $IPTABLES -A FORWARD -i $EXTIF -o $INTIF -p icmp -m state --state RELATED -j ACCEPT ##Catch all rule/Deny every other forwarding $IPTABLES -A FORWARD -j LDROP ################ ## PREROUTING ## ################ ##Port-Forwarding-Entries static section # ##Rest of Port-Forwarding-Entries already generated in the dynamic section # ################### ## POSTROUTING ## ################### ## Masquerade static section # ##Rest of Masquerade entries already generated in the dynamic section # ##Re-enable forwarding echo "1" > /proc/sys/net/ipv4/ip_forward ###-------------------------------END RULESET-------------------------------### echo "...done" echo "" echo "--> IPTABLES firewall loaded/activated <--" ####--------------------------------END FIREWALL--------------------------------#### ;; *) echo "Usage: $0 (start|stop|restart|status) EXTIF INTIF" exit 1 esac exit 0