Checkpoint VPN FW4.1
Firewall FW4.1
This guide will walk you through setting up your freebsd machine and debian machine on
site-to-site vpn through IPSec. This document is not for the faint of heart.
Below is my hypothetical network which we will use throughout the document.
192.168.0.122 192.168.0.115
/ \
CPfw-1 / \ IPfilter
on Debian 2.2 / \ on FreeBSD 4.5
0.12 +--+ / \ +--+ 0.100
+--+ | | / /-----\ \ | | +--+
| | 0.1| |/ /// \\\ \| |0.1 | |
+--+ +---+ +-------+ internet +-------+ +---+ +--+
---+-- | | | \\\ /// | | | ---+--
+--------+ | +--+ \-----/ +--+ | +-----+
| | | |
++-+--+ +--+-++
+-----+ +-----+
172.17.x.x/16 172.16.x.x/16
CPfw-1 Protected Net IPF Protected Net
Mission
Our goal here is to setup two different firewalls and let them talk together using standard encryption
protocol and that is IPSec. We also need to implement a policy so that CPFW-1's protected
network (172.17.0.0/16) will be able to established communication with IPF's protected network (172.16.0.0/16).
Let's Get Started
Here are the things you need for your own test lab.
1.) I used 2 intel machines for the 2 firewalls
2.) Each of those 2 machines are equiped with 256mb ram
3.) 4pcs. network interface cards (I used 3c905x on Debian and Intel Pro on Freebsd)
4.) 6pcs. straight UTP cables and 2 hubs (you can use cross-over cable to minimize number of hubs)
5.) And another 2 workstations that you will use for your testing (those 2 will be in the protected networks)
Building your FreeBSD machine
You can grab an ISO from ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/ISO-IMAGES/4.5 and burn that iso image
to a cd. Burning of ISO images is beyond the scope of this document. Or you can just buy FreeBSD software
from http://www.freebsdmall.com
Once you've installed your FreeBSD boxen, I highly recommended rebuilding the kernel and updating your ports
collection. Rebuilding the kernel allows you to explicitly specify the hardware that only exists on your puter.
You ask, what does that mean? That means, we will be freeing up resources that aren't needed.
Here is how you will rebuild your kernel. You must be root! You must also have an internet connection.
1. update your /usr/src. This is done by editing /usr/share/examples/cvsup/stable-supfile and using this file with cvsup.
Normally, you would only edit the CHANGE_THIS string. I always use cvsup14.freebsd.org.
---snipped from stable-supfile---
*default host=CHANGE_THIS.FreeBSD.org
mine is *default host=cvsup14.FreeBSD.org
Now, start the cvsup
# cvsup -g -L2 /usr/share/examples/cvsup/stable-supfile
You will see a lot of scrolling text. Don't worry, it's normal. It means that you were able to successfully
login to the cvs server and it started retrieving files. If not, yell at your firewall admin and tell him to
open up port 5999/tcp.
2. create your own KERNEL file. An example is GENERIC which you can find in /usr/src/sys/i386/conf directory.
I created one and named it as TUNED.
Note: The ident attribute inside TUNED file should correspond to the filename used.
3. Now it's time to rebuild your kernel. You can find my other document on rebuilding the kernel on this link.
It's kinda old but still applicable.
4. I also recommend that you upgrade your /stand/sysinstall after the mergemaster command given on the link
in step 3. Refer to http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/makeworld.html, item 19.4.12.
NOTE: The file TUNED which I created contains IPSEC support.
Just in case you don't want to take a look at that file, here is what you'll add on your kernel file:
options IPSEC
options IPSEC_ESP
options IPSEC_DEBUG
Building your Debian machine
Installation of Debian is straight forward. I downloaded the Debian ISO image from http://www.linuxiso.org and the
version is 2.2r5. I got a problem and that is, Debian didn't detect my lan cards.
I was really shocked because the lan card that was not detected was 3com 3C905 TX.
So again, I had to rebuild my kernel to add support for that lan card. It's actually my first time touching Debian.
Since Debian is also linux anyway, I tried the old way of recompiling the kernel.
Along the rebuild, I had some errors like, curses.h was not found so I had to install libncurses. And also
during the make, as86 was not found. as86 is included with the bin86 package so install this one also.
To cut it short, the rebuilding of the kernel was successful.
Here is the procedure on how to recompile your linux kernel.
1.) downloaded linux-2.2.20-tar.gz from http://www.kernel.org and burned it to a cd
2.) moved that file to /usr/src and untarred it, tar zxvf linux-2.2.20.tar.gz
3.) cd /usr/src/linux; then make menuconfig. I started tweaking the kernel
4.) make dep clean modules modules_install bzImage
5.) copied arch/i386/boot/bzImage to /boot and modified lilo.conf
6.) rebooted my machine
Now, the two(2) 3c905 TX nics were detected. :-)
Network configuration of the 2 opensource unix o.s.
In freebsd, the files that needs to be edited are:
1.) /etc/rc.conf
2.) /etc/resolv.conf
3.) /etc/hosts
Here is my rc.conf file:
defaultrouter="192.168.0.254"
gateway_enable="YES"
hostname="ipsec.remingtonltd.com"
ifconfig_fxp0="inet 192.168.0.115 netmask 255.255.255.0"
ifconfig_fxp1="inet 172.16.0.1 netmask 255.255.0.0"
kern_securelevel_enable="NO"
linux_enable="YES"
nfs_reserved_port_only="YES"
sendmail_enable="NO"
sshd_enable="YES"
usbd_enable="YES"
ipfilter_enable="YES"
ipfilter_rules="/etc/ipf.rules"
ipnat_enable="YES"
While in debian, the files I edited are:
1.) /etc/hosts
2.) /etc/network/interfaces
3.) /etc/resolv.conf
Here is my /etc/network/interfaces file:
iface lo inet loopback
iface eth0 inet static
address 192.168.0.122
netmask 255.255.255.0
broadcast 192.168.0.255
network 192.168.0.0
gateway 192.168.0.254
iface eth1 inet static
address 172.17.0.1
netmask 255.255.0.0
broadcast 172.17.255.255
network 172.17.0.0
After finishing the networking configuration of the 2 o.s., I fired up ping and it was successful.
IPfilter firewall configuration on FreeBSD
IPFilter is a software package that can be used to provide network address translation (NAT) or firewall services.
More information can be found at http://www.ipfilter.org.
Going back to my /etc/rc.conf, you would notice that ipfilter_enable is set to "YES" on boot. Since we already did
add support on ipfilter on the kernel, we won't see any errors during bootup while IPfilter is being initialized.
This also means that our freebsd is ready to protect the internal network.
Since we will be using IPSec, you, as a firewall administrator should know about the ports needed by IPSec to successfully
established site-to-site vpn.
Fortunately, I'm generous today. Here are the ports that needs to be opened.
1.) protocol 50, ESP Encap Security Payload for IPv6 [RFC1827]
2.) protocol 51, AH Authentication Header for IPv6 [RFC1826]
3.) UDP protocol 17 on port 500, IPSEC Internet Key Exchange [RFC2409]
You can find my /etc/ipf.rules here and my ipnat.rules here.
VPN Policy Configuration
Next, we have to create a policy. We will use setkey tool. The setkey allows us to manually manipulate the
IPSec SA/SP database. Refer to manpage setkey(8).
The policy that you're going to create must include the remote's internal network. The policy will also include
the tunnel ip address.
Here is the script which I used to set up SAs. It is saved in /usr/local/etc/rc.d. Filename I used was 5tunnel.sh.
/usr/local/etc/rc.d/5tunnel.sh
#!/bin/sh
#
/usr/sbin/setkey -FP
/usr/sbin/setkey -F
/usr/sbin/setkey -c << EOF
spdadd 172.16.0.0/16 172.17.0.0/16 any -P out ipsec esp/tunnel/192.168.0.115-192.168.0.122/require;
spdadd 172.17.0.0/16 172.16.0.0/16 any -P in ipsec esp/tunnel/192.168.0.122-192.168.0.115/require;
EOF
After you have created this script, you should set the execute bit permission so that it will run.
chmod +x 5tunnel.sh
This script will always be run automatically on bootup.
To learn more about IPSec, in (Free|Open|Net)BSD, visit http://www.x-itec.de/projects/tuts/ipsec-howto.txt
Installing Racoon
Now, we need to find a way on how to facilitate negotiation of IPsec keys on the FreeBSD GW. The script
we created cannot handle this. Luckily, racoon is included on the Freebsd Ports Collection. Racoon can be installed
from the ports.
To install racoon:
cd /usr/ports/security/racoon && make install
This will install the racoon daemon and also create the directory /usr/local/etc/racoon.
Next thing we'll do is to modify racoon.conf in /usr/local/etc/racoon directory. Below is the working copy
for my test lab.
/usr/local/etc/racoon/racoon.conf
# $KAME: racoon.conf.in,v 1.18 2001/08/16 06:33:40 itojun Exp $
# "path" must be placed before it should be used.
# You can overwrite which you defined, but it should not use due to confusing.
path include "/usr/local/etc/racoon" ;
# This file contains the remote firewall ip address and the pre-shared key
# The permission of this file should be 600 or racoon will complain. Might not run also.
# chmod 600 /usr/local/etc/racoon/psk.txt
path pre_shared_key "/usr/local/etc/racoon/psk.txt" ;
# racoon will look for certificate file in the directory,
# if the certificate/certificate request payload is received.
path certificate "/usr/local/etc/cert" ;
# "log" specifies logging level. It is followed by either "notify", "debug"
# or "debug2".
# I turned this on so that I will be able to figure out what's happening.
# Enable it until everything is ok.
log debug;
# "padding" defines some parameter of padding. You should not touch these.
padding
{
maximum_length 20; # maximum padding length.
randomize off; # enable randomize length.
strict_check off; # enable strict check.
exclusive_tail off; # extract last one octet.
}
# if no listen directive is specified, racoon will listen to all
# available interface addresses.
listen
{
#isakmp ::1 [7000];
#isakmp 202.249.11.124 [500];
#admin [7002]; # administrative's port by kmpstat.
#strict_address; # required all addresses must be bound.
}
# Specification of default various timer.
timer
{
# These value can be changed per remote node.
counter 5; # maximum trying count to send.
interval 20 sec; # maximum interval to resend.
persend 1; # the number of packets per a send.
# timer for waiting to complete each phase.
phase1 30 sec;
phase2 15 sec;
}
remote anonymous
{
exchange_mode aggressive,main;
nonce_size 16;
lifetime time 10 min; # sec,min,hour
initial_contact on;
support_mip6 on;
proposal_check obey; # obey, strict or claim
proposal {
encryption_algorithm 3des;
hash_algorithm md5;
authentication_method pre_shared_key ;
dh_group 2 ;
}
}
sainfo anonymous
{
pfs_group 1;
lifetime time 10 min;
encryption_algorithm 3des ;
authentication_algorithm hmac_md5;
compression_algorithm deflate ;
}
Firing up racoon
You can create your own script so that on bootup, racoon will be automatically executed.
Here is the content of /usr/local/etc/rc.d/6racoon.sh
/usr/local/sbin/racoon -f /usr/local/etc/racoon/racoon.conf
Don't forget to set execute bit on 6racoon.sh file.
Check if your racoon is working by showing the processes.
# ps ax |grep racoon
221 ?? Is 0:01.04 /usr/local/sbin/racoon -f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log
While on my /var/log/racoon.log, it contained:
2002-03-22 23:43:09: INFO: main.c:167:main(): @(#)package version 20011215a
2002-03-22 23:43:09: INFO: main.c:169:main(): @(#)internal version 20001216 sakane@kame.net
2002-03-22 23:43:09: INFO: main.c:170:main(): @(#)This product linked OpenSSL 0.9.6a 5 Apr 2001 (http://www.openssl.org/)
2002-03-22 23:43:09: DEBUG: algorithm.c:610:alg_oakley_dhdef(): hmac(modp1024)
2002-03-22 23:43:09: DEBUG: algorithm.c:610:alg_oakley_dhdef(): hmac(modp1024)
2002-03-22 23:43:09: DEBUG: pfkey.c:2240:pk_checkalg(): compression algorithm can not be checked because sadb message
doesn't support it.
2002-03-22 23:43:09: DEBUG: pfkey.c:2240:pk_checkalg(): compression algorithm can not be checked because sadb message
doesn't support it.
2002-03-22 23:43:09: DEBUG: sainfo.c:100:getsainfo(): anonymous sainfo selected.
2002-03-22 23:43:09: DEBUG: pfkey.c:2240:pk_checkalg(): compression algorithm can not be checked because sadb message
doesn't support it.
2002-03-22 23:43:09: DEBUG: sainfo.c:100:getsainfo(): anonymous sainfo selected.
2002-03-22 23:43:09: DEBUG: grabmyaddr.c:205:grab_myaddrs(): my interface: 192.168.0.115 (fxp0)
2002-03-22 23:43:09: DEBUG: grabmyaddr.c:205:grab_myaddrs(): my interface: 172.16.0.1 (fxp1)
2002-03-22 23:43:09: DEBUG: grabmyaddr.c:205:grab_myaddrs(): my interface: 127.0.0.1 (lo0)
2002-03-22 23:43:09: DEBUG: grabmyaddr.c:472:autoconf_myaddrsport(): configuring default isakmp port.
2002-03-22 23:43:09: DEBUG: grabmyaddr.c:494:autoconf_myaddrsport(): 3 addrs are configured successfully
2002-03-22 23:43:09: INFO: isakmp.c:1357:isakmp_open(): 127.0.0.1[500] used as isakmp port (fd=6)
2002-03-22 23:43:09: INFO: isakmp.c:1357:isakmp_open(): 172.16.0.1[500] used as isakmp port (fd=7)
2002-03-22 23:43:09: INFO: isakmp.c:1357:isakmp_open(): 192.168.0.115[500] used as isakmp port (fd=8)
2002-03-22 23:43:09: DEBUG: pfkey.c:192:pfkey_handler(): get pfkey X_SPDDUMP message
2002-03-22 23:43:09: DEBUG: pfkey.c:192:pfkey_handler(): get pfkey X_SPDDUMP message
2002-03-22 23:43:09: DEBUG: policy.c:184:cmpspidxstrict(): sub:0xbfbff954: 172.16.0.0/16[0] 172.17.0.0/16[0] proto=any
dir=out
2002-03-22 23:43:09: DEBUG: policy.c:185:cmpspidxstrict(): db :0x80a3c08: 172.17.0.0/16[0] 172.16.0.0/16[0] proto=any
dir=in
This means that you have properly configured your racoon.
Installation of Checkpoint on Debian
Here is a very quicky but working step on installing Checkpoint 4.1.2 3DES on a Debian system.
Credits goes to Christian Mock. I also would like to thank Robert Waldner for sharing
his ideas.
Needed packages:
- alien (for the rpm's)
- csh (for FW1s scripts)
- tcsh (ditto)
- libstdc++2.9-glibc2.1
TIP: make a _huge_ /opt, it installs there
Install FW1 with:
`alien -i CPfw*rpm`
Now add to /etc/profile:
.-.-.-.-.
FWDIR=/etc/fw
PATH=$PATH:$FWDIR/bin
export FWDIR
.-.-.-.-.
Add "/etc/fw/bin" to /etc/login.defs and /root/.profile.
Perform these steps:
# echo "#!/bin/sh"> /etc/rc.d/rc.local
# chmod 755 /etc/rc.d/rc.local
# mkdir -p /etc/rc.d/rc2.d
# ln -s /etc/rc.d/init.d/fw1boot /etc/init.d
# ln -s /etc/rc.d/rc.local /etc/init.d/fw1
# update-rc.d fw1boot start 41 S . start 36 0 6 .
# update-rc.d fw1 defaults
# touch /boot/System.map
# ln -s /usr/bin/tcsh /bin
When cpconfig asks "want to start automatically from /etc/rc.d/rc.local", answer "yes".
Checkpoint FW-1 configuration
We're finished configuring FreeBSD+IpFilter+Ipsec. Also, Checkpoint 4.1.2 is also installed.
We will start by creating a workstation object for FreeBSD gateway.
To recall our hypothetical network, below is the information needed to continue on with
the configuration of Checkpoint.
FreeBSD-external = 192.168.0.115/255.255.255.0
-internal = 172.16.0.0/255.255.0.0
Debian-CP-external = 192.168.0.122/255.255.255.0
-internal = 172.17.0.0/255.255.0.0
To create objects, you will use this icon on the toolbar.

or you can use the menu bar

Step 1: Create a workstation object for FreeBSD firewall

Figure 1. freebsd workstation object
Step 2: Create a network object for the network that is being protected by FreeBSD.
This network object will be placed inside BSD-encdomain group later.

Figure 2. freebsd protected lan network.
Step 3: Create a group and name it as BSD-encdomain. This group will contain
the network object freebsd-lan.

Figure 3: Group Properties of BSD-encdomain
Step 4: Now, we need to modify the VPN tab of freebsd workstation object.
Select Other then select BSD-encdomain. Make sure IKE is checked.

Figure 4: VPN tab of freebsd workstation object.
Step 5: Edit the IKE properties. Make sure that "Supports Aggresive Mode" and "Supports Subnets" are checked.
Don't forget to check 3DES, MD5 and Pre-shared Secret since this are the algorithm and encryption that we
enabled on the FreeBSD.

Figure 5: IKE Properties
We're finished creating the objects related to FreeBSD. Now we're going to modify/create other objects of Checkpoint.
Step 6: You can modify your firewall object. Mine looks like this.

Figure 6: Workstation Properties of debian (the Firewall Gateway)
Step 7: Create a network object of the network that is being protected by your Firewall-1 firewall.
Normally, when you use the wizard, this is also created automatically for you.

Figure 7: Network properties of localnet
Step 8: Create a group and name it as FW1-encdomain. This group will contain
the network object localnet.

Figure 8: Group Properties of FW1-encdomain
Step 9: Now, we need to modify the VPN tab of "debian" workstation object.
Select Other then select BSD-encdomain. Make sure IKE is checked.

Figure 9: Workstation properties of debian workstation object.
Step 10: Edit the IKE properties. Make sure that "Supports Aggresive Mode" and "Supports Subnets" are checked.
Don't forget to check 3DES, MD5 and Pre-shared Secret since this are the algorithm and encryption that we
enabled on the FreeBSD.

Figure 10: IKE Properties of debian workstation object
Step 11: Click on Edit Secrets. This is where you will configure the pre-shared key. This is just any string.
For our test lab, I just used "secret" string. This should match the psk.txt file in freebsd.

After setting the pre-shared secret in the Firewall-1 Network Object definition, place this
secret in /usr/local/etc/racoon/psk.txt on FreeBSD GW. The format for psk.txt is:
192.168.0.122 secret
Don't forget to chmod 600 this file.
We're done with the creation of objects but we're not yet finished. :-)
Firewall-1 VPN Rule Configuration
Now, we need to create a rule so that the packets coming from FreeBSD protected net will be encrypted and
likewise on the Firewall-1 side.

Explanation
1. Rule 2 will accept IPsec communication between debian CPFW-1 and FreeBSD IPFilter.
2. Rule 3 will encrypt communication between FW-1 protected net and IPfilter protected net.
3. Rule 4 - I included this rule so that it will be easier for readers where to place the 2 rules above.
So you think we're done? I think not but one more :-).
I've never seen this on Checkpoint PDF file(s). It was not documented.
Fortunately, I saw it on page 340, item 10.8 of "Essential Checkpoint Firewall-1 by Dameon D. Welch-Abernathy".
That guy is phoneboy :-) Great job dude!!!

NAT is applied before a packet is encrypted or applied after decryption.
NOTE: Assuming we don't have this rule., and if you try connecting from behind the checkpoint fw-1 to
the network 172.16.0.0 network, your packet will be rewritten. In this case, establishing connection
to 172.16.0.0 will fail.
If you think you have done everything, install the new Policy.
Captured logs from Checkpoint Log Viewer
This was taken from the logs of Checkpoint Firewall-1.
Workstation 172.16.0.100 initiated a webmin session (port 10000) to 172.17.0.12.
The same workstation sent a ping request to 172.17.0.12.

TCPDUMP logs
Workstation 172.16.0.100 established a connection to 172.17.0.12 via webmin (port 10000)
Here's my tcpdump params:
# tcpdump dst port 10000 or src port 10000 or esp
22:15:06.170286 192.168.0.115 > 192.168.0.122: ESP(spi=0xf915f925,seq=0x1c)
22:15:06.170296 172.16.0.100.1100 > 172.17.0.12.10000: S 831974464:831974464(0) win 32120 (DF)
22:15:06.171151 172.16.0.100.1100 > 172.17.0.12.10000: S 831974464:831974464(0) win 32120 (DF)
22:15:06.171387 172.17.0.12.10000 > 172.16.0.100.1100: S 1773788391:1773788391(0) ack 831974465 win 32120 (DF)
22:15:06.172531 192.168.0.122 > 192.168.0.115: ESP(spi=0x009fc4f7,seq=0x3d)
22:15:06.172715 172.17.0.12.10000 > 172.16.0.100.1100: S 1773788391:1773788391(0) ack 831974465 win 32120 (DF)
22:15:06.172912 192.168.0.115 > 192.168.0.122: ESP(spi=0xf915f925,seq=0x1d)
22:15:06.172919 172.16.0.100.1100 > 172.17.0.12.10000: . ack 1 win 32120 <nop,nop,timestamp 88537361 27795895> (DF)
22:15:06.173479 172.16.0.100.1100 > 172.17.0.12.10000: . ack 1 win 32120 <nop,nop,timestamp 88537361 27795895> (DF)
Tailing racoon logs
Here is a snipped from /var/log/racoon.log
2002-03-21 19:48:00: DEBUG: oakley.c:389:oakley_compute_keymat(): KEYMAT computed.
2002-03-21 19:48:00: DEBUG: isakmp_quick.c:647:quick_i2send(): call pk_sendupdate
2002-03-21 19:48:00: DEBUG: algorithm.c:509:alg_ipsec_encdef(): encription(3des)
2002-03-21 19:48:00: DEBUG: algorithm.c:552:alg_ipsec_hmacdef(): hmac(hmac_md5)
2002-03-21 19:48:00: DEBUG: pfkey.c:971:pk_sendupdate(): call pfkey_send_update
2002-03-21 19:48:00: DEBUG: isakmp_quick.c:652:quick_i2send(): pfkey update sent.
2002-03-21 19:48:00: DEBUG: algorithm.c:509:alg_ipsec_encdef(): encription(3des)
2002-03-21 19:48:00: DEBUG: algorithm.c:552:alg_ipsec_hmacdef(): hmac(hmac_md5)
2002-03-21 19:48:00: DEBUG: pfkey.c:1212:pk_sendadd(): call pfkey_send_add
2002-03-21 19:48:00: DEBUG: isakmp_quick.c:659:quick_i2send(): pfkey add sent.
2002-03-21 19:48:00: DEBUG: pfkey.c:192:pfkey_handler(): get pfkey UPDATE message
2002-03-21 19:48:00: DEBUG: pfkey.c:1100:pk_recvupdate(): pfkey UPDATE succeeded: ESP/Tunnel 192.168.0.122->192.168.0.115 spi=184590122(0x
b009f2a)
2002-03-21 19:48:00: INFO: pfkey.c:1107:pk_recvupdate(): IPsec-SA established: ESP/Tunnel 192.168.0.122->192.168.0.115 spi=184590122(0xb00
9f2a)
2002-03-21 19:48:00: DEBUG: pfkey.c:1145:pk_recvupdate(): ===
2002-03-21 19:48:00: DEBUG: pfkey.c:192:pfkey_handler(): get pfkey ADD message
2002-03-21 19:48:00: INFO: pfkey.c:1319:pk_recvadd(): IPsec-SA established: ESP/Tunnel 192.168.0.115->192.168.0.122 spi=1363518081(0x5145a
281)
Links that helped me
FreeBSD Handbook: IPSEC
http://www.freebsd.org/handbook/ipsec.html
IPSEC Tunnel
http://www.freebsddiary.org/ipsec-tunnel.php
VPN Information on the World Wide Web
http://vpn.shmoo.com/
FreeBSD IPSEC mini-HOWTO
http://www.x-itec.de/projects/tuts/ipsec-howto.txt
FreeBSD mini-IPSEC HOWTO
http://www.daemonnews.org/200101/ipsec-howto.html
KAME Project
http://www.kame.net