# Config for /etc/init.d/firewall
# Gentoo Linux

# iptables firewall script
# written and copied by Pekka "PQ" Paalanen

# I used Iptables Tutorial 1.1.13 as a base.
# http://iptables-tutorial.haringstad.com/iptables-tutorial.html

# This is designed for a single host with no local network.

# Version 1.1
# 9.10.2002
# - added traceroute support
# - totally ignore UDP netbios-ns queries
# - changed tcp denied msg from icmp-port-unreachable to tcp-reset
# - cleaned commented lines
# - added bad_addr and drop_addr chains

# Version 1.0
# - initial script based on the tutorial

## configs ->

# internet interface, uses DHCP
INET_IFACE="eth0"

# local loopback
LO_IFACE="lo"
LO_IP="127.0.0.1"

# who are allowed to connect to our identd
IDENT_MASK="192.89.123.0/24"


# ports used by UDP traceroute
UDP_TRACE_SRC="32769:65535"
UDP_TRACE_DEST="33434:33523"


## <- configs


# executable
IPTABLES=/sbin/iptables


set_firewall() {


# required modules
/sbin/modprobe ip_conntrack
/sbin/modprobe ip_tables
/sbin/modprobe iptable_filter
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit

# additional modules
/sbin/modprobe ipt_REJECT
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe ip_conntrack_irc


# set policies
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP

# clear everything
$IPTABLES -F
$IPTABLES -X


# create user-defined chains
# - for INPUT and OUTPUT
$IPTABLES -N bad_tcp
# - for INPUT
$IPTABLES -N bad_addr
   $IPTABLES -N drop_addr
$IPTABLES -N tcp_in
   $IPTABLES -N allowed
$IPTABLES -N udp_in
$IPTABLES -N icmp_in
$IPTABLES -N igmp_in


#
# bad_tcp chain
#
$IPTABLES -A bad_tcp -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "New not syn: "
$IPTABLES -A bad_tcp -p tcp ! --syn -m state --state NEW -j DROP

# these are from Gentoo Security Guide example ->
$IPTABLES -A bad_tcp -p tcp --tcp-flags ALL FIN,URG,PSH -m limit --limit 5/minute -j LOG --log-level alert --log-prefix "NMAP-XMAS: "
$IPTABLES -A bad_tcp -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP

$IPTABLES -A bad_tcp -p tcp --tcp-flags ALL ALL -m limit --limit 5/minute -j LOG --log-level 1 --log-prefix "XMAS: "
$IPTABLES -A bad_tcp -p tcp --tcp-flags ALL ALL -j DROP

$IPTABLES -A bad_tcp -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -m limit --limit 5/minute -j LOG --log-level 1 --log-prefix "XMAS-PSH: "
$IPTABLES -A bad_tcp -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP

$IPTABLES -A bad_tcp -p tcp --tcp-flags ALL NONE -m limit --limit 5/minute -j LOG --log-level 1 --log-prefix "NULL_SCAN: "
$IPTABLES -A bad_tcp -p tcp --tcp-flags ALL NONE -j DROP

$IPTABLES -A bad_tcp -p tcp --tcp-flags SYN,RST SYN,RST -m limit --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/RST: "
$IPTABLES -A bad_tcp -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

$IPTABLES -A bad_tcp -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/FIN: "
$IPTABLES -A bad_tcp -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
# <-


#
# bad_addr chain
#
$IPTABLES -A bad_addr -j drop_addr -s 127.0.0.0/8
$IPTABLES -A bad_addr -j drop_addr -s 1.0.0.0/8
$IPTABLES -A bad_addr -j drop_addr -s 23.0.0.0/8
$IPTABLES -A bad_addr -j drop_addr -s 31.0.0.0/8
$IPTABLES -A bad_addr -j drop_addr -s 96.0.0.0/3
$IPTABLES -A bad_addr -j drop_addr -s 128.0.0.0/16
$IPTABLES -A bad_addr -j drop_addr -s 128.9.64.26/32
$IPTABLES -A bad_addr -j drop_addr -s 128.66.0.0/16
$IPTABLES -A bad_addr -j drop_addr -s 191.255.0.0/16
$IPTABLES -A bad_addr -j drop_addr -s 197.0.0.0/16
$IPTABLES -A bad_addr -j drop_addr -s 201.0.0.0/8
$IPTABLES -A bad_addr -j drop_addr -s 223.255.255.0/24
$IPTABLES -A bad_addr -j drop_addr -s 240.0.0.0/5
$IPTABLES -A bad_addr -j drop_addr -s 248.0.0.0/5

#
# drop_addr chain
#
$IPTABLES -A drop_addr -m limit --limit 5/minute -j LOG --log-level 5 --log-prefix "spoofed IP: "
$IPTABLES -A drop_addr -j DROP


#
# allowed chain
#
$IPTABLES -A allowed -p TCP -m limit --limit 1/second --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m limit --limit 5/minute -j LOG --log-level 5 --log-prefix "allowed TCP invalid: "
$IPTABLES -A allowed -p TCP -j DROP

#
# TCP rules
#
$IPTABLES -A tcp_in -p TCP -s 0/0 --dport ssh -j allowed
$IPTABLES -A tcp_in -p TCP -s $IDENT_MASK --dport ident -j allowed

$IPTABLES -A tcp_in -p TCP -m limit --limit 5/minute -j LOG --log-level 6 --log-prefix "tcp knocked: "
$IPTABLES -A tcp_in -p TCP -m limit --limit 5/second -j REJECT --reject-with tcp-reset
$IPTABLES -A tcp_in -p TCP -j DROP


#
# UDP ports
#

# don't even log netbios name service queries
$IPTABLES -A udp_in -p UDP --dport 137 -j DROP

# for traceroute:
$IPTABLES -A udp_in -p UDP --sport $UDP_TRACE_SRC --dport $UDP_TRACE_DEST -m limit --limit 5/second -j REJECT --reject-with icmp-port-unreachable

# log'n'drop:
$IPTABLES -A udp_in -p UDP -m limit --limit 5/minute -j LOG --log-level 6 --log-prefix "udp knocked: "
$IPTABLES -A udp_in -p UDP -j DROP

#
# ICMP rules
#
# - allow echo request (ping):
$IPTABLES -A icmp_in -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT
# - allow TTL equals 0 during transit and TTL equals 0 during reassembly (traceroute):
$IPTABLES -A icmp_in -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT
# other ICMP messages should come through conntrack

#
# IGMP rules
#
# - allow all IGMP messages:
$IPTABLES -A igmp_in -p IGMP -j ACCEPT


#
# INPUT chain
#

$IPTABLES -A INPUT -m state --state INVALID -j DROP

#
# Let ESTABLISHED and RELATED go right through
#
$IPTABLES -A INPUT -p ALL -i $INET_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT

#
# Bad TCP packets we don't want.
#
$IPTABLES -A INPUT -p tcp -j bad_tcp

#
# Rules for special networks not part of the Internet
#
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -j ACCEPT

# filter reserved addresses
$IPTABLES -A INPUT -p ALL -i $INET_IFACE -j bad_addr

#
# Rules for incoming packets from the internet.
#
$IPTABLES -A INPUT -p TCP -i $INET_IFACE -j tcp_in
$IPTABLES -A INPUT -p UDP -i $INET_IFACE -j udp_in
$IPTABLES -A INPUT -p ICMP -i $INET_IFACE -j icmp_in
$IPTABLES -A INPUT -p IGMP -i $INET_IFACE -j igmp_in

#
# Log weird packets that don't match the above.
#
$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level DEBUG --log-prefix "IPT INPUT packet died: "


#
# FORWARD chain
#

# the default DROP is good for me


#
# OUTPUT chain
#

#
# Bad TCP packets we don't want.
#
$IPTABLES -A OUTPUT -p tcp -j bad_tcp

# accept everything going out
# You could prevent your own computer from spoofing source IP's, but
# that would require our own IP address, and we are use DHCP.
$IPTABLES -A OUTPUT -p ALL -j ACCEPT


### There should be nothing in the nat and mangle tables.

# THE END #

}