[Date Prev][Date Next][Thread Prev][Thread Next][Date
Index][Thread Index]
linux-ipsec: My FreeS/WAN 1.5 setup diary
I succesfully got my FreeS/WAN test network to work. I made a little diary
of it -- you can find it as an attachment to this email. Maybe someone has
use for it?
Of course I'd appreciate all comments about my setup -- I might have done
something unnecessary and stupid :) But it's working!
Peter
This diary describes how I built a test network of two local nets and a
"simulated" internet, and how I built a VPN between these local nets over
the virtual internet.
As an information source I used the book "Securing and Optimizing Linux
v.1.3 RedHat Edition". It was for FreeSWAN 1.3 but almos everything in it
was still up to date.
BUILDING THE TEST NET
=====================
Here is the geography of the test network and information about the
machines I used:
----------
| JERSEY | local (right) client (win98 celeron laptop)
----------
eth0 192.168.1.2
|
|
eth1 192.168.1.1
-----------
| MOSKOVA | local (right) gateway and freeswan 1.5 server (redhat 6.2 p90)
-----------
eth0 172.16.2.2
|
|
eth0 172.16.2.1
--------
| JOLO | router (redhat 6.2 celeron)
--------
eth1 172.16.1.1
|
|
eth0 172.16.1.2
-----------
| OKINAWA | remote(left) gateway and freeswan 1.5 server (redhat 6.2 p100)
-----------
eth1 10.1.2.1
|
|
eth0 10.1.2.2
-------
| MMA | remote (left) client (redhat 6.2 p200)
-------
I wanted the 172.16.1.0 and 172.16.2.0 nets to simulate the public
internet and the 10.1.2.0 and 192.168.1.0 to be private local networks.
I created a /etc/hosts file for all RH boxes, which looked like this:
--snip--
jersey 192.168.1.2
moskova1 192.168.1.1
moskova0 172.16.2.2
jolo0 172.16.2.1
jolo1 172.16.1.1
okinawa0 172.16.1.2
okinawa1 10.1.2.1
--snip--
On RedHat machines I edited the /etc/sysconfig/network files, where I put
information about gateways and the gateway interfaces. Here's a list of
who is using which gateway and using which interface:
mma's gw (eth0) is 10.1.2.1
okinawa's gw (eth0) is 172.16.1.1
moskova's gw (eth0) is 172.16.2.1
jersey's gw (eth0) is 192.168.1.1
For example mma's network file looked like this:
--snip--
NETWORKING=yes
HOSTNAME=mma
GATEWAY=10.1.2.1
GATEWAYDEV=eth0
--snip--
Jolo has no gateways as it is the place where the gateways are leading
(the internet).
On Jersey I of course used Window's own network configuration utilities.
The hosts file can be found on Win98 from the Windows directory where it
is named as hosts.sam. You have to remove the .sam from the filename for
it to work.
On RH boxes I also configured the network interface cards by editing the
/etc/sysconfig/network-scripts/ifcfg-ethX files where X is the number of
the ethernet interface. Here's for example mma's ifcfg-eth0:
--snip--
DEVICE=eth0
BOOTPROTO=static
IPADDR=10.1.2.2
NETMASK=255.255.255.0
--snip--
To get routing enabled for moskova, jolo and okinawa I edited their
/etc/sysctl.conf files to look like this:
--snip--
net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_filter = 0
net.ipv4.ip_always_defrag = 1
kernel.sysrq = 0
--snip--
Now the config files are ok. I restarted my network services on every
machine with '/etc/rc.d/init.d/network restart'.
For the VPN to work I added additional routes in moskova and okinawa to
the remove private nets:
[root@moskova root]# route add -net 10.1.2.0 netmask 255.255.255.0 gw
172.16.2.1
[root@mokinawa root]# route add -net 192.168.1.0 netmask 255.255.255.0 gw
172.16.1.1
I also fetched from RedHat's site the update for iputils
(iputils-20001010-1.6x.i386.rpm) because without it pinging would fail
to work for me. I now tested the network from moskova with 'ping
okinawa0'. mma cannot ping jersey or vice versa because they are on
localnets and cannot see each other yet -- actually they can ping only
their gateways at this moment, because jolo doesn't know about the
private nets. You could of course at this point setup masquerading
firewalls on moskova and okinawa to get mma and jersey to ping the
machines in the internet we just created.
SETTING UP FREES/WAN IN MOSKOVA
===============================
I fetched the freeswan 1.5 tar ball and unpacked it in /usr/src. For
getting freeswan to work we need to build a patched kernel for it so I
grabbed the linux kernel 2.2.17 from my local mirror and unpacked it in
/usr/src also (first moving the old kernel sources away from
/usr/src/linux). Then I compiled freeswan and inserted the freeswan code
to the kernel source:
[root@moskova freeswan-1.5]# make insert
[root@moskova freeswan-1.5]# make programs
[root@moskova freeswan-1.5]# make install
Configuring and building the kernel
-----------------------------------
First I removed old asm, linux and scsi links from /usr/include. Then I
made the new ones:
[root@moskova linux]# ln -s /usr/src/linux/include/scsi /usr/include/scsi
[root@moskova linux]# ln -s /usr/src/linux/include/asm-i386
/usr/include/asm
[root@moskova linux]# ln -s /usr/src/linux/include/linux
/usr/include/linux
Then I ran 'make menuconfig' in /usr/src/linux and configured my kernel. I
answered Y to all questions under Networking --> IPSec options
(FreeS/WAN). I enabled routing, firewalling, masquerading, loopback device
support and everything else I thought would be necessary for my server to run. My information
source told me to not to disable "Kernel/User netlink socket" nor "Netlink
device emulation" under "Network Options" and I believed it. Then I exited
and saved my configuration and started compiling:
[root@moskova linux]# make dep; make clean; make bzImage
Now we have to move the kernel binary to the right place and fix some
symbolic links:
[root@moskova linux]# rm /boot/vmlinuz
[root@moskova linux]# rm /boot/System.map
[root@moskova linux]# mv arch/i386/boot/bzImage /boot/vmlinuz-2.2.17
[root@moskova linux]# ln -s /boot/vmlinuz-2.2.17 /boot/vmlinuz
[root@moskova linux]# mv System.map /boot/System.map-2.2.17
[root@moskova linux]# ln -s /boot/System.map-2.2.17 /boot/System.map
[root@moskova linux]# mkinitrd /boot/initrd-2.2.17.img 2.2.17
Made and installed the kernel modules:
[root@moskova linux]# rm -fR /lib/modules/2.2.17/
[root@moskova linux]# make modules; make modules_install
[root@moskova linux]# depmod -a
I edited /etc/modules.conf where I put all the necessary information about
the modules I need. For example I needed the driver for my 3COM's 3C590C
network cards. Moskova's modules.conf looked like this:
alias parport_lowlevel parport_pc
alias eth0 3c59x
alias eth1 3c59x
alias sound-slot-0 es1371
And finally I edited /etc/lilo.conf for my liking and ran lilo after
that with 'lilo -v'. Here's Moskova's lilo.conf (for example only, your
setup may differ):
--snip--
boot=/dev/hda
map=/boot/map
install=/boot/boot.b
prompt
timeout=50
linear
default=linux
image=/boot/vmlinuz-2.2.16-3
initrd=/boot/initrd-2.2.16-3.img
label=linux-old
read-only
root=/dev/hda2
image=/boot/vmlinuz-2.2.17
initrd=/boot/initrd-2.2.17.img
label=linux
read-only
root=/dev/hda2
--snip--
After that I rebooted!
The Ipsec configuration files
-----------------------------
There are two config files for freeswan to work with. They are
/etc/ipsec.sercrets and /etc/ipsec.conf. You may take a peek to look at
them now.
I made Moskova's /etc/ipsec.conf look like:
config setup
interfaces="ipsec0=eth0"
klipsdebug=none
plutodebug=none
plutoload=%search
plutostart=%search
# sample connection
conn okinawa-moskova
left=172.16.0.2
leftsubnet=10.0.0.0/24
leftnexthop=172.16.0.1
right=172.16.9.2
rightsubnet=10.0.3.0/24
rightnexthop=172.16.9.1
keyingtries=0
auth=esp
authby=rsasig
I created a shared key to be inserted in ipsec.secrets:
[root@moskova freeswan-1.5]# ipsec ranbits 256 >temp
I copied the contents of the temp file and pasted it into my ipsec.secrets
and made it look like this:
--snip--
172.16.0.1 172.16.9.2
"0x50c570e3_e918c81e_98d81257_e7db3802_61655fc2_60802c77_61d1f9a7_660eb276"
--snip--
I removed the temp file after this.
As I want to use RSA I made the public keys like this:
[root@moskova freeswan-1.5]# ipsec rsasigkey --verbose 1023 >moskova-keys
[root@moskova freeswan-1.5]# ipsec rsasigkey --verbose 1023 >okinawa-keys
I pasted the lines starting with #pubkey= to my ipsec.conf file
leftrsasigkey (from okinawa-keys) and rightrsasigkey (from moskova-keys):
--snip--
config setup
interfaces="ipsec0=eth0"
klipsdebug=none
plutodebug=none
plutoload=%search
plutostart=%search
# sample connection
conn okinawa-moskova
left=172.16.0.2
leftsubnet=10.0.0.0/24
leftnexthop=172.16.0.1
right=172.16.9.2
rightsubnet=10.0.3.0/24
rightnexthop=172.16.9.1
keyingtries=0
auth=ah
authby=rsasig
leftrsasigkey=0x01037906285fd5b928416852b4d8ba468dfbc30612c232ce4b92780bbb762a4365b71ef54c57f721a76c61d382972a35c03360a59ef8a4b1f9f2488c1eafb9d34db26a777c555b9b5b3170d292318f0a03c7ce090c3444c7a3b07f8d467924ffd8d85b32374651dbff36d7096940e8ce171af413ddb4c99cb59137f746f4db8afe89
rightrsasigkey=0x010392e1752adbcd9bc25ffc8196add8d6dad8acb0a2f34b6b00a31685f0a9c62da40aed42d12724de5c23883724b20f3df77eecca06a1c962ca2ea71961b76bf85b9aa46477f50ea74f32a33a8af3228e801f757605a47361ba49deb711bfa2f0f03d19026e8bb9faf3ad2aa70f1642015e9fe0286b72ad32cd788dc80d0e76a7ff
auto=start
--snip--
Then I copied the content of the moskova-keys file to my ipsec.secrets. It
looks like this now:
--snip--
172.16.0.1 172.16.9.2
"0x50c570e3_e918c81e_98d81257_e7db3802_61655fc2_60802c77_61d1f9a7_660eb276"
: RSA {
# 1024 bits, Fri Nov 3 19:16:11 2000
# for signatures only, UNSAFE FOR ENCRYPTION
#pubkey=0x010392e1752adbcd9bc25ffc8196add8d6dad8acb0a2f34b6b00a31685f0a9c62da40aed42d12724de5c23883724b20f3df77eecca06a1c962ca2ea71961b76bf85b9aa46477f50ea74f32a33a8af3228e801f757605a47361ba49deb711bfa2f0f03d19026e8bb9faf3ad2aa70f1642015e9fe0286b72ad32cd788dc80d0e76a7ff
#IN KEY 0x4200 4 1
AQOS4XUq282bwl/8gZat2Nba2KywovNLawCjFoXwqcYtpArtQtEnJN5cI4g3JLIPPfd+7MoGocliyi6nGWG3a/hbmqRkd/UOp08yozqK8yKOgB91dgWkc2G6Sd63Eb+i8PA9GQJui7n6860qpw8WQgFen+Aoa3KtMs14jcgNDnan/w==
# (0x4200 = auth-only host-level, 4 = IPSec, 1 = RSA)
Modulus:
0x92e1752adbcd9bc25ffc8196add8d6dad8acb0a2f34b6b00a31685f0a9c62da40aed42d12724de5c23883724b20f3df77eecca06a1c962ca2ea71961b76bf85b9aa46477f50ea74f32a33a8af3228e801f757605a47361ba49deb711bfa2f0f03d19026e8bb9faf3ad2aa70f1642015e9fe0286b72ad32cd788dc80d0e76a7ff
PublicExponent: 0x03
# everything after this point is secret
PrivateExponent:
0x61eba371e7de67d6eaa8566473e5e491e5c875c1f7879cab1764594b1bd973c2b1f381e0c4c33ee817b024c3215f7ea4ff4886af168641dc1f1a10ebcf9d503c0f12e1227c00fe7af45f775729376bc30d7c7c81e0cb6538ba0247616ad4c38096540de5e8942056a7b2aa92cf8ecc1fa4aab01a89684fb50409bdf4b0519a7b
Prime1:
0xc86470207a511a3bf437550055ea01c14d5bf9666f2f4d94c91b7ab7f6e850fead0addb9bff6c8690c6a5b727a219187de64cba1e67cfd8332f0809c7ac6d18d
Prime2:
0xbba3a2a3c0bc0f5acfdcb287df656b1a3ddec1dc6412fc5069bfd147a87b7ab0ae900fdbeee50208a5344bc064ca3da74a7b54a1be13bdbabf8eaa818b356ebb
Exponent1:
0x85984ac0518b66d2a2cf8e003946abd63392a6444a1f890ddb67a7254f458b54735c93d12aa4859b5d9c3cf6fc1661053eeddd1699a8a90221f5ab12fc848bb3
Exponent2:
0x7d17c1c2807d5f91dfe877053f98f2117e94813d980ca8359bd5362fc5a7a72074600a929f4356b06e22dd2aeddc291a31a78dc129627e7c7fb471abb2239f27
Coefficient:
0x3976b2acf5141fdc988d8e45bccaf07e3444989ed5e0f3b09c718ebd05fcd3d9f96cf9d43978d65fbc989b7f31d4d81d968aa2a3d0b50268624a2e0be2717d3a
}
# end
--snip--
That's it. Now it was time to configure the other freeswan server,
Okinawa.
I compiled the 2.2.17 kernel and installed ipsec the same way as I did in
Moskova.
After that I copied the ipsec.conf and ipsec.secrets from Okinawa to
Moskova. As they were using the same interfaces for ipsec (eth0) I didn't
have to change anything in the ipsec.conf file. But in ipsec.secrets I of
course had to change RSA information which could be retriveved from the
file okinawa-keys I had created in Moskova. Okinawa's ipsec.secrets file
looked like this:
--snip--
172.16.0.1 172.16.9.2
"0x50c570e3_e918c81e_98d81257_e7db3802_61655fc2_60802c77_61d1f9a7_660eb276"
: RSA {
# 1024 bits, Fri Nov 3 19:11:43 2000
# for signatures only, UNSAFE FOR ENCRYPTION
#pubkey=0x01037906285fd5b928416852b4d8ba468dfbc30612c232ce4b92780bbb762a4365b71ef54c57f721a76c61d382972a35c03360a59ef8a4b1f9f2488c1eafb9d34db26a777c555b9b5b3170d292318f0a03c7ce090c3444c7a3b07f8d467924ffd8d85b32374651dbff36d7096940e8ce171af413ddb4c99cb59137f746f4db8afe89
#IN KEY 0x4200 4 1
AQN5Bihf1bkoQWhStNi6Ro37wwYSwjLOS5J4C7t2KkNltx71TFf3IadsYdOClyo1wDNgpZ74pLH58kiMHq+5002yand8VVubWzFw0pIxjwoDx84JDDREx6Owf41GeST/2NhbMjdGUdv/NtcJaUDozhca9BPdtMmctZE390b024r+iQ==
# (0x4200 = auth-only host-level, 4 = IPSec, 1 = RSA)
Modulus:
0x7906285fd5b928416852b4d8ba468dfbc30612c232ce4b92780bbb762a4365b71ef54c57f721a76c61d382972a35c03360a59ef8a4b1f9f2488c1eafb9d34db26a777c555b9b5b3170d292318f0a03c7ce090c3444c7a3b07f8d467924ffd8d85b32374651dbff36d7096940e8ce171af413ddb4c99cb59137f746f4db8afe89
PublicExponent: 0x03
# everything after this point is secret
PrivateExponent:
0x50aec59539261ad6458c78907c2f095282040c8177343261a55d27a41c2cee7a14a3883aa4c11a484137ac64c6ce8022406e69fb1876a6a185b2bf1fd1378920ac25be2547abe97a11ee4701a3617bc5fe7c9d523ba0f18854f4366aa2dfa5643d3ad6e515ff26806aefa169f1106838b964048c2354525b881d8cbf2efab40b
Prime1:
0xda5c17f2c79251f625e2ae46a0d6bc792136aa032f97b5cdd168d9a8e3795715e63f42efd0d51b1d80cd8bd23ca2f21bca9fd9333eedb9fb317d8a0adf977fbd
Prime2:
0x8de2c72aa8872b04300a796879210da5af177635bbbe83962eb61b304d3709ac191ab1fee0082a58b5d46b4fc29288aa135dfdaf55b0800cba4d69cb357b70bd
Exponent1:
0x9192baa1da618bf96e971ed9c08f2850c0cf1c021fba7933e0f0911b4250e4b9442a2c9fe08e1213ab33b28c286ca167dc6a90ccd49e7bfccba906b1ea64ffd3
Exponent2:
0x5e972f71c5af7202cab1a645a61609191f64f97927d457b97479677588cf5bc810bc76a9eab01c3b23e2f2352c61b071623ea91f8e75aab326de468778fcf5d3
Coefficient:
0x4fd954347c830e14704cde1f2514e3c8be5e0baf734e2b8550ac13f2b4df79d16c8fd42ce19dab62d6bee3855915ff47bed737f13d62404f8941a9c2e356cd91
}
#end
--snip--
After that I rebooted both gateways and watached how on boot both
of my freeswan servers negotiated with eachother and started my VPN. After
the servers were up I could ping from jersey to mma and vice versa. I ran
'tcpdump' on Jolo and saw that the traffic was encrypted (only traffic
from ports 50 and 51 was to be seen).
For testing purposes I found convient to remove the ipsec service from the
list of automatically started services at boot (just use the 'setup'
command and choose "System Services" and unselect ipsec with hitting
space) and to start and stop it using the commands '/etc/rc.d/init.d/ipsec
start' and '/etc/rc.d/init.d/ipsec stop'.
As I wanted mma and jersey to bee in the same Windows workgroup I started
WINS in mma using Samba. I defined the WINS server's ip address in jersey
and soon (after reboot and a few minutes waiting) I could see mma in
jersey's Network neighborhood.
IPCHAINS FIREWALL
=================
I wanted my both private nets to be behind a masquerading firewall.
Natural choice for me was to build an ipchains script which would provide
me this. As I'm no guru with ipchains I first tried to use the one that is
specified in the book "Securing and Optimizing Linux" but couldn't get it
working. So I asked my friend to build me a working script. Here's the
result, a working ipchains script for moskova:
--snip--
#!/bin/bash
#--------------------------------------------------
# Variables
#--------------------------------------------------
PATH=/sbin:/usr/sbin
ETH0IP=172.16.2.2
ETH1IP=192.168.1.1
GOODIF=eth1
GOODIP=192.168.1.1
BADIF=eth0
BADIP=172.16.2.2
ETH0MASK=255.255.255.0
ETH1MASK=255.255.255.0
NATNET=192.168.1.0/255.255.255.0
DEFGW=172.16.2.1
ANYWHERE=0.0.0.0/0
IPSECSG=172.16.1.2
FREESWANIF=ipsec0
REMOTEGOOD=10.1.2.0/24
#---------------------------------------------
# Preparations
#---------------------------------------------
# Remove old chains
ipchains -F
ipchains -X
# Secure the execution of this script. Removed in the end.
ipchains -I input 1 -j DENY
ipchains -I output 1 -j DENY
ipchains -I forward 1 -j DENY
# Define the chains between networks
ipchains -N good-bad
ipchains -N bad-good
# Enable loopback device usage
ipchains -A input -i lo -s 0/0 -d 0/0 -j ACCEPT
ipchains -A output -i lo -s 0/0 -d 0/0 -j ACCEPT
#--------------------------------------------------------------------
# ICMP
#--------------------------------------------------------------------
# let's create the icmp-acc chain where we define the icmp rules
ipchains -N icmp-acc
ipchains -A icmp-acc -p icmp --icmp-type destination-unreachable -j ACCEPT
ipchains -A icmp-acc -p icmp --icmp-type parameter-problem -j ACCEPT
ipchains -A icmp-acc -p icmp --icmp-type source-quench -j ACCEPT
ipchains -A icmp-acc -p icmp --icmp-type time-exceeded -j ACCEPT
#---------------------------------------------------------------------
# Chains for interfaces
#----------------------------------------------------------------------
# create the chains bad-if and good-if
ipchains -N bad-if
ipchains -N good-if
#
ipchains -A input -i $FREESWANIF -s $ANYWHERE -d $ANYWHERE -j ACCEPT
ipchains -A input -d $BADIP -j bad-if
ipchains -A input -d $GOODIP -j good-if
ipchains -A output -i $FREESWANIF -s $ANYWHERE -d $ANYWHERE -j ACCEPT
#
# bad-if
#
# ssh
ipchains -A bad-if -p TCP ! -y --sport ssh -j ACCEPT
ipchains -A bad-if -p UDP --sport ssh -j ACCEPT
# masq replies
ipchains -A bad-if -p TCP --dport 61000:65096 -j ACCEPT
ipchains -A bad-if -p UDP --dport 61000:65096 -j ACCEPT
# icmp
#ipchains -A bad-if -j icmp-acc
ipchains -A bad-if -p ICMP --icmp-type pong -j ACCEPT
ipchains -A bad-if -p udp -s $IPSECSG -j ACCEPT
ipchains -A bad-if -p 50 -s $IPSECSG -j ACCEPT
ipchains -A bad-if -p 51 -s $IPSECSG -j ACCEPT
ipchains -A bad-if -j DENY -l
#
# good-if
#
ipchains -A good-if -i ! $GOODIF -j DENY -l
# icmp
ipchains -A good-if -j icmp-acc
# proxy
ipchains -A good-if -p tcp --dport 3005 -j ACCEPT
ipchains -A good-if -p udp --dport 3005 -j ACCEPT
# http
ipchains -A good-if -p tcp ! -y --sport 80 -j ACCEPT
ipchains -A good-if -p udp --sport 80 -j ACCEPT
# ssh
ipchains -A good-if -p tcp --sport ssh -j ACCEPT
ipchains -A good-if -p udp --sport ssh -j ACCEPT
ipchains -A good-if -p tcp --dport ssh -j ACCEPT
ipchains -A good-if -p udp --dport ssh -j ACCEPT
ipchains -A good-if -p udp -s $IPSECSG -j ACCEPT
ipchains -A good-if -p 50 -s $IPSECSG -j ACCEPT
ipchains -A good-if -p 51 -s $IPSECSG -j ACCEPT
ipchains -A good-if -j DENY -l
#-------------------------------------------------------------
# rp filtering
#-------------------------------------------------------------
# rp filtering is bad for ipsec
echo 0 > /proc/sys/net/ipv4/conf/$BADIF/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/$FREESWANIF/rp_filter
# forward anything from the freeswan virtual if ipsec tunnel
#---------------------------------------------------------------------
# Forwarding and masq modules
echo "1" > /proc/sys/net/ipv4/ip_forward
modprobe ip_masq_ftp
modprobe ip_masq_raudio
ipchains -M -S 3600 10 50
ipchains -A forward -i $FREESWANIF -s $ANYWHERE -d $ANYWHERE -j ACCEPT -l
ipchains -A forward -s $REMOTEGOOD -d $NATNET -i $GOODIF -j ACCEPT -l
ipchains -A forward -s $NATNET -i $BADIF -j good-bad -l
ipchains -A forward -i $GOODIF -j bad-good -l
ipchains -A forward -j DENY -l
# Allow all tcp udp imcp good-bad. Masquerade.
ipchains -A good-bad -j MASQ -l
# Deny all nonmasqueraded from bad to good. Log.
ipchains -A bad-good -j DENY -l
#-----------------------------------------------------------------
# The final touch
#-----------------------------------------------------------------
# Remove the blocks that we defined in the beginning
ipchains -D input 1
ipchains -D output 1
ipchains -D forward 1
--snip--
That's it! Time for a cup of coffee...
Follow-Ups:
References: