#!/bin/bash # # K.I.S.S. My Firewall - Version 2.2 # http://www.geocities.com/steve93138/ # # EXTN Configuration Required! - See Below # ############################################################################## # Version 2.2 Changes: # # Modified to block IP addresses only on SERVER_IPS specified below # ############################################################################## # Version 2.1 Changes: # # Changed: MAIN_IP=`ifconfig eth0 | grep inet | cut -d: -f2 | awk '{print $1}'` # To: MAIN_IP=`ifconfig eth0 | grep "inet addr" | cut -d: -f2 | awk '{print $1}'` # # Support for alternate module filename extensions using EXTN variable (See below) # # Enabled DNS Zone Transfers - Seems highly neccessary based on user feedback! # ############################################################################## # ############################################################################## # # Optional KISS Configurtion Variables: # BLOCK_LIST="" TCP_IN="20 21 25 53 80 110 143 443 995 3306 8443 10000 19638" TCP_OUT="21 22 25 37 43 53 80 443 55000" UDP_IN="53" UDP_OUT="53" TCP_IN_TRUSTED="22" TRUSTED_IPS="0.0.0.0/0" SERVER_IPS="0.0.0.0/0" # Enable this for Pre Fedora Core 2 or Red Hat EXTN="o" # Enable this for Fedore Core 2 or later # EXTN="ko" ############################################################################## # # ALL DONE WITH CONFIGURATIONS! # # No real need to modify anything for the remainder of this file except to # maybe remove the comments from certains lines at the end of this file. # # Some variables here. Modify if needed for your system. IPTABLES="/sbin/iptables" MODPROBE="/sbin/modprobe" LOOPBACK="127.0.0.0/8" CLASS_A="10.0.0.0/8" CLASS_B="172.16.0.0/12" CLASS_C="192.168.0.0/16" CLASS_D_MULTICAST="224.0.0.0/4" CLASS_E_RESERVED_NET="240.0.0.0/4" BROADCAST_SRC="0.0.0.0" BROADCAST_DEST="255.255.255.255" PRIVPORTS="0:1023" UNPRIVPORTS="1024:65535" ############################################################################## # Determine if iptables and modprobe exist # if [ ! -e "$IPTABLES" ]; then echo "$IPTABLES does not exist. Firewall script aborted!" exit 1 fi if [ ! -e "$MODPROBE" ]; then echo "$MODPROBE does not exist. Firewall script aborted!" exit 1 fi ############################################################################## # Determine MAIN_IP & SERVER_IPS if needed # MAIN_IP=`ifconfig eth0 | grep "inet addr" | cut -d: -f2 | awk '{print $1}'` if [ "$MAIN_IP" == "" ]; then echo "Could not determine MAIN_IP. Firewall script aborted!" exit 1 fi if [ "$SERVER_IPS" == "" ]; then SERVER_IPS=$MAIN_IP fi if [ "$SERVER_IPS" == "" ]; then echo "Could not determine SERVER_IPS. Firewall script aborted!" exit 1 fi ############################################################################## # Arguments: if [ "$1" == "stop" ] || [ "$1" == "-stop" ] || [ "$1" == "--stop" ]; then $IPTABLES -P INPUT ACCEPT $IPTABLES -P OUTPUT ACCEPT $IPTABLES -F $IPTABLES -L -n echo "" echo "" echo -e "\033[31mKISS My Firewall - Stopped!" echo -e -n "\033[0m " echo "" exit 0 fi if [ "$1" == "status" ] || [ "$1" == "-status" ] || [ "$1" == "--status" ]; then NUM_LINES=`$IPTABLES -L -n | wc -l | awk '{print $1}'` $IPTABLES -L -n echo "" echo "" if [ "$NUM_LINES" -le "15" ]; then echo -e "\033[31mKISS My Firewall - Stopped!" else echo -e "\033[32mKISS My Firewall - Running!" fi echo -e -n "\033[0m " echo "" exit 0 fi ############################################################################## # We don't want ipchains loaded: IPCHAINS=`/sbin/lsmod | grep ipchains` if [ ! "$IPCHAINS" == "" ]; then /sbin/rmmod ipchains fi ############################################################################## # Note: KISS requires that ip_tables, ipt_state, and ipt_multiport exist: if [ ! -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ip_tables.$EXTN" ] || [ ! -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ipt_state.$EXTN" ] || [ ! -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ipt_multiport.$EXTN" ]; then echo "Since the ip_tables, ipt_state, and/or ipt_multiport modules do not exist, KISS can not function. Firewall script aborted!" exit 1 fi # All is well, load modules: if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ip_tables.$EXTN" ]; then $MODPROBE ip_tables fi if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ipt_state.$EXTN" ]; then $MODPROBE ipt_state fi if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ipt_multiport.$EXTN" ]; then $MODPROBE ipt_multiport fi if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ip_tables.$EXTN" ]; then $MODPROBE ip_tables fi if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ipt_state.$EXTN" ]; then $MODPROBE ipt_state fi if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ipt_multiport.$EXTN" ]; then $MODPROBE ipt_multiport fi if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/iptable_filter.$EXTN" ]; then $MODPROBE iptable_filter fi if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ipt_unclean.$EXTN" ]; then $MODPROBE ipt_unclean fi if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ipt_limit.$EXTN" ]; then $MODPROBE ipt_limit fi if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ipt_LOG.$EXTN" ]; then $MODPROBE ipt_LOG fi if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ipt_REJECT.$EXTN" ]; then $MODPROBE ipt_REJECT fi if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ip_conntrack.$EXTN" ]; then $MODPROBE ip_conntrack fi if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ip_conntrack_irc.$EXTN" ]; then $MODPROBE ip_conntrack_irc fi if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/ip_conntrack_ftp.$EXTN" ]; then $MODPROBE ip_conntrack_ftp fi if [ -e "/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/iptable_mangle.$EXTN" ]; then $MODPROBE iptable_mangle fi ############################################################################## # Remove any existing rules from all chains $IPTABLES --flush $IPTABLES -t nat --flush $IPTABLES -t mangle --flush # Allow unlimited traffic on the loopback interface $IPTABLES -A INPUT -i lo -j ACCEPT $IPTABLES -A OUTPUT -o lo -j ACCEPT # Set the default policy to DROP $IPTABLES --policy INPUT DROP $IPTABLES --policy OUTPUT DROP $IPTABLES --policy FORWARD DROP # DO NOT MODIFY THESE! # # If you set these to DROP, you will be locked out of your server. # $IPTABLES -t nat --policy PREROUTING ACCEPT $IPTABLES -t nat --policy OUTPUT ACCEPT $IPTABLES -t nat --policy POSTROUTING ACCEPT $IPTABLES -t mangle --policy PREROUTING ACCEPT $IPTABLES -t mangle --policy OUTPUT ACCEPT # Remove any pre-existing user-defined chains $IPTABLES --delete-chain $IPTABLES -t nat --delete-chain $IPTABLES -t mangle --delete-chain ############################################################################## # Enable broadcast echo Protection if [ -e /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts ]; then echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts fi # Disable Source Routed Packets if [ -e /proc/sys/net/ipv4/conf/all/accept_source_route ]; then echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route fi # Enable TCP SYN Cookie Protection if [ -e /proc/sys/net/ipv4/tcp_syncookies ]; then echo "1" > /proc/sys/net/ipv4/tcp_syncookies fi # Disable ICMP Redirect Acceptance if [ -e /proc/sys/net/ipv4/conf/all/accept_redirects ]; then echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects fi # Don't send Redirect Messages if [ -e /proc/sys/net/ipv4/conf/all/send_redirects ]; then echo "0" > /proc/sys/net/ipv4/conf/all/send_redirects fi # Drop Spoofed Packets coming in on an interface, which if replied to, would # result in the reply going out a different interface. if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]; then echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter fi # Log packets with impossible addresses if [ -e /proc/sys/net/ipv4/conf/all/log_martians ]; then echo "1" > /proc/sys/net/ipv4/conf/all/log_martians fi # Reduce DoS'ing ability by reducing timeouts if [ -e /proc/sys/net/ipv4/tcp_fin_timeout ]; then echo "1800" > /proc/sys/net/ipv4/tcp_fin_timeout fi if [ -e /proc/sys/net/ipv4/tcp_keepalive_time ]; then echo "1800" > /proc/sys/net/ipv4/tcp_keepalive_time fi if [ -e /proc/sys/net/ipv4/tcp_window_scaling ]; then echo "0" > /proc/sys/net/ipv4/tcp_window_scaling fi if [ -e /proc/sys/net/ipv4/tcp_sack ]; then echo "0" > /proc/sys/net/ipv4/tcp_sack fi ############################################################################## # Silently Drop Stealth Scans # All of the bits are cleared $IPTABLES -A INPUT -p tcp --tcp-flags ALL NONE -j DROP # SYN and FIN are both set $IPTABLES -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP # SYN and RST are both set $IPTABLES -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP # FIN and RST are both set $IPTABLES -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP # FIN is the only bit set, without the expected accompanying ACK $IPTABLES -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP # PSH is the only bit set, without the expected accompanying ACK $IPTABLES -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j DROP # URG is the only bit set, without the expected accompanying ACK $IPTABLES -A INPUT -p tcp --tcp-flags ACK,URG URG -j DROP ############################################################################## # Provide some syn-flood protection # # THIS CODE SLOWS DOWN WEB PAGE LOADS DRAMATICALLY!!! # # Only enable this code if you find that you are the victim of a syn-flood # attack! # #$IPTABLES -N syn-flood #$IPTABLES -A INPUT -p tcp --syn -j syn-flood #$IPTABLES -A syn-flood -m limit --limit 1/s --limit-burst 4 -j RETURN #$IPTABLES -A syn-flood -j DROP # ############################################################################## # BLOCK_LIST # # To add someone to this block list, use the BLOCK_LIST configuration variable # above. # # We block here, before our stateful packet inspection below, because if the # offender is already logged in, he won't be kicked out. Note also that we # include the offender's IP in the OUTPUT chain. This should help to reduce # the threat a little bit more. # for blocked_ip in $BLOCK_LIST; do for server_ips in $SERVER_IPS; do # Lock him out: $IPTABLES -A INPUT -s $blocked_ip -d $server_ips -j DROP # Make sure that he never hears from us again: $IPTABLES -A OUTPUT -d $blocked_ip -s $server_ips -j DROP done done ############################################################################## # Use Connection State to Bypass Rule Checking # # By accepting established and related connections, we don't need to # explicitly set various input and output rules. For example, by accepting an # established and related output connection, we don't need to specify that # the firewall needs to open a hole back out to client when the client # requests SSH access. # $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A INPUT -m state --state INVALID -j DROP $IPTABLES -A OUTPUT -m state --state INVALID -j DROP ############################################################################## # Source Address Spoofing and Other Bad Addresses # Refuse Spoofed packets pretending to be from the external interface's IP #for server_ips in $SERVER_IPS; do # $IPTABLES -A INPUT -i eth0 -s $server_ips -j DROP #done #for server_ips in $SERVER_IPS; do # for subnet_broadcast in $SUBNET_BROADCAST; do # $IPTABLES -A INPUT -i eth0 -s $server_ips -d !$subnet_broadcast -j DROP # done #done # Refuse packets claiming to be from a Class A private network $IPTABLES -A INPUT -i eth0 -s $CLASS_A -j DROP # Refuse packets claiming to be from a Class B private network $IPTABLES -A INPUT -i eth0 -s $CLASS_B -j DROP # Refuse packets claiming to be from a Class C private network #$IPTABLES -A INPUT -i eth0 -s $CLASS_C -j DROP # Refuse packets claiming to be from the loopback interface $IPTABLES -A INPUT -i eth0 -s $LOOPBACK -j DROP # Refuse malformed broadcast packets $IPTABLES -A INPUT -i eth0 -s $BROADCAST_DEST -j DROP $IPTABLES -A INPUT -i eth0 -d $BROADCAST_SRC -j DROP # Refuse directed broadcasts # Used to map networks and in Denial of Service attacks #for subnet_base in $SUBNET_BASE; do # $IPTABLES -A INPUT -i eth0 -d $subnet_base -j DROP #done #for subnet_broadcast in $SUBNET_BROADCAST; do # $IPTABLES -A INPUT -i eth0 -d $subnet_broadcast -j DROP #done # Refuse limited broadcasts $IPTABLES -A INPUT -i eth0 -d $BROADCAST_DEST -j DROP # Refuse Class D multicast addresses - illegal as a source address #$IPTABLES -A INPUT -i eth0 -s $CLASS_D_MULTICAST -j DROP #$IPTABLES -A INPUT -i eth0 -p ! udp -d $CLASS_D_MULTICAST -j DROP #$IPTABLES -A INPUT -i eth0 -p udp -d $CLASS_D_MULTICAST -j ACCEPT # $IPTABLES -A INPUT -i eth0 -s $CLASS_D_MULTICAST -j DROP $IPTABLES -A INPUT -i eth0 -p udp -d $CLASS_D_MULTICAST -j ACCEPT $IPTABLES -A INPUT -i eth0 -p 2 -d $CLASS_D_MULTICAST -j ACCEPT $IPTABLES -A INPUT -i eth0 -p all -d $CLASS_D_MULTICAST -j DROP # Refuse Class E reserved IP addresses $IPTABLES -A INPUT -i eth0 -s $CLASS_E_RESERVED_NET -j DROP # Refuse addresses defined as reserved by the IANA # 0.*.*.* - Can't be blocked unilaterally with DHCP # 169.254.0.0/16 - Link Local Networks # 192.0.2.0/24 - TEST-NET $IPTABLES -A INPUT -i eth0 -s 0.0.0.0/8 -j DROP $IPTABLES -A INPUT -i eth0 -s 169.254.0.0/16 -j DROP $IPTABLES -A INPUT -i eth0 -s 192.0.2.0/24 -j DROP ############################################################################## # Now we can open up some holes in our firewall... # ############################################################################## # If we are not accepting 113 (ident), then we explicitly reject it! # if [ "$(echo $IN_PORTS | tr ',' '\n' | grep -w 113)" == "" ]; then $IPTABLES -A INPUT -p tcp -s 0/0 -d 0/0 --dport 113 -j REJECT $IPTABLES -A INPUT -p udp -s 0/0 -d 0/0 --dport 113 -j REJECT fi ############################################################################## # TCP IN # for tcp_in in $TCP_IN; do for server_ips in $SERVER_IPS; do $IPTABLES -A INPUT -i eth0 -s 0/0 -d $server_ips -p tcp -m state --state NEW --sport $UNPRIVPORTS --dport $tcp_in -j ACCEPT done done ############################################################################## # TCP OUT # for tcp_out in $TCP_OUT; do $IPTABLES -A OUTPUT -o eth0 -p tcp -m state --state NEW --sport $UNPRIVPORTS --dport $tcp_out -j ACCEPT done ############################################################################## # UDP IN # for udp_in in $UDP_IN; do for server_ips in $SERVER_IPS; do $IPTABLES -A INPUT -i eth0 -s 0/0 -d $server_ips -p udp -m state --state NEW --sport $UNPRIVPORTS --dport $udp_in -j ACCEPT done done ############################################################################## # UDP OUT # for udp_out in $UDP_OUT; do $IPTABLES -A OUTPUT -o eth0 -p udp -m state --state NEW --sport $UNPRIVPORTS --dport $udp_out -j ACCEPT done ############################################################################## # TCP IN TRUSTED # #for tcp_in_trusted in $TCP_IN_TRUSTED; do # for server_ips in $SERVER_IPS; do # for trusted_ips in $TRUSTED_IPS; do # $IPTABLES -A INPUT -i eth0 -s $trusted_ips -d $server_ips -p tcp -m state --state NEW --sport $UNPRIVPORTS --dport $tcp_in_trusted -j ACCEPT # done # done #done for tcp_in_trusted in $TCP_IN_TRUSTED; do for trusted_ips in $TRUSTED_IPS; do $IPTABLES -A INPUT -i eth0 -s $trusted_ips -d $MAIN_IP -p tcp -m state --state NEW --sport $UNPRIVPORTS --dport $tcp_in_trusted -j ACCEPT done done ############################################################################## # Allow pinging of this server's MAIN_IP by trusted IPs only. # for trusted_ips in $TRUSTED_IPS; do $IPTABLES -A INPUT -s $trusted_ips -d $MAIN_IP -i eth0 -m state --state NEW -p icmp --icmp-type ping -j ACCEPT done ############################################################################## # OUTPUT - PORT 113 - IDENTD # #for server_ips in $SERVER_IPS; do # $IPTABLES -A OUTPUT -o eth0 -s $server_ips -p tcp --syn --sport $UNPRIVPORTS --dport 113 -m state --state NEW -j REJECT --reject-with tcp-reset #done ############################################################################## # Allow DNS zone transfers # $IPTABLES -A INPUT -i eth0 -p udp --sport 53 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -i eth0 -p tcp --sport 53 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p udp --sport 53 --dport 53 -m state --state NEW -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -p tcp --sport 53 --dport 53 -m state --state NEW -j ACCEPT ############################################################################## # Uncomment to allow for outgoing ping # #$IPTABLES -A OUTPUT -o eth0 -s $MAIN_IP -m state --state NEW -p icmp --icmp-type ping -j ACCEPT ############################################################################## # Uncomment to allow outgoing traceroutes # #$IPTABLES -A OUTPUT -o eth0 -p udp -s $MAIN_IP --sport 32769:65535 --dport 33434:33523 -m state --state NEW -j ACCEPT $IPTABLES -L -n echo "" echo "" echo -e "\033[32mKISS My Firewall - Running!" echo -e -n "\033[0m " echo "" exit 0