Alan Mead wrote:
> Wow, I just sat down to ask this question!  I want to run some services
> that are accessible locally but which do not appear to be running from the
> outside.  I have a Linux 6.1 machine Masq'ing a small LAN on the @Home
> network.  "Servers" are forbidden on this network and they scan me 12 times
> each day looking for illegitimate servers, only port 119 so far.  I would
> like to run news (I want to gate some mail lists to INN and look into
> sucking a feed) and http.  The local LAN is 192.168.0.x with .1 as the
> gateway and I have a static IP for the second interface connected to the
> cable modem.

OK, take a look at the attached script. Install it in /etc/rc.d/init.d
if you feel that it will do what you want it to do.  I wrote it to make
it easy for me to easily firewall some of my machines.  All the
configuration is done with a few environment variables at the head of
the script, nothing below them should need editing, unless you want
something specific changed. 

If you have questions, ask  :)

MSG
#!/bin/sh
#
# firewall        Configures Linux firewall services
#
#
# chkconfig: 2345 11 89
# description: Configure firewalling and ip forwarding using ipchains

# Source functions
. /etc/rc.d/init.d/functions

#
# <CONFIGURATION>
#

IPCHAINS="/sbin/ipchains"
IPMASQADM="/usr/sbin/ipmasqadm"

#
# All of the following variables accept space separated lists of items
#
# SPOOF_PROTECTION can be set to a device name, or "ALL"
SPOOF_PROTECTION_ON="ALL"

# PARANOID_DEV and PARANOID_ADDR allow you to specify interfaces which should
# be as closed as possible.  These interfaces will have all ports under 1024 
# closed, as well as 6000-6010.  Under some situations, specifying a dev 
# doesn't work well, particularly on routers.  In other cases, like web servers
# with many addr's on a single interface, the dev is much simpler. In order to 
# use a port on a paranoid dev/addr, you must specifically open that port using 
# PARANOIA_ALLOWS_PORTS.  PARANOIA_EXTRA_PORTS can be used to close specific
# ports in addition to those normally closed (stuff like MySQL or NFS).
PARANOID_DEV="eth1"
# PARANOID_ADDR="232.123.123.123"
PARANOIA_ALLOWS_PORTS="22"
PARANOIA_EXTRA_PORTS="2049 3306"

# Prove paranoia:  REJECT'ed packets will be logged to syslog if set to TRUE
LOG_DENIED="TRUE"

# MASQ_NET allows you to specify hosts or networks that should be masqueraded.
MASQ_NET="192.168.1.0/24"
# FORWARD_NET allows you to specify networks whose IP traffic will be 
# forwarded/routed.  ONLY networks listed here will be forwarded.
# FORWARD_NET="192.168.10.0/24"

#
# This is a little weird, but I wanted to provide a simple way to
# do it, so here's the best you get:
# format: local_ip(local_port)-remote_ip(remote_port)
# e.g.:  192.168.0.2(21)-192.168.1.5(21)
#
# PORT_FORWARDS="192.168.0.2(5155)-192.168.1.5(22)"

# These rules allow you to specify additional rules for host based access
# control.  
# To allow 232.123.123.6 to access all privliged ports, even on paranoid 
# devices, and deny all access to 232.123.123.3, use the following:
#HOSTS_ALLOW="232.123.123.6()-192.168.0.2(:1024)"
#HOSTS_DENY="232.123.123.3()-192.168.0.2()"


#
# </CONFIGURATION>
#



configure_system() {

        # Turn on Source Address Verification and get
        # spoof protection on all current and future interfaces.
        if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ] ; then
                if [ "$SPOOF_PROTECTION_ON" = "ALL" ]; then
                        echo -n "Setting up IP spoofing protection..."
                        for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
                                echo 1 > $f
                        done
                        echo "done"
                fi
        else
                echo "SPOOF PROTECTION NOT AVAILABLE ON THIS SYSTEM."
        fi


        if [ ! -f /proc/sys/net/ipv4/ip_forward ] ; then
                echo "/proc/sys/net/ipv4/ip_forward is missing --" \
                     "cannot control IP forwarding" >&2
                return 1
        fi

        if [ 1 != "`cat /proc/sys/net/ipv4/ip_forward`" ]; then
                echo "Routing has not been enabled." >&2
                echo "Please set FORWARD_IPV4=\"yes\" in /etc/sysconfig/network" >&2
                echo "  or use your network configuration tool to enable ip 
forwarding." >&2
                return 1
        fi

        #
        # Flush the old rules, so that we don't duplicate them.
        # This is important if the rules have changed.
        #
        action "Flushing old firewalling rules" $IPCHAINS -F

        [ -x $IPMASQADM ] && \
        action "Flushing forwarded ports" $IPMASQADM portfw -f

        #
        # Set the default for packet forwarding to REJECT.  We only want to 
        # forward packets for those in our own network.
        #
        action "Denying packet forwarding by default" \
                $IPCHAINS -P forward REJECT

        #action "Extending default timouts for masqueraded IP connections" \
        #       $IPCHAINS -M -S 14400 0 0

        # Load all available ip_masq modules.  Red Hat 6.2's modutils package
        # (version 2.3.9-6) will not modprobe if the given argument has the 
        # trailing ".o", so strip it off with sed.
        OLD_DIR="$PWD"
        cd /lib/modules/`uname -r`/ipv4/
        ls ip_masq* | sed 's/.o$//' | while read masqmod ; do
                action "Loading masquerade module $masqmod " \
                        modprobe "$masqmod"
        done
        cd "$OLD_DIR"


}

lock_down_dev() {

    LOG=""
    if [ "$LOG_DENIED" = "TRUE" ]; then
        LOG=" -l "
    fi

    action "Disallowing incoming connections on $ARG_PARANOID_DEV" \
        ipchains -A input -i "$ARG_PARANOID_DEV" -y \
        -p TCP --destination-port :1023 -j REJECT $LOG
        ipchains -A input -i "$ARG_PARANOID_DEV" \
        -p UDP --destination-port :1023 -j REJECT $LOG
        ipchains -A input -i "$ARG_PARANOID_DEV" -y \
        -p TCP --destination-port 6000:6010 -j REJECT $LOG
        ipchains -A input -i "$ARG_PARANOID_DEV" \
        -p UDP --destination-port 6000:6010 -j REJECT $LOG
    [ -n "$PARANOIA_EXTRA_PORTS" ] && for PORTS in $PARANOIA_EXTRA_PORTS; do
        action "  including extra port $PORTS" \
                ipchains -A input -i "$ARG_PARANOID_DEV" -y \
                -p TCP --destination-port "$PORTS" -j REJECT $LOG
                ipchains -A input -i "$ARG_PARANOID_DEV" \
                -p UDP --destination-port "$PORTS" -j REJECT $LOG
    done
    [ -n "$PARANOIA_ALLOWS_PORTS" ] && for PORTS in $PARANOIA_ALLOWS_PORTS; do
        action "  except for port $PORTS" \
                ipchains -I input 1 -i "$ARG_PARANOID_DEV" -y \
                -p TCP --destination-port "$PORTS" -j ACCEPT
                ipchains -I input 1 -i "$ARG_PARANOID_DEV" \
                -p UDP --destination-port "$PORTS" -j ACCEPT
    done
    [ -e /proc/sys/net/ipv4/conf/all/rp_filter ] &&
    for DEV in "$SPOOF_PROTECTION_ON"; do
                [ "$DEV" = "$ARG_PARANOID_DEV" ] &&
                action "Setting up IP spoofing protection on $ARG_PARANOID_DEV" \
                        echo 1 > /proc/sys/net/ipv4/conf/"$ARG_PARANOID_DEV"/rp_filter
    done

}

lock_down_addr() {

    LOG=""
    if [ "$LOG_DENIED" = "TRUE" ]; then
        LOG=" -l "
    fi

    action "Disallowing incoming connections on $ARG_PARANOID_ADDR" \
        ipchains -A input -d "$ARG_PARANOID_ADDR" -y \
        -p TCP --destination-port :1023 -j REJECT $LOG
        ipchains -A input -d "$ARG_PARANOID_ADDR" \
        -p UDP --destination-port :1023 -j REJECT $LOG
        ipchains -A input -d "$ARG_PARANOID_ADDR" -y \
        -p TCP --destination-port 6000:6010 -j REJECT $LOG
        ipchains -A input -d "$ARG_PARANOID_ADDR" \
        -p UDP --destination-port 6000:6010 -j REJECT $LOG
    [ -n "$PARANOIA_EXTRA_PORTS" ] && for PORTS in $PARANOIA_EXTRA_PORTS; do
        action "  including extra port $PORTS" \
                ipchains -A input -d "$ARG_PARANOID_ADDR" -y \
                -p TCP --destination-port "$PORTS" -j REJECT $LOG
                ipchains -A input -d "$ARG_PARANOID_ADDR" \
                -p UDP --destination-port "$PORTS" -j REJECT $LOG
    done
    [ -n "$PARANOIA_ALLOWS_PORTS" ] && for PORTS in $PARANOIA_ALLOWS_PORTS; do
        action "  except for port $PORTS" \
                ipchains -I input 1 -d "$ARG_PARANOID_ADDR" -y \
                -p TCP --destination-port "$PORTS" -j ACCEPT
                ipchains -I input 1 -d "$ARG_PARANOID_ADDR" \
                -p UDP --destination-port "$PORTS" -j ACCEPT
    done
    [ -e /proc/sys/net/ipv4/conf/all/rp_filter ] &&
    for DEV in "$SPOOF_PROTECTION_ON"; do
                [ "$DEV" = "$ARG_PARANOID_ADDR" ] &&
                action "Setting up IP spoofing protection on $ARG_PARANOID_ADDR" \
                        echo 1 > /proc/sys/net/ipv4/conf/"$ARG_PARANOID_ADDR"/rp_filter
    done

}

do_hosts_deny() {

    for DENY in $HOSTS_DENY; do
        LOCAL_DENY=`echo $DENY | cut -f2 -d-`
        REMOTE_DENY=`echo $DENY | cut -f1 -d-`

        LOCAL_IP=`echo $LOCAL_DENY | sed "s/(.*)//g"`
        LOCAL_PORT=`echo $LOCAL_DENY | sed "s/.*(\|)//g"`
        REMOTE_IP=`echo $REMOTE_DENY | sed "s/(.*)//g"`
        REMOTE_PORT=`echo $REMOTE_DENY | sed "s/.*(\|)//g"`

        action "  removing access from $REMOTE_IP $REMOTE_PORT to $LOCAL_IP 
$LOCAL_PORT" \
        ipchains -I input 1 -i "$ARG_PARANOID_DEV" -y \
        -p TCP -s $REMOTE_IP $REMOTE_PORT -d $LOCAL_IP $LOCAL_PORT -j REJECT $LOG
        ipchains -I input 1 -i "$ARG_PARANOID_DEV" \
        -p UDP -s $REMOTE_IP $REMOTE_PORT -d $LOCAL_IP $LOCAL_PORT -j REJECT $LOG
    done
}

do_hosts_allow() {

    for ALLOW in $HOSTS_ALLOW; do
        LOCAL_ALLOW=`echo $ALLOW | cut -f2 -d-`
        REMOTE_ALLOW=`echo $ALLOW | cut -f1 -d-`

        LOCAL_IP=`echo $LOCAL_ALLOW | sed "s/(.*)//g"`
        LOCAL_PORT=`echo $LOCAL_ALLOW | sed "s/.*(\|)//g"`
        REMOTE_IP=`echo $REMOTE_ALLOW | sed "s/(.*)//g"`
        REMOTE_PORT=`echo $REMOTE_ALLOW | sed "s/.*(\|)//g"`

        action "  allowing $REMOTE_IP $REMOTE_PORT to access $LOCAL_IP $LOCAL_PORT" \
        ipchains -I input 1 -i "$ARG_PARANOID_DEV" -y \
        -p TCP -s $REMOTE_IP $REMOTE_PORT -d $LOCAL_IP $LOCAL_PORT -j ACCEPT
        ipchains -I input 1 -i "$ARG_PARANOID_DEV" \
        -p UDP -s $REMOTE_IP $REMOTE_PORT -d $LOCAL_IP $LOCAL_PORT -j ACCEPT
    done

}

masq_network() {

    action "Activating masquerading for network $ARG_MASQ_NET" \
        $IPCHAINS -A forward -s $ARG_MASQ_NET -d 0/0 -j MASQ

}

forward_network() {

    action "Allowing network $ARG_FWD_NET to be forwarded" \
        $IPCHAINS -A forward -b -s $ARG_FWD_NET -d 0/0 -j ACCEPT

}

do_port_forward() {

    [ ! -x $IPMASQADM ] && {
        echo "Please install ipmasqadm for port forwarding" >&2 
        return 1
    }

    LOCAL_F=`echo $ARG_PORT_FORWARD | cut -f1 -d-`
    REMOTE_F=`echo $ARG_PORT_FORWARD | cut -f2 -d-`

    LOCAL_IP=`echo $LOCAL_F | sed "s/(.*)//g"`
    LOCAL_PORT=`echo $LOCAL_F | sed "s/.*(\|)//g"`
    REMOTE_IP=`echo $REMOTE_F | sed "s/(.*)//g"`
    REMOTE_PORT=`echo $REMOTE_F | sed "s/.*(\|)//g"`

    action "Forwarding $LOCAL_F to $REMOTE_F" \
        $IPMASQADM portfw -a -P tcp \
        -L "$LOCAL_IP" "$LOCAL_PORT" -R "$REMOTE_IP" "$REMOTE_PORT"

}

#-----------------------

case "$1" in
    start)
        configure_system

        [ -n "$PARANOID_DEV" ] && for PD in $PARANOID_DEV; do
            ARG_PARANOID_DEV="$PD"
            lock_down_dev
        done
        [ -n "$PARANOID_ADDR" ] && for PD in $PARANOID_ADDR; do
            ARG_PARANOID_ADDR="$PD"
            lock_down_addr
        done

        [ -n "$HOSTS_ALLOW" ] && do_hosts_allow
        [ -n "$HOSTS_DENY"  ] && do_hosts_deny

        [ -n "$MASQ_NET" ] && for MN in $MASQ_NET; do 
            ARG_MASQ_NET=$MN
            masq_network
        done


        [ -n "$FORWARD_NET" ] && for FN in $FORWARD_NET; do
            ARG_FWD_NET=$FN
            forward_network
        done


        [ -n "$PORT_FORWARDS" ] && for PF in $PORT_FORWARDS ; do
            ARG_PORT_FORWARD=$PF
            do_port_forward
        done
        ;;


    stop)
        action "Flushing old firewalling rules" $IPCHAINS -F
        ;;

    status)
        echo "Current firewalling rules are:" ; $IPCHAINS -L
        ;;

    restart)
        $0 stop
        $0 start
        ;;

    *)
        echo "Usage: firewall {start|stop|restart|status}"
        exit 1

esac

# Port sentry:
#if ( ! /sbin/pidof portsentry > /dev/null ); then
#
#       if [ -x /usr/local/psionic/portsentry/portsentry ]; then
#               action "Starting portsentry watching tcp" \
#                       /usr/local/psionic/portsentry/portsentry -atcp
#               action "Starting portsentry watching udp" \
#                       /usr/local/psionic/portsentry/portsentry -audp
#       fi
#
#fi

Reply via email to