A VPN Gateway Setup
A VPN Gateway Setup
First you need to build and install a kernel with at least the following options:
options INET
options GATEWAY
options PFIL_HOOKS
options IPSEC
options IPSEC_ESP
options IPSEC_NAT_T
pseudo-device ipfilter
You need to enable IPv4 packet forwarding, by using the following command:
# sysctl -w net.inet.ip.forwarding=1
net.inet.ip.forwarding=1
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
# openssl genrsa > certs/ca.key
# umask 022
# openssl req -days 3650 -x509 -key certs/ca.key -new > certs/ca.crt
# openssl ca -in certs/vpngw.csr -keyfile certs/ca.key -cert certs/ca.crt -out
certs/vpngw.crt
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.
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.
# racoon
In order to have racoon(8) started up at boot time, you need the following in /etc/rc.conf:
racoon=YES
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:
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.
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.
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; # IPv4 pool size
auth_source radius; # login validated against RADIUS
conf_source radius; # IPv4 address obtained by RADIUS
accounting radius; # RADIUS accounting
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;
}
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:
VPN client
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.
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
listen {
# socket used for communication between racoon and racoonctl
adminsock "/var/racoon/racoon.sock" "root" "operator" 0660;
}
sainfo anonymous {
lifetime time 1 hour;
encryption_algorithm aes;
authentication_algorithm hmac_sha1;
compression_algorithm deflate ;
}
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/
# racoon
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:
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.
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