FreeBSD IPFW rules for honeypot

I promised a month ago (!) to put up the firewall rules I'd come up with for FreeBSD; here we are at last. With any luck this'll be useful for someone.

By way of background, I had the honeypot, a default server install of Redhat 6.2, sitting behind my main box running FreeBSD; the FreeBSD box had one external card (cable internet), one internal card for my LAN (yes, I was using my LAN while this was all going on...) and one internal card dedicated to the honeypot.

This is a fairly restrictive ruleset, but I didn't want to fuck up and risk letting Bad Packets (tm) out. As related earlier, I had to shut it all down about five minutes after I got cracked anyhow, so it was a moot point.

Oh, almost forgot: the funky part is not just the firewall rules below, but running the natd daemon w/the right options:

natd -t 10.0.1.1 -interface xl0

From man natd:

-t | -target_address address
Set the target address. When an incoming packet not associated
with any pre-existing link arrives at the host machine, it will be
sent to the specified address.

That made it a great deal easier to pass traffic initiated from the outside to the honepot. I'm sure there's a way to do this in Linux, but it's been long enough since I worked w/Linux firewall rules that I wouldn't know what that is.

Anyhow, w/o further ado:

#!/bin/sh

IPFW="/sbin/ipfw"
PRIVATE_LAN="10.0.0.0/24"
HONEYPOT_LAN="10.0.1.0/24"
HONEYPOT="10.0.1.1"
EXTERNAL_NIC="xl0"
INTERNAL_NIC="ep0"
HONEYPOT_NIC="ep2"
MY_HONEYPOT_IP="10.0.2.2"
PUBLIC_IP=`ifconfig $EXTERNAL_NIC | awk '/inet / {print $2}'`

$IPFW -f flush

$IPFW add 100 pass all from any to any via lo0
$IPFW add 200 deny all from any to 127.0.0.0/8
$IPFW add 300 deny ip from 127.0.0.0/8 to any

$IPFW add divert natd all from any to any via $EXTERNAL_NIC

$IPFW add check-state

$IPFW add skipto 40000 all from any to any via $INTERNAL_NIC

# Honeypot rules...be very careful!

# Logging.
$IPFW add allow log udp from $HONEYPOT to $MY_HONEYPOT_IP syslog
via $HONEYPOT_NIC

# Allow in from outside world. Remember, natd will be passing
  these
# packets on. Keep traffic from own network out.

$IPFW add allow log tcp from not $PRIVATE_LAN to $HONEYPOT via
$HONEYPOT_NIC
$IPFW add allow log tcp from not $PRIVATE_LAN to $HONEYPOT via
$HONEYPOT_NIC
$IPFW add allow log udp from not $PRIVATE_LAN to $HONEYPOT via
$HONEYPOT_NIC keep-state
$IPFW add allow icmp from not $PRIVATE_LAN to $HONEYPOT icmptypes
0,3,8,11,12,13,14 out via $HONEYPOT_NIC keep-state

# Allow replies from ftp, ssh, pop and web...put in mainly for ftp
  replies. NO SMTP!
$IPFW add allow log tcp from $HONEYPOT 20,21,22,110,80 to not
  $PRIVATE_LAN via $HONEYPOT_NIC

# Do we need this?

$IPFW add allow log tcp from any to $HONEYPOT in via $EXTERNAL_NIC
$IPFW add allow log udp from any to $HONEYPOT in via $EXTERNAL_NIC
$IPFW add allow log icmp from any to $HONEYPOT icmptypes
0,3,8,11,12,13,14 in via $EXTERNAL_NIC

# What we allow out: established, mail, ftp, web, domain, selected
  ICMP.

$IPFW add allow log tcp from $HONEYPOT to not $PRIVATE_LAN
established via $HONEYPOT_NIC
$IPFW add allow log tcp from $HONEYPOT to not $PRIVATE_LAN
20,21,22,25,80,110 via $HONEYPOT_NIC
$IPFW add allow log tcp from $HONEYPOT 20,21,22,110,80 to not
$PRIVATE_LAN via $HONEYPOT_NIC
$IPFW add allow log udp from $HONEYPOT to not $PRIVATE_LAN domain
via $HONEYPOT_NIC keep-state
$IPFW add allow log icmp from $HONEYPOT to not $PRIVATE_LAN
icmptypes 0,3,8,11,12,13,14 via $HONEYPOT_NIC

# Deny the rest

$IPFW add deny log all from $HONEYPOT to any

# Should this be in or via?

$IPFW add deny log all from any to any in recv $HONEYPOT_NIC
$IPFW add deny log all from any to any via $HONEYPOT_NIC

#add allow udp from any to any keep-state
$IPFW add 40000 allow udp from $PRIVATE_LAN to any keep-state
$IPFW add 40100 allow udp from $PUBLIC_IP to any keep-state

$IPFW add 40200 allow tcp from any to any established

$IPFW add 40300 allow tcp from any to $PUBLIC_IP 22,8000

$IPFW add 40400 allow all from any to any out via $EXTERNAL_NIC
$IPFW add 40500 allow all from any to any in via $INTERNAL_NIC
$IPFW add 40600 allow all from any to any out via $INTERNAL_NIC

#add allow all from any to ${PUBLIC_IP} 22, 8000 via ep0
$IPFW add 40700 allow all from localhost to 25 via lo0

$IPFW add 40700 allow icmp from any to any icmptypes 0,3,8,11,12,13,14

$IPFW add 40900 deny log all from any to any

Original entry.