Text 7665, 358 rader
Skriven 2006-10-19 18:42:00 av Paul Rogers (1:105/360.0)
Ärende: Latest firewall script
==============================
#!/bin/bash
# firewall.sh - Configurable per-host firewall for workstations
# Parts James Stephens (jns@ias.edu)
# PGR was here
# PGR Workstation firewall, not appropriate for server
# PGR Attitude: Tight limitations to protect us from the big, bad world,
# as well as our local network from rogue processes. Access to the
# big, wide, world is limited to well-known ports as much as possible.
# Passive mode FTP is allowed, but is a potential security risk. If
# you uncomment DHCP rules, you might want to tell kernel not to log
# "martians".
# PGR Sources of some variables are: "/etc/sysconfig/rc",
# "/etc/sysconfig/network", & "$network_devices/ifconfig.eth0",
# including $IP (my IP address), & $BASEIP (the first 3 octets).
# PGR Blacklisted IP addresses/CIDR's in /etc/blacklisted_ip
# PGR No warranties, expressed or implied!
######################################################################
#
NAMESERVER_1=209.102.124.14 # change as necessary
NAMESERVER_2=209.102.124.15 # change as necessary
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/5"
KNOWN="0:1023" # "well known" ports
EPHEM="1024:65535" # ephemeral ports
TR_SRC_PORTS="32769:65535"
TR_DEST_PORTS="33434:33523"
#PGR source our variables, i.e. IP address
. /etc/sysconfig/rc
. /etc/sysconfig/network
. $network_devices/ifconfig.eth0 # Changes in LFS-6.x
LOCAL_NET=$BASEIP.0/24
function on {
echo "Firewall: enabling filtering"
# Set up a default DROP policy for the built-in chains. If we modify and
# re-run the script mid-session then (because we have a default DROP
# policy), what happens is that there is a small time period when
# packets are denied until the new rules are back in place. There is no
# period, however small, when packets we don't want are allowed.
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# These lines are here in case rules are already in place and the script
# is ever rerun on the fly. We want to remove all rules and
# pre-exisiting user defined chains and zero the counters before we
# implement new rules.
iptables -F
iptables -X
iptables -Z
## LOOPBACK
# Allow my own traffic on the loopback interface.
iptables -A INPUT -i lo -s $LOOPBACK -j ACCEPT
iptables -A OUTPUT -o lo -d $LOOPBACK -j ACCEPT
iptables -A INPUT -i lo -s $IP -j ACCEPT
iptables -A OUTPUT -o lo -d $IP -j ACCEPT
# Everything else comes from an external interface. This firewall is
# for a network workstation, so in the default case that's one ethernet
# interface, eth0. But rules apply to all!
#### USER DEFINED CHAINS
# Syn-flood limiting
# Up to limit-burst connections can arrive in 1/limit seconds ..... in
# this case 4 connections in one second. After this, one of the burst
# is regained every second and connections are allowed again.
# The default limit is 3/hour. The default limit burst is 5.
iptables -N syn-flood
iptables -A syn-flood -m limit --limit 1/s --limit-burst 4 -j RETURN
iptables -A syn-flood -j DROP
##PGR User-defined chain to log & drop packets
iptables -N log-it
iptables -A log-it -j LOG -m limit --limit 40/minute --log-prefix "firewall:
"
iptables -A log-it -j DROP
#### PGR: BLACKLIST CHECKING (comes early)
for BAD_BOY in `cat /etc/blacklisted_ip`
do
echo "Blacklisting " $BAD_BOY
# Input packets are logged & forgotten
iptables -A INPUT -s $BAD_BOY -j log-it
# Output packets from internal processes receive an error code,
# but they still don't go through.
iptables -A OUTPUT -d $BAD_BOY -j REJECT --reject-with
icmp-host-unreachable
done
#### PACKET CHECKING
## SYN-FLOODING PROTECTION
# This rule maximises the rate of incoming connections. In order to do
# this we divert tcp packets with the SYN bit set off to a
# user-defined chain.
iptables -A INPUT -p tcp --syn -j syn-flood
## Make sure NEW tcp connections are SYN packets
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
## FRAGMENTS
# Sending lots of non-first fragments was what allowed Jolt2 to
# effectively "drown" Firewall-1. Fragments can be overlapped, and the
# subsequent interpretation of such fragments is very OS-dependent. Do
# not trust any fragments. Log fragments just to see if we get any, and
# deny them too. The kernel may be managing them.
iptables -A INPUT -f -j log-it
## SPOOFING
# Most of this anti-spoofing stuff is theoretically not really necessary
# with the flags we have set in the kernel but you never know there
# isn't a bug somewhere in your IP stack.
# Refuse spoofed packets pretending to be from your IP address.
iptables -A INPUT -s $IP -j DROP
# Refuse packets claiming to be from a Class A private network.
iptables -A INPUT -s $CLASS_A -j DROP
# Refuse packets claiming to be from a Class B private network.
iptables -A INPUT -s $CLASS_B -j DROP
# Refuse packets claiming to be from a Class C private network.
# iptables -A INPUT -s $CLASS_C -j DROP
#PGR Can't do that, our LAN is a Class C private network
# Refuse Class D multicast addresses. Multicast is illegal as a source
address.
iptables -A INPUT -s $CLASS_D_MULTICAST -j DROP
# Refuse Class E reserved IP addresses.
iptables -A INPUT -s $CLASS_E_RESERVED_NET -j DROP
# Refuse packets claiming to be to the loopback interface. Refusing
# packets claiming to be to the loopback interface protects against
# source quench, whereby a machine can be told to slow itself down by an
# icmp source quench to the loopback.
iptables -A INPUT -d $LOOPBACK -j DROP
# Refuse broadcast address packets.
iptables -A INPUT -d $BROADCAST -j DROP
##PGR Limit furtive port scanners
iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit
1/second -j DROP
## ===========================================
#### TCP packets
## SSH clients
iptables -A INPUT -p tcp --sport ssh -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport ssh -m state --state NEW,ESTABLISHED -j
ACCEPT
## TELNET clients
iptables -A INPUT -p tcp --sport telnet -m state --state ESTABLISHED -j
ACCEPT
iptables -A OUTPUT -p tcp --dport telnet -m state --state NEW,ESTABLISHED -j
ACCEPT
## SMTP clients
iptables -A INPUT -p tcp --sport smtp -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport smtp -m state --state NEW,ESTABLISHED -j
ACCEPT
## POP3 clients
iptables -A INPUT -p tcp --sport pop3 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport pop3 -m state --state NEW,ESTABLISHED -j
ACCEPT
## AUTH server
iptables -A INPUT -p tcp --dport auth -s $LOCAL_NET -j ACCEPT
iptables -A OUTPUT -p tcp --sport auth -d $LOCAL_NET -j ACCEPT
# Reject ident probes with a tcp reset. I need to do this for a broken
# mailhost that won't accept my mail if I just drop its ident probe.
iptables -A INPUT -p tcp --dport auth -j REJECT --reject-with tcp-reset
## WWW clients
iptables -A INPUT -p tcp --sport www -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport www -m state --state NEW,ESTABLISHED -j
ACCEPT
iptables -A INPUT -p tcp --sport https -m state --state ESTABLISHED -j
ACCEPT
iptables -A OUTPUT -p tcp --dport https -m state --state NEW,ESTABLISHED -j
ACCEPT
# Special cases
# Allow connection terminations out, even if already terminated
iptables -A OUTPUT -p tcp --dport www --tcp-flags syn,fin,ack fin,ack -j
ACCEPT
# Ports 81 & 8080 are typically side-channels up to no good
iptables -A OUTPUT -p tcp --dport 81 -j log-it
iptables -A OUTPUT -p tcp --dport 8080 -j log-it
## SAMBA/Windows clients to LAN server(s)
iptables -A INPUT -p tcp --dport netbios-ns -s $LOCAL_NET -m state --state
ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --dport netbios-dgm -s $LOCAL_NET -m state --state
ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --dport netbios-ssn -s $LOCAL_NET -m state --state
ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport netbios-ns -s $LOCAL_NET -m state --state
NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport netbios-dgm -s $LOCAL_NET -m state --state
NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport netbios-ssn -s $LOCAL_NET -m state --state
NEW,ESTABLISHED -j ACCEPT
## FTP clients
# Allow ftp-control (port 21) outbound.
iptables -A INPUT -p tcp --sport ftp -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport ftp -m state --state NEW,ESTABLISHED -j
ACCEPT
# Now for the connection tracking part of ftp.
# 1) Active ftp.
# This involves a connection INbound from port 20 on the remote machine,
# to a local port passed over the ftp channel via a PORT command. The
# ip_conntrack_ftp module recognizes the connection as RELATED to the
# original outgoing connection to port 21 so we don't need NEW as a
# state match.
iptables -A INPUT -p tcp --sport ftp-data -m state --state
ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp --dport ftp-data -m state --state ESTABLISHED -j
ACCEPT
# 2) Passive ftp.
# This involves a connection outbound from a port >1023 on the local
# machine, to a port >1023 on the remote machine previously passed over
# the ftp channel via a PORT command. The ip_conntrack_ftp module
# recognizes the connection as RELATED to the original outgoing
# connection to port 21 so we don't need NEW as a state match.
### WARNING: These allow use of ephemeral ports by ANY established
connection!
iptables -A INPUT -p tcp --sport $EPHEM --dport $EPHEM -m state --state
ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp --sport $EPHEM --dport $EPHEM -m state --state
ESTABLISHED,RELATED -j ACCEPT
##=============================================
#### UDP packets
##PGR SAMBA/Windows host's NETBIOS enquiries
iptables -A INPUT -p udp --dport netbios-ns -s $LOCAL_NET -j ACCEPT
iptables -A INPUT -p udp --dport netbios-dgm -s $LOCAL_NET -j ACCEPT
##PGR Allow DHCP broadcast requests out, leases back in
## (Uncomment if using DHCP.)
# If we're using DHCP, a-priori we don't know anything about the network
# iptables -A INPUT -p udp --sport bootps --dport bootpc -j ACCEPT
# iptables -A OUTPUT -p udp --sport bootpc --dport bootps -j ACCEPT
## DNS
# NOTE: DNS uses tcp for zone transfers, for transfers greater than 512 bytes
# (possible, but unusual), and on certain platforms like AIX (I am told),
# so you might have to add a copy of this rule for tcp if you need it.
# Allow UDP packets in for DNS client from nameservers.
iptables -A INPUT -p udp -s $NAMESERVER_1 --sport domain -m state --state
ESTABLISHED -j ACCEPT
iptables -A INPUT -p udp -s $NAMESERVER_2 --sport domain -m state --state
ESTABLISHED -j ACCEPT
#PGR allow DNS from local LAN too.
iptables -A INPUT -p udp -s $LOCAL_NET --sport domain -m state --state
ESTABLISHED -j ACCEPT
# Allow UDP packets to DNS servers from client.
iptables -A OUTPUT -p udp -d $NAMESERVER_1 --dport domain -m state --state
NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p udp -d $NAMESERVER_2 --dport domain -m state --state
NEW,ESTABLISHED -j ACCEPT
#PGR allow DNS to local LAN too.
iptables -A OUTPUT -p udp -d $LOCAL_NET --dport domain -m state --state
NEW,ESTABLISHED -j ACCEPT
## TRACEROUTE
# Outgoing traceroute anywhere.
# The reply to a traceroute is an icmp time-exceeded which is dealt with
# by the next rule.
iptables -A OUTPUT -p udp --sport $TR_SRC_PORTS --dport $TR_DEST_PORTS -m
state --state NEW -j ACCEPT
##=============================================
#### ICMP packets
# We accept icmp in if it is "related" to other connections (e.g a time
# exceeded (11) from a traceroute) or it is part of an "established"
# connection (e.g. an echo reply (0) from an echo-request (8)).
iptables -A INPUT -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT
# We always allow icmp out.
iptables -A OUTPUT -p icmp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
#PGR protect echo-requests against "The Ping of Death"
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/second
-j ACCEPT
## =============================================
#### FALL-THROUGH
#PGR be nice to local network processes
iptables -A INPUT -s $LOCAL_NET -j REJECT
iptables -A OUTPUT -d $LOCAL_NET -j REJECT
#PGR log & drop the rest
iptables -A INPUT -j log-it
iptables -A OUTPUT -j log-it
}
######################################################################
function off {
# stop firewall
echo "Firewall: disabling filtering (allowing all access)"
echo "Are you sure? Really sure?"
read ans
if [ $ans = "y" -o $ans = "Y" ]; then
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
iptables -X
echo "The gates to the citadel are wide open!"
echo "Welcome, sailor!"
else
echo "Good idea! Firewall stop, cancelled."
fi
}
######################################################################
function stop {
# stop all external connections
echo "Firewall: stopping all external connections"
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
iptables -F
iptables -X
iptables -Z
# allow anything over loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
##PGR Chain to log & drop packets
iptables -N log-it
iptables -A log-it -j LOG -m limit --limit 40/minute --log-prefix "firewall:
"
iptables -A log-it -j DROP
#PGR be nice to local network processes
iptables -A INPUT -s $LOCAL_NET -j REJECT
iptables -A OUTPUT -s $LOCAL_NET -j REJECT
#PGR log & drop the rest
iptables -A INPUT -j log-it
iptables -A OUTPUT -j log-it
}
######################################################################
case "$1" in
start)
on
;;
stop)
stop
;;
off)
off
;;
*)
echo "$0 {start|stop|off}"
echo "Start establishes all filtering rules"
echo "Off disables all filtering!"
echo "Stop disables all non-loopback connections"
;;
esac
iptables -L -n >/var/log/iptables # Document rules in place
echo "$0: Done."
Paul Rogers, paulgrogers@yahoo.com -o)
http://www.angelfire.com/or/paulrogers /\\
Rogers' Second Law: Everything you do communicates. _\_V
... Network Management is like herding cats.
___ MultiMail/MS-DOS v0.35
---
* Origin: The Bare Bones BBS (1:105/360)
|