ipchains to iptables quickie

(This is an old email I found I had written for some of my friends. No support provided, sorry.)

Here's my mini write-up for people to lazy too read the HOWTOs. ;)
See also: http://netfilter.kernelnotes.org/unreliable-guides/index.html

The attached file goes in your startup stuff.
In-line comments for ya to understand this stuff, I hope... bold stuff isn't in the real file. If you have any Q's lemme know. LEARN BY DOING. ;)
<lotsa snips in here>
Do a "iptables --help" to see the quick commands of P, F, N, I, A, X, and D...
                # Set policies
                ./iptables -P INPUT ACCEPTI allow anything not specifically blocked thru the firewall... oh well.
                ./iptables -P FORWARD ACCEPTJeff claims to block everything he doesn't accept, and then accepts
                ./iptables -P OUTPUT ACCEPT1024 and above.... 6 of one, 1/2 dozen the other ;)
                # User defined tables
                # Shared by INPUT and FORWARD
                  ./iptables -N Protect"N" means new chain creation. But in case we run this multiple times....
                  ./iptables -F Protect"F" flushes the chain if it already existed
                # Now set up the INPUT chain  There are three default chains - INPUT, FORWARD, OUTPUT.
*** UNLIKE 2.2/IPCHAINS the INPUT and OUTPUT chains are only if the packet is destined for the firewall. FORWARD means the packet is gonna be FORWARDed (duh). ***
                  ./iptables -A INPUT -j Protect                         # Spoofs, etcEverything coming IN goes thru Protect
                  ./iptables -A INPUT -p tcp --dport 20:21 -j In_FTP     # FTP inTCP w/ destination ports 20-21 go thru In_FTP
                  ./iptables -A INPUT -p tcp -j In_Mail                  # Mail in (port can be 25 or 110)ANY TCP packet goes to In_Mail
                  ./iptables -A INPUT -p udp --dport 123 -j In_TimeSrv   # Time ServersUDP with port 123 destination goes
                  ./iptables -A INPUT -j In_New     # Any new extIF connections not specified above are blocked (telnet, ssh, etc)All check
                # The FORWARD chain
                  ./iptables -A FORWARD -j Protect                       # Spoofs, etcEverything FORWARDED goes thru Protect also
(this is why Protect is separate from others)
                # The Protect chains
                  ./iptables -A Protect -j Protect_HackersAll go here...
                  ./iptables -A Protect -i $extIF -p udp --sport 53 -j Protect_DNSuUDP source port 53 coming IN ppp+ (any ppp)
Bill would put eth2 or whatever cable modem set to

*** UNLIKE 2.2/ipchains *** -i means INPUT interface NOT 'INTERFACE'. -o means OUTPUT interface now. -i can only match INPUT and FORWARD chains, -o can only match in OUTPUT chains...
                  ./iptables -A Protect -p icmp -j Protect_ICMPICMP packets go to Protect_ICMP
These next ones get complicated. "-d" is DESTINATION IP. "-m limit" limits the number of matches of a rule. Check the HOWTO for more info. That stops it to one log entry per second. The "--log-prefix" is required for fireparse 2.0. The "Hackers" part tells me what chain matched, and the ":1" says what rule number matched. **NOTE** that you need TWO rules to LOG and then do something!!! (I am not happy with that) Oh yeah the a= part is for fireparse too... tells what its action was.
                  ./iptables -A Protect_Hackers -d -m limit --limit 1/s -j LOG --log-prefix "fp=Hackers:1 a=DROP "
                  ./iptables -A Protect_Hackers -d -j DROPDROP the packet (vs. ACCEPT, REJECT, LOG, RETURN)
[RETURN = Fall off the end of the chain. New to 2.4/IPTables. YAY!!!]
                  ./iptables -A Protect_Hackers -s -j DROP-s is source IP
This next line is just a little combo adding the input interface
                  ./iptables -A Protect_Spoofs -s -i $extIF -m limit --limit 1/s -j LOG --log-prefix "fp=Spoofs:3 a=DROP "
                  ./iptables -A Protect_Spoofs -s -i $extIF -j DROP
NOTE this next line! The new system combines NAT and packet filtering - by time the filter sees the packet, it HAS ALREADY BEEN MASQ'D BACK - meaning the destination can EASILY be the internal address of your other machines!!!
                  # Destination of 192.168.x.x is NOT a spoof because packet filter sees MASQ answers coming back with that!
Just showing that you can do subnetting on the matches (some above too):
                  ./iptables -A Protect_DNSu -s -j ACCEPT
This line logs that DNS came thru that didn't come from my "normal" DNS sources. Note there is no related action, so it falls off the end of the chain and back to where it started (in the INPUT or FORWARD chain)
                  ./iptables -A Protect_DNSu -m limit --limit 1/s -j LOG --log-prefix "fp=DNS:1 a=ACCEPT "
Just like TCP/UDP have ports, ICMP has types.... numeric or words:
                  ./iptables -A Protect_ICMP -p icmp --icmp-type 5 -i $extIF -m limit --limit 1/s -j LOG --log-prefix "fp=ICMP:1 a=DROP "
                  ./iptables -A Protect_ICMP -p icmp --icmp-type 5 -i $extIF -j DROP
                  ./iptables -A Protect_ICMP -p icmp --icmp-type echo-request -m limit --limit 2/s -j ACCEPT # Stop ping floods
                  ./iptables -A Protect_ICMP -p icmp --icmp-type echo-request -m limit --limit 1/s -j LOG --log-prefix "fp=ICMP:2 a=DROP "
                  ./iptables -A Protect_ICMP -p icmp --icmp-type echo-request -j DROP
These are for future use (I may open FTP some day)... states can be NEW, INVALID, RELATED, CONNECTED. This stops any NEW or bad connections (note I don't waste processor time checking the protocol or port since that was already done to get here!!!) Note that FTPs from my internal network will be let thru:
                  ./iptables -A In_FTP -i $extIF -m state --state NEW,INVALID -m limit --limit 1/s -j LOG --log-prefix "fp=In_FTP:1 a=DROP "
                  ./iptables -A In_FTP -i $extIF -m state --state NEW,INVALID -j DROP
Some day I may do POP3 (port 110) so I have my 'mail' rule handle 25 and 110:
                  ./iptables -A In_Mail -p tcp --dport 25 -i $extIF -j ACCEPT
                  ./iptables -A In_Mail -p tcp --dport 110 -i $extIF -m limit --limit 1/s -j LOG --log-prefix "fp=In_Mail:1 a=DROP "
                  ./iptables -A In_Mail -p tcp --dport 110 -i $extIF -j DROP
This stops any NEW connections from ppp+ to ports 0 to 1023 (the classical Unix "reserved" ports) - combo of state, limit, LOG:
                  ./iptables -A In_New -i $extIF -p tcp --dport 0:1023 -m state --state NEW,INVALID -m limit --limit 1/s -j LOG --log-prefix "fp=In_New:1 a=DROP "
                  ./iptables -A In_New -i $extIF -p tcp --dport 0:1023 -m state --state NEW,INVALID -j DROP

Now comes Part II - NAT:
                # Just masq everything outbound
IPTables is extensible. One extension is NAT - "-t nat" says to load the NAT table. It must be FIRST on the line. For NAT, there are a few internal chains, the most important being PREROUTING and POSTROUTING (entering and leaving the machine). MASQUERADE means SNAT - Source Network Address Translation - what we want to do to hide a network behind a single IP for outbound data. Note the use of "-o" vs. the "-i" above. iptables actually has primitive load balancing for both SNAT and DNAT...
                ./iptables -t nat -A POSTROUTING -o $extIF -j MASQUERADE
                # Set some hooks for the port forwarding scripts
                ./iptables -t nat -N PortFW
Seems odd, but I made a chain called PortFW. That way my firewall setup scripts can just wipe it without worrying about other things that may be in the PREROUTING chain.
                ./iptables -t nat -A PREROUTING -i $extIF -j PortFW
The "PortFW" chain is "DNAT" - Destination NAT - we hide from the internet the DESTINATION of the packet. AKA "Port Forwarding" in its simplest form. Again, this also allows load balancing if we wanted to run web server clusters. I will give you those other scripts some other time.
                echo 1 > /proc/sys/net/ipv4/ip_forwardTurns on the kernel packet forwarding
                echo "."
        # Make sure we get called to stop later
        touch /var/lock/subsys/packetfilterThe shutdown script ("/etc/rc.d/rc" sees this file and tells us to "stop")


No comments.