The problem we are trying to solve is that of letting two networks communicate securely when the only connection between them is over a third network which they do not trust.
The solution is to put a security gateway machine between each of the communicating networks and the untrusted network. The gateway machines encrypt packets entering the untrusted net and decrypt packets leaving it, creating a secure tunnel through it.
The result is called a VPN, a Virtual Private Network. If the cryptography is strong, the implementation careful, and the administration of the gateways competent, then one can reasonably place considerable confidence in the security of the tunnel. The two networks then behave like a large private network, some of whose links are encrypted tunnels through untrusted nets.
Actual VPNs are often more complex. One organisation may have fifty branch offices, plus some suppliers and clients, with whom it needs to communicate securely. Another might have 5,000 stores, or 50,000 point-of-sale devices. Many VPNs need to handle travelling users, the "road warrior" connecting to home base from a laptop machine.
The untrusted network need not be the Internet. All the same issues
arise on a corporate or institutional network whenever two
departments want to communicate privately with each other.
We also assume here that all machines involved have known, fixed IP
addresses. See our Configuration
document for some information on supporting "road warriors".
In our example, we'll call the two gateways East and West. We'll have only
one client machine on each net: Sunrise in the East and Sunset in the West.
A diagram:
Our goal in this document is to tell you how to set up the two gateways,
East and West. We assume your goal is to ensure that East and West encrypt
all traffic between them, or at least all that your security policies
require them to encrypt.
Our example network
For our example, we assume that there are only three networks involved,
two that want to talk to each other plus the Internet in the role of
the third, untrusted, net. Once you have this working between two
network gateways, extending it to three or more is straightforward.
Sunset==========West------------------East=========Sunrise
local net untrusted net local net
SuSE 6.3
The European version of the SuSE 6.3 distribution ships with FreeS/WAN included. If you are using that, you need not download kernel source and FreeS/WAN code, then apply our kernel patches and install the rest of FreeS/WAN. That should all be done for you already. All you have to do is:
If you are going to use any 2.0.x kernel, we strongly recommend 2.0.38 (or a later version if one appears). 2.0.38 has fixes for a number of small security-related glitches; nothing major, but definitely worth having on a security gateway machine. Also, some things we were patching in 2.0.36 are built into 2.0.38 kernels. Our patch set should still work on earlier kernels, but this is not something we test often.
For 2.2 kernels, we suggest using either 2.2.12 to match our development systems, or the latest kernel release. Our code is intended to work on any 2.2 kernel.
Our code includes patches, mostly user-contributed, to make it work on 2.3 kernels. (In the Linux release numbering system, an even second digit as in 2.2.x indicates a stable or production release while an odd number as in 2.3.x indicates an experimental or development release). The patches have been tested successfully on 2.3 kernels up to 2.3.20-something, but are not regularly or intensively tested by our team. If you are working with 2.3.x, we suggest you use our latest snapshot rather than our release to be sure of getting the latest patches.
For information on other CPU architectures see our Implementation Notes file and our Compatibility document.
The International kernel patches add cryptographic code that cannot be in the vanilla kernel because that is distributed from the US and must comply with American export laws. These patches are not required for FreeS/WAN; we add our own cryptographic code.
For any of these, choose a mirror that is close to you and bookmark it.
Using a kernel from your distribution vendor may save you some annoyance later.
We suggest the same procedure for FreeS/WAN. Put the tarfile under /usr/src. You will get a directory /usr/src/freeswan<version> when you untar.
Note that these methods don't work:
You should compile, install and test the kernels as you have configured them, so that you have a known stable starting point. Then if there is a problem after you add FreeS/WAN, tracking it down is much simpler.
If you need advice on this process, or general Linux background information, try our list of Linux web references. The most directly relevant document is the Kernel HOWTO. We also provide a file of notes on kernel installation.
Note that Redhat turns off packet forwarding by default, even for kernels in which it has been enabled. To turn it on:
echo "1" > /proc/sys/net/ipv4/ip_forward
FORWARD_IPV4=yes
The client machines, Sunrise and Sunset in our example, may have assigned routable IP addresses, or they may be using private non-routable addresses (as defined in RFC 1918) with the gateways doing IP masquerade. It doesn't matter which, as long as whatever it is works correctly.
Configure and test any other software you will want to use for testing once IPSEC is up. For example, you might put an HTTP daemon on Sunset and a browser on Sunrise. Make sure these work without IPSEC.
If these tests fail, figure out why and fix it.
Do not proceed until it works.
This installs various programs, man pages,
and configuration files. It also adds FreeS/WAN code to the kernel, then
re-compiles and re-configures the kernel to activate that code.
NOTE:
Note that these edits must be done securely if you are
to have any
confidence in your IPSEC security. If someone can get the contents of
these files, for example by looking at your screen as you work or by
intercepting packets between your X desktop and the gateway machine,
then they can easily bypass IPSEC.
You need to edit these two files to configure at least one IPSEC connection.
As with most things on any Unix-like system, most parts of Linux FreeS/WAN
are documented in online manual pages. We provide a list of
FreeS/WAN man pages, with links to HTML versions
of them. The /etc/ipsec.conf file is documented in the
ipsec.conf(5) man page. You should now read that page, either
via this link or with the command:
We currently support two types of connections, started with commands
such as:
Here we will set up a connection for both manual mode (useful for testing)
and automatic mode (more secure, used in production). The steps involved
are:
In other cases, you can name one or more specific interfaces to be used by FreeS/WAN.
For example:
The interfaces specified here are the only ones this gateway machine can use to
communicate with other IPSEC gateways.
If this is not correct, nothing works.
If you need to discover interface names, use the command:
plutoload and plutostart can be quoted lists of connection
names, but are often set to %search as in our example. Any connection
with auto=add in its connection definition is then loaded, and any
connection with auto=start is started.
For testing, you might wish to set this to 10 or even 1 to avoid wasting
resources on incorrectly set up connections. In production, it is often
set to zero (retry forever); keeping the connection up is what machine
resources are for.
Note that the keys we supply here are
intended only for testing. Testing is easier if everyone
uses the same key, but these keys are utterly useless for
security since any attacker with a grain of sense can be
expected to discover them.
For real use, you should go to automatic
keying. If that is not possible, create your own keys for manual mode
and keep them secret.
Once you are finished testing, you should edit these defaults:
Building the software
When you get to the step using config
menuconfig or xconfig to check configuration after
adding the FreeS/WAN patches to your kernel:
The ipsec.conf(5) configuration file
man 5 ipsec.conf
You may also want to look at manual pages for
ipsec_manual(8) and ipsec_auto(8) which
document the two types of connections you will set up here, and
at our example configurations file.
ipsec manual --start name
ipsec auto --up name
The difference is in how they are keyed.
The setup section of /etc/ipsec.conf
The first section of ipsec.conf contains overall setup
parameters for IPSEC, which apply to all connections. In our example
file, it is:
# basic configuration
config setup
# THIS SETTING MUST BE CORRECT or almost nothing will work;
# %defaultroute is okay for most simple cases.
interfaces=%defaultroute
# Debug-logging controls: "none" for (almost) none, "all" for lots.
klipsdebug=none
plutodebug=none
# Use auto= parameters in conn descriptions to control startup actions.
plutoload=%search
plutostart=%search
The variables set here are:
Both tell KLIPS to use eth0 as ipsec0. The second one also supports IPSEC over PPP.
ifconfig
If you have PCMCIA or other interfaces that are not available at boot time,
special measures are required. See our
Configuration document.
Editing connections in /etc/ipsec.conf
Connection defaults
There is a special name %default that lets you define things that apply
to all connections. e.g. our example file has:
# defaults for subsequent connection descriptions
conn %default
# How persistent to be in (re)keying negotiations (0 means very).
keyingtries=0
# Parameters for manual-keying testing (DON'T USE OPERATIONALLY).
spi=0x200
esp=3des-md5-96
espenckey=0x01234567_89abcdef_02468ace_13579bdf_12345678_9abcdef0
espauthkey=0x12345678_9abcdef0_2468ace0_13579bdf
Variables set here are:
conn sntThe connection name is "snt" and to define another connection you make a copy with a new name such as:
conn reno-vanA sample connection description is:
# sample tunnel (manually or automatically keyed) # "(manual)" means relevant only to manual keying, "(auto)" only to automatic. # For manual keying, we use ESP for both encryption and authentication, the # simplest and often the best method. # The network here looks like: # leftsubnet====left----leftnexthop......rightnexthop----right====rightsubnet # If left and right are on the same Ethernet, omit leftnexthop and rightnexthop. conn sample # left security gateway (public-network address) left=10.0.0.1 # next hop to reach right leftnexthop=10.44.55.66 # subnet behind left (omit if there is no subnet) leftsubnet=172.16.0.0/24 # right s.g., subnet behind it, and next hop to reach left right=10.12.12.1 rightnexthop=10.88.77.66 rightsubnet=192.168.0.0/24 auto=startWe omit here the variables we have shown as set in the default connection above. All of them could also be set here. If they are set in both places, settings here take precedence. Defaults are used only if the specific connection description has no value set.
Many of the variables in this file come in pairs such as "leftsubnet: and "rightsubnet", one for each end of the connection. The variables on the left side are:
This need not always be set. If:
(Yes, we know that design is not ideal, and we plan to change it. See extensive discussions on the mailing list, mostly with "routing" in the subject lines.)
If the conn setup section has plutostart=%search, then all connections marked auto=start are started when Pluto starts.
We suggest that you name connections by their ends. For example, name the link between Fred and Susan's machines "fred-susan" or the link between your Reno and Vancouver offices "reno-van". You can then let "left" refer to the left half of the name, "fred" or "reno" in our examples, and "right" to the other half.
Note that the names should be the same in the ipsec.conf files on both ends. The name "reno", for example, refers to the machine in Reno, no matter which city the file is in, and if "reno" is "left" in the reno-van description in Reno, then "reno" is "left" in that description on the Vancouver machine as well. When you copy the file from one machine to the other, the only change you should make on the second machine is changing the interfaces= line to match the interface the second machine uses for IPSEC.
In general, you should use numeric IP addresses, not names, here. The file syntax allows names to be used, but this creates an additional risk. If someone can subvert the DNS service, then they can redirect packets whose addresses are looked up via that service.
The "nexthop" parameters are not needed if the two gateways are directly connected to each other, or for a machine which has interfaces=%defaultroute. Otherwise they are the addresses of the next network gateways on both ends. For example, if the network is like this:
Sunset======West------Westgate........Eastgate-------East======Sunrise
and West is "left", then leftnexthop=Westgate and rightnexthop=Eastgate.
You can create new random keys with the
ranbits(8) utility. For example, the commands:
If you want to use SHA instead of
MD5, that requires a 160-bit key
Note that any temporary files used must be kept
secure since they contain keys. That is the reason
for the umask command above. The temporary file should be deleted as
soon as you are done with it. You may also want to change the umask
back to its default value after you are finished working on keys.
The ranbits utility may pause for a few seconds if not enough entropy
is available immediately. See ipsec_ranbits(8) and random(4) for details.
This file stores the secrets used to
authenticate communication
for the Diffie-Hellman key exchange in
the IKE protocol.
Each line has the IP addresses of the two gateways plus the secret. It should look
something like this:
For details, see the ipsec.secrets(5) man page.
You want the same secret on the two gateways used, so you create a line
with that secret and the two gateway IP addresses.
The installation process supplies an example secret, useful only
for testing. You should change it for production use. To create a new secret, use:
to the other gateway machine by some secure means.
Don't just FTP or mail these files! It is vital that the keys
in /etc/ipsec.conf and the secrets in
/etc/ipsec.secrets remain secret. An attacker who knew those
could easily have all the data on your "secure" connection.
Carry the files on a floppy, and lock the floppy in a good safe or erase
it extremely thoroughly afterward. Or use PGP
or SSH to make the transfer.
Note also that those files should be owned by root. /etc/ipsec.secrets
should have permissions rw-------.
If /etc/ipsec.conf contains keys, then it too should have permissions
rw-------. In production use, it will not normally contain keys; the
keys are automatically generated.
Note that /etc/ipsec.conf is installed with permissions
rw-r--r--. If you plan to use manually keyed connections
for anything more than initial testing, you must:
Creating keys with ranbits
Notice that at this point you may have two connections with identical keys,
the one you copied and the one you just created. This
creates a potential security hole. If you ever use the duplicate keys on
two different connections, then either of the remote admins can read traffic
destined for the other's system. Delete one copy of the key material
now to avoid any risk of inadvertently doing that.
umask 177
ipsec ranbits 192 > temp
ipsec ranbits 128 >> temp
create keys in the sizes needed for our default algorithms:
(only 168 bits are used; parity bits are ignored)
Putting secrets in /etc/ipsec.secrets
10.0.0.1 11.0.0.1 "0xf568175c_97462413_6db3d6ae_f2b46f40_d4e891fc_99d422f4_d6160755_0410164c"
This shows a secret generated by our ipsec ranbits which produces a hexadecimal
string as output. Note that the quotes are required. You can use any character string as
your secret. For security, it should be both long and extremely hard to guess.
umask 177
ipsec ranbits 256 > temp
Remember to delete the temporary file.
For now, all you need to do in the overall config setup section
of the file is set interfaces. We cover other options in our
Configuration document.
When you go to three or more gateways, however, you should
ensure that distribution of keys and secrets is kept to a minimum. If Reno,
Vancouver and Munich offices all communicate, there is no reason to give
Reno keys to the Vancouver-Munich tunnel, for example.
So in our example, if eth0 has IP address 101.101.101.101 then ipsec0
inherits that address, the
correct match is found, and this FreeS/WAN discovers that it is left.
It then sets itself up with the other left* parameters
Of course, there must also be an interface and routes set up so
that this machine can exchange non-IPSEC packets with clients on
leftsubnet. This is done with standard Linux utilities such as
ifconfig(8) and route(8). Also, things must be correct on right
in Vancouver; it takes two to tunnel.
A data mismatch anywhere in this configuration will cause FreeS/WAN
to fail and to log various error messages. Depending on just how
confused FreeS/WAN is and about what, the error messages may be
somewhat confusing. See our problem reporting
file to get help interpreting them if required.
We recommend double-checking for consistency here before continuing.
Examine /var/log/messages for any signs of trouble.
On both gateways, the following entries should now exist in the /proc/net/
directory:
and the IPSEC interfaces should be attached on top of the specified
physical interfaces. Confirm that with:
You should see at least device ipsec0. Routing connections through this
pseudo-device with our eroute(8) utility causes the data to be encrypted
before being delivered to the underlying network interface.
Minor confusion sometimes arises when people find that /dev/ipsec0,
and /dev/ipsec1 are not visible with 'ls'. This is as it should be. Other
network pseudo-devices such as eth0 and eth1 do not have entries in /dev
either. In general, network devices do not need such entries.
If it doesn't generate any errors, do
and see if the output looks something like this:
If it does, you're probably in business.
This example shows:
The routing is:
on the other gateway and look for similar results.
In general, pings or other tests using the public interfaces of East and/or West are
entirely useless. The IPSEC tunnel is for packets between the two protected subnets
and the outside interfaces are not on those subnets. Depending on your routing configuration,
test packets sent via those interfaces will be:
Sometimes it will be inconvenient to use the client machines (Sunrise
and Sunset in our example) for testing. In these cases, use a command
such as:
For information on setting things up so that gateways can do IPSEC to each
other or to remote subnets, see our
configuration document.
If you have other software set up, test with it as well. Telnet from
Sunrise to Sunset, browse a web server on the remote net and so on.
This really has to be done from a third machine, not from one of the
gateways. On the gateways you'll see packets at intermediate stages
of processing and the result will be confusing. Also, both tcpdump(8)
and nmap(8) use the libpcap library. That library does not recognise
ipsec? devices and will generate "bad physical medium" error messages
if you try to use it with them.
The packets should, except for some of the header information, be
utterly unintelligible. The output of good encryption looks exactly
like random noise.
You can put recognizable data in the ping packets with something like:
For many other protocols, you need to check if you have encrypted data
or ASCII text. Encrypted data has approximately equal frequencies for
all 256 possible characters. ASCII text has most characters in the
printable range 0x20-0x7f, a few control characters less than 0x20,
and none at all in the range 0x80-0xff.
0x20, space, is a good character to look for. In normal English text
space occurs about once in seven characters, versus about once in 256
for random or encrypted data. You can put long sequences of spaces in
your data and look for 0x20202020 in output, but this is not usually
necessary.
If packets look like total garbage, nothing recognizable, all is well.
Note that to shut down a connection, you must do:
Again, you can verify with the same commands.
Repeat the ping test. Repeat the tcpdump test.
If everything succeeds, congratulations.
You now have a working Linux FreeS/WAN installation.
For information on configuring the system for production use, see our
Configuration document.
Matching numbers
It is important that the numbers here match the network configuration.
Suppose you are at the Reno office and your ipsec.conf file now has,
among others, these lines:
config setup
interfaces="ipsec0=eth0"
conn reno-van
left=101.101.101.101
right=202.202.202.202
When you tell FreeS/WAN to start the reno-van connection, it doesn't
automagically know that it is in Reno, or that it is "left" in the
configuration. It discovers that by comparing the IP address for
ipsec0 (and, if it is set, for ipsec1) to the addresses for left and
right. ipsec0 inherits its address from the underlying device, eth0
in our example.
Once it has these parameters, FreeS/WAN sets things so that
leftsubnet=192.168.3.0/24
This can be omitted if there is no subnet, if left is acting as its
own gateway.
All should be well.
Testing the installation
cat /proc/net/ipsec_tncfg
Manually keyed test
The initial tests should be done with manually keyed connections.
This
lets you test the lower-level parts of Linux FreeS/WAN (mainly the
KLIPS code which you've added to your kernel)
while bypassing the higher-level parts. We will get to those once we're sure
the low level works right.
ipsec manual --up name
replacing name with the connection name you used in /etc/ipsec.conf.
ipsec look
foo.spsystems.net Wed Nov 25 22:51:45 EST 1998
-------------------------
10.0.1.0/24 -> 11.0.1.0/24 => tun0x200@11.0.0.1 esp0x202@11.0.0.1
-------------------------
tun0x200@11.0.0.1 IPv4_Encapsulation: dir=out 10.0.0.1 -> 11.0.0.1
esp0x203@10.0.0.1 3DES-MD5-96_Encryption: dir=in iv=0xc2cbca5ba42ffbb6 seq=0 bit=0x00000000 win=0 flags=0x0<>
esp0x202@11.0.0.1 3DES-MD5-96_Encryption: dir=out iv=0xc2cbca5ba42ffbb6 seq=0 bit=0x00000000 win=0 flags=0x0<>
Destination Gateway Genmask Flags MSS Window irtt Iface
11.0.0.0 0.0.0.0 255.255.255.0 U 1500 0 0 eth1
11.0.1.0 11.0.0.1 255.255.255.0 UG 1404 0 0 ipsec0
a tunnel tun0x200 going to 11.0.0.1
outgoing connection esp0x202
incoming connection esp0x203
Both connections use ESP with
3DES encryption and
MD5 authentication.
11.0.0.0 via eth1 and the Internet
11.0.1.0 via ipsec0 which encrypts and then sends to 11.0.0.1
This routes all traffic to the protected network 11.0.1.0 through an IPSEC tunnel
to the gateway 11.0.0.1.
ipsec manual --up name
ipsec look
In either case, they tell you nothing about the tunnel.
traceroute -i eth0 -f 20 192.168.7.1
where each of the interfaces specified (eth0 and 192.168.7.1 in the example)
are on one of the protected subnets, eth0 being the local
gateway's interface on that side and 192.168.7.1 the remote gateway's subnet
interface. This forces the packets through the IPSEC tunnel you want to test.
Testing with tcpdump
ping -p feedfacedeadbeef 11.0.1.1
"feedfacedeadbeef" is a legal hexadecimal pattern that is easy to pick
out of hex dumps.
Testing Automatic connections
ipsec manual --down name
on both gateways. This shuts down the named tunnel. You can verify with the same
commands used to check it was up:
ps -ax
ipsec look
ipsec auto --add name
on both gateway machines. Then do:
ipsec auto --up name
on one gateway. The first command adds the information on this connection
to Pluto's database. The second makes the connection active.
ipsec auto --down name
on both gateway machines, even though you only start it
from one.