FreeBSD on a common desktop class machine is sufficient as a RAS for the needs of a small enterprise. It can support up to 256 clients, more than 4 MBit 3des and more than 10MB des-cbc, blowfish or aes throughput on a 700MHz PIII. If you need more than this you most likely will have to go for a specialized access point from Cisco, Nortel or other vendors and/or specialized client software that supports algorithms more efficient than 3des.
These numbers are quoted for the specific deployment scenario when FreeBSD accepts connections from Windows2000 and XP machines that do not run any additional software. Without additional software these OSes can do only PPTP and L2TP VPNs. IPSEC is simply an additional protection. This results in the following peculiarities (I will intentionally avoid classifying them as advantages or disadvantages):
Initially I have designed the setup described in this document for Windows only. It currently supports Linux with FreeSWAN 1.96 after it has been patched with the x509 patch. It can also be extended further to support other VPN clients that can do PPTP or L2TP and IPSEC with certificates. I have added the clients other then windows for reasons of the "because it can be done" variety rather then because of a specific need. Most of these can do IPSEC tunnel mode and are better behaved in tunnel mode as well. There are not that many cases for this approach for non-windows systems. For example:
All usual disclaimers apply:
/usr/local/etc/openssl. Create the necessary subdirectories and files:
mkdir /usr/local/etc/openssl/certs
mkdir /usr/local/etc/openssl/crl
mkdir /usr/local/etc/openssl/newcerts
mkdir /usr/local/etc/openssl/private
echo "01" > /usr/local/etc/openssl/serial
touch /usr/local/etc/openssl/index.txt
RANDFILE = /usr/local/etc/openssl/.rand
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = /usr/local/etc/openssl # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are
kept
database = $dir/index.txt # database index file.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/private/CAcert.pem # The CA certificate
serial = $dir/serial # The current serial number
crl = $dir/clr/crl.pem # The current CRL
private_key = $dir/private/CAkey.pem # The private key
RANDFILE = $dir/private/.rand # private random number
file
#x509_extensions = x509v3_extensions # The extentions
to add to the cert
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = md5 # which md to use.
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = optional
localityName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ] default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = UK
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default =
localityName = Locality Name (eg, city)
localityName_default = Cambridge
organizationName = Organization Name (eg, company)
organizationName_default = IP Access
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default =
commonName = Common Name (eg, YOUR name)
commonName_default = ipaccess.com
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 40
emailAddress_default = root-ca@ipaccess.com
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
openssl req -new -x509 -keyout /var/openssl/private/CAkey.pem \
-out /var/openssl/private/CAcert.pem -config openssl.conf
openssl pkcs12 -export -in private/CAcert.pem \
-inkey private/CAkey.pem -nokeys -out CA.p12
openssl req -new -keyout server-key-encrypted.pem \
-out server.pem -days 360 -config openssl.conf
cat server.pem server-key.pem > server-req.pem
openssl ca -policy policy_match -out server-signed.pem \
-config openssl.conf -infiles server-req.pem
openssl rsa -in server-key-encrypted.pem -out server-key.pem
openssl rsa line.
openssl req -new -keyout user-key.pem -out user.pem \
-days 360 -config openssl.conf
cat user.pem user-key.pem > user-req.pem
openssl ca -policy policy_match -out user-signed.pem \
-config openssl.conf -infiles user-req.pem
openssl pkcs12 -export -in user-signed.pem -inkey user-key.pem \
-name "User Name Goes Here" -certfile private/CAcert.pem -out user.p12
options IPSEC #IP security
options IPSEC_ESP
Notes:
/usr/ports/security/racoon. In most cases a simple
make install should be enough. Best of all put the config under
its own directory like /usr/local/etc/racoon/. The config is quite simple:
path pre_shared_key "/usr/local/etc/racoon/racoon.keys" ;
path certificate "/usr/local/etc/racoon/cert" ;
log debug;
# timer
{
# These value can be changed per remote node.
counter 5; # maximum trying count to send.
interval 20 sec; # maximum interval to resend.
persend 1; # the number of packets per a send.
# timer for waiting to complete each phase.
phase1 30 sec;
phase2 15 sec;
}
remote anonymous
{
# exchange_mode main, aggressive, base; uncomment this for windows only
# linux does not do aggresive mode and requires a different phase 1 proposal
exchange_mode main, base;
passive on;
certificate_type x509 "server-signed.pem" "server-key.pem";
my_identifier asn1dn;
proposal {
# Windows 2000, Cisco, others
encryption_algorithm des;
hash_algorithm md5;
authentication_method rsasig ;
dh_group 1 ;
}
proposal {
# linux freeswan, more paranoic clients
# delete if you are dealing with windows only
# and enable aggressive mode
encryption_algorithm 3des;
hash_algorithm md5;
authentication_method rsasig ;
dh_group 2 ;
}
}
sainfo anonymous
{
encryption_algorithm cast128, blowfish, aes, 3des, des ;
authentication_algorithm non_auth, hmac_sha1;
compression_algorithm deflate;
}
ln -s demon.pem `openssl x509 -noout -hash -in demon.pem`.0
/usr/ports/net/poptop. FreeBSD by default builds
it with userland ppp which by default does not support RC4 encryption
(it can be rebuilt with it).
Considering that encryption is delegated to IPSec this is not a problem.
Alternatively there is another VPN daemon and kernel ppp both of which support
RC4 but I have not tested them. At least the kernel ppp with the RC4 patches
is reported to be unstable. It may also be illegal to use it in some
countties.
After building it you need to add the following section to the bsd ppp options file.
loop:
set timeout 0
set log phase chat connect lcp ipcp command
set device localhost:pptp
set dial
set login
# Server (local) IP address, Range for Clients, and Netmask
set ifaddr 192.168.20.1 192.168.20.130-192.168.20.254 255.255.255.255
set server /tmp/loop "" 0177
loop-in:
set timeout 0
set log phase lcp ipcp command
allow mode direct
pptp:
load loop
enable chap
disable pap
# Authenticate against /etc/passwd
#enable passwdauth
# The next depends on your routing. Proxy arp is an easy way out
# enable proxy
accept dns
# DNS Servers to assign client
set dns 192.168.0.1 192.168.0.2
# NetBIOS/WINS Servers to assign client
set nbns 192.168.0.15 192.168.0.16
set device !/etc/ppp/secure
Notes:
setkey -c
spdadd 172.28.1.2 0.0.0.0/0 gre -P out ipsec
esp/transport//require;
spdadd 0.0.0.0/0 172.28.1.2 gre -P in ipsec
esp/transport//require;
spdadd 172.28.1.2[1723] 0.0.0.0/0 tcp -P out ipsec
esp/transport//require;
spdadd 0.0.0.0/0 172.28.1.2[1723] tcp -P in ipsec
esp/transport//require;
Under the Certificates, right button click on Trusted Root Certification
authorities. From all actions choose import
. Import your certificate authority PKCS#12 certificate here. Check if it
is displayed.
Under the Certificates, right button click on Personal.
From all actions choose import. Import the user
PKCS#12 certificate here. Check if it is correctly displayed and the root
authority is known.
Under IP Security policies choose a policy which you are not using or create a new one. Specify it as follows:
require data encryption field is left blank. You
do not need it. This is the RC4 encryption for the PPTP which will be unnecessary
overhead if IPSEC is protecting the connection. It may also be a good idea
to force the connection to be a PPTP one. Windows 2000 tries L2TP first, so
leaving this setting on automatic may slow down the connection process.
I have used debian woody and compiled freeswan-1.96 from the unstable distribution. The reason for this choice is that the package in unstable already has x509 and several other important patches applied. If you are on a non-debian system I would suggest to start from the debian sources and patches in order to minimise the hassle. Otherwise the x509 patch is available from http://www.strongsec.com.
Overall, the linux IPSEC stack still has a way to go and is not 100% integrated into linux networking. Also, the syntax of ipsec.conf leaves more to be desired. There are several strong sides as well, like CRL support but they do not really come into play as a client.
Obtain freeswan if possible patched with the x509 patch and install it according to the instructions supplied on freeswan's web site and the instructions for the x509 patches.
Extract the subject lines out of the certificates on the linux system and the FreeBSD
VPN access machine. In theory you should not need to specify these in ipsec.conf. In practice
I could not make it work. If you specify leftid=%cert or rightid=%cert
for the system identity it will still
supply/ask for an IP address instead of ASN1_DN in IKE phase 1.
This results in the following config
config setup
interfaces=%defaultroute
klipsdebug=none
plutodebug=none
manualstart=
plutoload=%search
plutostart=%search
conn vpn
authby=rsasig
leftrsasigkey=%cert
rightrsasigkey=%cert
left=%defaultroute
leftcert=YourCert
leftid="Your FreeSWAN ASN1_DN goes here"
right=172.28.1.2
rightid="Your VPN Access point ASN1_DN goes here"
type=transport
auto=start
leftcert is completely ignored. It is taken from /etc/x509cert.der insteadleft=%defaultroute is not a pleasant way to do it but there is nothing
you can do if you are dealing with a dynamically assigned addresses (dialup). It will become more
clear in the networking section.There is a pptp client package available nowdays in almost all distributions. Once again it has been tested on debian, so if there is no pptp package on your system I would suggest using debian sources.
The setup from now on revolves around the problem of left=%defaultroute as
well as several other problems related to the fact that IPSEC is still not properly
integrated into linux networking code
left=%defaultroute. If the IP address is dynamic, then
you need this statement to be able to chose the correct interface for IPSEC. This
choses the "external" interace or where your default route goes. This means that
you can no longer use a default route down the pptp tunnel. If you do, and the SA needs to be
renegotiated it will fail most miserably. As a result you will have to set statics (not default)
in the ppp ip-up scripts. Another way to deal with this is to set up the connections
directly in the ip-up/down or their equivalents instead of using ipsec.conf.
Overall, there is no cookbook solution here.
I found most errors to be self-explanatory except one:
openssl rsa in order to decrypt
it.
Sequencing problems with the GRE packets. Windows VPN stops working if the packets are reordered along the way. Same goes for the pptpd implementation. This is a known problem and there is nothing you can do about it besides fixing the network or changing the provider. If the reordering occurs in your network look for any of the following:
These condition can be easily discovered on the pptpd side (large and small jumps in GRE sequence numbers) and I will hopefully fix them once I have some time to get to it. Watch this place ;-) This of course lives the windows side but not like there is anything I can do there.