#!/bin/sh

# ----------------------------------------------------------------------------
# Copyright (C) 1997, 1998, 1999, 2000  Robert L. Ziegler
#
#  Permission to use, copy, modify, and distribute this software and its
#  documentation for educational, research, private and non-profit purposes,
#  without fee, and without a written agreement is hereby granted. 
#  This software is provided as an example and basis for individual firewall
#  development.  This software is provided without warranty.
#
#  Any material furnished by Robert L. Ziegler is furnished on an 
#  "as is" basis.  He makes no warranties of any kind, either expressed 
#  or implied as to any matter including, but not limited to, warranty 
#  of fitness for a particular purpose, exclusivity or results obtained
#  from use of the material.
# ----------------------------------------------------------------------------

#  /etc/rc.d/rc.firewall
#  Invoked from /etc/ppp/ip-up, or
#  from /sbin/ifup-local, or
#  from /etc/sysconfig/network-scripts/ifup-post.
#  from /etc/rc.d/rc.local.

echo "Starting firewalling... "

# ----------------------------------------------------------------------------
#  Some definitions for easy maintenance.
#  EDIT THESE TO SUIT YOUR SYSTEM AND ISP.

EXTERNAL_INTERFACE="ppp0"		# Internet connected interface
LOOPBACK_INTERFACE="lo"			# or your local naming convention
LOCAL_INTERFACE_1="eth0"		# internal LAN interface

IPADDR="192.168.0.1"			# your IP address
LOCALNET_1="192.168.1.0/24"		# whatever private range you use

ANYWHERE="any/0"			# match any IP address

NAMESERVER_1="217.15.134.65"			# everyone must have at least one 
NAMESERVER_2="217.15.135.68"

SMTP_SERVER="smtp.yaroslavl.ru"			# Your ISP mail gateway. Your relay.
POP_SERVER="pop.yaroslavl.ru"		# Your ISP pop mail server.
IMAP_SERVER="imap.mailru.com"		# Your ISP imap mail server.

LOOPBACK="127.0.0.0/8"			# reserved loopback address range
CLASS_A="10.0.0.0/8"			# class A private networks
CLASS_B="172.16.0.0/12"			# class B private networks
CLASS_C="192.168.0.0/16"		# class C private networks
BROADCAST_SRC="0.0.0.0"			# broadcast source address
BROADCAST_DEST="255.255.255.255"	# broadcast destination address
PRIVPORTS="0:1023"			# well known, privileged port range
UNPRIVPORTS="1024:65535"		# unprivileged port range

# ----------------------------------------------------------------------------

NFS_PORT="2049"				# (TCP/UDP) NFS
SOCKS_PORT="1080"			# (TCP) Socks

# X Windows port allocation begins at 6000 and increments to 6063
# for each additional server running.
XWINDOW_PORTS="6000:6063"		# (TCP) X windows

# The SSH client starts at 1023 and works down to 513 for each
# additional simultaneous connection originating from a privileged port.
# Clients can optionally be configured to use only unprivileged ports.
SSH_LOCAL_PORTS="1022:65535"		# port range for local clients
SSH_REMOTE_PORTS="513:65535"		# port range for remote clients

# traceroute usually uses -S 32769:65535 -D 33434:33523
TRACEROUTE_SRC_PORTS="32769:65535"
TRACEROUTE_DEST_PORTS="33434:33523"

# ----------------------------------------------------------------------------
# Default policy is DENY
# Explicitly accept desired INCOMING & OUTGOING connections

    # Remove all existing rules belonging to this filter
    ipchains -F

    # Set the default policy of the filter to deny.
    ipchains -P input  DENY
    ipchains -P output REJECT
    ipchains -P forward DENY

    # set masquerade timeout to 10 hours for tcp connections
    ipchains -M -S 36000 0 0


# ----------------------------------------------------------------------------

    # Enable IP Forwarding, if it isn't already
    echo 1 > /proc/sys/net/ipv4/ip_forward

    # Enable TCP SYN Cookie Protection
    echo 1 > /proc/sys/net/ipv4/tcp_syncookies

    # Enable always defragging Protection
    echo 1 > /proc/sys/net/ipv4/ip_always_defrag

    # Enable broadcast echo  Protection
    echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

    # Enable bad error message  Protection
    echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

    # Enable IP spoofing protection
    # turn on Source Address Verification
    for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
        echo 1 > $f
    done

    # Disable ICMP Redirect Acceptance
    for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do
        echo 0 > $f
    done

    for f in /proc/sys/net/ipv4/conf/*/send_redirects; do
        echo 0 > $f
    done

    # Disable Source Routed Packets
    for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do
        echo 0 > $f
    done

    # Log Spoofed Packets, Source Routed Packets, Redirect Packets
    for f in /proc/sys/net/ipv4/conf/*/log_martians; do
        echo 1 > $f
    done


    # These modules are necessary to masquerade their respective services.
    /sbin/modprobe ip_masq_ftp

# ----------------------------------------------------------------------------
# LOOPBACK

    # Unlimited traffic on the loopback interface.

    ipchains -A input  -i $LOOPBACK_INTERFACE  -j ACCEPT 
    ipchains -A output -i $LOOPBACK_INTERFACE  -j ACCEPT 

# ----------------------------------------------------------------------------
# Unlimited traffic within the local network.

    # All internal machines have access to the fireall machine.

    ipchains -A input  -i $LOCAL_INTERFACE_1 -s $LOCALNET_1 -j ACCEPT 
    ipchains -A output -i $LOCAL_INTERFACE_1 -d $LOCALNET_1 -j ACCEPT 

# ----------------------------------------------------------------------------
# Masquerade internal traffic.

    # All internal traffic is masqueraded externally.
    ipchains -A forward -i $EXTERNAL_INTERFACE -s $LOCALNET_1 -j MASQ

# ----------------------------------------------------------------------------
# SPOOFING & BAD ADDRESSES
# Refuse spoofed packets.
# Ignore blatantly illegal source addresses.
# Protect yourself from sending to bad addresses.

    # Refuse incoming packets pretending to be from the external address.
    ipchains -A input   -s $IPADDR -j DENY -l

# ----------------------------------------------------------------------------
# NOTE:
#      The symbolic names used in /etc/services for the port numbers vary by
#      supplier.  Using them is less error prone and more meaningful, though.

# ----------------------------------------------------------------------------
# TCP UNPRIVILEGED PORTS
# Avoid ports subject to protocol & system administration problems.

    # NFS: establishing a TCP connection
    ipchains -A input  -i $EXTERNAL_INTERFACE -p tcp -y \
             --destination-port $NFS_PORT -j DENY -l
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -y \
             --destination-port $NFS_PORT -j REJECT 

    # Xwindows: establishing a connection
    ipchains -A input  -i $EXTERNAL_INTERFACE -p tcp -y \
             --destination-port $XWINDOW_PORTS -j DENY -l
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -y \
             --destination-port $XWINDOW_PORTS -j REJECT 

    # SOCKS: establishing a connection
    ipchains -A input  -i $EXTERNAL_INTERFACE -p tcp -y \
             --destination-port $SOCKS_PORT -j DENY -l
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp -y \
             --destination-port $SOCKS_PORT -j REJECT 

# ----------------------------------------------------------------------------
# UDP UNPRIVILEGED PORTS
# Avoid ports subject to protocol & system administration problems.

    ipchains -A input  -i $EXTERNAL_INTERFACE -p udp  \
             --destination-port $NFS_PORT -j DENY -l

    # UDP INCOMING TRACEROUTE
    # traceroute usually uses -S 32769:65535 -D 33434:33523

    ipchains -A input  -i $EXTERNAL_INTERFACE -p udp  \
             --source-port $TRACEROUTE_SRC_PORTS \
             --destination-port $TRACEROUTE_DEST_PORTS -j DENY -l

# ----------------------------------------------------------------------------

    ipchains -A input  -i $EXTERNAL_INTERFACE -p tcp ! -y \
             -d $IPADDR -j ACCEPT 

    # ------------------------------------------------------------------

    # DNS client (53)
    # ---------------
    ipchains -A output -i $EXTERNAL_INTERFACE -p udp  \
             -s $IPADDR $UNPRIVPORTS \
             -d $NAMESERVER_1 53 -j ACCEPT 

    ipchains -A input  -i $EXTERNAL_INTERFACE -p udp  \
             -s $NAMESERVER_1 53 \
             -d $IPADDR $UNPRIVPORTS -j ACCEPT 


    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp  \
             -s $IPADDR $UNPRIVPORTS \
             -d $NAMESERVER_1 53 -j ACCEPT 

    ipchains -A output -i $EXTERNAL_INTERFACE -p udp  \
             -s $IPADDR $UNPRIVPORTS \
             -d $NAMESERVER_2 53 -j ACCEPT 

    ipchains -A input  -i $EXTERNAL_INTERFACE -p udp  \
             -s $NAMESERVER_2 53 \
             -d $IPADDR $UNPRIVPORTS -j ACCEPT 


    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp  \
             -s $IPADDR $UNPRIVPORTS \
             -d $NAMESERVER_2 53 -j ACCEPT 

    # ------------------------------------------------------------------

    # HTTP client (80)
    # ----------------
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp  \
             -s $IPADDR $UNPRIVPORTS \
             --destination-port 80 -j ACCEPT 

    # ------------------------------------------------------------------

    # HTTPS client (443)
    # ------------------
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp  \
             -s $IPADDR $UNPRIVPORTS \
             --destination-port 443 -j ACCEPT 

    # ------------------------------------------------------------------

    # POP client (110)
    # ----------------
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp  \
             -s $IPADDR $UNPRIVPORTS \
             -d $POP_SERVER 110 -j ACCEPT 

    # ------------------------------------------------------------------

    # IMAP client (143)
    # -----------------
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp  \
             -s $IPADDR $UNPRIVPORTS \
             -d $IMAP_SERVER 143 -j ACCEPT 

    # ------------------------------------------------------------------

    # SMTP client (25)
    # ----------------
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp  \
             -s $IPADDR $UNPRIVPORTS \
             -d $SMTP_SERVER 25 -j ACCEPT 

    # ------------------------------------------------------------------

    # SSH client (22)
    # ---------------
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp  \
             -s $IPADDR $SSH_LOCAL_PORTS \
             --destination-port 22 -j ACCEPT 

    # ------------------------------------------------------------------

    # TELNET client (23)
    # ------------------
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp  \
             -s $IPADDR $UNPRIVPORTS \
             --destination-port 23 -j ACCEPT 

    # ------------------------------------------------------------------

    # AUTH server (113)
    # -----------------

    # Reject, rather than deny, the incoming auth port. (NET-3-HOWTO)
    ipchains -A input  -i $EXTERNAL_INTERFACE -p tcp  \
             --source-port $UNPRIVPORTS \
             -d $IPADDR 113 -j REJECT 


    # AUTH client (113)
    # -----------------
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp  \
             -s $IPADDR $UNPRIVPORTS \
             --destination-port 113 -j ACCEPT 

    # ------------------------------------------------------------------

    # WHOIS client (43)
    # -----------------
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp  \
             -s $IPADDR $UNPRIVPORTS \
             --destination-port 43 -j ACCEPT 

    # ------------------------------------------------------------------

    # FTP client (21)
    # ---------------

    # outgoing request
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp  \
             -s $IPADDR $UNPRIVPORTS \
             --destination-port 21 -j ACCEPT 


    # PORT mode data channel
    ipchains -A input  -i $EXTERNAL_INTERFACE -p tcp  \
             --source-port 20 \
             -d $IPADDR $UNPRIVPORTS -j ACCEPT 

    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp ! -y \
             -s $IPADDR $UNPRIVPORTS \
             --destination-port 20 -j ACCEPT 


    # PASSIVE mode data channel creation
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp  \
             -s $IPADDR $UNPRIVPORTS \
             --destination-port $UNPRIVPORTS -j ACCEPT 

    # ------------------------------------------------------------------

    # ICQ client (4000)
    # -----------------
    ipchains -A output -i $EXTERNAL_INTERFACE -p tcp  \
             -s $IPADDR $UNPRIVPORTS \
             --destination-port 2000:4000 -j ACCEPT 

    ipchains -A output -i $EXTERNAL_INTERFACE -p udp  \
             -s $IPADDR $UNPRIVPORTS \
             --destination-port 4000 -j ACCEPT 

    ipchains -A input  -i $EXTERNAL_INTERFACE -p udp  \
             --source-port 4000 \
             -d $IPADDR $UNPRIVPORTS -j ACCEPT 

# ----------------------------------------------------------------------------
# UDP accept only on selected ports
# ---------------------------------

    # ------------------------------------------------------------------

    # OUTGOING TRACEROUTE
    # -------------------
    ipchains -A output -i $EXTERNAL_INTERFACE -p udp  \
             -s $IPADDR $TRACEROUTE_SRC_PORTS \
             --destination-port $TRACEROUTE_DEST_PORTS -j ACCEPT -l

# ----------------------------------------------------------------------------
# ICMP

    #    To prevent denial of service attacks based on ICMP bombs, filter
    #    incoming Redirect (5) and outgoing Destination Unreachable (3).
    #    Note, however, disabling Destination Unreachable (3) is not
    #    advisable, as it is used to negotiate packet fragment size.

    # For bi-directional ping.
    #     Message Types:  Echo_Reply (0),  Echo_Request (8)
    #     To prevent attacks, limit the src addresses to your ISP range.
    # 
    # For outgoing traceroute.
    #     Message Types:  INCOMING Dest_Unreachable (3), Time_Exceeded (11)
    #     default UDP base: 33434 to base+nhops-1
    # 
    # For incoming traceroute.
    #     Message Types:  OUTGOING Dest_Unreachable (3), Time_Exceeded (11)
    #     To block this, deny OUTGOING 3 and 11

    #  0: echo-reply (pong)
    #  3: destination-unreachable, port-unreachable, fragmentation-needed, etc.
    #  4: source-quench
    #  5: redirect
    #  8: echo-request (ping)
    # 11: time-exceeded
    # 12: parameter-problem

    ipchains -A input  -i $EXTERNAL_INTERFACE -p icmp  \
             --icmp-type echo-reply \
             -d $IPADDR -j ACCEPT 

    ipchains -A input  -i $EXTERNAL_INTERFACE -p icmp  \
             --icmp-type destination-unreachable \
             -d $IPADDR -j ACCEPT 

    ipchains -A input  -i $EXTERNAL_INTERFACE -p icmp  \
             --icmp-type source-quench \
             -d $IPADDR -j ACCEPT 

    ipchains -A input  -i $EXTERNAL_INTERFACE -p icmp  \
             --icmp-type time-exceeded \
             -d $IPADDR -j ACCEPT 

    ipchains -A input  -i $EXTERNAL_INTERFACE -p icmp  \
             --icmp-type parameter-problem \
             -d $IPADDR -j ACCEPT 


    ipchains -A output -i $EXTERNAL_INTERFACE -p icmp  \
             -s $IPADDR fragmentation-needed -j ACCEPT 

    ipchains -A output -i $EXTERNAL_INTERFACE -p icmp  \
             -s $IPADDR source-quench -j ACCEPT 

    ipchains -A output -i $EXTERNAL_INTERFACE -p icmp  \
             -s $IPADDR echo-request -j ACCEPT 

    ipchains -A output -i $EXTERNAL_INTERFACE -p icmp  \
             -s $IPADDR parameter-problem -j ACCEPT 

# ----------------------------------------------------------------------------
# Enable logging for selected denied packets

    ipchains -A input  -i $EXTERNAL_INTERFACE -p tcp  -j DENY -l

    ipchains -A input  -i $EXTERNAL_INTERFACE -p udp  \
             --destination-port $PRIVPORTS -j DENY -l

    ipchains -A input  -i $EXTERNAL_INTERFACE -p udp  \
             --destination-port $UNPRIVPORTS -j DENY -l


    ipchains -A input  -i $EXTERNAL_INTERFACE -p icmp  \
             --icmp-type 5 -j DENY -l
    ipchains -A input  -i $EXTERNAL_INTERFACE -p icmp  \
             --icmp-type 13:255 -j DENY -l

    ipchains -A output -i $EXTERNAL_INTERFACE  -j REJECT -l

# ----------------------------------------------------------------------------

echo "done"

exit 0


    
