3/24/2005
Eric Low
Download:
bridge-utils from http://bridge.sourceforge.net
iptables from http://www.netfilter.org
ebtables from http://ebtables.sourceforge.net/
First, install iptables:
cd /programs/iptables-1.3.1
make KERNEL_DIR=/usr/src/linux-2.6.11.5 BINDIR=/usr/bin LIBDIR=/usr/lib
MANDIR=/usr/share/man
make KERNEL_DIR=/usr/src/linux-2.6.11.5 BINDIR=/usr/bin LIBDIR=/usr/lib
MANDIR=/usr/share/man install |
Next, install ebtables:
make install KERNEL_INCLUDES=/usr/src/linux-2.6.11.5/include BINDIR=/usr/bin
MANDIR=/usr/share/man |
Next, install bridge-utils:
./configure --bindir=/usr/bin --libdir=/usr/lib --mandir=/usr/share/man
make install
|
copy bridge script to /etc/rc.d/init.d directory.
copy firewall script to /usr/bin directory.
Add the following lines to /etc/rc.d/rc.local:
# ---- Disable Source Routing
for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do
echo 0 > $f
done
# ---- Enable IP forwarding
echo 1 >/proc/sys/net/ipv4/ip_forward
#IP forwarding does NOT need to be enabled in our current
#bridging configuration.
# ---- Disable Explicit Congestion Notification
if [ -e /proc/sys/net/ipv4/tcp_ecn ]; then
echo 0 >/proc/sys/net/ipv4/tcp_ecn
fi
# ---- Always defrag incoming packets
#echo 1 >/proc/sys/net/ipv4/ip_always_defrag
# ---- Tell kernel to drop spoofed packets
for f in /proc/sys/net/ipv4/conf/*; do
echo 1 >$f/rp_filter
done
# ---- Enable bad error message protection
echo 1 >/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
# ---- Kill timestamps
echo 0 >/proc/sys/net/ipv4/tcp_timestamps
# ---- Enable SYN cookies (helps protect against DoS attacks)
echo 1 >/proc/sys/net/ipv4/tcp_syncookies
# -------------- Shut off system beep --------------------
echo -e "\033[11;0]"
|
Create ebtables rules in the file /etc/sysconfig/ebtables,
in the following format:
#Important: eth0 is the internal interface, and eth1 is the
# external interface. eth2 is DMZ. Our network is 198.173.192.0/24,
# and our gateway is 198.173.192.254.
-F
-t nat -F
#Flush all chains.
#-c y
#-t nat -c y
#Turn on counters (this option may not exist any longer?)
-t broute -P BROUTING ACCEPT
-t nat -P PREROUTING ACCEPT
-t nat -P OUTPUT ACCEPT
-t nat -P POSTROUTING ACCEPT
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
#Set default actions on all chains.
-A FORWARD -p IPV4 -j ACCEPT
-A FORWARD -p ARP -j ACCEPT
-A OUTPUT -p IPV4 -j ACCEPT
-A OUTPUT -p ARP -j ACCEPT
#Allow normal IP traffic through. Everything else is blocked,
# including IPX/SPX.
-A INPUT -p IPV4 -j ACCEPT
#IP traffic must be allowed through the INPUT chain, then CHECKED
BY
#IPTABLES, so as not to show a 'blackhole' on any portscans.
#Note that ARP is not allowed through.
-A INPUT -p ARP -d FF:FF:FF:FF:FF:FF -j ACCEPT
#Allow ARP broadcasts (needed if you want to access firewall from
remotely).
|
Create iptables rules in the file /etc/sysconfig/iptables,
in the following format:
#Important: eth0 is the internal interface, and eth1 is the
# external interface. eth2 is DMZ. Our network is 198.173.192.0/24,
# and our gateway is 198.173.192.254.
-F
#Flush all chains before we do anything else.
-t nat -P PREROUTING ACCEPT
-t nat -P POSTROUTING ACCEPT
-t nat -P OUTPUT ACCEPT
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
-t mangle -P PREROUTING ACCEPT
-t mangle -P POSTROUTING ACCEPT
-t mangle -P INPUT ACCEPT
-t mangle -P FORWARD ACCEPT
-t mangle -P OUTPUT ACCEPT
#Drop all rules by default (unless specifically allowed).
#The FORWARD and INPUT chains are really the only ones we need
to worry about.
-A FORWARD -i eth1 -p tcp --dport 135 -j DROP
-A FORWARD -o eth1 -p tcp -s 198.173.192.59 --dport 135 -j MIRROR
-A FORWARD -o eth1 -p tcp -s 198.173.192.84 --dport 135 -j MIRROR
-A FORWARD -o eth1 -p tcp --dport 135 -j LOG --log-level 0
-A FORWARD -i eth1 -p tcp --dport 139 -j DROP
#Block W32.Blaster virus immediately.
-A INPUT -m unclean -j DROP
-A FORWARD -m unclean -j DROP
#Kill any abnormal packets, including packets that are too short
to have
#a full ICMP/UDP/TCP header, TCP/UDP packets with no source or
#destination ports, illegal combination of TCP flags, either zero
length
#or too long TCP options or options that occur after the END-OF-OPTIONS
#portion, fragments of an illegal length or offset (such as used
in the
#Ping of Death).
-A INPUT -m state --state INVALID -j DROP
-A FORWARD -m state --state INVALID -j DROP
#Also, kill packets with an illegal combination of flags.
-A INPUT -m state --state ESTABLISHED,RELATED -d 198.173.192.7
-j ACCEPT
-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
#Allow packets that are part of an already established connection.
#The input chain should only allow established connections from
#inside our own network.
-A INPUT -p tcp --dport 113 -m state --state NEW -j LOG --log-level
0
#Log NMAP connections. These appear to be port 113.
-A INPUT -i lo -j ACCEPT
#Allow packets from loopback
-A INPUT -d 127.0.0.0/8 -j REJECT
#But do not allow connections to the local interface from external.
-A FORWARD -i eth0 -o eth1 -p udp -s 0.0.0.0/32 --sport 68 -d
255.255.255.255/32 --dport 67 -m state --state NEW,ESTABLISHED
-j ACCEPT
#Let DHCP requests come from internal (client port=68,server port=67).
-A FORWARD -p udp --dport 137:138 -j REJECT
-A FORWARD -p tcp --dport 139 -j REJECT
-A INPUT -p udp --dport 137:138 -j REJECT
-A INPUT -p tcp --dport 139 -j REJECT
#Block NETBIOS (both directions). Don't let people use the windows
#NET command against our network.
-A FORWARD -p udp --dport 520 -j DROP
#Block RIP.
-A FORWARD -p ospf -j DROP
#Block OSPF (another routing protocol).
-A FORWARD -i eth1 -p tcp --dport 3372 -j DROP
#Drop packets destined for Microsoft MSDTC (installed on W2k or
SQL).
-A FORWARD -i eth1 -s 198.173.192.254/32 -j ACCEPT
#Let the gateway come through (this should be the only internal
address
#coming in through the external interface).
-A FORWARD -i eth0 -s 198.173.192.254 -j DROP
-A FORWARD -i eth2 -s 198.173.192.254 -j DROP
#Do not allow any packets from internal or DMZ claiming to be
gateway.
-A FORWARD -i eth1 -s 198.173.192.0/24 -j DROP
#Drop any packets from external claiming to be from an internal
address
-A FORWARD -i eth0 -o eth1 -p tcp --dport 21:23 -j ACCEPT
#Allow FTP (21), Telnet (23), and SSH (22) from internal to external.
|
All of the above rules are recommended as a bare minimum ruleset. I
keep an extremely conservative ruleset, allowing almost
nothing inbound, and only specific ports outbound.
My iptables ruleset is currently 760 lines long. And for the record,
I've never, ever, ever noticed it running slow, even when that was on
an 800MHz Athlon under a 2.4 kernel.
=================================
Next, I wanted to do SNAT, and
therefore needed a DHCP server installed. DHCP is pretty
fucking easy.
=================================
Next, I wanted to implement fair
queueing. We currently have our main network and two DMZ's.
DMZ 1 has all of our web servers in it, and since we do web surveys,
it is very important that this particular zone has a guaranteed bandwidth
and has top priority. DMZ 2 is the IT department, and for various
reasons, we also need a guaranteed bandwidth, albeit small.
First, I enabled the following options in the kernel, under Device
Drivers -> Networking -> Networking Options:
QoS and/or fair queueing
-- CBQ packet scheduler
-- HTB packet scheduler
-- SFQ queue
-- Packet classifier API
-- -- TC index classifier
-- -- Firewall based classifier
-- -- U32 classifier
-- -- -- Use nfmark as a key in U32 classifier |
The base of my fair queueing would be the Heirarchical Token Bucket
queueing discipline, perhaps with a Stochastic Fairness Queue underneath.
Here's what my tc commands look like to shape my traffic how
I want it:
tc qdisc add dev eth0 root handle 1:0 htb default 1
tc class add dev eth0 parent 1:0 classid 1:1 htb rate 1400kbit
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 256kbit
ceil 1080kbit prio 10
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 256kbit
ceil 1080kbit prio 5
tc class add dev eth0 parent 1:1 classid 1:13 htb rate 64kbit
ceil 888kbit prio 10
tc qdisc add dev eth0 parent 1:11 handle 11:0 sfq perturb 10
tc qdisc add dev eth0 parent 1:13 handle 13:0 sfq perturb 10
tc class add dev eth0 parent 1:12 classid 1:131 htb rate 128kbit
ceil 1080kbit prio 2
tc class add dev eth0 parent 1:12 classid 1:139 htb rate 32kbit
ceil 128kbit prio 10
tc filter add dev eth0 protocol ip parent 1:12 prio 2 u32 match
ip dport 443 0xffff flowid 1:131
tc filter add dev eth0 protocol ip parent 1:12 prio 3 u32 match
ip dport 80 0xffff flowid 1:131
tc filter add dev eth0 protocol ip parent 1:12 prio 10 u32 match
ip dport 25 0xffff flowid 1:139
|
Now if you have a netfilter bridge running on your machine, tc
will not see packets on the actual physical interface. To get
around this, I simply marked all of my packets going out of my external
physical interface, eth0, with iptables using the CLASSIFY
target in the mangle table's POSTROUTING chain. Here is the one simple
rule I added, right up at the top of my rule list:
iptables -t mangle -A POSTROUTING -m physdev --physdev-out eth0
-j CLASSIFY --set-class 1:0 |
To see what that qdisc is looking like, as far as packets go, type tc
-s -d qdisc dev eth0.
|