A VPN gateway setup
Kernel configuration (top) First you need to build and install a kernel with at least the following options:
options options options options options options INET GATEWAY PFIL_HOOKS IPSEC IPSEC_ESP IPSEC_NAT_T ipfilter
pseudo-device
Packet forwarding (top) You need to enable IPv4 packet forwarding, by using the following command:
# sysctl -w net.inet.ip.forwarding=1
This can be automatically executed on reboot by adding this line to /etc/sysctl.conf:
net.inet.ip.forwarding=1
Certificate generation (top) If you have not already configured OpenSSL, start by installing the sample config file:
# cp /usr/share/examples/openssl/openssl.cnf /etc/openssl/
Then create a private key and use it to create a Certificate Signing Request (CSR):
# # # # # cd /etc/openssl umask 077 openssl genrsa > certs/vpngw.key umask 022 openssl req -new -key certs/vpngw.key -out certs/vpngw.csr
Send the CSR, vpngw.csr to a Certificate Authority (CA) for signature. You will get a x509 certificate, that we shall name vpngw.crt If you want to be your own CA, then perform the following steps to generate the CA private key and certificate, and to sign your CSR:
# # # # # cd /etc/openssl mkdir -p demoCA/newcerts touch demoCA/index.txt echo "00" > demoCA/serial umask 077
Keep the secret keys secret, as your VPN will not be secure anymore if they get disclosed. Give the CA certificate ca.crt to remote users, and move to the next step. Configuring racoon(8) (top) ere is a sample /etc/racoon/racoon.conf file:
path certificate "/etc/openssl/certs"; listen { adminsock disabled; } remote anonymous { exchange_mode aggressive; certificate_type x509 "vpngw.crt" "vpngw.key"; my_identifier asn1dn; proposal_check claim; generate_policy on; # automatically generate IPsec policies dpd_delay 20; # DPD poll every 20 seconds nat_traversal force; # always use NAT-T ike_frag on; # use IKE fragmentation esp_frag 552; # use ESP fragmentation at 552 bytes proposal { encryption_algorithm aes; hash_algorithm sha1; authentication_method hybrid_rsa_server; dh_group 2; } } mode_cfg { network4 10.99.99.1; # 1st address of VPN IPv4 pool pool_size 253; # size of the VPN IP pool: 253 addresses auth_source system; # validate logins against /etc/passwd dns4 10.0.12.1; # IPv4 DNS server wins4 10.0.12.1; # IPv4 WINS server banner "/etc/racoon/motd"; # Banner message for clients pfs_group 2; } sainfo anonymous { pfs_group 2; lifetime time 1 hour; encryption_algorithm aes; authentication_algorithm hmac_sha1; compression_algorithm deflate; }
The mode_cfg section defines the configuration sent from the VPN gateway to the client using ISAKMP mode config. For now only IPv4 configuration is supported. The VPN address pool is defined there, by a base address (network4) and a pool size (pool_size). auth_source explains how the login and password are validated. Possible values are system, to validate against the system user database, pam to use the Pluggable Authentication Module (PAM) system (/etc/pam.d/racoon will be used), and radius to validate logins against RADIUS. Once your /etc/racoon/racoon.conf file is ready, you can launch racoon(8):
# racoon
In order to have racoon(8) started up at boot time, you need the following in /etc/rc.conf:
racoon=YES
More fragmentation problems (top) In the configuration sample, esp_frag is specified so that ESP fragmentation is used to avoid sending packets bigger than 552 bytes. 552 bytes is quite low, but it should work with the most broken DSL modem-routers appliances. The higher esp_frag is, the better the performances are. Using ESP fragmentation, it is possible to exchange IP packets of any size through the tunnel. However, there is a special case for TCP, which may have trouble with Path Maximum Transmission Unit (PMTU) discovery. The solution is to use Maximum Segment Size (MSS) clamping. This can be done in /etc/ipnat.conf, assuming your VPN internal address pool is 10.99.99.0/24:
map ex0 10.99.99.0/24 -> 0/0 mssclamp 512
And type the following to enable that configuration:
# ipf -E; ipnat -f /etc/ipnat.conf
In order to have those commands executed on startup, you need the following in /etc/rc.conf:
ipfilter=YES ipnat=YES
Note that the system will not boot with ipfilter=YES if the /etc/ipf.conf file is missing. You can create a blank file if you do not need any IP filtering. Interaction with firewalls (top) In this VPN solution, the client needs to send UDP packets to ports 500 and 4500 of the VPN gateway. The first packets are exchanged on port 500, then NAT-T negotiation moves the transaction to port 4500.
Firewalls in front of the VPN gateway must be configured to let udp/500 and udp/4500 pass through to the VPN gateway. VPN gateway and RADIUS (top) RADIUS can be used for login validation, IP addresses allocation and accounting. Here is a sample mode_cfg section for /etc/racoon/racoon.conf that enforces RADIUS usage:
mode_cfg { pool_size 253; auth_source radius; conf_source radius; accounting radius; dns4 10.0.12.1; wins4 10.0.12.1; banner "/etc/racoon/motd"; pfs_group 2; } IPv4 pool size login validated against RADIUS IPv4 address obtained by RADIUS RADIUS accounting # IPv4 DNS server # IPv4 WINS server # Banner message for clients # # # #
Additionally, you need to create a /etc/radius.conf file that contains the RADIUS server address and the secret shared with the RADIUS server. This file must be owned by root and mode 0600 in order to keep the shared secret secure. Here is an example, see radius.conf(5) for the details:
auth radius.example.net MyDirtySecret acct radius.example.net MyDirtySecret
VPN client
Cisco VPN client (top) The VPN gateway setup presented in the previous section is interoperable with the Cisco VPN client configured in mutual group authentication (this is a synonym for Hybrid authentication). The group and group password required by Cisco VPN client are ignored by racoon(8), but that does not make user authentication unsecure. Do not forget to set up the client with IPsec over UDP transport to get NAT-T enabled. racoon(8) as the client: configuration example (top) It is also possible to use racoon(8) as a client. You need to install the CA certificate in /etc/openssl/certs/ca.crt, and the configuration below in /etc/racoon/racoon.conf
path certificate "/etc/openssl/certs"; path pre_shared_key "/etc/racoon/psk.txt"; listen { # socket used for communication between racoon and racoonctl
The phase1-up.sh and phase1-down.sh scripts are called when the IKE phase 1 is established and terminated, that is, at VPN connection and disconnect time. They are responsible for setting up and deleting the IPsec Security Policies (SP), VPN IP address, and routing entries. The sample scripts should do what you need, but you can customize them to fit your particular needs.
# cp /usr/share/examples/racoon/roadwarrior/client/*.sh /etc/racoon/
Once this is ready, you can start racoon(8):
# racoon
In order to have it started at boot time, add racoon=YES to /etc/rc.conf. Connecting to and disconnecting from the VPN (top) racoonctl(8) can be used to connect to the VPN and to disconnect from it. The login is given through the -u option and the password is prompted on the terminal:
$ racoonctl vc -u username 192.0.2.50 Password: password Bound to address 10.99.99.3
DNS addresses can be used instead of IP addresses in this example. Note that if for some reason the routing entries or Security Policy Database (SPD) get screwed, the DNS resolution will not work at VPN disconnect time. To recover from such a situation, type the following commands as root:
# # # # setkey -F setkey -FP route flush route add default your_default_gateway
Anyone with read/write rights to the racoon(8) socket /var/racoon/racoon.sock can start or stop the VPN. The ownership and rights to the socket can be set using the adminsock statement in the listen section of /etc/racoon/racoon.conf. Saving Xauth password (top) If you want to avoid typing the Xauth password, you can store it in racoon's Pre-Shared Key (PSK) file. Add the following statement in the remote section of /etc/racoon/racoon.conf:
xauth_login "username";
Then add a line in /etc/racoon/psk.txt with the login and the password:
username password
With that setup, this command will establish the VPN connection using the toto login, without prompting for a password:
$ racoonctl vc 192.0.2.50