#!/bin/sh # iptables firewall script # Use this to create a NAT between a single Internet-facing interface and a # local network interface. # # Installation: # Copy this script to /etc/rc.firewall. Make sure iptables is installed and # the proper kernel modules are loaded. Edit port-forwarding rules # (nat_forward) appropriately for your setup. # Usage: # /etc/rc.firewall [-v] {start|stop|restart} ### Settings # LAN: local area network in CIDR format LAN="192.168.0.0/24" # LAN_INT: interface on LAN LAN_INT="eth0" # WAN_INT: Internet-facing interface WAN_INT="eth1" # IPTABLES: path to iptables binary IPTABLES="/sbin/iptables" ### if [ "$1" == "-v" ]; then verbose=1 command=$2 else verbose=0 command=$1 fi ## nat_forward() # parameters: [dest port] # example: nat_forward tcp 2100 2200 192.168.0.2 7000 # (will forward external ports 2100-2200 to 7000-7100 on 192.168.0.2) nat_forward() { proto=$1; sport=$2; eport=$3; dest=$4; dport=$5; edport=$6 if [ "$dport" ]; then verbose_output "Forward: $proto ports $sport-$eport to $dest:$dport" $IPTABLES -t nat -A PREROUTING -p $proto --dport $sport:$eport -i ${WAN_INT} -j DNAT --to-destination $dest:$dport else dport=$sport; edport=$eport verbose_output "Forward: $proto ports $sport-$eport to $dest:$dport-$edport" $IPTABLES -t nat -A PREROUTING -p $proto --dport $sport:$eport -i ${WAN_INT} -j DNAT --to-destination $dest:$dport-$edport fi } verbose_output() { [ $verbose == "1" ] && echo $@ } firewall_start() { ### Logging ### verbose_output "Creating primary log rules" # Dropped packets $IPTABLES -N LOG_DROP # comment/uncomment this to log dropped packets $IPTABLES -A LOG_DROP -j LOG --log-prefix 'iptables drop ' $IPTABLES -A LOG_DROP -j DROP # Accepted packets $IPTABLES -N LOG_ACCEPT #$IPTABLES -A LOG_ACCEPT -j LOG --log-prefix 'iptables accept ' $IPTABLES -A LOG_ACCEPT -j ACCEPT # Rejected packets $IPTABLES -N LOG_REJECT # comment/uncomment this to log rejected packets $IPTABLES -A LOG_REJECT -j LOG --log-prefix 'iptables reject ' $IPTABLES -A LOG_REJECT -j REJECT # Allow localhost & LAN to run free $IPTABLES -A INPUT -i lo -j ACCEPT $IPTABLES -A OUTPUT -o lo -j ACCEPT $IPTABLES -A INPUT -i ${LAN_INT} -j ACCEPT $IPTABLES -A OUTPUT -o ${LAN_INT} -j ACCEPT # Allow packets to forward from the LAN $IPTABLES -A FORWARD -i ${LAN_INT} -s ${LAN} -j ACCEPT $IPTABLES -A FORWARD -o ${LAN_INT} -d ${LAN} -j ACCEPT # Allow ICMP $IPTABLES -A INPUT -p icmp -j LOG_ACCEPT $IPTABLES -A OUTPUT -p icmp -j LOG_ACCEPT # BootP/DHCP $IPTABLES -A INPUT -d 255.255.255.255 -p udp --sport 67 --dport 68 -j ACCEPT # Drop invalid packets $IPTABLES -A INPUT -m state --state INVALID -j LOG_DROP $IPTABLES -A FORWARD -m state --state INVALID -j LOG_DROP # NAT verbose_output "Setting up NAT" $IPTABLES -t nat -A POSTROUTING -s ${LAN} -o ${WAN_INT} -j MASQUERADE $IPTABLES -t nat -A PREROUTING -i ${LAN_INT} -j ACCEPT $IPTABLES -t nat -A PREROUTING -i lo -j ACCEPT verbose_output "Forwarding ports" ### TCP Ports ### ## SSH # godfather, public port 22 nat_forward tcp 22 22 192.168.0.9 # root, public port 222 nat_forward tcp 222 222 192.168.0.3 22 # ock, public port 2222 nat_forward tcp 2222 2222 192.168.0.15 22 # sentinel, public port 22222 nat_forward tcp 22222 22222 192.168.0.1 22 # SMTP nat_forward tcp 25 25 192.168.0.9 ## HTTP # root nat_forward tcp 90 90 192.168.0.3 # godfather nat_forward tcp 91 91 192.168.0.9 # Identd (for outside) $IPTABLES -A INPUT -p tcp --dport 113 -j ACCEPT # dcc ports, godfather nat_forward tcp 2020 2030 192.168.0.9 ### UDP Ports ### # DNS nat_forward udp 53 53 192.168.0.3 # Counter-strike, root nat_forward udp 27015 27015 192.168.0.3 # bittorrent, godfather nat_forward tcp 49133 49133 192.168.0.9 ## Allow traffic outbound $IPTABLES -A OUTPUT -o ${WAN_INT} -j ACCEPT ## Stateful checking $IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT $IPTABLES -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT ### Mark packets for QoS ### verbose_output "Creating mangle rules for Quality of Service (QoS)" # Upload marking $IPTABLES -t mangle -A FORWARD -s ${LAN} -m length --length 0:500 -j MARK --set-mark 3 $IPTABLES -t mangle -A FORWARD -s ${LAN} -m length --length 500:1500 -j MARK --set-mark 5 # Download marking $IPTABLES -t mangle -A POSTROUTING -s ! ${LAN} -d ${LAN} -m length --length 0:500 -j MARK --set-mark 4 $IPTABLES -t mangle -A POSTROUTING -s ! ${LAN} -d ${LAN} -m length --length 500:1500 -j MARK --set-mark 6 ## Drop everything else & Log $IPTABLES -A INPUT -j LOG_DROP $IPTABLES -A OUTPUT -j LOG_DROP $IPTABLES -A FORWARD -j LOG_DROP verbose_output "Adjusting values in /proc" # Allow forwarding echo "1" > /proc/sys/net/ipv4/ip_forward # Log spoofed packets, source routed packets, redirect packets echo "1" > /proc/sys/net/ipv4/conf/all/log_martians } firewall_stop() { $IPTABLES -P INPUT ACCEPT $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IPTABLES -F $IPTABLES -Z $IPTABLES -X $IPTABLES -t nat -F $IPTABLES -t mangle -F echo "0" > /proc/sys/net/ipv4/ip_forward } firewall_restart() { firewall_stop sleep 1 firewall_start } case "$command" in start) echo "Committing firewall rules.." firewall_start echo "done" ;; stop) echo "Clearing firewall rules.." firewall_stop echo "done" ;; restart) echo "Recommitting firewall rules.." firewall_restart echo "done" ;; *) echo "Usage: $0 {start|stop|restart}" ;; esac exit 0