Introduction : VPN system
This VPN will be configured for road warriors clients :
- 100% of the outgoing clients traffic will transit through the VPN server.
- 100% of the outgoing clients traffic will be encrypted before leaving the client computer.
I use this system to secure my connection when using untrusted networks (public WiFi) and to avoid constraints and limitations in some countries.
OpenVPN : server (FreeBSD 10.1)
Install
OpenVPN installation :
pkg install openvpn
Updating FreeBSD repository catalogue...
FreeBSD repository is up-to-date.
All repositories are up-to-date.
The following 3 packages will be affected (of 0 checked):
New packages to be INSTALLED:
openvpn: 2.3.6_1
easy-rsa: 2.2.0.m
lzo2: 2.09
The process will require 2 MiB more space.
522 KiB to be downloaded.
Proceed with this action? [y/N]: y
Fetching openvpn-2.3.6_1.txz: 100% 401 KiB 410.3kB/s 00:01
Fetching easy-rsa-2.2.0.m.txz: 100% 19 KiB 20.0kB/s 00:01
Fetching lzo2-2.09.txz: 100% 102 KiB 104.8kB/s 00:01
Checking integrity... done (0 conflicting)
[1/3] Installing easy-rsa-2.2.0.m...
[1/3] Extracting easy-rsa-2.2.0.m: 100%
[2/3] Installing lzo2-2.09...
[2/3] Extracting lzo2-2.09: 100%
[3/3] Installing openvpn-2.3.6_1...
[3/3] Extracting openvpn-2.3.6_1: 100%
Message for openvpn-2.3.6_1:
### ------------------------------------------------------------------------
### Edit /etc/rc.conf[.local] to start OpenVPN automatically at system
### startup. See /usr/local/etc/rc.d/openvpn for details.
### ------------------------------------------------------------------------
### For compatibility notes when interoperating with older OpenVPN
### versions, please, see <http://openvpn.net/relnotes.html>
### ------------------------------------------------------------------------
Configuration
To enable automatic start of services, we edit the rc.conf :
vi /etc/rc.conf
Add these lines :
#OpenVPN
gateway_enable="YES";
openvpn_enable="YES";
To enable traffic forwarding without rebooting the server :
/etc/rc.d/routing restart
We can check by using this command (must return 1) :
sysctl -a | grep net.inet.ip.forwarding
net.inet.ip.forwarding: 1
Configuration preparation :
cd /usr/local/etc
mkdir openvpn
cd /usr/local/share/examples/openvpn/sample-config-files/
cp server.conf /usr/local/etc/openvpn/openvpn.conf
cd /usr/local/share/easy-rsa/
sh
. ./vars
./clean-all
Build the certificate authority (CA) :
./build-ca
Generating a 1024 bit RSA private key
......................++++++
.................++++++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:FR
State or Province Name (full name) [CA]:MyRegion
Locality Name (eg, city) [SanFrancisco]:MyCity
Organization Name (eg, company) [Fort-Funston]:MyCompany
Organizational Unit Name (eg, section) [changeme]:IT
Common Name (eg, your name or your server's hostname) [changeme]:MyHostname
Name [changeme]:MyName
Email Address [mail@host.domain]:MyEmail
Server private key and certificate generation :
./build-key-server server
Generating a 1024 bit RSA private key
......++++++
........++++++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:FR
State or Province Name (full name) [CA]:MyRegion
Locality Name (eg, city) [SanFrancisco]:MyCity
Organization Name (eg, company) [Fort-Funston]:MyCompany
Organizational Unit Name (eg, section) [changeme]:IT
Common Name (eg, your name or your server's hostname) [server]:MyHostname
Name [changeme]:MyName
Email Address [mail@host.domain]:MyEmail
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /usr/local/share/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'FR'
stateOrProvinceName :PRINTABLE:'MyRegion'
localityName :PRINTABLE:'MyCity'
organizationName :PRINTABLE:'MyCompany'
organizationalUnitName:PRINTABLE:'IT'
commonName :PRINTABLE:'MyHostname'
name :PRINTABLE:'MyName'
emailAddress :IA5STRING:'MyEmail'
Certificate is to be certified until Mar 12 03:23:58 2025 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Generation of our first client key :
./build-key client1_laptop
Generating a 1024 bit RSA private key
...................++++++
...............++++++
writing new private key to 'client1_laptop.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:FR
State or Province Name (full name) [CA]:MyRegion
Locality Name (eg, city) [SanFrancisco]:MyCity
Organization Name (eg, company) [Fort-Funston]:MyCompany
Organizational Unit Name (eg, section) [changeme]:IT
Common Name (eg, your name or your server's hostname) [client1_laptop]:
Name [changeme]:MyName
Email Address [mail@host.domain]:MyEmail
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /usr/local/share/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'FR'
stateOrProvinceName :PRINTABLE:'MyRegion'
localityName :PRINTABLE:'MyCity'
organizationName :PRINTABLE:'MyCompany'
organizationalUnitName:PRINTABLE:'IT'
commonName :T61STRING:'client1_laptop'
name :PRINTABLE:'MyName'
emailAddress :IA5STRING:'MyEmail'
Certificate is to be certified until Mar 12 03:30:26 2025 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Generate the Diffie Hellman parameters :
./build-dh
This is going to take a long time
.................+..............+..+.....................
We copy the generated files in the OpenVPN folder:
cd /usr/local/share/easy-rsa/keys
cp server.crt /usr/local/etc/openvpn/
cp dh1024.pem /usr/local/etc/openvpn/
cp server.key /usr/local/etc/openvpn/
cp ca.crt /usr/local/etc/openvpn/
We backup the original configuration :
cp /usr/local/etc/openvpn/openvpn.conf /usr/local/etc/openvpn/openvpn.conf.bak
We can now edit this configuration :
vi /usr/local/etc/openvpn/openvpn.conf
My configuration :
;local a.b.c.d
port 443
proto tcp
dev tun
ca ca.crt
cert server.crt
key server.key # This file should be kept secret
dh dh1024.pem
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
#push "dhcp-option DNS 208.67.220.220"
client-to-client
keepalive 10 120
cipher AES-256-CBC
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
verb 3
;mute 20
OpenVPN : client (Windows 7)
Install
As a first step, we download the client software on the official OpenVPN website.
Configuration
We have to retrieve some files from the server to our client. This is a critical step in terms of safety : Do not transfer these file with a not encrypted protocol !
Here we used the SFTP (SSH File Transfer Protocol) with FileZilla client :
Retrieve the following files, and copy them in “C:Program Files\OpenVPNconfig” :
- client1_laptop.key
- client1_laptop.crt
- ca.crt
In the same folder, we create a configuration file “client.ovpn”, and edit it :
# Client
client
dev tun
proto tcp
remote A.B.C.D 443
resolv-retry infinite
cipher AES-256-CBC
; client-config-dir ccd
# Cles
ca ca.crt
cert client1_laptop.crt
key client1_laptop.key
# Securite
nobind
persist-key
persist-tun
comp-lzo
verb 3
You have to adapt/replace :
- A.B.C.D : IP of the VPN server
- client1_laptop.crt : client’s certificate
- client1_laptop.key : client’s key name
Start OpenVpn server
On the server, we can start the OpenVPN service :
service openvpn start
If everything is OK, you should see this :
Starting openvpn.
add net 10.8.0.0: gateway 10.8.0.1
Just after start-up, we can check the logs :
tail -n 100 /var/log/messages
openvpn[8109]: OpenVPN 2.3.6 amd64-portbld-freebsd10.1 [SSL (OpenSSL)] [LZO] [MH] [IPv6] built on Mar 6 2015
openvpn[8109]: library versions: OpenSSL 1.0.1j-freebsd 15 Oct 2014, LZO 2.09
openvpn[8109]: Diffie-Hellman initialized with 1024 bit key
openvpn[8109]: Socket Buffers: R=[65536->65536] S=[32768->65536]
kernel: tun0: link state changed to UP
openvpn[8109]: TUN/TAP device /dev/tun0 opened
openvpn[8109]: do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
openvpn[8109]: /sbin/ifconfig tun0 10.8.0.1 10.8.0.1 mtu 1500 netmask 255.255.255.0 up
devd: Executing '/etc/pccard_ether tun0 start'
openvpn[8109]: /sbin/route add -net 10.8.0.0 10.8.0.1 255.255.255.0
openvpn[8113]: GID set to nobody
openvpn[8113]: UID set to nobody
openvpn[8113]: Listening for incoming TCP connection on [undef]
openvpn[8113]: TCPv4_SERVER link local (bound): [undef]
openvpn[8113]: TCPv4_SERVER link remote: [undef]
openvpn[8113]: MULTI: multi_init called, r=256 v=256
openvpn[8113]: IFCONFIG POOL: base=10.8.0.2 size=252, ipv6=0
openvpn[8113]: IFCONFIG POOL LIST
openvpn[8113]: MULTI: TCP INIT maxclients=1024 maxevents=1028
openvpn[8113]: Initialization Sequence Completed
Client connection
From the windows client, we should be able to connect to the server :
The client should be able to communicate with the server. Note : The OpenVPN client should be started with Administrator rights.
At this step, the server is not forwarding the traffic to/from internet yet.The clients don’t have access to internet.
Traffic forwarding
To allow the server to forward traffic between clients and internet, we will use the firewall Packet-filter.
To enable automatic start, we edit the rc.conf file :
vi /etc/rc.conf
Add these lines :
#Firewall
pf_enable="YES"
pf_rules="/etc/pf.conf"
Create the PF’s rules :
vi /etc/pf.conf
Here is my file (use as an example) :
vpn_net = "10.8.0.0/24"
vpn_if = "tun0"
ext_if = "em0"
# ---- NAT rules ---- #
nat on $ext_if inet from $vpn_net to any -> $ext_if
# ---- Default policy ---- #
block in
# ---- Loopback ---- #
pass on lo0 all
# ---- ICMP ---- #
pass in on $ext_if proto icmp
# ---- SSH ---- #
pass in on $ext_if proto tcp from any to $ext_if port 22
# ---- HTTP ---- #
pass in on $ext_if proto tcp from any to $ext_if port 80
# ---- OPENVPN ---- #
pass in on $ext_if proto tcp from any to $ext_if port 443
pass out quick
pass in on $vpn_if from any to any
Load the kernel module :
kldload pf
Start PF :
service pf start
Enabling pfNo ALTQ support in kernel
ALTQ related functions disabled
No ALTQ support in kernel
ALTQ related functions disabled
.
While you don’t plan to do QOS (Quality Of Service), you can ignore these messages.
Now you should be able to surf on internet through your secure tunnel ! Enjoy :).