How to create an OpenVPN client to a public OpenVPN provider
I thought I'd put 2 howto's together to show people how to get the most out of OpenVPN and pfSense. This first one is a straightforward one, but the next howto, 'How to load balance multiple OpenVPN clients' refers to this as well. Hope they're of use!
With legislation allowing over zealous and officious bodies to strip away all of your online dignity, privacy is becoming a very important point to protect. While the likes of tor and other anonymising techniques are valiant efforts, the problem them is their speed is usally drastically slower. Connecting to OpenVPN providers, with the right set up, allows you to encrypt your traffic. With decent hardware counteracting the additional overhead of encryption and compression processing on your connection stream, if you're lucky like me, you may even see slightly increased connection speeds (I see an 11% speed boost on average) as well as being encrypted and private.
In pfSense 1.2.3 it was possible, though hard to make an OpenVPN client a WAN connection, in 2.0, it's significantly easier but still not perfect. Nevertheless, this howto explains how to set up an OpenVPN client connection and use it as a WAN connection.
A. Find a good provider!
Before I go ahead, let me say a couple of words on doing your own research about VPN providers. Like everything in life, not all VPN providers are created equal, and you get what you pay for. If you are also going on to load balance multiple connections, your choice of provider is absolutely vital.
For those who don't have OpenVPN servers of their own, you must understand most VPN providers only allow one connection to any of their servers, however some allow as many different means (ie proxy servers, SSH tunnels, PPTP, L2TP/Ipsec or OpenVPN, etc) and connections to as many of their servers as possible - look for the ability to 'chain servers' (connecting to a server by proxying or tunnelling though another), and of course decent connection speeds to and from the servers from your location. A good overview of the state of the VPN Provider industry, including a list of providers, is available in French here (Translation here). For this howto, I'm using Perfect Privacy, as a provider that does allow chaining and for me has decent speeds. Doing your research is key, and you may find getting several cheaper subs to different providers might be more versatile for you.
Avoid the free one's though as their OVPN setups are generally appalling (so useless even for testing) and of course freetards flocking to them mean they're totally overloaded and their speed is terrible.
B. Preliminary info gathering
When setting up an OpenVPN connection, you need a number of files (usually through a member-only download page from your chosen provider). While under proper OVPN setups, each client has their own client certicate and key, VPN providers tend to use the 'auth-user-pass' method of authentication and provide the same client certificate and key to all their users. Nevertheless, I'll refer to these files in the course of the howto:
- The server's Certicate Authority (CA) certificate, (usually ca.crt)
- The Client certificates (Usually client.crt)
- The Client private key (Usually client.key)
- Sometimes they also provide a PKCS#12 (client.p12) key which you'd need to convert via OpenSSL's command line to get the PEM-format client.crt and client.key files
- Optionally, sometimes the provider also gives a TLS key for the handshake process as well (Usually tls.key).
- An OpenVPN configuration file, (either client.conf or more usually, client.ovpn).
- Sometimes, providers only give you one certificate, a 'Shared Key'.
I found naming the various options properly, especially when managing various connections mattered quite a lot. Where I say 'ProviderName', replace with the name of your provider (in my case 'Perfect Privacy') and in the 'ServerLocation' enter the server's identifier (in my case 'Steinsel').
Throughout the course of this howto, you need to have your client.ovpn file handy, and read it. If you're unsure of any command, refer to the OpenVPN docs to decipher. You'll need to mirror the settings in pfSense and constantly refer to it, but you can't unfortunately just import the file in pfSense.
C. Import Certificates
First you need to import the certificates.
1. Navigate to System -> Cert Manager. You should be in the 'CAs' tab.
2. Click the '+' to add a new CA.
3. Provide a descriptive name like 'ProviderName / ServerLocation / CA', leave 'Import an existing Certification Authority' selected.
4. Paste the contents of the ca.crt from your provider in the 'Certificate data' box.
5. Press Save.
6. Navigate to the 'Certificates' tab
7. Enter a descriptive name like 'ProviderName / ServerLocation / Client', and leave 'Import an existing Certificate' selected.
8. In the 'Certificate data', paste the contents of the client.crt file.
9. In the 'Private key data', paste the contents of the client.key file.
D. Username / Password file
If your client.ovpn file says 'auth-user-pass', then you need to follow this step and also add the line in E.21:
1. Navigate to Diagnostics -> Edit File
2. Enter '/conf/ProviderName-ServerLocation.pas' in the 'Save/Load from path' field (be careful on nanobsd setups to save it in a location that persists across boots)
3. In the box, you need to enter:
On 2 lines, according to the credentials of provided to you from your provider.
4. Press Save.
E. Create the OpenVPN Client connection
1. Navigate to VPN -> OpenVPN -> Clients tab
2. Click the '+' button to add a new connection.
3. By default, 'Server Mode' is 'Peer to Peer ( SSL/TLS )'. If only 1 certificate has been provided, select 'Peer to Peer (Shared Key)'.
4. By default, 'Protocol' is 'UDP'. If the client.ovpn says 'remote 22.214.171.124 1194 tcp', select 'TCP' here.
5. By default, 'Device mode' is 'tun'. If the client.ovpn says 'dev tap' or 'dev-type tap', then select 'tap'
6. Leave the 'Interface' as 'WAN'.
7. (Optional) Under 'Local port', enter some arbitrary port you don't use like '50011'. This allows the management interface to keep tabs on the connection and for it to appear under Status -> OpenVPN
8. In 'Server host or address', enter the host (domain or IP) of the VPN server. In the client.ovpn take 'domain.name' or '126.96.36.199' out of the line 'remote domain.name 1194 udp' or 'remote 188.8.131.52 1194 udp'.
9. In 'Server port', if the same 'remote x.x.x.x' says something different to 1194, enter it here
10. Check 'Infinitely resolve server' if the client.ovpn says 'resolv-retry infinite'
11. Provide a good description like 'ProviderName / ServerLocation / Client'.
12. Keep 'Enable authentication of TLS packets' checked
13. If you have a tls.key file, uncheck 'Automatically generate a shared TLS authentication key' and paste the contents of this file in the box that appears.
14. Under 'Peer Certificate Authority' select the name you entered for the 'CA' certificate you entered for this provider.
15. Under 'Client Certificate', select the name of the 'Client' certificate you entered for this provider.
16. Under 'Encryption algorithm', select the algorithm like 'AES-256-CBC' as used in the client.ovpn file where it says 'cipher AES-256-CBC'. If nothing is entered, select an AES algorithm if you have a fast computer, or 'BF-CBC' for slower machines.
17. Leave 'Tunnel Network' empty
18. Leave 'Remote Network' empty
19. Leave 'Limit outgoing bandwidth' unchecked
20. Check 'Compress tunnel packets using the LZO algorithm' if the client.ovpn has a line saying 'comp-lzo', 'comp-lzo yes' or 'comp-lzo adaptive'.
21. In the 'Advanced' field, we need to enter several options, all separated by a ';':
- verb 5 (Increases the verbosity for the logs so we can see what really is happening!)
- engine cryptodev (this will make use of any encryption acceleration hardware in your machine (ie AMD Geode LX or Hifn card). VIA Padlock users should use 'engine padlock')
- auth-user-pass /conf/ProviderName-ServerLocation.pas (where the file is the same as the file you entered above)
22. If your client.ovpn file contains any other lines, such as those for adjusting MTU sizes, put them into the advanced box as well.
23. Press Save!
F. Verify it's working
Now we need to check what happens and look at the logs.
1. First navigate to Status -> System Logs -> OpenVPN tab
2. Because we entered 'verb 5' in the advanced field, you'll see a lot more information than normal being logged.
3. You need to look for is the line that says:
openvpn: PUSH: Received control message: 'PUSH_REPLY,redirect-gateway def1,dhcp-option DNS 184.108.40.206,dhcp-option DNS 220.127.116.11,dhcp-option DNS 18.104.22.168,route 10.0.61.1,topology net30,ifconfig 10.0.61.54 10.0.61.53'
4. If that line says 'redirect-gateway def1', then your pfSense should be routing all traffic over the VPN connection. Browse to a 'what's my IP' page, and see if your connection is coming from another IP than your own. If not, you're going to have to play around with some of the 'route' commands to sort out your routing table, but generally if you add 'redirect-gateway def1' to the advanced box if it's not being pushed, OpenVPN should modify the routing table and all traffic will flow through the VPN connection.
5. If you entered a local port in the config, you should also see the connection as 'up' and bandwidth usage under Status -> OpenVPN.
Dev notes for improved support:
1. It's really necessary to have auth-user-pass fields in the config page - especially as you do it for the proxy server section.
2. It might be an idea to import a .ovpn file directly and have a script do a lot of the decisions in the config in a future release?
3. 'engine cryptodev' or 'engine padlock' where it's supported by the system should also automatically be set for OVPN configs - the index.php page shows this, so PHP scripts already have detection code somewhere.
4. Uploading PKCS#12 certificates into the Cert Manager and get pfSense to automatically convert them to PEM format would be a nice addition in a future release
5. For some reason, the Traffic Graph doesn't report any traffic over OVPN interfaces - RRD traffic graphs however are fine.
It has been mentioned that we need some kind of importable openvpn config format that could be exported on the server side and then uploaded/pasted on the client side. This is already possible using the OpenVPN client export package for normal clients, but not for clients which are pfSense or other routers.
I agree splitting the info out of a PKCS#12 file should be possible, as it's fairly easy to grab the info out of it with OpenSSL.
First of all - thank your very much for this howto!
I've got this working for 99% now after creating a VPN interface and adding a AON rule for outbound connections. No only DNS is my problem: openvpn doesn't modify my resolv.conf. When I modify it manually, everything works. Is there a way to do this? I there a env variable like $foreign_option_1 so I can write a up- and down-script?
Here's my vpn log:
Apr 29 00:32:32 openvpn: auth_user_pass_verify_script = '[UNDEF]' Apr 29 00:32:32 openvpn: auth_user_pass_verify_script_via_file = DISABLED Apr 29 00:32:32 openvpn: ssl_flags = 0 Apr 29 00:32:32 openvpn: port_share_host = '[UNDEF]' Apr 29 00:32:32 openvpn: port_share_port = 0 Apr 29 00:32:32 openvpn: client = ENABLED Apr 29 00:32:32 openvpn: pull = ENABLED Apr 29 00:32:32 openvpn: auth_user_pass_file = '/conf/logincred' Apr 29 00:32:32 openvpn: OpenVPN 2.1_rc20 i386-portbld-freebsd8.0 [SSL] [LZO2] built on Apr 20 2010 Apr 29 00:32:32 openvpn: WARNING: file '/conf/logincred' is group or others accessible Apr 29 00:32:32 openvpn: WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info. Apr 29 00:32:32 openvpn: NOTE: the current --script-security setting may allow this configuration to call user-defined scripts Apr 29 00:32:32 openvpn: Control Channel Authentication: using '/var/etc/openvpn/client1.tls-auth' as a OpenVPN static key file Apr 29 00:32:32 openvpn: Outgoing Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication Apr 29 00:32:32 openvpn: Incoming Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication Apr 29 00:32:32 openvpn: LZO compression initialized Apr 29 00:32:32 openvpn: Control Channel MTU parms [ L:1562 D:166 EF:66 EB:0 ET:0 EL:0 ] Apr 29 00:32:32 openvpn: Data Channel MTU parms [ L:1562 D:1300 EF:62 EB:135 ET:0 EL:0 AF:3/1 ] Apr 29 00:32:32 openvpn: Fragmentation MTU parms [ L:1562 D:1300 EF:61 EB:135 ET:1 EL:0 AF:3/1 ] Apr 29 00:32:32 openvpn: Local Options String: 'V4,dev-type tun,link-mtu 1562,tun-mtu 1500,proto UDPv4,comp-lzo,mtu-dynamic,keydir 1,cipher AES-256-CBC,auth SHA1,keysize 256,tls-auth,key-method 2,tls-client' Apr 29 00:32:32 openvpn: Expected Remote Options String: 'V4,dev-type tun,link-mtu 1562,tun-mtu 1500,proto UDPv4,comp-lzo,mtu-dynamic,keydir 0,cipher AES-256-CBC,auth SHA1,keysize 256,tls-auth,key-method 2,tls-server' Apr 29 00:32:32 openvpn: Local Options hash (VER=V4): 'e05aa1c5' Apr 29 00:32:32 openvpn: Expected Remote Options hash (VER=V4): '0088baee' Apr 29 00:32:32 openvpn: Socket Buffers: R=[42080->65536] S=[57344->65536] Apr 29 00:32:32 openvpn: UDPv4 link local: [undef] Apr 29 00:32:32 openvpn: UDPv4 link remote: 22.214.171.124:1149 Apr 29 00:32:32 openvpn: TLS: Initial packet from 126.96.36.199:1149, sid=be774924 ccda1ef7 Apr 29 00:32:32 openvpn: WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this Apr 29 00:32:32 openvpn: VERIFY OK: depth=1, /C=LU/ST=Luxembourg/L=Steinsel/O=PP_Internet_Services/CN=OpenVPN-CA/emailAddressemail@example.com Apr 29 00:32:32 openvpn: VERIFY OK: depth=0, /C=LU/ST=Luxembourg/L=Steinsel/O=PP_Internet_Services/CN=server/emailAddressfirstname.lastname@example.org Apr 29 00:32:45 openvpn: Data Channel Encrypt: Cipher 'AES-256-CBC' initialized with 256 bit key Apr 29 00:32:45 openvpn: Data Channel Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication Apr 29 00:32:45 openvpn: Data Channel Decrypt: Cipher 'AES-256-CBC' initialized with 256 bit key Apr 29 00:32:45 openvpn: Data Channel Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication Apr 29 00:32:45 openvpn: Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 4096 bit RSA Apr 29 00:32:45 openvpn: [server] Peer Connection Initiated with 188.8.131.52:1149 Apr 29 00:32:47 openvpn: SENT CONTROL [server]: 'PUSH_REQUEST' (status=1) Apr 29 00:32:47 openvpn: PUSH: Received control message: 'PUSH_REPLY,redirect-gateway def1,dhcp-option DNS 184.108.40.206,dhcp-option DNS 220.127.116.11,dhcp-option DNS 18.104.22.168,route 10.0.61.1,topology net30,ifconfig 10.0.61.50 10.0.61.49' Apr 29 00:32:47 openvpn: OPTIONS IMPORT: --ifconfig/up options modified Apr 29 00:32:47 openvpn: OPTIONS IMPORT: route options modified Apr 29 00:32:47 openvpn: OPTIONS IMPORT: --ip-win32 and/or --dhcp-option options modified Apr 29 00:32:47 openvpn: ROUTE default_gateway=xxx.xxx.232.1 Apr 29 00:32:47 openvpn: TUN/TAP device /dev/tun1 opened Apr 29 00:32:47 openvpn: /sbin/ifconfig ovpnc1 10.0.61.50 10.0.61.49 mtu 1500 netmask 255.255.255.255 up Apr 29 00:32:47 openvpn: /etc/rc.filter_configure ovpnc1 1500 1562 10.0.61.50 10.0.61.49 init Apr 29 00:32:50 openvpn: /sbin/route add -net 22.214.171.124 xxx.xxx.232.1 255.255.255.255 Apr 29 00:32:50 openvpn: /sbin/route add -net 0.0.0.0 10.0.61.49 126.96.36.199 Apr 29 00:32:50 openvpn: /sbin/route add -net 188.8.131.52 10.0.61.49 184.108.40.206 Apr 29 00:32:51 openvpn: /sbin/route add -net 10.0.61.1 10.0.61.49 255.255.255.255 Apr 29 00:32:51 openvpn: Initialization Sequence Completed
Since OVPN is using its magic 'redirect-gateway def1' which effectively overrides the default gateway, you should find all traffic originating from pfSense is routed over the OVPN connection, so whatever you use in the General setup page for DNS should also be piped through OVPN.
As pfSense doesn't know of the OVPN connection as a proper interface, the option in the General setup page 'Allow DNS server list to be overridden by DHCP/PPP on WAN" won't work either.
You can manually control your gateways by setting up the OVPN connection as a proper interface and gateway and also force DNS requests over that gateway. See my other howto to setup an OVPN interface and gateway - then the General Page where you enter the DNS settings you'll find a drop down to specify the gateway for each DNS server to use.
In that setup though, because 'redirect-gateway def1' is disabled, unless you specify static routes and ensure any other traffic originating from pfSense is routed over OVPN, then the traffic will use the default unencrypted WAN gateway and not the OVPN connection, and with DNS especially, you begin to have a DNS leak.
thanks for your guide very useful.
However i have a problem.
Just as I had in 1.2.3, I'm able to open a vpn successfully, but apparently no connections are routed over the vpn. I'll post my route table which looks ok to me.
Hope you can help.
Destination Gateway Flags Refs Use Mtu Netif Expire
0.0.0.0/2 172.31.255.254 UGS 0 0 1500 ovpnc3 =>
default 220.127.116.11 UGS 0 10016 1500 vr1
18.104.22.168/20 link#2 U 0 17766 1500 vr1
22.214.171.124 link#2 UHS 0 0 16384 lo0
126.96.36.199 00:0d:b9:19:89:9d UHS 0 0 1500 vr1
188.8.131.52/9 172.31.255.254 UGS 0 0 1500 ovpnc3
184.108.40.206/11 172.31.255.254 UGS 0 0 1500 ovpnc3
220.127.116.11/12 172.31.255.254 UGS 0 0 1500 ovpnc3
18.104.22.168/13 172.31.255.254 UGS 0 0 1500 ovpnc3
22.214.171.124/14 172.31.255.254 UGS 0 0 1500 ovpnc3
126.96.36.199/15 172.31.255.254 UGS 0 0 1500 ovpnc3
188.8.131.52/16 172.31.255.254 UGS 0 0 1500 ovpnc3
184.108.40.206/18 172.31.255.254 UGS 0 0 1500 ovpnc3
220.127.116.11/19 172.31.255.254 UGS 0 0 1500 ovpnc3
18.104.22.168/20 172.31.255.254 UGS 0 0 1500 ovpnc3
22.214.171.124/23 172.31.255.254 UGS 0 0 1500 ovpnc3
126.96.36.199/24 172.31.255.254 UGS 0 0 1500 ovpnc3
188.8.131.52/28 172.31.255.254 UGS 0 0 1500 ovpnc3
184.108.40.206/29 172.31.255.254 UGS 0 0 1500 ovpnc3
220.127.116.11/30 172.31.255.254 UGS 0 0 1500 ovpnc3
18.104.22.168/32 172.31.255.254 UGS 0 0 1500 ovpnc3
22.214.171.124/31 172.31.255.254 UGS 0 0 1500 ovpnc3
126.96.36.199/27 172.31.255.254 UGS 0 0 1500 ovpnc3
188.8.131.52/26 172.31.255.254 UGS 0 0 1500 ovpnc3
184.108.40.206/25 172.31.255.254 UGS 0 0 1500 ovpnc3
220.127.116.11/22 172.31.255.254 UGS 0 0 1500 ovpnc3
18.104.22.168/21 172.31.255.254 UGS 0 0 1500 ovpnc3
22.214.171.124/17 172.31.255.254 UGS 0 0 1500 ovpnc3
126.96.36.199/10 172.31.255.254 UGS 0 0 1500 ovpnc3
188.8.131.52/8 172.31.255.254 UGS 0 0 1500 ovpnc3
184.108.40.206/7 172.31.255.254 UGS 0 0 1500 ovpnc3
220.127.116.11/6 172.31.255.254 UGS 0 0 1500 ovpnc3
18.104.22.168/5 172.31.255.254 UGS 0 0 1500 ovpnc3
22.214.171.124/4 172.31.255.254 UGS 0 0 1500 ovpnc3
126.96.36.199 00:0d:b9:19:89:9d UHS 0 0 1500 vr1
188.8.131.52/3 172.31.255.254 UGS 0 0 1500 ovpnc3
127.0.0.1 link#7 UH 0 19 16384 lo0
127.0.0.2 127.0.0.1 UHS 0 0 16384 lo0
184.108.40.206/1 172.31.255.254 UGS 0 2 1500 ovpnc3
172.18.0.0/24 link#1 U 0 676009 1500 vr0
172.18.0.254 link#1 UHS 0 0 16384 lo0
172.31.0.0/16 link#11 U 0 0 1500 ovpnc3
172.31.97.101 link#11 UHS 0 0 16384 lo0
192.168.1.0/24 link#3 U 0 17745 1500 vr2
192.168.1.250 link#3 UHS 0 0 16384 lo0
I have an update.
I tried a traceroute on the pfsense itself to a website, and it routes correlty over the vpn.
But i still can't get traffic from the LAN to route through it.
Since you can traceroute correctly from the shell it's not the routing table or the default gateway… this is more likely an issue with your firewall rules, including the floating rules used by the traffic shaper. Be sure no rule specifies a gateway directly and uses the 'default' gateway which uses the routing table. Beyond that it might be your NAT setup (especially manual outbound NAT).