#!/bin/sh
# /etc/rc.d/rc.firewall
# %%%%%%%%%%%
# Modules %%%
# %%%%%%%%%%%
/sbin/depmod -a
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe iptable_nat
/sbin/modprobe ip_nat_ftp
/sbin/modprobe ipt_MASQUERADE
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_state
# %%%%%%%%%%%%
# Constants %%
# %%%%%%%%%%%%
IPTABLES="/sbin/iptables"
LOOPBACK_INTERFACE="lo" # loopback interface
LOCAL_INTERFACE_1="eth1" # internal LAN interface
EXTERNAL_INTERFACE="eth0" # external net interface
LOCALNET_1="10.1.1.0/24" # private range
WWW_IP="10.1.1.3" # WWW server
FTP_IP="10.1.1.3" # FTP server
WIN_IP="10.1.1.2" # Windows telnet client
MAIL_IP="10.1.1.4" # MAIL server
DNS_IP="10.1.1.3" # Inside DNS server
FIREWALL_IP="10.1.1.1"
PENGUIN_IP="10.1.1.6" # Test mail server
CISCO_IP="10.1.1.7"
NAMESERVER_1="209.124.193.250" # nameserver 1
NAMESERVER_2="209.124.203.12" # nameserver 2
POPSERVER="mail.eatel.net" # POP mail server
SMTPSERVER="mail.eatel.net" # SMTP mail server
NEWSSERVER="news.eatel.net" # NEWS server
LOOPBACK="127.0.0.1" # 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
CLASS_D_MULTICAST="224.0.0.0/4" # class D multicast addresses
CLASS_E_RESERVED_NET="240.0.0.0/5" # class E reserved addresses
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_PORTS="1022:65535" # 2 allowed connection
# traceroute usually uses -s 32769:65535 -d 33434:33523
TRACEROUTE_SRC_PORTS="32769:65535"
TRACEROUTE_DEST_PORTS="33434:33523"
# %%%%%%%%
# Flush %%
# %%%%%%%%
$IPTABLES -F
$IPTABLES -X
$IPTABLES -Z
$IPTABLES -t nat -F
$IPTABLES -t mangle -F
# %%%%%%%
# Drop %%
# %%%%%%%
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP
# $IPTABLES -t nat -P POSTROUTING DROP
# $IPTABLES -t nat -P PREROUTING DROP
$IPTABLES --delete-chain
$IPTABLES -t nat --delete-chain
# %%%%%%%%%%
# System %%%
# %%%%%%%%%%
# Enable IPv4 packet forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# Enable redirects
for f in /proc/sys/net/ipv4/conf/*/send_redirects; do
echo 0 > $f
done
# For dynamic IP
echo 1 > /proc/sys/net/ipv4/ip_dynaddr
# Enable TCP SYN Cookie Protection
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
# 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
# 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
# %%%%%%%%%%%%%%
# DHCP client %%
# %%%%%%%%%%%%%%
# Read DHCP info
if [ -f /etc/dhcpc/dhcpcd-$EXTERNAL_INTERFACE.info ];then
. /etc/dhcpc/dhcpcd-$EXTERNAL_INTERFACE.info
DHCP_SERVER=$DHCPSID
IPADDR=$IPADDR
HOST=$HOSTNAME
DOMAIN=$DOMAIN
# MAILSERVER="mail.$DOMAIN"
# NEWSSERVER="news.$DOMAIN"
fi
echo "DHCP INFO..."
echo "Host Name: $HOST"
echo "Domain Name: $DOMAIN"
echo "HOST IP: $IPADDR"
echo "DHCP SERVER IP: $DHCP_SERVER"
# echo "Mail Server: $MAILSERVER"
# echo "News Server: $NEWSSERVER"
DHCP_SERVER="0/0"
# allow dhcp server (67) to connect to dhcp client (68)
# Note: the DHCP server is the only externel source of broadcast
# messages we should see, ever.
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p udp \
-s $DHCP_SERVER --sport 67 \
-d $IPADDR --dport 68 -j ACCEPT
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p udp \
-s $IPADDR --sport 68 \
-d $DHCP_SERVER --dport 67 -j ACCEPT
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p udp \
-s $DHCP_SERVER --sport 67 \
-d $BROADCAST_DEST --dport 68 -j ACCEPT
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p udp \
-s $BROADCAST_SRC --sport 68 \
-d $DHCP_SERVER --dport 67 -j ACCEPT
# Get renumbered
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p udp \
-s $BROADCAST_SRC --sport 67 \
-d $BROADCAST_DEST --dport 68 -j ACCEPT
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p udp \
-s $BROADCAST_SRC --sport 68 \
-d $BROADCAST_DEST --dport 67 -j ACCEPT
# As a result of the above, we're supposed to change our IP
# address with this message, which is addressed to our new
# address before the dhcp client has received the update.
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p udp \
-s $DHCP_SERVER --sport 67 \
--dport 68 -j ACCEPT
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p udp \
--sport 67 \
-d $IPADDR --dport 68 -j DROP
# %%%%%%%%%%%%%%%
# Postrouting %%%
# %%%%%%%%%%%%%%%
# NAT RULE FOR LAN
$IPTABLES -t nat -A POSTROUTING -o $EXTERNAL_INTERFACE -j MASQUERADE
# %%%%%%%%%%%%%
# Prerouting %%
# %%%%%%%%%%%%%
# Drop bad packets
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s $IPADDR -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s $CLASS_A -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s $CLASS_B -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s $CLASS_C -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s $BROADCAST_DEST -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -d $BROADCAST_SRC -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s $CLASS_D_MULTICAST -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s $CLASS_E_RESERVED_NET -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s 127.0.0.0/8 -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s 169.254.0.0/16 -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s 192.0.2.0/24 -j DROP
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -s 224.0.0.0/3 -j DROP
# Stealth Scans and TCP State Flags
# All of the bits are cleared
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp \
--tcp-flags ALL NONE -j DROP
# SYN and FIN are both set
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp \
--tcp-flags SYN,FIN SYN,FIN -j DROP
# SYN and RST are both set
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp \
--tcp-flags SYN,RST SYN,RST -j DROP
# FIN and RST are both set
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp \
--tcp-flags FIN,RST FIN,RST -j DROP
# FIN is the only bit set, without the expected accompanying ACK
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp \
--tcp-flags ACK,FIN FIN -j DROP
# PSH is the only bit set, without the expected accompanying ACK
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp \
--tcp-flags ACK,PSH PSH -j DROP
# URG is the only bit set, without the expected accompanying ACK
$IPTABLES -t nat -A PREROUTING -i $EXTERNAL_INTERFACE -p tcp \
--tcp-flags ACK,URG URG -j DROP
# Blacklist
if [ -f /etc/rc.d/rc.firewall.blocked ]; then
. /etc/rc.d/rc.firewall.blocked
fi
# NAT
# Create syn-flood chain for detecting
# Denial of Service attacks
$IPTABLES -t nat -N syn-flood
# Limit 12 connections per second (burst to 24)
$IPTABLES -t nat -A syn-flood -m limit --limit 12/s \
--limit-burst 24 -j DROP
$IPTABLES -t nat -A syn-flood -m limit --limit 3/minute --limit-burst 3 \
-j LOG --log-level DEBUG --log-prefix "SYN-FLOOD! "
# DNAT - HTTP - Port 80
$IPTABLES -t nat -A PREROUTING -p TCP -i $EXTERNAL_INTERFACE \
-s 0/0 --sport $UNPRIVPORTS --dport 80 -j DNAT \
--to-destination $WWW_IP:80
# DNAT - HTTPS - Port 443
$IPTABLES -t nat -A PREROUTING -p TCP -i $EXTERNAL_INTERFACE \
-s 0/0 --sport $UNPRIVPORTS --dport 443 -j DNAT \
--to-destination $MAIL_IP:443
$IPTABLES -t nat -A PREROUTING -p TCP -i $EXTERNAL_INTERFACE \
-s 0/0 --sport $UNPRIVPORTS --dport 25 -j DNAT \
--to-destination $MAIL_IP:25
# DNAT - POP3S
$IPTABLES -t nat -A PREROUTING -p TCP -i $EXTERNAL_INTERFACE \
-s 0/0 --sport $UNPRIVPORTS --dport 995 -j DNAT \
--to-destination $MAIL_IP:995
# DNAT - SSH
$IPTABLES -t nat -A PREROUTING -p TCP -i $EXTERNAL_INTERFACE \
-s 0/0 --sport $SSH_PORTS --dport 22 -j DNAT \
--to-destination $WWW_IP:22
# DNAT - IMAPS
$IPTABLES -t nat -A PREROUTING -p TCP -i $EXTERNAL_INTERFACE \
-s 0/0 --sport $UNPRIVPORTS --dport 993 -j DNAT \
--to-destination $MAIL_IP:993
# DNAT - LDAPS
$IPTABLES -t nat -A PREROUTING -p TCP -i $EXTERNAL_INTERFACE \
-s 0/0 --sport $UNPRIVPORTS --dport 636 -j DNAT \
--to-destination $MAIL_IP:636
# %%%%%%%%%
# Input %%%
# %%%%%%%%%
$IPTABLES -A INPUT -p TCP -i $EXTERNAL_INTERFACE -d $IPADDR -j DROP
$IPTABLES -A INPUT -p ICMP -i $EXTERNAL_INTERFACE -d $IPADDR -j DROP
$IPTABLES -A INPUT -p UDP --dport 53 --sport $UNPRIVPORTS -j ACCEPT
# LAN
$IPTABLES -A INPUT -i $LOCAL_INTERFACE_1 -s $LOCALNET_1 -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LOOPBACK_INTERFACE -j ACCEPT
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 \
-j LOG --log-level DEBUG --log-prefix "IN DROP! "
# %%%%%%%%%
# Output %%
# %%%%%%%%%
$IPTABLES -A OUTPUT -p ALL -s $LOOPBACK -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $IPADDR -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $LOCALNET_1 -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -m state --state ESTABLISHED,RELATED \
-j ACCEPT
$IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 \
-j LOG --log-level DEBUG --log-prefix "OUT DROP! "
# %%%%%%%%%%
# Forward %%
# %%%%%%%%%%
$IPTABLES -N fwtcpOK
$IPTABLES -A fwtcpOK -p TCP -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A fwtcpOK -m limit --limit 3/minute --limit-burst 3 \
-j LOG --log-level DEBUG --log-prefix "FW DROP TCP: "
$IPTABLES -A fwtcpOK -p TCP -j DROP
$IPTABLES -N estfwtcpOK
$IPTABLES -A estfwtcpOK -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A estfwtcpOK -m limit --limit 3/minute --limit-burst 3 \
-j LOG --log-level DEBUG --log-prefix "FW DROP TCP: "
$IPTABLES -A estfwtcpOK -p TCP -j DROP
$IPTABLES -N fwtcpi
$IPTABLES -A fwtcpi -p TCP --dport 80 --sport $UNPRIVPORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 22 --sport $SSH_PORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 25 --sport $SSH_PORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 110 --sport $UNPRIVPORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 119 --sport $UNPRIVPORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 443 --sport $UNPRIVPORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 636 --sport $UNPRIVPORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 993 --sport $UNPRIVPORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport 995 --sport $UNPRIVPORTS -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport $UNPRIVPORTS --sport $UNPRIVPORTS -j estfwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport $UNPRIVPORTS --sport $PRIVPORTS -j estfwtcpOK
$IPTABLES -A fwtcpi -p TCP -d $WIN_IP --dport $UNPRIVPORTS --sport 23 -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport $SSH_PORTS --sport 22 -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport $UNPRIVPORTS \
-s $POPSERVER --sport 110 -j fwtcpOK
$IPTABLES -A fwtcpi -p TCP --dport $UNPRIVPORTS \
-s $NEWSSERVER --sport 119 -j fwtcpOK
$IPTABLES -N fwicmpin
# destination unreachable: used by traceroute
$IPTABLES -A fwicmpin -p ICMP --icmp-type 3 -j ACCEPT
# source quench
$IPTABLES -A fwicmpin -p ICMP --icmp-type 4 -j ACCEPT
# time exceeded: used by traceroute
$IPTABLES -A fwicmpin -p ICMP --icmp-type 11 -j ACCEPT
# parameter problem
$IPTABLES -A fwicmpin -p ICMP --icmp-type 12 -j ACCEPT
$IPTABLES -A fwicmpin -p ICMP -m state --state ESTABLISHED,RELATED \
-j ACCEPT
$IPTABLES -A fwicmpin -m limit --limit 3/minute --limit-burst 3 \
-j LOG --log-level DEBUG --log-prefix "FW DROP ICMP: "
$IPTABLES -A fwicmpin -p ICMP -j DROP
$IPTABLES -N fwudpin
$IPTABLES -A fwudpin -p UDP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A fwudpin -p UDP --dport 53 --sport $UNPRIVPORTS -j ACCEPT
$IPTABLES -A fwudpin -p UDP --sport 53 --dport $UNPRIVPORTS -j ACCEPT
$IPTABLES -A fwudpin -m limit --limit 3/minute --limit-burst 3 \
-j LOG --log-level DEBUG --log-prefix "FW DROP UDP: "
$IPTABLES -A fwudpin -p UDP -j DROP
$IPTABLES -A FORWARD -p TCP -o $EXTERNAL_INTERFACE \
-s $MAIL_IP -j ACCEPT
$IPTABLES -A FORWARD -p TCP -o $EXTERNAL_INTERFACE \
-s $WWW_IP -j ACCEPT
$IPTABLES -A FORWARD -p TCP -o $EXTERNAL_INTERFACE \
-s $PENGUIN_IP -j ACCEPT
$IPTABLES -A FORWARD -p TCP -o $EXTERNAL_INTERFACE \
-s $WIN_IP -j ACCEPT
$IPTABLES -A FORWARD -p TCP -i $EXTERNAL_INTERFACE \
-d $LOCALNET_1 -j fwtcpi
$IPTABLES -A FORWARD -p ICMP -o $EXTERNAL_INTERFACE \
-s $LOCALNET_1 -j ACCEPT
$IPTABLES -A FORWARD -p ICMP -i $EXTERNAL_INTERFACE \
-d $LOCALNET_1 -j fwicmpin
$IPTABLES -A FORWARD -p UDP -o $EXTERNAL_INTERFACE \
-s $LOCALNET_1 -j ACCEPT
$IPTABLES -A FORWARD -p UDP -i $EXTERNAL_INTERFACE \
-d $LOCALNET_1 -j fwudpin
$IPTABLES -A FORWARD -p UDP -i $EXTERNAL_INTERFACE \
# %%%%%% # Log %% # %%%%%%
# TCP
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p tcp -j LOG \
--log-prefix "LOG TCP-IN: "
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p tcp -j DROP
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp -j LOG \
--log-prefix "LOG TCP-OUT: "
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p tcp -j DROP
# ICMP
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p icmp -j LOG \
--log-prefix "LOG ICMP-IN: "
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p icmp -j DROP
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p icmp -j LOG \
--log-prefix "LOG ICMP-OUT: "
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p icmp -j DROP
# UDP
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p udp -j LOG \
--log-prefix "LOG UDP-IN: "
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -p udp -j DROP
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p udp -j LOG \
--log-prefix "LOG UDP-OUT: "
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -p udp -j DROP
# Paranoid
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -j LOG \
--log-prefix "LOG PROTOCOL-X-IN: "
$IPTABLES -A INPUT -i $EXTERNAL_INTERFACE -j DROP
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -j LOG \
--log-prefix "LOG PROTO-X-OUT: "
$IPTABLES -A OUTPUT -o $EXTERNAL_INTERFACE -j DROP
exit 0