#!/bin/sh # # A firewall / masquerading script. Written by Grigor Gatchev.# #------------------------------------------------- -------------------------- # # -- Initialization -- # # --------------------------------------------------------------------------- # # ----- Some useful values ----- # NETWORK_WORLD=0.0.0.0/0 # Everything. NETWORK_RSVDA=10.0.0.0/8 # Intranet Reserved Diapazone A NETWORK_RSVDB=172.16.0.0/12 # Intranet Reserved Diapazone B NETWORK_RSVDC=192.168.0.0/16 # Intranet Reserver Diapazone C # ----- System initialization ----- # # iptables command (some distros, eg. Debian, may have more than one). IPTABLES=/sbin/iptables if ! [ "$($IPTABLES -V | grep "not found" -)"=="" ] ; then echo "Could not find iptables (not installed?) - quitting." exit fi # Proxy port, if proxy installed. If empty, script will assume there's no proxy. PROXY_PORT=3128 # Internal and External interfaces. INT_IF=eth0 EXT_IF=eth1 # Internal network/netmask. INT_NETWORK=$NETWORK_RSVDC # Use masquerading? USE_MASQ=yes # Use transparent proxying? (Will work only if proxy port is specified!) USE_PROXY_TRANSPARENT=yes #--------------------------------------------------------------------------- # # -- Execution -- # # ---------------------------------------------------------------------------# # ----- Setting command strings ----- # # Filtering strings: FW=$IPTABLES" -t filter" # Firewall commands for the INPUT, OUTPUT, FORWARD chains. FW_INP=$FW" -A INPUT " FW_OUT=$FW" -A OUTPUT" FW_FRW=$FW" -A FORWARD" # External interface Input / Output firewall commands. EFW_INP=$FW_INP" -i "$EXT_IF EFW_OUT=$FW_OUT" -o "$EXT_IF # Internal interface Input / Output firewall commands. IFW_INP=$FW_INP" -i "$INT_IF IFW_OUT=$FW_OUT" -o "$INT_IF # Inbound / Outboind FORWARD connections firewall commands. IFW_FRW=$FW_FRW" -i "$EXT_IF" -o "$INT_IF OFW_FRW=$FW_FRW" -i "$INT_IF" -o "$EXT_IF # NAT strings: NAT=$IPTABLES" -t nat" # NAT commands for the PREROUTING and POSTROUTING chains. NAT_PRE=$NAT" -A PREROUTING " NAT_POST=$NAT" -A POSTROUTING" NAT_PRE_IINP=$NAT_PRE" -i "$INT_IF NAT_PRE_IOUT=$NAT_PRE" -o "$INT_IF NAT_POST_EINP=$NAT_POST" -i "$EXT_IF NAT_POST_EOUT=$NAT_POST" -o "$EXT_IF # ----- Global settings ----- # # Flush the old firewall state. $FW -F $FW -X $FW -Z $NAT -F $NAT -X $NAT -Z # Set default policy to DROP (instead of putting DROP as final rule). $IPTABLES -P INPUT DROP $IPTABLES -P OUTPUT DROP $IPTABLES -P FORWARD DROP # ----- Loopback firewall configurations ----- # # Allow all loopback connections. Almost always a good idea. $FW_INP -i lo -j ACCEPT $FW_OUT -o lo -j ACCEPT # ----- External interface firewall configuration ----- # # Check for addresses that should be on the internal interface. if ! [ "$INT_NETWORK"=="" ]; then $EFW_INP -s $INT_NETWORK -j DROP # IP spoofing? $EFW_OUT -d $INT_NETWORK -j DROP # stuffed routing? # You may also prefer to REJECT them instead, and/or to log before dropping. fi # Allow ping. $EFW_INP -p icmp -j ACCEPT $EFW_OUT -p icmp -j ACCEPT # Allow outgoing traceroute. $EFW_OUT -p udp --dport 33434:33464 --sport 1024: -j ACCEPT # Allow DNS requests. (Seems that they use UDP protocol only.) $EFW_INP -p udp --sport domain --dport 1024: -j ACCEPT $EFW_OUT -p udp --dport domain --sport 1024: -j ACCEPT # Allow outgoing SSH. $EFW_INP -p tcp --sport ssh --dport 1024: ! --syn -j ACCEPT $EFW_OUT -p tcp --dport ssh --sport 1024: -j ACCEPT # Allow outgoing FTP. # Control connection. $EFW_INP -p tcp --sport ftp --dport 1024: ! --syn -j ACCEPT $EFW_OUT -p tcp --dport ftp --sport 1024: -j ACCEPT # Data - Active (classic) FTP. Bad idea - allows inbound connections! $EFW_INP -p tcp --sport ftp-data --dport 1024: -j ACCEPT $EFW_OUT -p tcp --dport ftp-data --sport 1024: -j ACCEPT # Data - Passive FTP. (Possibly allows other exchanges, too!) $EFW_INP -p tcp --sport 1024: --dport 1024: ! --syn -j ACCEPT $EFW_OUT -p tcp --dport 1024: --sport 1024: -j ACCEPT # Allow outgoing HTTP. $EFW_INP -p tcp --sport http --dport 1024: ! --syn -j ACCEPT $EFW_OUT -p tcp --dport http --sport 1024: -j ACCEPT $EFW_INP -p tcp --sport https --dport 1024: ! --syn -j ACCEPT $EFW_OUT -p tcp --dport https --sport 1024: -j ACCEPT # Some (mostly file-sharing) sites use other ports for HTTP. $EFW_INP -p tcp --sport 8080 --dport 1024: ! --syn -j ACCEPT $EFW_OUT -p tcp --dport 8080 --sport 1024: -j ACCEPT # Allow outgoing mail exchange (also mail retrieving by POP3). $EFW_INP -p tcp --sport smtp --dport 1024: ! --syn -j ACCEPT $EFW_OUT -p tcp --dport smtp --sport 1024: -j ACCEPT $EFW_INP -p tcp --sport pop3 --dport 1024: ! --syn -j ACCEPT $EFW_OUT -p tcp --dport pop3 --sport 1024: -j ACCEPT # Allow incoming SSH. $EFW_INP -p tcp --dport ssh -j ACCEPT $EFW_OUT -p tcp --sport ssh -j ACCEPT # ----- Internal interface firewall configuration ----- # # Wide open, by now (NOT a good practice!) $IFW_INP -j ACCEPT $IFW_OUT -j ACCEPT # -- Allow ping. $IFW_INP -p icmp -j ACCEPT $IFW_OUT -p icmp -j ACCEPT # -- Allow ssh. $IFW_INP -p tcp --dport ssh -j ACCEPT $IFW_OUT -p tcp --sport ssh -j ACCEPT # -- Allow HTTP(S). $IFW_INP -p tcp --dport www --sport 1024: -j ACCEPT $IFW_OUT -p tcp --sport www --dport 1024: -j ACCEPT $IFW_INP -p udp --dport www --sport 1024: -j ACCEPT $IFW_OUT -p udp --sport www --dport 1024: -j ACCEPT $IFW_INP -p tcp --dport https --sport 1024: -j ACCEPT $IFW_OUT -p tcp --sport https --dport 1024: -j ACCEPT $IFW_INP -p udp --dport https --sport 1024: -j ACCEPT $IFW_OUT -p udp --sport https --dport 1024: -j ACCEPT $IFW_INP -p tcp --dport 3128 --sport 1024: -j ACCEPT $IFW_OUT -p tcp --sport 3128 --dport 1024: -j ACCEPT # -- Allow SMB protocol. (Seems that it uses only TCP.) $IFW_INP -p tcp --dport netbios-ns -j ACCEPT $IFW_OUT -p tcp --sport netbios-ns -j ACCEPT $IFW_INP -p tcp --dport netbios-dgm -j ACCEPT $IFW_OUT -p tcp --sport netbios-dgm -j ACCEPT $IFW_INP -p tcp --dport netbios-ssn -j ACCEPT $IFW_OUT -p tcp --sport netbios-ssn -j ACCEPT $IFW_INP -p tcp --dport microsoft-ds -j ACCEPT $IFW_OUT -p tcp --sport microsoft-ds -j ACCEPT $IFW_INP -p tcp --sport netbios-ns -j ACCEPT $IFW_OUT -p tcp --dport netbios-ns -j ACCEPT $IFW_INP -p tcp --sport netbios-dgm -j ACCEPT $IFW_OUT -p tcp --dport netbios-dgm -j ACCEPT $IFW_INP -p tcp --sport netbios-ssn -j ACCEPT $IFW_OUT -p tcp --dport netbios-ssn -j ACCEPT $IFW_INP -p tcp --sport microsoft-ds -j ACCEPT $IFW_OUT -p tcp --dport microsoft-ds -j ACCEPT # -- Allow inet daemon services (what they are needed for? :-) -- # $IFW_INP -p tcp --dport auth -j ACCEPT $IFW_OUT -p tcp --sport auth -j ACCEPT $IFW_INP -p tcp --dport daytime -j ACCEPT $IFW_OUT -p tcp --sport daytime -j ACCEPT $IFW_INP -p tcp --dport discard -j ACCEPT $IFW_OUT -p tcp --sport discard -j ACCEPT $IFW_INP -p udp --dport discard -j ACCEPT $IFW_OUT -p udp --sport discard -j ACCEPT $IFW_INP -p tcp --dport time -j ACCEPT $IFW_OUT -p tcp --sport time -j ACCEPT $IFW_INP -p udp --dport time -j ACCEPT $IFW_OUT -p udp --sport time -j ACCEPT # -- Allow the portmapper and the RPC functions -- # $IFW_INP -p tcp --dport portmapper -j ACCEPT $IFW_OUT -p tcp --sport portmapper -j ACCEPT # rpc.statd etc. will take random ports inside 512-1023 diapazone. # ----- IP forwarding ----- # # Allow outbound and inbound (if initiated by us) transition. $IFW_FRW -m state --state ESTABLISHED,RELATED -j ACCEPT $OFW_FRW -j ACCEPT # ----- IP masquerading ----- # if [ "$USE_MASQ"=="yes" ]; then if modprobe ipt_MASQUERADE ; then $NAT_POST_EOUT -j MASQUERADE # Add here other interfaces that may need masquerading, eg. PPPOE connection: # $IPTABLES -t nat -A POSTROUTING -o ppp0 -j MASQUERADE else echo "iptables MASQUERADE module could not be loaded - no NAT applied!" fi fi # ----- Transparent proxying ----- # if [ "$USE_PROXY_TRANSPARENT"=="yes" ]; then if modprobe ipt_REDIRECT ; then $NAT_PRE_IINP -p tcp --dport 80 -j REDIRECT --to-port $PROXY_PORT else echo "iptables REDIRECT module could not be loaded - no transparent proxy!" fi fi # Transparent proxying may require tuning also the proxy software. # For Squid 2.x, for example, you will have to add to squid.conf these lines: # httpd_accel_host virtual # httpd_accel_port 80 # httpd_accel_with_proxy on # httpd_accel_uses_host_header on # end of fw.sh