#!/bin/sh # rc.firewall - Initial SIMPLE IP Firewall script for Linux 2.4.x and iptables # Copyright (C) 2001 Oskar Andreasson # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program or from the site that you downloaded it # from; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA ################################################################################# ################################################################################# # TODO: this isn't nearly perfect yet. should unload modules upon stopping, # TODO: consider whether NAT should remain enabled or disabled upon stopping, # TODO: and maybe more. also clean up the rest of this file a lot. # TODO: currently can't be used for forwarding one port range to another. # TODO: see DESTINATION variable (can't have ip:port1:port2). ################################################################################# ################################################################################# ################################################################################# # allowPort - opens the specified port and forwards to another IP, if necessary. # usage: allowPort # # src ip: wan source ip/subnet of packet. can be the word "all". # int ip: lan destination for packet. # # external port and internal port allow you to forward from an external port on the # public ip to a different internal port on a private ip. # # port desc: quoted string describing the port usage, ie "www", "unreal tournament". # # optional dest hostname is currently not used, and is more for informational purposes. # in the future it may be used for dynamic hostname/ip forwarding. ################################################################################# function setPorts { allowPort tcp all 22 192.168.0.1 22 "ssh" Gateway allowPort tcp all 53 192.168.0.1 53 "dns (bind)" Gateway allowPort tcp all 113 192.168.0.1 113 "ident (irc)" Gateway allowPort udp all 53 192.168.0.1 53 "dns (bind)" Gateway allowPort udp all 67 192.168.0.1 67 "dhcp (isp)" Gateway allowPort udp all 68 192.168.0.1 68 "dhcp (isp)" Gateway allowPort tcp all 20 192.168.0.2 20 "ftp-data" TheCart allowPort tcp all 21 192.168.0.2 21 "ftp-control" TheCart allowPort tcp all 25 192.168.0.2 25 "smtp" TheCart allowPort tcp all 80 192.168.0.2 80 "http" TheCart allowPort tcp all 110 192.168.0.2 110 "pop3" TheCart allowPort tcp all 143 192.168.0.2 143 "imap" TheCart allowPort tcp all 443 192.168.0.2 443 "https" TheCart allowPort tcp all 873 192.168.0.2 873 "rsync" TheCart allowPort tcp all 993 192.168.0.2 993 "imap/ssl" TheCart allowPort tcp all 1214 192.168.0.2 1214 "fasttrack" TheCart allowPort tcp all 1723 192.168.0.2 1723 "pptp vpn" TheCart allowPort tcp all 2010:2020 192.168.0.2 2010:2020 "karr dcc" TheCart allowPort tcp all 2525 192.168.0.2 25 "smtp (xjjk relay)" TheCart allowPort tcp all 2222 192.168.0.2 22 "ssh (www people)" TheCart allowPort tcp all 3333 192.168.0.2 3333 "karr telnet" TheCart allowPort tcp all 3334 192.168.0.2 3334 "/dev/bot telnet" TheCart allowPort tcp all 4662 192.168.0.2 4662 "mldonkey" TheCart allowPort tcp all 6346 192.168.0.2 6346 "gnutella" TheCart allowPort tcp all 6347 192.168.0.2 6347 "gnutella 2" TheCart allowPort tcp all 6885:6889 192.168.0.2 6885:6889 "bt client" TheCart allowPort tcp all 6891:6892 192.168.0.2 6891:6892 "bt/filelist" TheCart allowPort tcp all 8082 192.168.0.2 8082 "bt tracker 1" TheCart allowPort tcp all 8083 192.168.0.2 8083 "bt tracker 2" TheCart allowPort tcp all 8084 192.168.0.2 8084 "bt 1 link" TheCart allowPort tcp all 8888:8892 192.168.0.2 8888:8892 "openvpn server" TheCart allowPort tcp all 60000:60010 192.168.0.2 60000:60010 "ftp (passive)" TheCart allowPort udp all 5000 192.168.0.2 5000 "openvpn server" TheCart allowPort udp all 8888:8892 192.168.0.2 8888:8892 "also openvpn?" TheCart allowPort udp all 6891:6892 192.168.0.2 6891:6892 "bt/filelist" TheCart allowPort tcp all 6881:6884 192.168.0.17 6881:6884 "bt" VeeAte allowPort tcp all 6894 192.168.0.17 6894 "bt/filelist" VeeAte allowPort tcp all 8081 192.168.0.17 8081 "crackattack" VeeAte allowPort tcp all 6000 192.168.0.17 6000 "gunzonline 1" VeeAte allowPort tcp all 7700 192.168.0.17 7700 "gunzonline 2" VeeAte allowPort tcp all 4400 192.168.0.17 4400 "gunzonline 3" VeeAte allowPort udp all 6000 192.168.0.17 6000 "gunzonline 1" VeeAte allowPort udp all 7700 192.168.0.17 7700 "gunzonline 2" VeeAte allowPort udp all 4400 192.168.0.17 4400 "gunzonline 3" VeeAte allowPort tcp all 6890 192.168.0.25 6890 "bt/filelist" Colgate } # examples of other things that can be done. # #$IPTABLES -A INPUT -p TCP -s $IPV6_SVR --dport 4343 -j ACCEPT # #$IPTABLES -t nat -A PREROUTING -p TCP -s 0/0 --dport 1723 -j LOG # #$IPTABLES -t nat -A PREROUTING -p TCP -s 0/0 --dport 25 -j LOG # # ASB, 20021228, allow ipv6 tunnel traffic # #$IPTABLES -A INPUT -p ipv6-tunnel -s $IPV6_SVR -j ACCEPT # # 20040102, ASB, block outgoing 44000 udp for ravenshield # #$IPTABLES -A OUTPUT -p udp -o $INET_IFACE --dport 44000 -j DROP # 1.5 IPTables Configuration. IPTABLES="/usr/sbin/iptables" function flush { # ASB, 20021228, flush rulesets (more or less) $IPTABLES -F $IPTABLES -t nat -F $IPTABLES -t mangle -F $IPTABLES -X $IPTABLES -t nat -X $IPTABLES -t mangle -X } # see documentation for allowPort above, where it's called. function allowPort { if [ $# -lt 6 -o $# -gt 7 ]; then echo "ERROR (allowPort): must specify 5-6 args (specified $(($# - 1)))." return fi PROTOCOL=$1; EXT_PORT=$3; INT_IP=$4; INT_PORT=$5; PORT_DESC="$6" DEST_HOST=$7 # allow for wildcard: all = 0/0 if [ "$2" = "all" ]; then SRC_IP=0/0 else SRC_IP="$2" fi # _insert_ rules for localhost at beginning of chains. if [ "$INT_IP" = "$LAN_IP" ]; then #if [ "$EXT_PORT" != "$INT_PORT" ]; then #$IPTABLES -t nat -I PREROUTING -p $PROTOCOL -d $INET_IP -s "$SRC_IP" --dport $EXT_PORT -j DNAT --to-destination $INET_IP: #fi if echo "$PROTOCOL" | grep -i '^tcp$' 1> /dev/null 2> /dev/null ; then $IPTABLES -I tcp_packets -p $PROTOCOL -s "$SRC_IP" --dport $INT_PORT -j allowed elif echo "$PROTOCOL" | grep -i '^udp$' 1> /dev/null 2> /dev/null; then $IPTABLES -I udpincoming_packets -p $PROTOCOL -s "$SRC_IP" --destination-port $INT_PORT -j ACCEPT else echo "ERROR (allowPort): bad protocol \"$PROTOCOL\"." fi else # _insert_ rules FORWARD rules for opening/forwarding ports for other boxen. # PREROUTING can be -I or -A, but will -I to keep things consistent for now. if [ "$EXT_PORT" = "$INT_PORT" ]; then DESTINATION="$INT_IP" DPORT=$INT_PORT $IPTABLES -I FORWARD -p $PROTOCOL -i $INET_IFACE -o $LAN_IFACE -d $INT_IP --dport $DPORT -j ACCEPT else DESTINATION="$INT_IP:$INT_PORT" DPORT=$EXT_PORT $IPTABLES -I FORWARD -p $PROTOCOL -i $INET_IFACE -o $LAN_IFACE -d $INT_IP --dport $INT_PORT -j ACCEPT fi $IPTABLES -t nat -I PREROUTING -p $PROTOCOL -d $INET_IP -s "$SRC_IP" --dport $DPORT -j DNAT --to-destination $DESTINATION fi } function start { ########################################################################### # 1. Configuration options. # 1.1 Internet Configuration. INET_IFACE="eth0" INET_IP="$(ifconfig $INET_IFACE | sed -ne 's/.*inet addr:\([0-9\.]*\) .*/\1/p')" if [ -z "$INET_IP" ]; then echo "FATAL ERROR: Could not get IP for internet interface \"$INET_IFACE\"! Exiting." exit -1 fi # 1.2 Local Area Network configuration. # your LAN's IP range and localhost IP. /24 means to only use the first 24 # bits of the 32 bit IP adress. the same as netmask 255.255.255.0 LAN_IFACE="eth1" LAN_IP="$(ifconfig $LAN_IFACE | sed -ne 's/.*inet addr:\([0-9\.]*\) .*/\1/p')" # next line turns 192.168.0.1 into 192.168.0.0/24, assumes Class C. LAN_IP_RANGE="$(echo $LAN_IP | cut -d . -f -3).0/24" LAN_BCAST_ADRESS="255.255.255.255" # 1.4 Localhost Configuration. LO_IFACE="lo" LO_IP="127.0.0.1" # 1.6 Other Configuration. ########################################################################### # 2. Module loading. # yeah, i had a problem with diff ext/int ports on the gateway # i have a suggestion for your module loading section too # if you're serving up FTP from behind the firewall on a non-standard port, the modprobes need to look like this # modprobe ip_conntrack_ftp ports=21,2121 # modprobe ip_nat_ftp ports=21,2121 # where 2121 is that non-standard port # and ports= can define up to 8 ports # might wanna make a note of that in a comment # ahh, i see.. i never knew how to use that anyway # yeah, those are needed for passive ftp to work nat'd # Needed to initially load modules /sbin/depmod -A # 2.1 Required modules /sbin/modprobe ip_tables /sbin/modprobe ip_conntrack /sbin/modprobe iptable_filter /sbin/modprobe iptable_mangle /sbin/modprobe iptable_nat /sbin/modprobe ipt_LOG /sbin/modprobe ipt_limit /sbin/modprobe ipt_state # 2.2 Non-Required modules #/sbin/modprobe ipt_owner #/sbin/modprobe ipt_REJECT #/sbin/modprobe ipt_MASQUERADE /sbin/modprobe ip_conntrack_ftp /sbin/modprobe ip_conntrack_irc ########################################################################### # 3. /proc set up. # 3.1 Required proc configuration # moved to the end # 3.2 Non-Required proc configuration #echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter #echo "1" > /proc/sys/net/ipv4/conf/all/proxy_arp #echo "1" > /proc/sys/net/ipv4/ip_dynaddr ########################################################################### # 4. rules set up. # 4.0.5 All allowed ports # 4.1 Filter table # 4.1.1 Set policies $IPTABLES -P INPUT DROP $IPTABLES -P OUTPUT DROP $IPTABLES -P FORWARD DROP # 4.1.2 Create userspecified chains # Create chain for bad tcp packets $IPTABLES -N bad_tcp_packets # Create separate chains for ICMP, TCP and UDP to traverse $IPTABLES -N allowed $IPTABLES -N icmp_packets $IPTABLES -N tcp_packets $IPTABLES -N udpincoming_packets # 4.1.3 Create content in userspecified chains # bad_tcp_packets chain $IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \ --log-prefix "New not syn:" $IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP # allowed chain $IPTABLES -A allowed -p TCP --syn -j ACCEPT $IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A allowed -p TCP -j DROP # 20050115, ASB, for dad's laptop $IPTABLES -A INPUT -i ath0 -m mac --mac-source 00:0d:88:c1:4a:22 -j ACCEPT # 20050115, another on 23? $IPTABLES -A INPUT -i ath0 -m mac --mac-source 00:13:46:01:ba:ad -j ACCEPT # ICMP rules $IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT $IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT # 4.1.4 INPUT chain # Bad TCP packets we don't want. $IPTABLES -A INPUT -p tcp -j bad_tcp_packets # Rules for special networks not part of the Internet $IPTABLES -A INPUT -p ALL -i $LAN_IFACE -s $LAN_IP_RANGE -j ACCEPT # 20050115, ASB, for dad's laptop $IPTABLES -A INPUT -p ALL -i $LAN_IFACE -s 192.168.1.0/24 -j ACCEPT $IPTABLES -A INPUT -p ALL -i $LAN_IFACE -s $INET_IP -j ACCEPT $IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LO_IP -j ACCEPT $IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LAN_IP -j ACCEPT $IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $INET_IP -j ACCEPT $IPTABLES -A INPUT -p ALL -i $LAN_IFACE -d $LAN_BCAST_ADRESS -j ACCEPT # Rules for incoming packets from the internet. $IPTABLES -A INPUT -p ALL -d $INET_IP -m state --state ESTABLISHED,RELATED \ -j ACCEPT $IPTABLES -A INPUT -p TCP -i $INET_IFACE -j tcp_packets $IPTABLES -A INPUT -p UDP -i $INET_IFACE -j udpincoming_packets $IPTABLES -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets # Log weird packets that don't match the above. $IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \ --log-level DEBUG --log-prefix "IPT INPUT packet died: " # 4.1.5 FORWARD chain # Bad TCP packets we don't want $IPTABLES -A FORWARD -p tcp -j bad_tcp_packets # Accept the packets we actually want to forward $IPTABLES -A FORWARD -i $LAN_IFACE -j ACCEPT # 20050115, ASB, for dad's laptop $IPTABLES -A FORWARD -i ath0 -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # 20030628, ASB, workaround to make lanIPs->wanIP:forwardedPort work $IPTABLES -t nat -A POSTROUTING -s 192.168.0.0/24 -d 192.168.0.2 -j SNAT --to-source 192.168.0.1 # Log weird packets that don't match the above. $IPTABLES -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG \ --log-level DEBUG --log-prefix "IPT FORWARD packet died: " # 4.1.6 OUTPUT chain # Bad TCP packets we don't want. $IPTABLES -A OUTPUT -p tcp -j bad_tcp_packets # Special OUTPUT rules to decide which IP's to allow. $IPTABLES -A OUTPUT -p ALL -s $LO_IP -j ACCEPT $IPTABLES -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT # 20050115, ASB, for dad's laptop $IPTABLES -A OUTPUT -p ALL -s 192.168.1.1 -j ACCEPT $IPTABLES -A OUTPUT -p ALL -s $INET_IP -j ACCEPT # Log weird packets that don't match the above. $IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \ --log-level DEBUG --log-prefix "IPT OUTPUT packet died: " # Enable simple IP FORwarding and Network Address Translation $IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP setPorts # enable forwarding after all rules are setup echo "1" > /proc/sys/net/ipv4/ip_forward } case "$1" in 'start') start ;; 'stop') flush ;; 'restart') flush start ;; *) echo "Usage: $0 start|stop|restart" esac # EOF #vim:ts=2:sw=2