1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Networks iptables firewall script for home router

Discussion in 'Hardware' started by Pygo, 2 Jun 2007.

  1. Pygo

    Pygo Rick Relixed

    Joined:
    26 Jan 2003
    Posts:
    2,179
    Likes Received:
    8
    Firstly, I'll admit that this firewall script is rather overly complex. (Though, I could make it even more complex if I added some ipt_recent rules, even ones not commented out below.)

    I should also point out that this isn't quite complete yet. But mostly done.
    Any questions, comments, etc are well appreciated. Most of the code is commented to show what the rules are doing, but feel free to ask if unsure.


    Well, here goes the massive paste of code:

    Code:
    # Firewall ruleset for main home router.
    # eth0 is the outside interface, connected to the cable modem
    # eth1 is the internal interface, connected to computers, and NAS, xbox.
    # eth2 is connected to a dd-wrt router for laptop wifi. This is assumed
    # to be hacked. (room mate plugged in to actual router or wifi hacked.) This is located in a common area of the house.
    # eth2 and eth0 accept connections from port 443 for SSH and SSH-VPN.
    # eth1 and tun0 have specific rules allowing web, chat, game access to the web on eth0.
    # note that tun0 is commented out and not expanded to save space.
    
    ###
    ### Flush ALL rules
    ###
    iptables -F
    
    #
    # Drop all packets by default
    # If a packet does not match one of the other rules below
    # these ones, then it gets dropped.
    #
    iptables -P INPUT DROP
    iptables -P FORWARD DROP
    iptables -P OUTPUT DROP
    
    ###
    ### Flush all specific rules.
    ###
    iptables -F INPUT
    iptables -F FORWARD
    iptables -F OUTPUT
    iptables -F -t nat
    iptables -F MAC_FILTER
    
    ###
    ### Enable NAT Masquerading on eth0
    ###
    iptables -A POSTROUTING -t nat -o eth0 -j MASQUERADE
    
    
    ###
    ### MAC FILTERING.
    ###
    
    # Allow broadcasts
    iptables -A MAC_FILTER -d 255.255.255.255 -j RETURN
    
    # Why are these two lines commented? (may need uncommenting)
    #iptables -A MAC_FILTER -m pkttype --pkt-type ! unicast -j RETURN
    #iptables -A MAC_FILTER -m addrtype --dst-type BROADCAST -j RETURN
    
    # Allow internal broadcasts.
    iptables -A MAC_FILTER -d 192.168.12.255 -j RETURN
    iptables -A MAC_FILTER -d 192.168.123.255 -j RETURN
    
    # Allow these mac addresses
    # I need to add more mac addresses in here!
    #iptables -A MAC_FILTER -s eth1 -m mac --mac-source 00:00:00:00:00:00 -j RETURN
    
    # Drop all mac addresses not allowed above
    iptables -A MAC_FILTER -j DROP
    
    ###
    ### END OF MAC FILTERING SECTION
    ###
    
    
    ###
    ### TOS MANGLING SECTION
    ###
    
    # Mangles the TOS on standard ports so they get priority in routers
    # NOTE: this needs stuff added, games, chat, etc.
    ###################################################################
    # TOS table
    # Options:
    #               Normal-Service = 0 (0x00)
    #               Minimize-Cost = 2 (0x02)
    #               Maximize-Reliability = 4 (0x04)
    #               Maximize-Throughput = 8 (0x08)
    #               Minimize-Delay = 16 (0x10)
    # ToS: Client Applications; data => tos_client
    # Most of these are the RFC 1060/1349 suggested TOS values.
    # To view mangle table, type: iptables -L -t mangle
    
    # Mangle values of packets created locally.
    iptables -t mangle -A OUTPUT -o eth0 -p tcp --sport 443 -j TOS --set-tos Minimize-Delay
    iptables -t mangle -A OUTPUT -o eth0 -p tcp --dport 6667 -j TOS --set-tos Maximize-Reliability
    
    
    # Rules to mangle TOS values of packets routed through the firewall
    iptables -t mangle -A PREROUTING -p tcp --dport 20 -j TOS --set-tos Maximize-Throughput
    iptables -t mangle -A PREROUTING -p tcp --dport 21 -j TOS --set-tos Minimize-Delay
    iptables -t mangle -A PREROUTING -p tcp --dport 22 -j TOS --set-tos Minimize-Delay
    iptables -t mangle -A PREROUTING -p tcp --dport 23 -j TOS --set-tos Minimize-Delay
    iptables -t mangle -A PREROUTING -p tcp --dport 25 -j TOS --set-tos Minimize-Delay
    iptables -t mangle -A PREROUTING -p udp --dport 53 -j TOS --set-tos Minimize-Delay
    #iptables -t mangle -A PREROUTING -p tcp --dport 67 -j TOS --set-tos Minimize-Delay
    iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TOS --set-tos Maximize-Throughput
    iptables -t mangle -A PREROUTING -p tcp --dport 110 -j TOS --set-tos Maximize-Throughput
    #iptables -t mangle -A PREROUTING -p tcp --dport 113 -j TOS --set-tos Minimize-Delay
    iptables -t mangle -A PREROUTING -p tcp --dport 123 -j TOS --set-tos Minimize-Delay
    iptables -t mangle -A PREROUTING -p tcp --dport 143 -j TOS --set-tos Maximize-Throughput
    iptables -t mangle -A PREROUTING -p tcp --dport 443 -j TOS --set-tos Maximize-Throughput
    iptables -t mangle -A PREROUTING -p tcp --dport 993 -j TOS --set-tos Maximize-Throughput
    iptables -t mangle -A PREROUTING -p tcp --dport 995 -j TOS --set-tos Maximize-Throughput
    #iptables -t mangle -A PREROUTING -p tcp --dport 1080 -j TOS --set-tos Minimize-Delay
    #iptables -t mangle -A PREROUTING -p tcp --dport 6000:6063 -j TOS --set-tos Maximize-Throughput
    iptables -t mangle -A PREROUTING -p tcp --dport 6667 -j TOS --set-tos Maximize-Reliability
    
    ###
    ### END OF TOS MANGLING SECTION
    ###
    
    
    ###
    ### Accept packets of ESTABLISHED connections
    ###
    iptables -A INPUT -i eth0 -m state --state ESTABLISHED -j ACCEPT
    iptables -A INPUT -i eth1 -m state --state ESTABLISHED -j ACCEPT
    iptables -A INPUT -i eth2 -m state --state ESTABLISHED -j ACCEPT
    iptables -A INPUT -i tun0 -m state --state ESTABLISHED -j ACCEPT
    
    iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED -j ACCEPT
    iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED -j ACCEPT
    iptables -A FORWARD -i tun0 -o eth0 -m state --state ESTABLISHED -j ACCEPT
    iptables -A FORWARD -i eth0 -o tun0 -m state --state ESTABLISHED -j ACCEPT
    #iptables -A FORWARD -i tun0 -o eth1 -m state --state ESTABLISHED -j ACCEPT
    #iptables -A FORWARD -i eth1 -o tun0 -m state --state ESTABLISHED -j ACCEPT
    
    iptables -A OUTPUT -o eth0 -m state --state ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -o eth1 -m state --state ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -o eth2 -m state --state ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -o tun0 -m state --state ESTABLISHED -j ACCEPT
    
    
    ###
    ### Accept packets of RELATED connections
    ###
    iptables -A INPUT -i eth0 -m state --state RELATED -p tcp --dport 1024: -j ACCEPT
    iptables -A INPUT -i eth1 -m state --state RELATED -p tcp --dport 1024: -j ACCEPT
    iptables -A INPUT -i eth2 -m state --state RELATED -p tcp --dport 1024: -j ACCEPT
    iptables -A INPUT -i tun0 -m state --state RELATED -p tcp --dport 1024: -j ACCEPT
    
    iptables -A INPUT -i eth0 -m state --state RELATED -p udp --dport 1024: -j ACCEPT
    iptables -A INPUT -i eth1 -m state --state RELATED -p udp --dport 1024: -j ACCEPT
    iptables -A INPUT -i eth2 -m state --state RELATED -p udp --dport 1024: -j ACCEPT
    iptables -A INPUT -i tun0 -m state --state RELATED -p udp --dport 1024: -j ACCEPT
    
    iptables -A INPUT -i eth0 -m state --state RELATED -p icmp -j ACCEPT
    iptables -A INPUT -i eth1 -m state --state RELATED -p icmp -j DROP
    iptables -A INPUT -i eth2 -m state --state RELATED -p icmp -j DROP
    iptables -A INPUT -i tun0 -m state --state RELATED -p icmp -j DROP
    
    iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED -p tcp --dport 1024: -j ACCEPT
    iptables -A FORWARD -i eth0 -o tun0 -m state --state RELATED -p tcp --dport 1024: -j ACCEPT
    #iptables -A FORWARD -i eth1 -o tun0 -m state --state RELATED -p tcp --dport 1024: -j ACCEPT
    iptables -A FORWARD -i eth1 -o eth0 -m state --state RELATED -p tcp --dport 1024: -j ACCEPT
    iptables -A FORWARD -i tun0 -o eth0 -m state --state RELATED -p tcp --dport 1024: -j ACCEPT
    #iptables -A FORWARD -i tun0 -o eth1 -m state --state RELATED -p tcp --dport 1024: -j ACCEPT
    
    iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED -p udp --dport 1024: -j ACCEPT
    iptables -A FORWARD -i eth0 -o tun0 -m state --state RELATED -p udp --dport 1024: -j ACCEPT
    #iptables -A FORWARD -i eth1 -o tun0 -m state --state RELATED -p udp --dport 1024: -j ACCEPT
    iptables -A FORWARD -i eth1 -o eth0 -m state --state RELATED -p udp --dport 1024: -j ACCEPT
    iptables -A FORWARD -i tun0 -o eth0 -m state --state RELATED -p udp --dport 1024: -j ACCEPT
    #iptables -A FORWARD -i tun0 -o eth1 -m state --state RELATED -p udp --dport 1024: -j ACCEPT
    
    ###
    ### END PACKETS OF ESTABLISHED AND RELATED CONNECTIONS SECTION
    ###
    
    
    
    ###
    ### Drop any data packets from eth0 and eth2 that are spoofed internal ip addresses.
    ###
    iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP
    iptables -A INPUT -i eth0 -s 127.0.0.0/8 -j DROP
    iptables -A INPUT -i eth2 -s 192.168.12.0/24 -j DROP
    iptables -A INPUT -i eth2 -s 127.0.0.0/8 -j DROP
    
    
    
    
    
    ###
    ### PORT FORWARDING RULES
    ###
    # these rules forward an external port from the external ip of eth0 to an internal ip.
    
    # forward port 443 from eth0 to inside port 443 (example)
    #iptables -t nat -A PREROUTING -p tcp -i eth0 -d 0/0 --dport 443 -j DNAT --to 192.168.12.x:443
    #iptables -A FORWARD -p tcp -i eth0 -d 192.168.12.x --dport 443 -j ACCEPT
    
    ###
    ### END PORT FORWARDING RULES
    ###
    
    
    
    ###
    ### Forward syn packets from internal network(s) to the internet,
    ###
    # for typical internet use (web, games, chat, etc.)
    
    
    ##
    ## Fowarding for tun0
    ##
    
    # Temporay allow-all rule for tun0 to access the web
    #iptables -A FORWARD -i tun0 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --syn -j ACCEPT
    
    ##
    ## END Fowarding for tun0
    ##
    
    
    ##
    ## Forwarding for eth1
    ##
    
    # web
    iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 80 --syn -j ACCEPT
    iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 443 --syn -j ACCEPT
    
    # ssh
    iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 22 --syn -j ACCEPT
    
    # ftp (UFTP commented out due to lack of use)
    iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 20 --syn -j ACCEPT
    iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 21 --syn -j ACCEPT
    #iptables -A FORWARD -i eth1 -o eth0 -p udp -s 192.168.12.0/24 -d 0/0 --destination-port 20 -j ACCEPT
    #iptables -A FORWARD -i eth1 -o eth0 -p udp -s 192.168.12.0/24 -d 0/0 --destination-port 21 -j ACCEPT
    
    
    # email (commented out due to lack of use)
    #iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 25 --syn -j ACCEPT
    #iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 110 --syn -j ACCEPT
    #iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 143 --syn -j ACCEPT
    
    # email using ssl/tls (imap4 then pop3s) (commented out due to lack of use)
    #iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 993 --syn -j ACCEPT
    #iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 995 --syn -j ACCEPT
    
    # DNS
    iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 53 --syn -j ACCEPT
    iptables -A FORWARD -i eth1 -o eth0 -p udp -s 192.168.12.0/24 -d 0/0 --destination-port 53 -j ACCEPT
    
    # google talk (via gaim / pidgin)
    iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 5222 --syn -j ACCEPT
    
    # MSN
    iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 1863 --syn -j ACCEPT
    
    # IRC (and ident) (Commented out because irssi is used on this box, see output rules)
    # iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 113 --syn -j ACCEPT
    # quakenet servers to be added in to this list. don't forget the syn packets
    
    # NTP
    iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 123 --syn -j ACCEPT
    
    # rsync (add in specific IP of external backup server later)
    # maybe make this an output rule and only backup the backed up files.
    # iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 873 --syn -j ACCEPT
    
    # Half-Life
    iptables -A FORWARD -i eth1 -o eth0 -p tcp -s 192.168.12.0/24 -d 0/0 --destination-port 27015 --syn -j ACCEPT
    
    
    
    ##
    ## END Forwarding for eth1
    ##
    
    ###
    ### END Forwarding Rules
    ###
    
    
    
    ###
    ### OUTPUT TABLES
    ###
    
    # allow icmp/tcp ping/traceroute from this box, going out.
    iptables -A OUTPUT -p icmp -d 0/0 --syn -j ACCEPT
    iptables -A OUTPUT -p udp -d 0/0 --destination-port 33434 -j ACCEPT
    
    # allow connections outbound to main file server for rsync
    iptables -A OUTPUT -o eth1 -p tcp -d 192.168.12.55/32 --destination-port 873 --syn -j ACCEPT
    
    # allow connections outbound to other internal servers for ssh
    iptables -A OUTPUT -o eth1 -p tcp -d 192.168.12.0/24 --destination-port 22 --syn -j ACCEPT
    
    # allow connections outbound to the web for SSH / SSH on 443
    iptables -A OUTPUT -o eth0 -p tcp -d 0/0 --destination-port 22 --syn -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp -d 0/0 --destination-port 443 --syn -j ACCEPT
    
    # allow IRC connectivity to quakenet IRC servers (uk, followed by us)
    # (even though I'm in Canada, I find I have better reliability from UK servers)
    iptables -A OUTPUT -o eth0 -p tcp -d 213.48.150.5/32 --destination-port 6667 --syn -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp -d 195.68.221.111/32 --destination-port 6667 --syn -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp -d 194.159.164.211/32 --destination-port 6667 --syn -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp -d 193.138.95.129/32 --destination-port 6667 --syn -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp -d 85.236.110.226/32 --destination-port 6667 --syn -j ACCEPT
    
    iptables -A OUTPUT -o eth0 -p tcp -d 8.9.17.72/32 --destination-port 6667 --syn -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp -d 8.7.233.36/32 --destination-port 6667 --syn -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp -d 69.12.25.9/32 --destination-port 6667 --syn -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp -d 69.12.72.132/32 --destination-port 6667 --syn -j ACCEPT
    iptables -A OUTPUT -o eth0 -p tcp -d 66.225.225.66/32 --destination-port 6667 --syn -j ACCEPT
    
    ###
    ### END OF OUTPUT TABLES
    ###
    
    
    ###
    ### SSH Brute Force Protection
    ###
    # note that I'm actually running ssh on port 443 (to get around hotel firewalls, etc.)
    # ipt_recent module would be VERY nice for this (and other stuff)
    # because it is not loaded, most of below is commented
    # some of this section came from http://freshmeat.net/projects/iptables-firewall/?topic_id=151
    # in the 50_ssh_brute_force_protection script
    
    # Create new SSH_LOG_DROP chain for logging and dropping:
    #iptables -N SSH_LOG_DROP
    #iptables -F SSH_LOG_DROP
    #iptables -A SSH_LOG_DROP -m limit --limit 1/m --limit-burst 1 -j DROP
    
    # SSH Whitelist
    #iptables -N SSH_CHK
    #iptables -A SSH_CHK -s [accepted_IP] -j RETURN
    #iptables -A SSH_CHK -s 0/0 -j SSH_LOG_DROP
    
    ## Create rate1 & rate2 checker:
    #iptables -A SSH_CHK -m recent --name sshchk --set
    #iptables -A SSH_CHK -m recent --name sshchk --update \
    #          --seconds 60 --hitcount 4 -j SSH_LOG_DROP
    #iptables -A SSH_CHK -m recent --name sshchk --update \
    #         --seconds 1800 --hitcount 10 -j SSH_LOG_DROP
    
    # For now, I use a simpler version of the brute force protection until I get ipt_recent loaded properly
    iptables -A INPUT -p tcp --dport 443 -m state --state NEW -m limit --limit 1/m --limit-burst 1 -j DROP
    
    ###
    ### END SSH Brute Force Protection
    ###
    
    
    ###
    ### INPUT TABLES
    ###
    
    # allow main fileserver to connect to local rsync server
    # (I use this router as a secondary backup server)
    iptables -A INPUT -i eth1 -p tcp -s 192.168.12.55/32 --destination-port 873 --syn -j ACCEPT
    
    # allow inbound connections to local ssh server
    iptables -A INPUT -i eth0 -p tcp -s [colo_server_IP]/32 --destination-port 443 --syn -j ACCEPT
    iptables -A INPUT -i eth1 -p tcp -s 192.168.12.0/24 --destination-port 443 --syn -j ACCEPT
    iptables -A INPUT -i eth2 -p tcp -s 192.168.123.5/32 --destination-port 443 --syn -j ACCEPT
    iptables -A INPUT -i tun0 -p tcp -s 192.168.12.48/32 --destination-port 443 --syn -j ACCEPT
    
    ###
    ### END OF INPUT TABLES
    ###
    
    
    
    
    # links to read?
    #
    # http://www.badpenguin.co.uk/main/content/view/14/35/ ssh-vpn how-to!
    # Basics of above linked article:
    #
    # pppd tunnel:
    # pppd updetach noauth passive pty "ssh root@<hostname> pppd nodetach notty noauth" <localIP>:<RemoteIP>
    #
    # tun device:
    # open up the tunnel:
    #  ssh user@host -w tun0:tun0
    #
    # setup routing locally:
    #  - (switch tun0 for ppp0 if using pppd)
    #  ifconfig tun0 172.16.0.1 up
    #  route add -net 172.16.0.0/24 tun0
    #  route add -net 192.168.x.y gw 172.16.0.2
    #
    # setup routing remotely:
    #  ifconfig tun0 172.16.0.2 up
    #  route add -net 172.16.0.0/24 tun0
    #  route add -net 192.168.a.b gw 172.16.0.1
    #
    # done, enjoy.
    
    
    
    # eof (not really)
    
    
    
    
    ###
    ### Rules to organize in to propper place up top.
    ###
    
    
    # Many of these are to drop nmap scans, etc.
    
    # NMAP FIN/URG/PSH
    iptables -A VALID_CHK -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
    
    # SYN/RST/ACK/FIN/URG
    iptables -A VALID_CHK -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
    
    # ALL/ALL Scan
    iptables -A VALID_CHK -p tcp --tcp-flags ALL ALL -j DROP
    
    # NMAP FIN Stealth
    iptables -A VALID_CHK -p tcp --tcp-flags ALL FIN -j DROP
    
    # SYN/RST
    iptables -A VALID_CHK -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
    
    # SYN/FIN -- Scan(probably)
    iptables -A VALID_CHK -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
    
    # NMAP Null Scan
    iptables -A VALID_CHK -p tcp --tcp-flags ALL NONE -j DROP
    
    # Drop packets with bad tcp flags
    iptables -A VALID_CHK -p tcp --tcp-option 64 -j DROP
    iptables -A VALID_CHK -p tcp --tcp-option 128 -j DROP
    
    # Drop invalid packets
    iptables -A VALID_CHK -m state --state INVALID -j DROP
    
    
    # Do NOT allow DRDOS abuse (Distributed Reflection Denial Of Service attack)
    iptables -A INPUT -p tcp ! --dport 2049 -m multiport --sports 20,21,22,23,80,110,143,443,993,995 -j DROP
    iptables -A INPUT -p udp ! --dport 2049 -m multiport --sports 20,21,22,23,80,110,143,443,993,995 -j DROP
    
    ###
    ### END OF Rules to organize in to propper place up top.
    ###
    
    
    # eof (no really, it is this time )
    

    EDIT: I think I should also mention that not all of this is in production right now.
     
    Last edited: 2 Jun 2007
  2. tacticus

    tacticus What's a Dremel?

    Joined:
    14 Jan 2006
    Posts:
    360
    Likes Received:
    0
    hrrm you are making me get back to work on my dedicated router box :p
     
  3. Glider

    Glider /dev/null

    Joined:
    2 Aug 2005
    Posts:
    4,173
    Likes Received:
    21
Tags:

Share This Page