NetBSD firewall using IP Filter

by Hoang Q. Tran

It is really easy to configure a NetBSD to function as an Internet gateway and filtering packets. This howto will also guide on resource management using ALTQ on NetBSD 1.5 current. The final part will demonstrate how to encrypt a connection between two NetBSD gateways.

Here are the following steps:

Lock down the box

The first step is to disable all running services that are not necessary for a firewall box. Luckily, NetBSD ``out of the box'' is pretty safe. /etc/inetd.conf has all the services disable (commented out with #) but the inetd is running. Disable inetd daemon in /etc/rc.conf.
inetd=NO
If you need to remote logon, use ssh and add sshd=YES to /etc/rc.conf. Also, restrict which host can connect to the firewall box by adding trusted host in /etc/hosts.allow and deny everything else in /etc/hosts.deny.

Now, go to unixcircle.com portscan and self remotely port scan your own box from the outside. If you are behind a NAT/firewall box, the port scan script will scan that box instead. If you have another box, use nmap to scan the box from the inside.

Read the latest NetBSD security patches announcement:

then retrieve and apply them accordingly. or use cvs to synchronize the latest source.

Make sure to check out the 1.5 stable branch with -rnetbsd-1-5. Otherwise, you are checking out the development branch.

For more information on security vulnerabilities, read SANS The Twenty Most Critical Internet Security Vulnerabilities (Updated)

Install second ethernet card in the NetBSD box

Use any supported Ethernet card for the second NIC in the NetBSD machine. One card will be given a public static IP address (assigned by your ISP or obtained dynamically, e.g., with DHCP) and the other will be given an IP address in a non-routable network. Your choices for private network addresses must come from one of these ranges (see RFC 1918):
10.0.0.1 - 10.255.255.254      netmask 255.0.0.0
172.16.0.1 - 172.31.255.254    netmask 255.240.0.0
192.168.0.1 - 192.168.255.254  netmask 255.255.0.0
Assume the first card is ``ep", create /etc/ifconfig.ep0 with the following x.x.x.x netmask x.x.x.x where x.x.x.x is what you choose above.

192.168.1.1 netmask 0xffffff00 media 10baseT # First NIC - private

And if you have a static IP address for the second NIC, you naturally need to have it configured as /etc/ifconfig.ep1 as well.

123.121.8.1 netmask 0xffffff00 media 10baseT # Second NIC with public IP address

Be sure to indicate a correct IP address and netmask for both interfaces. Once you have chosen a private network address range (example above is using 192.168.0.1 range) for your inside machines, stay with that same range. Do not mix network numbers on the inside.

Whatever address you choose for this first NIC in the NetBSD gateway (with the non-routable address) becomes the default gateway IP address for all machines on the inside private network.

Customize the kernel

To compile the new kernel you need the kernel source. If you don't already, retrieve it here ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-1.5.1/source/sets/syssrc.tgz and unpack it as:

# tar xzvf syssrc.tgz -C /usr
( kernel source unpacking output... )
...
Or use AnonCVS to get just the kernel source it:
# setenv CVSROOT anoncvs@anoncvs.netbsd.org:/cvsroot
# cd /usr
# cvs checkout -rnetbsd-1-5 -P src/sys
( checking out files output... )
...
# cd /sys/arch/i386/conf
I usually name the kernel to the machine hostname, but you can give it any name. Edit the kernel config file:
# cp GENERIC firewall
# vi firewall
and make sure these lines are in the kernel file:
options         PFIL_HOOKS      # pfil(9) packet filter hooks
options         IPFILTER_LOG    # ipmon(8) log support
options         IPFILTER_DEFAULT_BLOCK #block all packets by default
Remove any hardware related options that are not relevant to your machine. One way to find out what to keep is to consult the dmesg(8) output and remove all the rest. For all available kernel options, refer to GENERIC in the same directory as your kernel file or man options(4).

Save the kernel configuration file and then compile and install it:

# config firewall
# cd ../compile/firewall
# make depend; make
( kernel building output... )
...
# cp /netbsd /netbsd.GENERIC
# cp netbsd /netbsd
# reboot
This will retain the GENERIC kernel as /netbsd.GENERIC just in case something has gone awry with the new one and the box doesn't boot. If that happens you can type 'netbsd.GENERIC' at the boot: prompt.

Enable packet forwarding, dhcp, firewall and network address translation

To enable packet forwarding by editing /etc/sysctl.conf and add:
net.inet.ip.forwarding=1
To enable high performance data transfers on hosts according to Enabling High Performance Data Transfers, add the following in addition to ip forwarding to /etc/sysctl.conf:
# 1. Enable Path MTU discovery
net.inet.ip.mtudisc=1
# 2. TCP Extension (RFC1323): enabled by default
# 3. Increase TCP Window size to 64K for increase in network performance
net.inet.tcp.recvspace=65535
net.inet.tcp.sendspace=65535
# 4. SACK (RFC2018): enabled by default
And if you get your public address assignment dynamically through DHCP, edit /etc/rc.conf and add:
dhclient=YES
dhclient_flags="ep1"
and edit /etc/dhclient.conf so that the dhcp client can query the dhcp server for appropriate information in order to connect. Example of a /etc/dhclient.conf
send host-name "crxxxxxx-a"; # Put your client IP here
request subnet-mask, broadcast-address, routers, domain-name-servers;
The dhcp server will assign the IP, netmask and default gateway for interface ``ep1''. /etc/resolv.conf will be created with ``search'' and ``nameservers'' statements from the ISP.

Filter rule:

Since you don't know what to block yet, you need to open up ingress and outgress traffic to flow through. Edit /etc/ipf.conf and add:

pass in all
pass out all
An example of a working /etc/ipf.conf

Network Address Translation rule:

For NAT and ftp clients behind NAT to work, add the following minimum mappings to /etc/ipnat.conf:

# Use ipfilter ftp proxy for ftp client transfers mode: active
map ep1 192.168.1.0/24 -> 0.0.0.0/32 proxy port ftp ftp/tcp

# Map all tcp and udp connections from 192.168.1.0/24 to external IP address,
# changing the source port number to something between 40,000 and 60,000 inclusive
map ep1 192.168.1.0/24 -> 0.0.0.0/32 portmap tcp/udp 40000:60000

# For all other IP packets, map to the external IP address
map ep1 192.168.1.0/24 -> 0.0.0.0/32
Make sure all the `proxy' lines are before any generic `portmap' lines, as the first match always wins.

An example of a working /etc/ipnat.conf

This is the minimum requirement on /etc/ipf.conf and /etc/ipnat.conf to get NAT and basic filtering to work.

Now, turn on NAT/firewall feature in /etc/rc.conf:

ipfilter=YES                #Stateful firewall
ipnat=YES                   #Network Address Translation
ipmon=YES                   #Firewall logging
ipmon_flags="-Dsn"

-D: Cause ipmon to turn itself into a daemon.
-n: IP addresses and port numbers will be mapped, where possible, back into hostnames and service names.
-s: Packet information read in will be sent through syslogd rather than saved to a file.

Some other interesting features with IPFilter you might find useful:

1. Transparent proxying

If there's a mail server as 192.168.1.2 inside the private network , use ``rdr'' statement to transparent proxying. Since NAT happens before ``rdr'', a ``pass in'' is required in /etc/ipf.conf for the translated packets to flow into the mail server.

/etc/ipnat.conf:

# Redirect incoming smtp traffic to mail server behind NAT
rdr ep1 0.0.0.0/0 port 25 -> 192.168.1.2 port 25

/etc/ipf.conf:

# Allow the translated packets with fragment and SYN flag to flow in. Keep state the connection.
pass in quick on ep1 proto tcp from any to any port = 25 flags S keep state keep frags
2. Load balancing

To load balancing a farm of 6 web servers behind NAT with address 192.168.1.1-192.168.1.6, use ``round-robin'' statement. IPFilter will distribute the load using round robin method. IPFilter will distribute the load even if one of the web servers is down. l4check which is part of IPFilter and can deal with this scenario.

rdr ep1 0.0.0.0/0 port 80 -> 192.168.1.1,192.168.1.2 port 80 tcp round-robin
rdr ep1 0.0.0.0/0 port 80 -> 192.168.1.3,192.168.1.4 port 80 tcp round-robin
rdr ep1 0.0.0.0/0 port 80 -> 192.168.1.5,192.168.1.6 port 80 tcp round-robin

More examples can be found in: /usr/share/examples/ipf

Log filtering rules to a dedicated log host:

A nice way to backup log messages and rely on if the NAT/firewall is rooted is to use a dedicated log server. Here is how you setup:

1. On the NAT/firewall, send log messages to a dedicated log server called e.g. ``loghost''

Edit /etc/syslog.conf and add:

# Send everyting to a dedicated ``loghost'' server
*.*                                             @loghost

Restart syslogd:
# /etc/rc.d/syslogd fastrestart
2. On the dedicated NetBSD log server

Switch syslogd from non-listening on UDP to listening on UDP by adding the following to /etc/rc.conf:

syslogd=YES             syslogd_flags=""
Restart syslogd:

# /etc/rc.d/syslogd fastrestart
The check out the /var/log files on the loghost for new log entries from the NAT/firewall. Caveat: The communication link between loghost and the firewall is not encrypted and therefore potentially vulnerable to eavedrop. Use IPsec to encrypt the channel.

Configure machines behind NAT

1. All the machines on the private network should be configured to use the address of the private interface of the NetBSD box as the default gateway.

To set the internal boxes to the default NetBSD gateway on various operating systems with IP address: 192.168.1.1

If you don't want to reboot to pick up the IP address for the default gateway, use ``route'' to manually add it.

AIX: route add 0 192.168.1.1

HP-UX: route add 192.168.1.1

FreeBSD,NetBSD,OpenBSD,Solaris: route add default 192.168.1.1

Linux Redhat: route add default gw 192.168.1.1

2. /etc/resolv.conf on unix client hosts need to edit/add to have nameserver statements in order to resolve hostnames.

UNIX clients:

$ cat /etc/resolv.conf
nameserver      <ISP DNS IP>
nameserver      <ISP DNS IP>
Win2k :
Start-Settings->Control Panel->Network and Dial-up Connections->Local Area Network->

       Properties->Internet Protocol (TCP/IP)->->Advanced TCP/IP Settings->DNS
and add the ISP DNS IPs.

Familiarize with IPFilter

Once your NAT/firewall is online, you should start to read the IPFilter How-To and add more blocking/passing rules to /etc/ipf.conf. Some other useful links can be found on the www.ipfilter.org home page.

Each time /etc/ipf.conf or /etc/ipnat.conf is modified, you have to them as follow. Reloading these rules will flush all current active connections.

# /etc/rc.d/ipfilter reload
# /etc/rc.d/ipnat reload
ipfstat display as top output:

You can use ipfstat to display firewall statistics a la ``top" command:

/usr/sbin/ipfstat -t and you will see something similar:

                     IP Filter: v3.4.16 - state top                     20:23:29
Src = 0.0.0.0  Dest = 0.0.0.0  Proto = any  Sorted by = # bytes

Source IP             Destination IP         ST   PR   #pkts    #bytes       ttl
192.168.1.200,1415    65.92.100.89,6699     4/4  tcp    8245   6923504  42:14:06
23.234.234.2,24064    208.31.160.30,22      4/4  tcp     576    199843 119:59:59
192.168.1.200,2091    64.124.41.191,8888    4/4  tcp     157    118770  51:36:40
192.168.1.200,1094    64.124.41.161,8888    4/4  tcp     125     94190  46:37:34

Some popular ipfilter commands you might want to use. man ipf(8), ipnat(8) and ipmon(8) and ipfstat(8) for details.

To find out the ipfilter version:

# ipf -V
ipf: IP Filter: v3.4.16 (264)
Kernel: IP Filter: v3.4.16
Running: yes
Log Flags: 0 = none set
Default: block all, Logging: available
Active list: 0

Notice the ``block all" setting from our options IPFILTER_DEFAULT_BLOCK in the kernel.

To display the current list of active MAP/Redirect filters and active sessions:

# /usr/sbin/ipnat -l
To find out the ``hit" statistic for each individual rule in /etc/ipf.conf:
# /usr/sbin/ipfstat -hio
Watch port scans going by on the screen:

Sit back and watch for sunrpc port scans. There will be lots of them. Notice the letter ``b'' below. It means block.

Aug 22 18:57:06 firewall ipmon[105]: 18:57:05.841491  ep1 @0:20 b script.kiddie.com,1876 -> \
my.lovely.fw,sunrpc PR tcp len 20 60 -S IN
Aug 22 19:59:52 firewall ipmon[105]: 19:59:51.509996  ep1 @0:20 b script.kiddie.com,2858 -> \
my.lovely.fw,sunrpc PR tcp len 20 60 -S IN

Test the firewall

To test firewall, the following links are useful: Some useful tools to test firewall:

Upgrading IPFilter

Upgrading from a old version of IPFilter that comes with the NetBSD base system to the latest IPFilter requires two steps.

Before upgrade:

# ipf -V
ipf: IP Filter: v3.4.9 (264)
Kernel: IP Filter: v3.4.9
Running: no
Log Flags: 0 = none set
Default: pass all, Logging: available
Active list: 0
Download the latest IPFilter:
# ftp ftp://coombs.anu.edu.au
ftp> cd pub/net/ip-filter
ftp> bin
ftp> get ip-fil3.4.20.tar.gz
ftp> bye
# tar xzvf ip-fil3.4.20.tar.gz -C /tmp
First step is to upgrade IPFilter kernel sources and binaries:
# cd /tmp/ip_fil3.4.20
# ./BSD/kupgrade
Make sure Makefile has entries for ipfstat -t `top' like output:
STATETOP_CFLAGS=-DSTATETOP
STATETOP_INC=-I/usr/include
STATETOP_LIB=-L/usr/lib -lcurses

# ln -s /usr/include/curses.h /usr/include/ncurses.h
# make netbsd
# make install-bsd
Second step is to upgrade the kernel:
# cd /sys/arch/i386/conf
# config firewall
# cd ../compile/firewall
# make depend; make
# mv /netbsd /netbsd.old
# mv netbsd /netbsd
# reboot
After upgrade:
# ipf -V
ipf: IP Filter: v3.4.20 (264)
Kernel: IP Filter: v3.4.20
Running: yes
Log Flags: 0 = none set
Default: block all, Logging: available
Active list: 0

QoS

Bandwidth limiting:

NetBSD 1.5 current has ALTQ integrated in the base system. Otherwise, download the latest KAME snap kit which has ALTQ bundled.

ALTQ is a QoS software with rate limiting feature. To use rate limiting feature, you need to recompile the kernel with:

options         ALTQ
boot the new kernel with ALTQ, grab the latest MAKEDEV.altq from: and put it in /dev. Next, edit MAKEDEV.altq and change the major device for NetBSD i386 from 75 to 77. Finally, turn on the executable bit and populate the ALTQ devices as /dev/MAKEDEV.altq all which will create altq devices in /dev/altq. Now, to configure a token bucket regulator (tbrconfig) for the interface ep1 to rate limit the pipe from 100Mbps to 10Mbps:
# tbrconfig ep1 10M auto
ep1: tokenrate 10.00M(bps)  bucketsize 12.21K(bytes)
#
To remove the installed token bucket regulator on ep1:

# tbrconfig -d ep1
deleted token bucket regulator on ep1
#
Class-based queuing (CBQ)

CBQ achieves both partitioning and sharing of link bandwidth by hierarchically structured classes. Each class has its own queue and is assigned its share of bandwidth. A child class can borrow bandwidth from its parent class as long as excess bandwidth is available.

In addition to options ALTQ, you will need:

options         ALTQ_CQB
options         ALTQ_RED
and recompile the kernel and reboot. Here is an example of a working /etc/altq.conf. /etc/altq.conf is read by altqd so to enable it on startup, edit /etc/rc.conf and add: # ALTQ configuration/monitoring daemon altqd=YES Or just manually start altqd. altqd won't start if there are errors in /etc/altq.conf. Watch /var/log/messages for any information.

Here's the class hierarchy: cbq.txt

#
# ep1: Interface to a 10M link
#
#
interface ep1 bandwidth 10M cbq
class cbq ep1 root NULL pbandwidth 100
#
# meta classes
#
class cbq ep1 ctl_class root pbandwidth 4 control
class cbq ep1 def_class root borrow pbandwidth 95 default
#
# Allocate bandwidth for:
# firstclass: 70%
# businessclass: 15%
# generalclass: 5%
#
class cbq ep1 firstclass def_class borrow pbandwidth 70
class cbq ep1 businessclass def_class borrow pbandwidth 15
class cbq ep1 generalclass def_class borrow pbandwidth 5
#
# Allocate bandwidth for firstclass (tcp) data classes:
# tcp: 28%
# smtp: 10%
# http: 30%
# dns: 2%
#
class cbq ep1 tcp firstclass borrow pbandwidth 28 red
    filter ep1 tcp 0 0 0 0 6    # other tcp
class cbq ep1 smtp firstclass borrow pbandwidth 10 red
    filter ep1 smtp 0 0 0 25 6  # smtp
    filter ep1 smtp 0 25 0 0 6  # smtp
class cbq ep1 http firstclass borrow pbandwidth 30 red
    filter ep1 http 0 0 0 80 6  # http
    filter ep1 http 0 80 0 0 6  # http
class cbq ep1 dns firstclass borrow pbandwidth 2 red
    filter ep1 dns 0 0 0 53 6   # dns
    filter ep1 dns 0 53 0 0 6   # dns

#
# Allocate bandwidth for businessclass (udp) classes:
# udp: 10%
# dns: 5%
#
class cbq ep1 udp businessclass borrow pbandwidth 10 red
    filter ep1 udp 0 0 0 0 17   # udp
class cbq ep1 dns businessclass borrow pbandwidth 5 red
    filter ep1 dns 0 0 0 53 17  # dns
    filter ep1 dns 0 53 0 0 17  # dns
#
# Allocate bandwidth for generalclass (icmp) classe:
# icmp: 5%
#
class cbq ep1 icmp generalclass borrow pbandwidth 5 red
    filter ep1 icmp 0 0 0 0 1   # icmp

IPsec

NetBSD gateway to NetBSD gateway encryption:

Recompile the kernel and add:

options         IPSEC           # IP security
options         IPSEC_ESP       # IP security (encryption part; define w/IPSEC)

A. Encryption using transport mode with manual keys:

Add the following to /etc/ipsec.conf to gateway A:

#!/bin/sh
#
# Gateway A: 192.168.1.1
# Gateway B: 192.168.1.2
#
# From A to B using:
#  Security Parameter Index (SPI): 9876
#  Algorithm: 3des-cbc
#  Secret key: hogehogehogehogehogehoge
# From B to A using:
#  Security Parameter Index (SPI): 10000
#  Algorithm: 3des-cbc
#  Secret key:0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef
#
setkey -c <<EOF
add 192.168.1.1 192.168.1.2 esp 9876 -E 3des-cbc "hogehogehogehogehogehoge";
add 192.168.1.2 192.168.1.1 esp 10000 -E 3des-cbc 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef;
spdadd 192.168.1.1 192.168.1.2 any -P out ipsec esp/transport//require;
EOF

Add the following to /etc/ipsec.conf to gateway B:

#!/bin/sh
#
# Gateway A: 192.168.1.1
# Gateway B: 192.168.1.2
#
# From A to B using:
#  Security Parameter Index (SPI): 9876
#  Algorithm: 3des-cbc
#  Secret key: hogehogehogehogehogehoge
# From B to A using:
#  Security Parameter Index (SPI): 10000
#  Algorithm: 3des-cbc
#  Secret key:0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef
#
setkey -c <<EOF
add 192.168.1.1 192.168.1.2 esp 9876 -E 3des-cbc "hogehogehogehogehogehoge";
add 192.168.1.2 192.168.1.1 esp 10000 -E 3des-cbc 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef;
spdadd 192.168.1.2 192.168.1.1 any -P out ipsec esp/transport//require;
EOF
NOTE:

With require key word on spdadd, only encrypted packets will flow through gateway A and B. To permit encrypted and unencrypted packets to flow through, substitute require with use.

Gateway A and B has the same ``add'' lines except for ``spdadd'' where the gateway IP on each node precedes the IP of the other gateway.

For 3des-cbc encryption, the key length must be 192 bits or 24 bytes. setkey(8) will complain if key length is shorter for longers than 24 bytes.

Finally, above shared secret keys are example only. Change it and don't let anyone know about it for real use.

Allow ``esp'' packets to flow between gateways with the following rules:


pass in quick on ep1 proto esp from any to any
pass out quick on ep1 proto esp from any to any

To enable encryption using transport mode on startup, add to /etc/rc.conf:

ipsec=YES

Now, the fun part is to test them out:

To load the ipsec(4) policy (/etc/ipsec.conf):


# /etc/rc.d/ipsec start

Test it out:

tcpdump on gateway A: tcpdump -i ep1 src host 192.168.1.1 and dst host 192.168.1.2
ping gateway A from gateway B: ping 192.168.1.1

Observe tcpdump output on gateway A:

tcpdump: listening on ep1
15:56:59.776017 192.168.1.1 > 192.168.1.2: ESP(spi=0x00002694,seq=0x3a)
15:57:00.787512 192.168.1.1 > 192.168.1.2: ESP(spi=0x00002694,seq=0x3c)
...

>From the tcpdump output, nobody can wiretap the connection between both gateways since they're encrypted.

To unload the IPsec policy from the kernel:

# /etc/rc.d/ipsec stop (basically does setkey -FP)
To dump the Security Association Database (SAD): # setkey -D
To dump the Security Policy Database (SPD): # setkey -P
To flush the SAD and SPD: # setkey -FP

B. Encryption using transport mode with IKE (ISAKMP/Oakley) key management daemon:

NetBSD 1.5 current has racoon IKE integrated in the base system. Otherwise, build it from the package source:

# cd /usr/pkgsrc/security/racoon
# make install clean

Define IPsec policy settings in the kernel:

Gateway A:

Add to /etc/ipsec.conf:

#!/bin/sh
setkey -c <<EOF
spdadd 192.168.1.1 192.168.1.2 any -P out ipsec esp/transport//require;
spdadd 192.168.1.2 192.168.1.1 any -P in ipsec esp/transport//require;
EOF
To load the IPsec policy: # /etc/rc.d/ipsec start

Gateway B:

Add to /etc/ipsec.conf:

#!/bin/sh
setkey -c <<EOF
spdadd 192.168.1.2 192.168.1.1 any -P out ipsec esp/transport//require;
spdadd 192.168.1.1 192.168.1.2 any -P in ipsec esp/transport//require;
EOF
To load the IPsec policy: # /etc/rc.d/ipsec start

Define a pre shared secret key for gateway A and B.

Gateway A:

# cd /etc/racoon
# cat psk.txt
192.168.1.2    secretkeysecretkeysecretkey

Change the shared secret key to r/w only for root since it should be secret and nobody can view it beside root.

# chmod 600 psk.txt

Gateway B:

# cd /etc/racoon
# cat psk.txt
192.168.1.1    secretkeysecretkeysecretkey
# chmod 600 psk.txt
Configure the IKE racoon daemon:

Both gateways should have similar IKE racoon configuration file to ease debugging.

# vi /etc/racoon/racoon.conf

#
# General section
#
path include "/etc/racoon";
path pre_shared_key "/etc/racoon/psk.txt";
log notify;

remote anonymous
{
        exchange_mode aggressive;
        lifetime time 24 hour;

        #
        # Phase 1 for ISAKMP security association
        #
        proposal {
                encryption_algorithm 3des;
                hash_algorithm sha1;
                authentication_method pre_shared_key;
                dh_group 2;
        }

        proposal_check obey;
}

#
# Phase 2 for IPsec security association
#
sainfo anonymous
{
        pfs_group 2;
        lifetime time 12 hour;
        encryption_algorithm 3des, cast128, blowfish, des, rijndael;
        authentication_algorithm hmac_sha1, hmac_md5;
        compression_algorithm deflate;
}
Start the IKE racoon to automatically exchange secret key:
# racoon -f /etc/racoon/racoon.conf -l /var/log/racoon.log
racoon will launch and output to /var/log/racoon.log.

Test it out:

tcpdump on gateway A: tcpdump -i ep1 src host 192.168.1.1 and dst host 192.168.1.2
ping gateway A from gateway B: ping 192.168.1.1

Observe tcpdump output on gateway A:

tcpdump: listening on ep1
15:56:59.776017 192.168.1.1 > 192.168.1.2: ESP(spi=0x00002694,seq=0x3a)
15:57:00.787512 192.168.1.1 > 192.168.1.2: ESP(spi=0x00002694,seq=0x3c)
...
Look in gateway A's /var/log/racoon.log for a hint that the security association is established:
2001-09-03 21:09:55: INFO: pfkey.c:1141:pk_recvupdate(): IPsec-SA established: ESP/Transport \
 192.168.1.2->192.168.1.1 spi=192065112(0xb72ae58)
Then dump the SAD entries on the gateway A and the output should look similar to:
# setkey -D
192.168.1.1 192.168.1.2
        esp mode=transport spi=76069675(0x0488bb2b) reqid=0(0x00000000)
        E: 3des-cbc  30aa82e3 5e361845 a0627c70 c35b2a37 e1ad54dc 50d8b32d
        A: hmac-sha1  3c0f63ec 2bda1c60 320dd03f 74549e13 1db6ec47
        replay=4 flags=0x00000000 state=mature seq=1 pid=216
        created: Sep  3 21:09:43 2001   current: Sep  3 21:09:51 2001
        diff: 8(s)      hard: 43200(s)  soft: 34560(s)
        last: Sep  3 21:09:50 2001      hard: 0(s)      soft: 0(s)
        current: 360(bytes)     hard: 0(bytes)  soft: 0(bytes)
        allocated: 3    hard: 0 soft: 0
        refcnt=2
192.168.1.2 192.168.1.1
        esp mode=transport spi=175635702(0x0a77fcf6) reqid=0(0x00000000)
        E: 3des-cbc  52aabdc3 c576b547 89def17a e735ea90 c0649c40 1f4d7457
        A: hmac-sha1  77f597e2 c5b6b760 1a52f679 a301483f f753547f
        replay=4 flags=0x00000000 state=mature seq=0 pid=216
        created: Sep  3 21:09:43 2001   current: Sep  3 21:09:51 2001
        diff: 8(s)      hard: 43200(s)  soft: 34560(s)
        last: Sep  3 21:09:50 2001      hard: 0(s)      soft: 0(s)
        current: 252(bytes)     hard: 0(bytes)  soft: 0(bytes)
        allocated: 3    hard: 0 soft: 0
        refcnt=1

Then you know that gateway A and B are communicating over an encryption channel using IKE racoon work.

To enable IKE racoon daemon on startup, add to /etc/rc.conf:

racoon=YES
Update IPFilter rule to permit IKE traffics:

Since IKE uses udp and listens on port 500, add the following to /etc/ipf.conf rule to let packets flow between gateways:

pass in on ep1 proto udp from any to any port = 500 keep state keep frags
pass out on ep1 proto udp from any to any port = 500 keep state keep frags

Reference

IPFilter home page:
   http://www.ipfilter.org
IPFilter examples:
   http://coombs.anu.edu.au/~avalon/examples.html
IPFilter how-to:
   http://www.unixcircle.com/ipf/
IPFilter mailing list archive:
   http://false.net/ipfilter
Guido van Rooij has written some real nice IPFilter papers:
   http://www.madison-gurkha.com/all_publications.shtml
Address Allocation for Private Internets:
   http://www.muine.org/rfc/rfc1918.txt
The IP Network Address Translator (NAT):
   http://www.muine.org/rfc/rfc1631.txt
Traditional IP Network Address Translator (Traditional NAT)
   http://www.muine.org/rfc/rfc3022.txt
NetBSD IPsec FAQ:
   http://www.netbsd.org/Documentation/network/ipsec/
Simple Configuration Sample of IPsec/Racoon
   http://www.kame.net/newsletter/20001119/
The ISAKMP/Oakley key management protocol
   http://www.muine.org/rfc/rfc2407.txt
   http://www.muine.org/rfc/rfc2408.txt
   http://www.muine.org/rfc/rfc2409.txt
The PKIX certificate with racoon
   http://www.kame.net/newsletter/20001119b/
The Twenty Most Critical Internet Security Vulnerabilities (Updated)
   http://www.sans.org/top20/


last update: Oct 20, 2003