1.0 DISCLAIMER AND CONVENTIONS
1.1 Disclaimer
1.2 Conventions
2.0 WHAT IS A VPN?
2.1 Concept behind a VPN
2.2 Why use a VPN?
2.3 What does ISAKMP do for you?
3.0 EXAMPLE SCENARIO
3.1 The basic VPN
3.2 Our goal
4.0 STEP BY STEP SETUP OF THE VPN
4.1 Preparing your internal network nodes for the VPN
4.2 Making sure you have all the proper files
4.3 Preparing both gateways for the VPN.
4.4 Editing the keynotes policy file
5.0 CONFIGURING ISAKMP
5.1 A basic VPN using ESP only
5.2 Starting your VPN
5.3 Stopping the daemon and flushing IPSEC routes
6.0 TROUBLESHOOTING YOUR VPN CONNECTION
6.1 Basic troubleshooting
6.2 Odd errors that are normal
7.0 EXPANDING THE VPN
8.0 ISAKMP, IPSEC, OPENBSD, AND OTHER TECHNOLOGIES
9.0 USEFUL LINKS
10.0 CREDITS:
Note that this is by no means a replacement to the related MAN pages but rather an addition.
Most of the information provided in this document is either a direct copy or a paraphrase of
these MAN pages.
As a reference, please read the vpn(8),isakmpd(8),isakmpd.conf(5),isakmpd.policy(5) and the RFCs
mentioned within these documents along with this Howto.

2. A few months later you install four more computers for the Accounting department. You decide to differentiate between your two departments by segmenting them. You assign 192.168.10.X to one side and 192.168.20.X to the other.

3. According to the laws of IP, if these two networks decide they wish to speak to each other you must introduce a Gateway between to route the packets from one subnet to the other. This gateway, most often called a router, is the basis of connecting networks together to form the Internet.
4. A VPN acts exactly like this router. Imagine that 192.168.10.X and 192.168.20.X are in different locations. Take a chainsaw and split the Router box in half. By doing so you would split the functionality of the single router into two separate routers. Then link these two halves through a public network containing public routable IPs (such as the Internet). Both your network segments would still be able to talk to each other through a virtual tunnel even if they are separated by a great distances. Provided you have made the tunnel secure, you now have a VPN.

Phase 1 - The two ISAKMP peers establish a secure, authenticated channel upon which to
communicate between two daemons. This establishes a Security Association (SA) between both hosts.
Main Mode and Aggressive Mode are the methods used to establish this channel. Main
Mode sends the various authentication information in a certain sequence, providing identity
protection. Aggressive Mode does not provide identity protection because all of the
authentication information is sent at the same time. Aggressive mode should only be used in
such cases where network bandwidth is of concern.
Phase 2 - Security Associations are
negotiated on behalf of services such as IPSec or any other service that needs key material and/or
parameter negotiation. Phase 2 is basically establishes the VPN link between the hosts behind your
gateways by creating the VPN tunnel. Quick Mode is used in Phase 2 because there is not need
to repeat a full authentication because Phase 1 has already established the SAs.
In brief, Phase 1 is used to get a secure channel in which to do the (quicker) phase 2 setups, there can be several. Phase 2 is used to setup the actual VPNs.**
This may sound a bit confusing at first but it makes sense. Phase 1 is basically where your two gateways establish a connection where they exchange authentication (Either a X509 certificate or a pre-shared secret). This allows each end to make sure the other end is who they say they are. Phase 2 is an exchange of keys to determine how the data between the two will be encrypted. In other words, Phase 1 is analogous to your phone ringing, you answering and 'Hi John, it's Jane.' Phase 2 is the determination of the language you are going to use to continue your conversation.
* See the OBSD FAQ for a lesson on how to use that method instead.
** Quoted from email by HÂkan Olsson to Patrick Ethier on Dec 21st 1999.

By executing the above on both Ragweed and Slippery, you should have the following
files in your OPenBSD 2.6 tree:
/etc/sysctl.conf
/etc/isakmpd.policy
/etc/isakmpd/isakmpd.conf
* (Note: this is where OBSD2.6 stores SSH by default, use $find / -name ssh to find the ssh binary if it is not in the default location)
Edit the /etc/sysctl.conf file:
$vi /etc/sysctl.conf
|
# $OpenBSD: sysctl.conf,v 1.10 1999/04/11 19:41:33 niklas Exp $ # This files contains a list of sysctl options the user wants set at # boot time. # ie. | |
| #net.inet.ip.forwarding=1 #net.inet.tcp.rfc1323=0 #net.inet.esp.enable=1 #net.inet.ah.enable=1 #ddb.panic=0 #ddb.console=1 #fs.posix.setuid=0 machdep.allowaperture=1 #machdep.apmwarn=10 |
# 1=Permit forwarding (routing) of packets # 0=disable TCP RFC1323 extensions (for if tcp is slow) # 1=Enable the ESP IPSec protocol # 1=Enable the AH IPSec protocol # 0=Do not drop into ddb on a kernel panic # 1=Permit entry of ddb from the console # 0=Traditional BSD chown() semantics # 1=On i386, permit access to aperture driver for XFree86 # battery % when apm status messages enabled |
Uncomment the lines:
net.inet.ip.forwarding=1
net.inet.esp.enable=1
This will enable IPSec and IP Forwarding. Note that we do not need to enable AH in this case because we are not using it. AH stands for Authentication Header. Read ipsec(4) for more information. If your are using transforms that have AH mentioned, then you should enable this feature. AH is not required and does not encrypt the payload data (The fancy term for the data you are transferring over the Internet). AH simply provides for a better authentication of each packet.
$ vi /etc/isakmpd.policy
KeyNote-Version: 2
Authoriser: "POLICY"
The sample file supplies what I consider to be to "minimum" security constraints. Unfortunately, there is a problem with the original sample policy file. It contains 2 lines of code that are not supported by keynote(5). Fortunately, we can fix this. Delete the two lines in question (As far as I know, these are added for CVS):
$ vi /etc/isakmpd.policy
KeyNote-Version: 2
Comment: This policy accepts ESP SAs from a remote that uses the right password
OpenBSD: policy,v 1.3 1999/11/18 21:45:52 angelos Exp $
$EOM: policy,v 1.3 1999/08/26 11:51:37 niklas Exp $
Authoriser: "POLICY"
Licensees: "mekmitasdigoat"
Conditions: app_domain == "IPSec policy" &&
esp_present == "yes" -> "true";
Remove the lines:
$OpenBSD: policy,v 1.3 1999/11/18 21:45:52 angelos Exp $
$EOM: policy,v 1.3 1999/08/26 11:51:37 niklas Exp $
Like we mentioned before, this is the basic example taken straight out of the isakmpd.conf MAN page.
Implementing this will give you a basic VPN using ESP only. I will explain as we go along why we are
making the changes. I will leave it up to some other brave fellow to further personalise this.
This file is in the traditional .ini format. My guess is that it was inspired from M$ windows
3.11 and win95. Let's not flame this. It works rather well. Anything in block quotes ([ ]) is a
section name. Each section has tag=value pairs. This is explained rather weirdly in the man
page but don't worry, you'll get the hang of it soon enough.
$ vi /etc/isakmpd/isakmpd.conf
Don't include the <MAN Name section Page> in your actual configuration file.
Please note: I use S> for text coming from Slippery and R> for text on Ragweed
S/R> is for text on both hosts.
S>[General] <GENERAL >
S>Retransmits= 5
S>Exchange-max-time= 120
S>Listen-on= Slippery_Internet_IP
R>[General] <GENERAL >
R>Retransmits= 5
R>Exchange-max-time= 120
R>Listen-on= Ragweed_Internet_IP
This is where we set up the variables that will affect the main behaviour of our VPN. It is okay to
use the defaults here.
The Listen-on= value is the only tag= value worth mentioning. This is basically the IP
that ISAKMPD should bind to. Only the Internet IP of our gateway is necessary here because our Private
IP has no need to connect to ISAKMPD. If we were to have multiple external interfaces on our gateway,
we could list which interfaces we want to be listening by entering them using a comma separated list.
<PHASE 1 >
S>[Phase 1]
S>Ragweed_Internet_IP= Ragweed
R>[Phase 1]
R>Slippery_Internet_IP= Slippery
This section describes the Source IP addresses to accept in order to negotiate the phase 1 connection.
Its value points to the <ISAKMP-PEER> section below (Remember that phase 1 simply
authenticates the remote peer to make sure they are who they say they are). You can list multiple peers
as IP_Address= <ISAKMP-PEER>.
<PHASE 2 >
S>[Phase 2]
S>Connections= Slippery-Ragweed
R>[Phase 2]
R>Connections= Ragweed-Slippery
This describes Phase 2 of the connection. This is the phase that determines what language the two peers will use to communicate.
The Connections= tag refers to the <IPSEC-CONNECTION> section name mentioned below. It initiates the requirements or the accepted methods to set up Phase 2. This also tells ISAKMPD which connections to initiate once started. Note that you can have multiple <IPSEC-CONNECTION> sections here separated by a comma if you are to connect with multiple peer hosts.
Note that if you do not have the IP address of the remote host, you can specify a Default= that points
to a section describing a GENERIC <IPSEC-CONNECTION> that will be referenced by any
incoming IP that is not listed in the Connections= tag.
<ISAKMP-PEER>
S>[Ragweed]
S>Phase= 1
S>Transport= udp
S>Local-address= Slippery_Internet_IP
S>Address= Ragweed_Internet_IP
S>Configuration= Default-main-mode
S>Authentication= mekmitasdigoat
S>#Flags=
R>[Slippery]
R>Phase= 1
R>Transport= udp
R>Local-address= Ragweed_Internet_IP
R>Address= Slippery_Internet_IP
R>Configuration= Default-main-mode
R>Authentication= mekmitasdigoat
R>#Flags=
These represent the sections referred to by the <PHASE 1> section above. They each
describe the requirements that the peer gateway must fulfil in order to proceed to Phase 2. There are
many other options here but the ones mentioned above are the minimum requirements.
Phase=1 is required because the ISAKMPD code uses the same procedures to process Phase 1 and
Phase 2. It must be 1 or nothing will work.
Transport= is just a way of giving you different possibilities for different peers. It's
suggested that udp be used here so we'll leave it at that.
Please note that some peers may be behind a firewall that doesn't let UDP traffic through.
Local-address is the destination address that the incoming packets point to. In some cases, you
can be listening on different Interfaces for Phase 1 connections. (See the <GENERAL>:Listen-on
= variable). In this case, we only have 1 interface listening, therefore this is the IP of the listening
interface on this peer.
Address= is the address that points to the source IP of the incoming packets. This usually points
to the peer gateway. This needs further explanation, because the question arises 'What if the source IP
is dynamic? How would Phase 1 be negotiated?'
Configuration= points to the <ISAKMP-CONFIGURATION> section below. You can specify
different <ISAKMP-CONFIGURATION> sections for different peers. We use the default one
specified by the sample file.
Authentication= is the pre-shared secret to be used for this particular peer. It is more or less
a passphrase that each peer uses. This passphrase gets passed to isakmpd.policy to verify whether this
peer is allowed to use IPSEC with this host. If you change this phrase, you must also change it in the
isakmpd.policy file because the sample file provides for this passphrase. If you decided to go with a
minimum policy file then you can specify whatever you want here.
Flags= is not currently being used. The RFC leaves room for extra options to be specified for
phase 1.
There are other tags here that will allow for other options to be set. Refer to the isakmpd.conf MAN page
for descriptions.
<IPSEC-CONNECTION>
S>[Slippery-Ragweed]
S>Phase= 2
S>ISAKMP-peer= Ragweed
S>Configuration= Default-quick-mode
S>Local-ID= Net-Carefull
S>Remote-ID= Net-Badplants
R>[Ragweed Slippery]
R>Phase= 2
R>ISAKMP-peer= Slippery
R>Configuration= Default-quick-mode
R>Local-ID= Net-Badplants
R>Remote-ID= Net-Carefull
These represent the sections referred to by the <PHASE 2> section above. They are the
individual settings that ISAKMPD must use to talk between the two gateways for the particular
connection.
Phase=2 is required because ISAKMPD code uses the same functions to authenticate Phase 1 and Phase
2. This is required for the VPN to work.
ISAKMPD-Peer= is the name of a <ISAKMP-PEER> section above. This means that we are
talking to that particular peer to establish a Phase 2 connection. This is provided because you can have
multiple <ISAKMP-PEER> sections and <IPSEC-CONNECTION> sections.
Configuration= refers to the <IPSEC-CONFIGURATION> section below that describes the
standards by which this host and the particular peer for this connection must abide.
Local-ID= refers to a <IPSEC-ID> section below that describes our Private Network to
the peer gateway. This is the portion that is passed so that the other gateway can set up the proper
routing table that will transfer data over the VPN to our network.
Remote-ID= refers to a <IPSEC-ID> section below that describes what is supposed to be
the remote Private Network to our host. This portion is interpreted to set up the proper routing tables
that will transfer data from our Private Network over the VPN to the remote Private Network.
There is another tag that is supported here called Flags=. If you require this tag, read the isakmpd.conf
MAN page.
>IPSEC-ID>
S/R>[NET-Badplants]
S/R>ID-type= IPV4_ADDR_SUBNET
S/R>Network= Badplants_Private_Network_Address
S/R>Netmask= Badplants_Private_Subnet_Mask
S/R>[NET-Carefull]
S/R>ID-type= IPV4_ADDR_SUBNET
S/R>Network= Carefull_Private_Network_Address
S/R>Netmask= Carefull_Private_Subnet_Mask
These two sections are in the conf file of each host. They are the sections referenced by the
Local-ID and Remote-ID of the <IPSEC-CONNECTION> section. They describe the
routes that should be set up to allow traffic from one private network to another.
Remember the router that we chain-sawed in half at the beginning of this text? Well, these two sections
describe the routing that you would have to put into this router for both Private Networks to talk to
each other.
ID-type= can be IPV4_ADDR_SUBNET or IPV4_ADDR (RFC2708 mentions more possible values
but I have no clue if they are supported or not by this implementation). Depending on which it is, the
following two tags may or may not be used. I discuss IPV4_ADDR_SUBNET in this case because this is
the default method used to get one private network to talk to the other.
<ISAKMP-CONFIGURATION>
S/R>[Default-main-mode]
S/R>DOI= IPSEC
S/R>EXCHANGE_TYPE= ID_PROT
S/R>Transforms= 3DES-SHA
This section describes the requirements for the encryption methods of Phase 1 connections. The name
reflects the value of <ISAKMP-PEER>:Configuration= .As we can see here, we are stating our
Domain of Interest which is IPSEC. The EXCHANGE_TYPE variable is set to ID_PROT for Phase 1,
which identifies the protocols to be covered by this Authentication.
Transforms= is the transform required (or assigned) for this exchange. In this case, this points to
a <ISAKMP-TRANSFORM> section in the configuration file that says we are receiving a packet
encrypted with 3DES and a checksum verifiable with SHA. There are a bunch of different transforms defined
inside the sample VPN-east.conf. These are provided because 3DES and SHA are not always supported
across different platforms. For OpenBSD there should be no reason to change this for a basic setup. Feel
free to create multiples of this section and change the transform. The only requirement is that you change <ISAKMP-PEER>:Configuration=<ISAKMP-CONFIGURATION>.
<ISAKMP-TRANSFORM>
S/R>[Default-quick-mode]
S/R>DOI= IPSEC
S/R>EXCHANGE_TYPE= QUICK_MODE
S/R>Suites= QM-ESP-3DES-SHA-PFS-SUITE,QM-ESP-DES-MD5-PFS-SUITE
This section describes the requirements for the encryption of the data to be sent through the VPN and
is referred to by <IPSEC-CONNECTION>:Configuration above. Note the difference between this
section and the Phase 1 equivalent just above is that the EXCHANGE_TYPE is QUICK_MODE.
This is always the case for Phase 2.
The Suites= points to a <IPSEC-SUITE> section describing the different encryption
schemes available between the two hosts.
There is much more to be said about ISAKMP and IPSec. By using the above basic descriptions you should
be able to create a simple but solid VPN that cares and feeds itself. I am posting the bare minimum
isakmpd.conf for both hosts here. I really suggest that you take the example VPN-east.conf
and modify it as you read this text.
ragweed_isakmpd_conf.txt
slippery_isakmpd_conf.txt
The second will display the clear text parts of IKE. You should be able to tell most of what happens
during the main mode transfer with this. (For a reference of what is supposed to happen, see section 4
of RFC2708).
If you get NO_PROPOSAL_CHOSEN, this means that one end is not meeting the requirements you have
set up for the Phase 1 peer section. Verify your setup and the connection.
If you get nothing at all then try pinging RAGWEED from SLIPPERY. You may be experiencing a network outage of sorts. Unfortunately, although it is fairly powerful, a ISAKMP daemon cannot fix network outages.J
Verify that there is ESP traffic between the two hosts
$ tcpdump -i EXT_IFACE host RAGWEED and proto esp
Then switch to another console and start ping Dandelion. Switch back to the console that is displaying the TCPDUMP. You should see some traffic. If it is not coming back, check that the ENCAP: routes are correct on both ends. If they are not, then you have not entered them properly in your conf file.
Example: pf_key_v2_delete_spi: DELETE: No such process
"DELETE: no such process"
When you create a VPN, you create SAs (Security Associations) that go into the OpenBSD kernel (they are
actually called tdb's there). Since not all systems that 'isakmpd' can run on support "in-kernel"
expiration of SAs, the isakmp-daemon keeps track of when to remove the SAs. If, as in OpenBSD's case,
the kernel does itself support these expirations, we get two parties that can remove SAs: the kernel
and the isakmp-daemon. So, when our time limited SA is about to expire, both will try to remove it. If
the kernel is slightly faster (normally this is what happens), isakmpd will try to remove a SA that just
"disappeared". This is what produces the "DELETE: no such process" message.*
Example: exchange_run: unexpected payload HASH'
"exchange_run: unexpected payload HASH" (and ".... payload DELETE"):
The IKE protocol specifies notifications that can be exchanged between the two isakmp-daemons. A HASH
payload that states that the notification is "correct" usually accompanies these exchanges. It was
decided _not_ to add support to isakmpd to act on (or even understand) some notifications. One of these
is the DELETE notification, which basically (if I remember) says that SA xxxxx has been removed, so
please remove "your SA". As we only want SAs to be removed following our internal decisions, isakmpd does
not care about receiving DELETE payloads from the outside. It does log them, though, and also logs the
HASH payload that accompanied the other.**
Most of these have been demoted to Debugging in the next version of ISAKMD for OBSD2.6
* Quoted from Email from HÂkan Olsson to Patrick Ethier on Dec 21st 1999.
** Quoted from email by HÂkan Olsson to Patrick Ethier on Dec 21st 1999.
Special thanks to the people from the misc@openbsd.org and vpn@securityfocus.com
Special thanks to Angelos Keromytis who helped me get through my first experience with ISAKMP on OpenBSD.
Matthew Patton (From netsec.net) and HÂkan Olsson who helped me verify the accuracy of the information provided and supplied a few words of their own.
Thank you to the original writer of the IPSec FAQ on http://www.openbsd.org/faq/faq13.html