this is obsolete doc -- see http://doc.nethence.com/ instead
Setting up a OpenVPN server and Windows clients
on FreeBSD v9
Introduction
Install the openvpn package (PKGNG),
pkg install openvpn
Setup defaults for certificates
Setup some defautlts,
cp -i /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.dist
vi /etc/ssl/openssl.cnf
dir = /etc/ssl/CA
default_days = 3650 # 10 years
default_bits = 2048
countryName_default = FR
stateOrProvinceName_default = IDF
+localityName_default = Paris
#0.organizationName_default = Internet Widgits Pty Ltd
SSL certification authority
Create your own CA,
mkdir -p /etc/ssl/CA/
cd /etc/ssl/CA/
mkdir -p certs/
mkdir -p crls/
mkdir -p newcerts/
mkdir -p private/
touch index.txt
echo 01 > serial
echo 01 > crlnumber
openssl req -nodes -new -x509 -keyout private/cakey.pem -out cacert.pem
#-days 3650
Common Name (e.g. server FQDN or YOUR name) []:cahost.example.com
Email Address []:email@example.com
ls -l private/cakey.pem
note. not sure it's mandatory but I would recommend to use the real hostname of the CA server here (with PTR).
and revocation,
openssl ca -gencrl -out crls/crl.pem
chown root:nogroup crls/crl.pem
ls -l crls/crl.pem
SSL request
Create a certificate request,
cd /etc/ssl/CA/certs/
openssl req -nodes -new -keyout ssl.example.com.key -out ssl.example.com.csr
Common Name (e.g. server FQDN or YOUR name) []: ssl.example.com
(no extra attributes...)
Then sign the certificate request with your own CA,
openssl ca -out ssl.example.com.crt -in ssl.example.com.csr -policy policy_anything
(check the expire date)
sign and commit
Generate Diffie-Hellman parameters for the keys exchange,
openssl dhparam -out dh2048.pem 2048
Check that you've got everything,
cd /etc/ssl/CA/
ls -l cacert.pem
ls -l private/cakey.pem
cd /etc/ssl/CA/certs/
ls -lkF
there should be,
dh2048.pem
the crt
the csr
the key
Configuration
Setup OpenVPN,
mkdir -p /usr/local/etc/openvpn/
cd /etc/
ln -s /usr/local/etc/openvpn
cd /etc/openvpn/
cp /usr/local/share/examples/openvpn/sample-config-files/server.conf openvpn.conf.dist
cp /usr/local/share/examples/openvpn/sample-config-files/server.conf openvpn.conf
chmod u+w openvpn.conf
vi openvpn.conf
e.g.
local IP_ADDRESS_INTERFACE_LISTEN
port 1194
proto udp
# (see "pkcs12" directive in man page).
ca /etc/ssl/CA/cacert.pem
cert /etc/ssl/CA/certs/ssl.nethence.com.crt
key /etc/ssl/CA/certs/ssl.nethence.com.key
crl-verify /etc/ssl/CA/crls/crl.pem
dh /etc/ssl/CA/certs/dh2048.pem
dev tun
;dev tap
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
;push "route 192.168.2.0 255.255.255.0"
keepalive 10 120
cipher BF-CBC
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
verb 6
mute 20
;verb 3
Note. eventually enable route push for the VPN client to access the network behind the VPN server (here 192.168.2.0/24).
Enabling the service
Enable and start the daemon,
echo 'openvpn_enable="YES"' >> /etc/rc.conf
/usr/local/etc/rc.d/openvpn start
and watch the logs.
Check the vpn interface,
ifconfig tun0
Open the 1194 port for UDP on your listening network device.
Creating client certificates
Enter the certs (not CA certs) folder and generate a request for a vpn client,
cd /etc/ssl/certs/
openssl req -nodes -new -keyout sslclient.key -out sslclient.csr
Common Name (e.g. server FQDN or YOUR name) []:public_fqdn_not_mandatory?
Email Address []:email@example.com
(you can specify a password here, it won't be asked when connecting anyway, or no extra attributes...)
Note. You don't have to use your client's public FQDN here (unless tls verify is enabled?) http://ip.nethence.com/
Increment the CA serial,
cat /etc/ssl/CA/serial
#echo 02 > /etc/ssl/CA/serial
echo 03 > /etc/ssl/CA/serial
Sign the request with your own CA,
cd /etc/ssl/certs/
openssl ca -out sslclient.crt -in sslclient.csr -policy policy_anything
Secure the files a little bit,
chown root:nogroup /etc/ssl/CA/cacert.pem
chown root:nogroup /etc/ssl/CA/certs/ssl*
chmod 600 /etc/ssl/CA/certs/ssl*.key
Preparing the Windows OpenVPN client
On the VPN server, prepare those files to send them to the client,
/etc/ssl/CA/certs/sslclient.crt
/etc/ssl/CA/certs/sslclient.key
/etc/ssl/CA/cacert.pem
e.g.,
tar czf clientcert.tar.gz sslclient.crt sslclient.key ../cacert.pem
(send this to the client host)
Fetch and install [OpenVPN for Windows](https://openvpn.net/index.php/open-source/downloads.html).
Open a command line prompt and proceed,
cd "C:\Program Files\OpenVPN\config\"
notepad sslclient.ovpn
containing,
client
dev tun
proto udp
remote ssl.example.com 1194
nobind
user nobody
group nobody
persist-key
persist-tun
ca cacert.pem
cert sslclient.crt
key sslclient.key
cipher BF-CBC
comp-lzo
:verb 3
verb 6
mute 20
Linking the networks
Local network on the client side: 192.168.1.0/24
System's IP on that network: 192.168.1.3
Local network on the server side: 192.168.2.0/24
System's IP on that network: 192.168.2.1
For the VPN client to connect to the VPN server's network, the push rule in openvpn.conf is enought (and eventually enable ip fwd on the server -- it's not mandatory to access only the server's IP). Verify the routes on the client, on Windows,
#route add 192.168.2.0 mask 255.255.255.0 10.8.0.5 metric 1 if 10.8.0.6 DOES NOT WORK MANUALLY
route print
you should have,
192.168.2.0 255.255.255.0 10.8.0.5 10.8.0.6 1
then try to ping the server's IP on its local network,
ping 192.168.2.1
For the VPN server to connect to the VPN client's network,
cd /etc/openvpn/
mkdir -p ccd/
vi openvpn.conf
client-config-dir ccd
route 192.168.1.0 255.255.255.0
echo "iroute 192.168.1.0 255.255.255.0" > ccd/client
note. client here corresponds to the common name in the client's certificate, change it accordingly depending on what you entered during the certificate creation.
note. both route directives are necessary, the server one tells to use tun0 and openvpn, the client one redirects from openvpn to the client.
restart the daemon and restart the client connection, then try to ping the client local IP from the server,
ping 192.168.1.3
check the route, on BSD systems,
netstat -rn -f inet
Ref. http://doc.ubuntu-fr.org/openvpn
Troubleshooting
If you get this error in the client logs,
Cannot load certificate file ssl-heg.crt: error:0906D06C:PEM routines:PEM_read_bio:
==> make sure the file is readable and has a non binary content (contains --- CERTIFICATE)
==> make sure the cert filename points to the right one
If you get this error in the client logs,
read UDPv4: Connection reset by peer (WSAECONNRESET) (code=10054)
==> make sure firewall is open on the server side
ref https://forums.openvpn.net/topic7624.html
If you get this error in the clients logs,
TLS_ERROR: BIO read tls_read_plaintext error: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
TLS Error: TLS object -> incoming plaintext read error
TLS Error: TLS handshake failed
==> you got some restrictive option (probably remote-cert-tls) which indicates that there is something wrong with the certificates, maybe use easy-rsa instead of making it all manually?
https://forums.openvpn.net/topic10261.html
In any case, if you have to enable IP forwarding on the FreeBSD VPN server,
sysctl -w net.inet.ip.forwarding=1 (temporarily)
and if you have to enable IP forwarding on Windows XP side,
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\IPEnableRouter
1
References
Installation d’un serveur VPN sous FreeBSD: http://blog.nicolargo.com/2009/04/installation-dun-serveur-vpn-sous-freebsd.html
Other resources
http://forum.hardware.fr/hfr/reseauxpersosoho/Reseaux/openvpn-connecte-trafic-sujet_23020_1.htm
TODO
- try bridge mode (tap)