Friday, April 16, 2010

HOWTO connect Nokia VPN to GNU/Linux

Overview

This HOWTO describes how to setup a GNU/Linux box as an IPSec gateway and a Nokia VPN client as a road-warrior so that they can talk to each other. The protocol used is IPSec with RSA authentication.
While most of the procedures described here are documented somewhere or other, I could not find them summarized under one roof, so I decided to do it myself.

To get this setup going, you will have to setup a certificate authority (CA) to issue certificates, hack the racoon IKE daemon to account for a problematic nat-t negotiation protocol by the Nokia VPN client, and configure both the racoon daemon and the Nokia vpn client so that they will be able to talk to each other and recognize the certificates.

This HOWTO assumes intermediate knowledge of GNU/Linux. You are assumed to know your shell, and have no problems in compiling packages from source. I do not assume any specific GNU/Linux distribution, just a 2.6.x kernel.

Prerequisites

GNU/Linux

  • openssl
  • ipsec-tools modified for Nokia (see this post)
  • possibly open the firewall to the IPsec packets (see this post)
  • 2.6 kernel



Nokia

(get it from Nokia)
  • Mobile VPN Client version >= 3.1
  • A compatible phone

Setting up a certificate infrastructure

Generating CA certificate

First we need to setup a certificate authority (CA) to sign all the certificates used for authenticating the gateway and clients.
# set certificate_dir to the directory you wish to keep all the certificates in:
mkdir ${certificate_dir} && cd ${certificate_dir}

# generate 2 2048 bit rsa key for the CA
openssl genrsa 2048 > ca.key

# generate the CA bookkeeping files
mkdir -p demoCA/newcerts
touch demoCA/index.txt
echo "00" > demoCA/serial 
echo "00" > demoCA/crlnumber

# generate the CA certificate and make link a hash to it
openssl req -days 1825 -x509 -new -key ca.key > ca.crt
ln -s ca.crt `openssl x509 -noout -hash -in ca.crt`.0

# generate the certificate revocation list (CRL) and hash
openssl ca -gencrl -cert ca.crt -keyfile ca.key -out crl.pem
ln -s crl.pem `openssl crl -noout -hash < crl.pem`.r0
At this stage we setup a CA which has enough function to support all of our IPSec needs.

Creating the gateway certificates

We now create the certificates for our gateway: we create a 2048 bit key, make a request and get it signed by our CA
cd ${certificate_dir}
openssl genrsa 2048 > vpngw.key
openssl req -new -key vpngw.key > vpngw.csr
openssl ca -keyfile ca.key -cert ca.crt -in vpngw.csr -out vpngw.crt

Creating certificates for Nokia clients

For each client (or group of clients), we need to create a private key and certificate in a format that Symbian will recognize:
cd ${certificate_dir}
mkdir -p Nokia/vpn

# key and certificate as for the client
openssl genrsa 2048 > client.key
openssl req -new -key client.key > client.csr
openssl ca -keyfile ca.key -cert ca.crt -in client.csr -out client.crt

# convert them into Nokia compatible format:
openssl x509 -outform der -in client.crt -out Nokia/vpn/client.cer
## MUST enter an encryption passwd! ##
openssl pkcs8 -outform DER -v2 des-ede3-cbc -topk8 -in client.key -out Nokia/vpn/client.key
# convert the CA certificate into Nokia compatible format:
openssl x509 -outform der -in ca.crt -out Nokia/vpn/ca.crt
Note: you must supply an encryption password for the client key!

Setting up IKE on GNU/Linux

Use the following raccon.conf file as a template:
#path to the certificate -- use the above defined certificate_dir
path certificate "/etc/racoon/certs";

## uncommend to get a lot of debug output
#log debug; 

#option of controlling racoon by racoonctl tool is disabled
# substituted the network address of the relevant (external) interface here
listen {
 adminsock disabled;
 isakmp 192.168.10.1 [500];
 isakmp_natt 192.168.10.1 [4500];
}

#remote section – anonymous address of road-warrior client
#any change in this section should be reflected in the Nokia vpn policy file
remote anonymous {
 exchange_mode main;
 certificate_type x509 "vpngw.crt" "vpngw.key";
 ca_type x509 "ca.crt";
 verify_cert on;
 proposal_check claim;
 generate_policy on;
 nat_traversal on;
 dpd_delay 20;
 ike_frag on;
 passive on;

 verify_identifier on;
 my_identifier asn1dn;
 peers_identifier asn1dn;
 
 #agreement proposal in IKE first phase
 proposal {
  encryption_algorithm aes 256;
  hash_algorithm sha1;
  authentication_method rsasig;
  dh_group modp1024;
 }
}

#SA information for IKE second phase
#any change in this section should be reflected in the Nokia vpn policy file
sainfo anonymous {
 pfs_group modp1024;
 lifetime time 1 hour;
 encryption_algorithm aes;
 authentication_algorithm hmac_sha1;
 compression_algorithm deflate;
}

#############################################################
## local network information
## change the settings in this section to suit your own network setup
mode_cfg {
 #starting address of the IP address pool
 network4 192.168.10.20;
 #maximum number of clients
 pool_size 20;
 #network mask
 netmask4 255.255.255.0; 
 #authentication source – user database on the system
 auth_source system;
 #configuration source – from data given in this section
 conf_source local;
 #DNS and WINS servers IP addresses
 dns4 192.168.10.1;
 wins4 192.168.10.1;
 #banner file – welcome message
 banner "/etc/racoon/motd";
}        
Things to remember
  • At the top of the file, set "path certificate" to the path of your CA and vpngw certificates
  • You would mostly need to change the things in the mode_cfg section to suit you own network. Other sections should be good as-is.
  • The "remote" and "sainfo" sections are especially tailored to fit the nokia vpn profile, so changing them will induce a change in the nokia vpn policy.

Setting up the Nokia VPN policy

The Nokia VPN policy file is really a zip archive containing two configuration files (.pol & ..pin), the client key and certificate and the CA certificate. We will construct this archive in the ${certificate_dir}/Nokia/vpn directory. The contents of the directory:
  • my-vpn.pin: policy information
  • my-vpn.pol: policy configuration
  • ca.crt: CA certificate. See above for info on how to create
  • client.cer: client certificate. See above for info on how to create
  • client.key: client key. See above for info on how to create
The policy information file contains information to be shown about the policy in the phone:
[POLICYNAME]
My First VPN Policy
[POLICYVERSION]
1.0
[POLICYDESCRIPTION]
This is my first policy. Lets see if it works
[ISSUERNAME]
Me LTD.
[CONTACTINFO]
me@me.org, +44-11111111
The policy configuration file contains all the config info. The following file is compatible with the racoon config given above:
SECURITY_FILE_VERSION: 1

[INFO]
My First VPN

[POLICY]
sa my-vpn = {
 esp 
 
 ## AES-256
 encrypt_alg 12   
 max_encrypt_bits 256
 ## SHA-1
 auth_alg 3
 identity_remote 0.0.0.0/0
 src_specific
 hard_lifetime_bytes 0
 hard_lifetime_addtime 3600
 hard_lifetime_usetime 3600
 soft_lifetime_bytes 0
 soft_lifetime_addtime 3600
 soft_lifetime_usetime 3600
 replay_win_len 0
 ## prefect forward secracy (see also IKE section)
 pfs
}



remote 0.0.0.0 0.0.0.0 = { my-vpn(**GATEWAY_IP**) }
inbound = { }
outbound = { }

[IKE]
ADDR: **GATEWAY_IP** 255.255.255.255
IKE_VERSION: 1
MODE: Main
ID_TYPE: 9
REPLAY_STATUS: FALSE
USE_MODE_CFG: TRUE
IPSEC_EXPIRE: TRUE
USE_XAUTH: FALSE
USE_COMMIT: FALSE
ESP_UDP_PORT: 0
SEND_NOTIFICATION: TRUE
INITIAL_CONTACT: TRUE
USE_INTERNAL_ADDR: TRUE
DPD_HEARTBEAT: 90
NAT_KEEPALIVE: 60
REKEYING_THRESHOLD: 90
GROUP_DESCRIPTION_II: MODP_1024

### Proposal
PROPOSALS: 1
ENC_ALG: AES256-CBC
AUTH_METHOD: RSA_SIGNATURES
HASH_ALG: SHA1
GROUP_DESCRIPTION: MODP_1024
GROUP_TYPE: DEFAULT
LIFETIME_KBYTES: 0
LIFETIME_SECONDS: 86400
PRF: NONE

### CA
CAs: 1
  FORMAT: BIN
  DATA: ca.crt

### CLient credentials
OWN_CERT_TYPE: USER
OWN_CERTS: 
  FORMAT: BIN
  DATA: client.cer
  PRIVATE_KEY_FORMAT: BIN
  PRIVATE_KEY_DATA: client.key
Notes:
  • Replace the 2 occurences of **GATEWAY_IP** with you actual gateway's IP
  • Set USE_XAUTH=TRUE for another password verification before connection
  • Set OWN_CERT_TYPE: DEVICE to allow for password-less access to the client key
Zip the above 5 files into my-vpn.vpn:
zip my-vpn.vpn bioc-vpn.pin bioc-vpn.pol ca.crt client.cer client.key
copy the my-vpn.vpn to the phone and install it. There should be no errors reported.

Enjoy the VPN

Thursday, April 15, 2010

iptable rule for allowing IPsec traffic

First, we need to open the firewall to the ESP protocol and open the IKE ports (UDP 500 and 4500). Assuming eth1 is the external interface of the firewall:
iptables --append INPUT --protocol ESP --in-interface eth1 --jump ACCEPT
iptables --append INPUT --protocol UDP --source-port 500 --destination-port 500 --in-interface eth1 --jump ACCEPT
iptables --append INPUT --protocol UDP --source-port 4500 --destination-port 4500 --in-interface eth1 --jump ACCEPT

A way to identify traffic originating from a valid IPsec session (presumably to allow it inside your network) is to use the policy module, which matches the policy used by IPsec for handling a packet.
A good catchall rule is:
iptables \
         --append INPUT \
         --in-interface eth1 \
         --match policy \
         --pol ipsec \
         --dir in \
         --jump LOG \
         --log-level debug \
         --log-prefix "IPSec "
This rule will log all packets coming from a IPsec connected peer with the message "IPSec ".

Sunday, April 4, 2010

ipsec-tools fix for Nokia VPN NAT-T

Nokia NAT-T is not compatible with the linux ipsec-tools. More info can be found in this ticket in the ipsec bug tracker.
An ugly hack which fixes this problem is provided at Nokia VPN (N97) -> raccon -> Nat-T. Since this is the only fix available, we'll go with ugly ...

Basically, the racoon daemon has to be complied without RFC nat-t support and one source line has to be changed.

I will spell out the procedures outlined above:

Using actual "raw" sources

To compile from source, get the ipsec-tools tarball from the ipsec-tools project page.

for compilation I used the following configure options:
./configure \
--enable-hybrid \
--enable-frag \
--enable-gssapi \
--enable-stats \
--enable-dpd \
--enable-fastquit \
--disable-ipv6 \
--enable-natt \
--enable-natt-versions=0,1,2,3,4,5,6,7,8 \
--enable-security-context=kernel
note the "--enable-natt-versions=0,1,2,3,4,5,6,7,8" switch

before compiling change one line in the file ipsec-tools-0.7.1/src/racoon/nattraversal.c:
--- ipsec-tools-0.7.1/src/racoon/nattraversal.c 2009-12-15 08:01:36.000000000 +0100
+++ ipsec-tools-0.7.1.patched/src/racoon/nattraversal.c 2009-10-11 13:39:36.000000000 +0200
@@ -314,7 +314,7 @@
return;
}

- if (iph1->natt_options->version < vid_numeric)
+ if (iph1->natt_options->version == 0)
if (natt_fill_options (iph1->natt_options, vid_numeric) == 0)
iph1->natt_flags |= NAT_ANNOUNCED;
}

You can now compile and install. The resulting racoon daemon will now accept nat-t connections from a Nokia VPN client

Using Debian sources

apt-get install devscripts build-essential fakeroot
apt-get build-dep racoon
apt-get source racoon
cd ipsec-tools*
dch -l local nokia
  • edit debian/rules and add the --enable-natt-versions=0,1,2,3,4,5,6,7,8 option to configure
  • patch src/racoon/nattraversal.c as per above
debuild -us -uc
dpkg -i ../*.deb