Building an economical OpenVPN server using the Raspberry Pi

5 January 2013 — 103 Comments

The Raspberry Pi is a $35 credit-card sized computer, with an ARM-based CPU. It uses very little power (only 3 Watt), so it’s ideal for a server that’s always-on. I was thinking what’d be a nice task for my Raspberry Pi and came up with an OpenVPN server. This enables me to connect to my home from anywhere, for example to access some files or to access the internet from there.

Before we start, Let’s have a look what’s on board the Raspberry Pi so you’ve an idea what we talk about:

RaspiModelB

Here’s mine in action:

RaspberryPi

Now, let’s see how we can turn it into a OpenVPN server. Actually this is very easy due to the fact that the Raspberry Pi is running (a modified) Debian Weezy called Raspbian. Since it’s Debian, you can use apt-get to install software:

apt-get install openvpn

After the install finishes, you need to generate keys for the server and the client(s). OpenVPN ships with the ‘easy-rsa’-tool. It’s easiest to copy the example folder and work from there.

cp -R /usr/share/doc/openvpn/examples/easy-rsa /etc/openvpn
cd /etc/openvpn/easy-rsa/2.0

The ‘easy-rsa’-tool has a file called ‘vars’ that you can edit to set some defaults. That will save you time later on but it’s not required to do so.

Load the vars like this (note the two dots):

. ./vars

Then we need to generate keys:

./clean-all
./build-ca
./build-key-server server
./build-key client-name
./build-dh

The first line makes sure we start from scratch. The second generates a key for the Certificate Authority. The key for the server itself is generated on the third line. Repeat the forth line for each client that needs to connect. Finally, we need the Diffie Hellman key as well, which is generated on the fifth line. Make sure you use a 2048 bit key, as suggested in the comments.

We need to copy the keys to the OpenVPN folder.

cd /etc/openvpn/easy-rsa/2.0/keys
cp ca.crt ca.key dh2048.pem server.crt server.key /etc/openvpn

Last step is to configure the server. You can copy the example config and make sure it points to the certs you just created.

cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn
gunzip /etc/openvpn/server.conf.gz
vim /etc/openvpn/server.conf

When you’re done, start OpenVPN like this:

/etc/init.d/openvpn start

Response looks like:

[ ok ] Starting virtual private network daemon: server.

Verify it by running:

ifconfig tun0

You’ll see:

tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 
 inet addr:10.8.0.1 P-t-P:10.8.0.2 Mask:255.255.255.255
 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
 RX packets:49 errors:0 dropped:0 overruns:0 frame:0
 TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:100 
 RX bytes:3772 (3.6 KiB) TX bytes:1212 (1.1 KiB)

Now you should be able to connect to the OpenVPN server with a client. I’m using Viscosity on Mac OSX, but there’re many clients available on almost any platform (Windows, Mac OSX, Linux). You need the client.crt, client.key and ca.crt files plus the ip-address of your Raspberry Pi.

viscosity-vpn-config

Connecting should now work without trouble. Have a look at ‘/var/log/syslog’ to access the logfiles. You’d be able to see which client connects:

Jan 5 22:07:56 raspberrypi ovpn-server[14459]: 1.2.3.4:64805 [client-name] Peer Connection Initiated with [AF_INET]1.2.3.4:64805

Now that all is working, time for a last tip: when you want to access the network behind the Raspberry Pi through your OpenVPN connection, configure OpenVPN to push the right route to the clients. Edit the OpenVPN server config, and add a parameter like this:

push "route 10.1.7.0 255.255.255.0"

Be sure to enter the network- and netmask address that match your network setup. The route is automatically added on connect, and removed on disconnect.

Finally, enable routing on the Rasperry Pi:

echo 1 > /proc/sys/net/ipv4/conf/all/forwarding

Have fun with it, you can do a lot of great things with this little machine!

Update: Also see these follow-up posts that contain more detailed info on some interesting use cases and help you set it up:

HOWTO connect to hosts on a remote network using OpenVPN and some routing

Secure browsing via untrusted wifi networks using OpenVPN and the Raspberry Pi

103 responses to Building an economical OpenVPN server using the Raspberry Pi

  1. 

    Hi,

    thanks for your tutorial everything works great, but I wasn’t able to setup access of network behind the Raspberry pi. Where can i find my network and netmask address?

    Tomas

    • 

      Hi Tomas,

      Cool you’ve got it running too 🙂
      You can find your network and netmask address using the ifconfig utility. This onleliner shows your netmask:

      ifconfig eth0 | grep "inet addr" | cut -d: -f4

      Also, make sure the hosts you are connecting to through the VPN do know the route back to your ip. If the VPN server is not the default gateway on the hosts you’re connecting to, you will need to add a route so they know how to reply.

      When you assign 10.8.0.0/24 addressess to your VPN clients (the default), add something like this to the hosts you are connecting to:

      route add -net 10.8.0.0/24 gw ip_of_vpn_server_here

      Then it should work 🙂

      PS: For network address calculations, have a look at the cmd line program called sipcalc.

      • 

        Ok. I’m almost there :). So you say that vpn server(Raspberry pi), have to point to default gateway (in my case ip of my router 192.168.0.1). Pointing is done trough setting this: push “route 192.168.0.1 255.255.255.0” in the /etc/openvpn/server.conf of my Raspberry pi. Then I need to run this command: route add -net 10.8.0.0/24 gw 192.168.0.109 ( the ip address of my vpn server Raspberry pi) on all of my computers in vpn network.

        Am i right? I believe not, because it doesn’t work 🙂

      • 

        Hi Tomas,
        It’s the other way around: when the pi is NOT the default gateway for the hosts you connect to on the local network, these hosts need to know the route back to the VPN client.

        Example:
        server1 is on the local network and has ip 192.168.0.11
        the pi is on the same network and had 192.168.0.2
        you also have a router with address 192.168.0.1

        You connect to some public ip-address and that’s how you connect to your pi using OpenVPN. When you connect, your OpenVPN clients get a route ‘pushed’ saying that 192.168.0.0/24 is behind the OpenVPN. So, when you connect to 192.168.0.11 the OpenVPN client knows this is behind the pi, and routes it to the pi. The pi also knows this ip, because it is on the local network. So far, so good. Now the server1 wants to respond to the OpenVPN client. The address is something like 10.8.0.6. Since server1 does not know 10.8.0.0/24 (only 192.168.0.0/24) it sends this to the default gateway. And this is your router that will probably drop it because it is unrelated and it too does not know 10.8.0.0/24.

        The solution? Add a route to 10.8.0.0/24 on the server1 so it knows how to respond. You might also be able to add this to your router, so packets that are sent to the default gateway make it to the pi. Because the pi knows 10.8.0.0/24 and routes it over the VPN to the client.

        This way the circle is complete and all should be working 🙂

        I hope this helps!

  2. 

    Thanks a lot Remi, that made it clear :). And another question, what if I want to use my Raspberry as VPN proxy? What do i need to setup to redirect http requests of my computer trough VPN to my VPN server?

    • 

      Hi Tomas,
      So, if I understand this correctly, you want to use a proxy server on the VPN client, that is in the network behind the VPN server? You should be able to reach this server already, so just ‘forget’ the VPN and enter the correct proxy url as you’d do when you’re on the local network: it’s the same.

      In case you want to use the pi as a proxy, I think the machine is not powerful enough for that task since you’d have a pretty bad disk performance. But a Proof-of-Concept will probably work.

      Good luck and have fun with the pi!

  3. 

    Hi Remi
    First, thanks for a great article. I’ve managed to get the OpenVPN server set up on the Raspberry PI and can connect to it from a Mac running Viscosity. However I run into trouble when I try to use the VPN connection to connect to the internet (i.e. I’ve configured the client to “send all traffic over VPN connection in Viscosity”). The Pi is receiving packets (as per ifconfig) but isn’t sending anything back. To eliminate one cause I still get the problem when I flush iptables with sudo iptables -F (hence I don’t think its firewall related)
    So its probably a config setting in a network file that I’m missing – I’m a complete newbie at this !
    If you have any suggestions I can try that would be great.
    Thanks

    • 

      Hi Sam, I think you might need to allow the Pi to forward packets (make it work like a router). Try:

      echo 1 > /proc/sys/net/ipv4/ip_forward

      If this works, make it permanent by editing /etc/sysctl.conf:

      net.ipv4.ip_forward = 1

      Good luck!

  4. 

    Thanks for the suggestion Remi but I already have net.ipv4.ip_forward=1 set in sysctl.conf. I’ve managed to get packets sent and received by adding this line to /etc/openvpn/server.conf

    push “dhcp-option DNS 10.8.0.1”

    Trying to browse BBC news now results in a timeout and this error message :-

    “The server at news.bbc.co.uk can’t be found, because the DNS lookup failed”

    From more research I’m wondering if I need to install bind9 and set that up to allow DNS requests from 10.8.0.1 (?) Again not entirely sure how best to do that ..

    To try and further eliminate causes :-
    – Vivacity client connection is set to “send all traffic over VPN connection”
    – VPN connects without issue and I can see packets received and sent both from Vivacity connection details and ifconfig on the Pi
    – I’m flushing iptables so firewall restrictions shouldn’t be a cause
    – I can ping sites by IP and name (e.g. news.bbc.co.uk) from the Pi
    – I can browse by IP to a WordPress site hosted locally on the Pi via the VPN connection

    I think I’m close and missing something obvious. Any suggestions would be much appreciated 🙂

    • 

      Hi Sam,

      Before spending a lot of time on setting up your own nameserver, just test with a public one. Use 8.8.8.8 or 8.8.4.4; these are Google’s public DNS servers. Quite easy to remember, and easy for testing as well!

      Can you access servers on the remote network from the VPN client?

      To further debug this, I’d use ‘traceroute’ and ‘tcpdump’ to find out what’s going on.

      Remi

  5. 

    I’m stuck on the first steps. For some reason clean-all doesn’t finish and subsequently when I run build-ca it prints that I should source vars and then clean-all. I’ve done everything I could think of. Can I not configure this over ssh? Can it not find this pkcs11-tool? I don’t know where it is or if it is aliased something else.

    • 

      You can do this over SSH, no problem. When sourcing the vars, did you run ‘. ./vars’ aka: ‘dot space dot slash vars’? Instead of the first dot, you can also enter ‘source’: ‘source ./vars’.

      After sourcing, you should see environment vars named like KEY_* when running ‘export’. When you see them, sourcing went ok. When not, something went wrong and we should look at any error messages in logs etc.

      Hope this helps!

      • 

        It was simple actually, I chown’d /etc/openvp/easy-rsa to change ownership to user: pi and then everything went smoothly. I was playing around with ssh’ing into the pi from my iphone and the interface is cumbersome on the app i’m using.

      • 

        Nice! Thanks for letting know how you fixed it!

      • 

        Almost there… OpenVPN gui on Windows 7 says it’s completed the initialization process and it looks connected. I can ssh into the pi still but no response from any servers via chrome. However, I can traceroute and it looks like my default gateway at home is being used to access the internet: http://pastebin.com/CJHtgLX7 I close the vpn connection and access to the internet via browser resumes like normal. Thanks for your help! This got me most of the way there. Also, I have ip_forward turned on.

      • 

        Could it be that the hosts in your network do not know the route back to the OpenVPN clients, as described and detailed here? Also make sure the Pi is enabled to route traffic for you and that you are actually pushing the route to the servers behind the Pi to the OpenVPN client. I think one of these might be the missing piece here.. Let me know!

  6. 

    Hi Remi
    I’m using 8.8.8.8 and 8.8.4.4 now in server.conf but no luck unfortunately.
    What would be the best way to try to connect to a server on the remote network – i.e. if I have a server on the remote network on 192.168.0.3 should I try to ping that once I’ve connected over the VPN? I’ve added push “route 192.168.0.3 255.255.255.0” to server.conf.
    When trying to traceroute to news.bbc.co.uk when the VPN is connected this stops and just reports “unknown host news.bbc.co.uk”)
    Traceroute without using the VPN (eg over local wifi network) correctly gets to news.bbc.co.uk (212.58.244.132) after about 10 hops.

    Thanks
    Sam

    • 

      Hi Sam,
      The route you push is a whole /24, so 192.168.0.0 should be ok. 192.168.0.3 and all ip’s starting with 192.168.0. are automatically included (due to the specified netmask). Pinging such a host is a good first test. Connect the VPN, then ping 192.168.0.3. It should reply. Next, try to SSH to it (if it runs it) or connect any other service. If this works, you can successfully access services on the remote network.

      Why do you want all internet traffic to go through the VPN as well? This should not be a problem, as long as there is a router on the remote side that does some NATting on the 10.8.x addresses. This router is probably the default gateway of the Pi.

      When all traffic goes through the VPN and you do a traceroute to news.bbc.co.uk. What happens?

  7. 

    Hi Remi
    OK, I now have push “route 192.168.0.0 255.255.255.0″. To test this I’m using a Macbook Air tethered to an iPhone so its not going over a wireless network. VPN is connected and redirecting all traffic through VPN. iptables are flushed on the Pi (probably irrelevant 🙂
    1) I can ping 10.8.0.1 and 10.8.0.6 (client IP indicated in Vivacity)
    2) I can SSH to the Raspberry PI no problem but can’t ping it (?). I have SSH on a non standard port for security.
    3) I can’t ping 192.168.0.3 or anything else under 192.168.0.* I get messages “Request timeout for icmp_seq 0 (1, 2, up to 13)” , 15 packets transmitted, 0 packets received, 100% packet loss”
    4) ping news.bbc.co.uk results in “cannot resolve news.bbc.co.uk: Unknown host”
    5) ping 212.58.244.56 results in the same timeout messages as for trying to ping 192.168.0.*.
    6) traceroute news.bbc.co.uk results in “traceroute: unknown host news.bbc.co.uk”

    What I’m hoping to achieve is ability to connect to the Raspberry Pi on public wifi but be able to browse the web through a secure connection that can’t be sniffed. I’m not fussed about connecting to other servers behind the Pi.

    Thanks for sticking with me on this 🙂

    • 

      Hi Sam,
      Well, that’s a nice use case! I did some testing this evening and managed to get this to work. Right now, my MacBook is connected to my iPhone and connects via 3G network to my Pi. It sends all traffic over the vpn link. When I browse right now and visit a site, my home-ip is shown. This is expected behavior of course.

      I was typing in this comment how I did it, when I realized I could as well write another blog about it 😉

      Have a look here, and let me know if it works for you too!

      When it doesn’t work for you, please check if your router (the default gw for the Pi) knows the 10.8.0.0/24 route. Otherwise, the router does not know how to reach the OpenVPN client and nothing works. From your story, I suspect this to be the case. More info also in this post.

      Have fun and let me know!

  8. 

    Hi Remi

    Glad to see you like the use case, still trying to get things working from this end unfortunately.
    Thanks for pointing me to the other article you wrote, very interesting.
    Here’s what I’ve done so far ..
    1. Double checked that I have net.ipv4.ip_forward=1 in /etc/sysctl.conf. Also made sure this was activated with sudo sysctl -p
    2. Confirmed I have push “dhcp option DNS 8.8.8.8” and push “dhcp-option DNS 8.8.4.4” in /etc/openvpn/server.conf
    3. My home network with the pi on it is 192.168.0.0. The Pi has a static IP – 192.168.0.111
    4. My router is on 192.168.0.1 and is a rather old Sky Netgear DG834GT. I added a static route on the router as follows (and rebooted the router for good measure)
    Destination IP address – 10.8.0.0
    IP Subnet mask – 255.255.255.0
    Gateway IP Address 192.168.0.111
    Metric – 3
    5. This didn’t work so I then entered this while logged into the Pi as root
    route add -net 10.8.0.0/24 gw 192.168.0.111
    6. No luck with this either – still get the DNS lookup failure when trying to browse via VPN.
    7. Running route -n on the Pi gives me this information :-
    Destination Gateway Genmask Flags Metric Ref Use Iface
    0.0.0.0 192.168.0.1 0.0.0.0 UG 0 0 0 eth0
    10.8.0.0 192.168.0.111 255.255.255.0 UG 0 0 0 eth0
    10.8.0.0 10.8.0.2 255.255.255.0 UG 0 0 0 tun0
    10.8.0.2 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
    192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

    Thanks
    Sam

    • 

      Hi Sam,

      Step 4: That does not help, as you can see in the routing table there are now two routes for the 10.8.0.0 network. Revert it like this:

      route del -net 10.8.0.0/24 gw 192.168.0.111

      Step 3: I’d use metric=1 because it’s a direct connection, but apart from that it looks ok. Can you try a ping test from the Netgear and ping 10.8.0.2 (this is the address of the OpenVPN server?

      If this works, and it should, then try the OpenVPN client (probably 10.8.0.6). If it doesn’t work, there’s something wrong in the routing between the Pi and the Netgear. That should be fixed first, because everything else (including Internet access and DNS resolving on the OpenVPN clients) depends on it.

      Do you still see the correct route on the Netgear (did it survive a reboot)?

      Good luck!

  9. 

    Hi Remi
    I can have another go when I’m bac tonight however looking at route -n its interesting that it is referring to 10.8.0.2 rather than 10.8.0.1. I believe my openvpn server should be running on 10.8.0.1 (ifconfig below). Could that be the cause; if so how can I change the routes?

    Thanks
    Sam

    tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
    inet addr:10.8.0.1 P-t-P:10.8.0.2 Mask:255.255.255.255
    UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
    RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    TX packets:40 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:100
    RX bytes:0 (0.0 B) TX bytes:3360 (3.2 KiB

  10. 

    On the Pi pinging 10.8.0.1 is successful. Pinging 10.8.0.2 fails (timeout)

    • 

      Ok, same here so this is expected behavior.. It’s a point-to-point connection, so you probably can only ping the .1 But, the route seems ok after all. To be sure: can you connect a VPN client, see what ip address it gets and try to ping that one (10.8.0.6?) from the Netgear? Also reversed, so ping 192.168.0.1 (I think) from VPN client -> Netgear. If one of them does not work, try ‘traceroute -I -n’ (I=capital i) so see where it goes.

      Are there any restrictions in the Netgear, for example only allowing 192.168.0.x or so?

      Anyway, a work-around is to NAT the 10.8.0.0/24 network on the Pi, but that shouldn’t be necessary. I haven’t done that and it works fine here.

      It does look promising so far, so we must be getting close 😉

  11. 

    Ok so I’ve done these tests with my Macbook Air tethered to my iPhone through USB.
    I’ve modified my Netgear static route to use metric 2 (metric 1 was not allowed).

    VPN client connects OK as usual – client IP is 10.8.0.6.
    Route Table on Pi

    0.0.0.0         192.168.0.1     0.0.0.0         UG    0      0        0 eth0
    10.8.0.0        10.8.0.2        255.255.255.0   UG    0      0        0 tun0
    10.8.0.2        0.0.0.0         255.255.255.255 UH    0      0        0 tun0
    192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0
    

    Route table on Netgear

    Destination             Mask             Gateway    Metric   Active
    x.x.x.0            255.255.255.192     x.x.x.x        0         Yes
    x.x.x.0            255.255.255.192     0.0.0.0       0         Yes
    10.8.0.0         255.255.255.0    192.168.0.111 2        Yes
    192.168.0.0   255.255.255.0     192.168.0.1    0         Yes
    192.168.0.0   255.255.255.0         0.0.0.0        0         Yes
    127.0.0.0       255.255.0.0             0.0.0.0        0         Yes
    239.0.0.0       255.0.0.0                 0.0.0.0        0         Yes
    0.0.0.0           0.0.0.0                     y.y.y.y         0         Yes
    

    Where x.x.x.x is my ADSL IP address and y.y.y.y is my ADSL gateway IP address

    When connected on VPN
    1. Router ping fails to 10.8.0.6 (100% packet loss) (this is if macbook connects via local wifi – if on VPN via 3G I can’t browse to 192.168.0.1)
    2. Router successfully pings 10.8.0.1 (if macbook connects via local wifi)
    3. Router successfully pings 192.168.0.111 (if macbook connects via local wifi)
    4. VPN client fails to ping 192.168.0.1 (100% packet loss)
    5. VPN client successfully pings 192.168.0.111 (Pi local IP address)
    6. VPN client successfully ping 10.8.0.1
    7. trace route -I -n from VPN client returns this

    traceroute to 192.168.0.1 (192.168.0.1), 64 hops max, 72 byte packets
     1  10.8.0.1  496.620 ms  206.351 ms  220.344 ms
     2  * * * (etc)
    

    I’ve had a look in the router for any restrictions but couldn’t see anything obvious ..
    Router is being used as a DHCP server. Starting IP is 192.168.0.2 (default). Ending IP is 192.168.0.254.

    Thanks
    Sam

    • 

      Hi Sam,

      Does the macbook, while connected to VPN server, has a route to the 192.168.0.x network (check netstat -nr)? If so, I wonder where it goes to. Did you disable the Wifi at the time you were testing with the iPhone connection? I’m wondering whether the macbook is getting confused about this (that is its routes: wifi knows 192.168.0.x and OpenVPN as well).

      To rule this one out: Would it be possible to test it at some place with pubic wifi or so? That gives a good real-world test anyway.

      Everything seems fine to me so I don’t think there’s something wrong with your configs.

      Let me know!

  12. 

    Hi Remi
    When I tested I disabled wifi on the Mac and only had a tethered connection with my iPhone. This was connecting over 3G to my router so there was no wifi involved.

    Interesting, I ran netstat -nr while connected to VPN and did spot a route to 192.168.0 going to 10.8.0.5 (x.x.x.x is my ADSL ip address)

    Destination        Gateway            Flags        Refs      Use   Netif Expire
    0/1                10.8.0.5           UGSc            4        0    tun0
    default            172.20.10.1        UGSc            9        9     en2
    x.x.x.x    172.20.10.1        UGSc            1        0     en2
    10.8.0.1/32        10.8.0.5           UGSc            0        0    tun0
    10.8.0.5           10.8.0.6           UHr             9        0    tun0
    127                127.0.0.1          UCS             0        0     lo0
    127.0.0.1          127.0.0.1          UH              3      627     lo0
    128.0/1            10.8.0.5           UGSc            1        0    tun0
    169.254            link#6             UCS             0        0     en2
    172.20.10/28       link#6             UCS             2        0     en2
    172.20.10.1        ac:de:48:ae:13:78  UHLWIir         3        0     en2    869
    172.20.10.4        127.0.0.1          UHS             1        0     lo0
    172.20.10.15       ff:ff:ff:ff:ff:ff  UHLWbI          0        6     en2
    192.168.0          10.8.0.5           UGSc            0        0    tun0
    

    When disconnecting the VPN the 192.168.0 entry no longer appears (along with the other tun0 entries)

  13. 

    Bloody hell, I’m going nuts over this! 🙂 I’ve been looking at the best way to set up a VPN server for my iOS devices on the go and OpenVPN seemed to be the best choice. I actually used this to set my OpenVPN up: http://www.raspberrypi.org/phpBB3/viewtopic.php?f=36&t=21566 including the config files, before I found this blog. I’m up to the point where I can connect to OpenVPN, both through Viscosity and also through the OpenVPN client on iOS, but after that it’s a no go, probably related to the routing configuration. I just can’t get this figured out, a bit confused here, so if you can lend a hand that would be greatly appreciated!

    My modem is at 192.168.100.1 (UBEE EVM2200)
    The router at 192.168.1.1 (Airport Extreme)
    RPi at 192.168.1.7

    So I thought I’d put ‘push “route 192.168.1.0 255.255.255.0″‘ into my server.conf and then execute ‘route add -net 10.8.0.0/24 gw 192.168.1.7’ and I’d be fine (not really knowing what I’m doing here) but so far no luck. I’ve tried all imaginable combinations so I’m slowly starting to pull my hair out. 🙂

    • 

      You probably have a routing issue: the router/modem should know the route to the OpenVPN network (are you using the default 10.8.0.0/24 by the way?).

      Think of it this way: the OpenVPN clients needs to know about the network behind the Pi to be able to contact it (use ‘push route’). Hosts in this network, or at least the default gateway of the Pi (probably the router) need to know the opposite route: the route back to the OpenVPN client (use ‘route add -net …. or some webbased tool to setup the route and point to the Pi’s internal ip). You should not have to add this routes to the Pi itself, but to its default gateway instead. I’d recommend to remove it from the Pi (use ‘route del …’).

      Good luck!

      • 

        Hmm. If I understand this correctly: I can connect to the VPN just fine from outside, it’s just getting connectivity to 192.168.1.7 (RPi int ip) from 10.8.0.0 (OpenVPN netw) then? And that gets routed within the router? Then I’m probably doomed because I can’t seem to find any way to do th is on my Airport Extreme or the modem I have… 😦

      • 

        Don’t worry. If the router does not support static routes, you can always configure them on the servers you connect to instead. So, say you’d want to connect to a server with ip address 192.168.1.10, you’d add a static route on this server back to the Pi. It depends on the OS how to do it exactly, but it definitely can be done. Just some more work, that’s all.

        To add a static route in Linux:

        sudo route add -net 10.8.0.0/24 gw 192.168.1.7

        To add a static route in OSX:

        sudo route -n add -net 10.8.0.0/24 192.168.1.7

        Please note that these are not persistent, so you need to add them to a shell script to make them available again after reboot.

      • 

        Thank you Remi, that very well did the trick! Splendid!

      • 

        Great, you’re welcome! 🙂

  14. 

    Hi Remi
    Ok I tried a slightly different test .. turned off wifi on the macbook air and tethered to my iphone, connecting over VPN (so not possibility off wireless confusing things).
    I can ping 192.168.0.1 from the VPN client (Macbook Air).
    I can ping 10.8.0.6 (VPN client IP) from the router (using another PC on the network).

    So the route looks ok 🙂 However when attempting to browse news.bbc.co.uk I get a timeout and a DNS failure message in the browser window. Trying to ping news.bbc.co.uk (or ping by IP) still fails to connect unfortunately (either host not found or Request timeout error)

    Sam

    • 

      Good news, because then routing is all working properly!

      Can you have a look at the /etc/resolv.conf file? Does that file include the right DNS servers? If not, dont’t bother changing that file, as OpenVPN (and Mac OSX) will update it anyway. Check Viscosity, I believe it’s located at: Preferences, then networking and check ‘Enable DNS support’ option. That should allow OpenVPN server to push the DNS servers (which option I suppose you have in your config, server side).

  15. 

    OK, I’ve got “Enable DNS support” option in Viscosity but left the DNS server field blank. Also double checked that I’ve got 8.8.8.8 and 8.8.4.4 as the DNS servers in /etc/open/vpn/server.conf. No luck unfortunately, still get DNS error.
    I tried entering 8.8.8.8 into Viscosity in the DNS servers field but didn’t work either. I can ping 8.8.8.8 when not on VPN but cannot ping 8.8.8.8 when VPN is not connected.

    • 

      That is strange, Sam. The only way to sort this out is to debug everything and try to rule stuff out and then finally pin it down to its root cause. That’s not easy from here 😉

      What I’d do is this:
      1. Restart OpenVPN on the Pi, so you know for sure the current config is loaded and active
      2. When connected, look what it puts in /etc/resolv.conf on the OpenVPN client. No need to supply DNS servers in Viscosity, just check the box and leave it empty
      If it has 8.8.8.8 and 8.8.4.4 the that’s correctly. If not, doublecheck both server and client config for this (and restart or reload after changes)
      3. If it’s ok, but does not resolve, try pinging the ip address as you did. When it does not work, run a traceroute to see where it gets stuck. You probably would want to run ‘traceroute -n -I 8.8.8.8’ (capital i).
      4. Do the same for 212.58.246.129 (BBC’s ip) and 173.194.34.130 (Google)
      You need to be able to ping and traceroute these ip’s
      5. See what DNS servers are used on other hosts on the network you connect to and try these instead
      6. Doublecheck you have no routes etc set for the 8.8.x.x network. Ping and traceroute the ip’s straight from the Pi as well
      7. Doublecheck the Pi allows routing. A traceroute should pass the 10.8.0.1 hop

      If you cannot contact 8.8.8.8 that is strange because you should. All is left to do now is find a properly working DNS server and have that one pushed to the clients. Then everything will work!

      Plan B is to install this DNS server on the Pi, and push that ip. It takes some time to configure but that might be quicker after all 😉

      Good luck!

  16. 

    I can certainly sympathise with this being difficult to debug from where you are. Definitely appreciate you helping me out, I am at least learning a good deal about networking 🙂

    1. Restarted and iptables flushed. /etc/openvpn/server.conf looks like this

    port 1194
    proto udp
    dev tun
    ca ca.crt
    cert server.crt
    key server.key  # This file should be kept secret
    dh dh1024.pem
    server 10.8.0.0 255.255.255.0
    ifconfig-pool-persist ipp.txt
    push "route 192.168.0.0 255.255.255.0"
    push "redirect-gateway def1 bypass-dhcp"
    push "dhcp-option DNS 8.8.8.8"
    push "dhcp-option DNS 8.8.4.4"
    keepalive 10 120
    comp-lzo
    persist-key
    persist-tun
    status openvpn-status.log
    verb 3
    

    2. When connected /etc/resolv.conf on VPN client looks OK
    nameserver 8.8.8.8
    nameserver 8.8.4.4

    3. Pinging 8.8.8.8 fails from VPN client. trace route gives this output
    traceroute to 8.8.8.8 (8.8.8.8), 64 hops max, 72 byte packets
    1 10.8.0.1 539.423 ms 569.774 ms 517.730 ms
    2 192.168.0.1 522.075 ms 511.242 ms 516.077 ms
    3 * * *

    4. Same result when trying 212.58.246.129 and 173.194.34.130

    5. Other DNS servers used on the router are 90.207.238.97 and 90.207.238.99. However using these rather than 8.8.x.x results in the same behaviour (steps 1-4)

    6. Confirmed in routing tables on router, pi and mac osx client that 8.8.x.x is not present

    7. trace route from Pi to 8.8.8.8, 212.58.246.129, 173.194.34.130 is successful. However traced route does not include 10.8.0.1 in any of the 3 cases so perhaps routing is not right ?
    trace route from pi
    traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
    1 192.168.0.1 (192.168.0.1) 2.006 ms 2.305 ms 2.528 ms
    2 027e8f3e.bb.sky.com (my IP) 32.542 ms 34.169 ms 35.545 ms
    3 10.245.175.161 (10.245.175.161) 34.810 ms 35.509 ms 36.126 ms
    4 te0-6-0-7.er11.thlon.ov.easynet.net (89.200.134.223) 41.775 ms 42.578 ms 42.618 ms
    5 72.14.215.13 (72.14.215.13) 39.237 ms 41.213 ms 42.824 ms
    6 209.85.240.63 (209.85.240.63) 43.222 ms 209.85.240.61 (209.85.240.61) 35.168 ms 35.380 ms
    7 209.85.253.90 (209.85.253.90) 36.184 ms 33.321 ms 34.040 ms
    8 209.85.243.33 (209.85.243.33) 40.289 ms 209.85.240.28 (209.85.240.28) 40.538 ms 209.85.243.33 (209.85.243.33) 41.274 ms
    9 216.239.49.38 (216.239.49.38) 95.765 ms 216.239.49.28 (216.239.49.28) 47.111 ms 47.289 ms
    10 * * *
    11 google-public-dns-a.google.com (8.8.8.8) 50.107 ms 50.254 ms 42.784 ms

    route table on pi
    Destination Gateway Genmask Flags Metric Ref Use Iface
    0.0.0.0 192.168.0.1 0.0.0.0 UG 0 0 0 eth0
    10.8.0.0 10.8.0.2 255.255.255.0 UG 0 0 0 tun0
    10.8.0.2 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
    192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

    However /etc/sysctl.conf has forwarding enabled. Anything else I need to add ?

    kernel.printk = 3 4 1 3
    net.ipv4.ip_forward=1
    vm.swappiness=1
    vm.min_free_kbytes = 8192
    
    • 

      Hi Sam,

      Thanks for all info! I have the same OpenVPN config and everything just looks right. From what you post it seems the 192.168.0.1 router does not allow the 10.8.0.0/24 network to access the network. Probably it has something to do with a NAT (Network Address Translation) rule there or so. What kind of router is this by the way? Does it say anything on NAT or the 192.168.0.0/24 network?

      To prove this is the problem, please run this command on the Pi:

      sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

      It will hide the 10.8.0.0/24 network behind the Pi’s address, so VPN traffic will now seem to appear from the Pi itself instead of the actual VPN client. May not be what you want, but it at least makes sure the other router does not get confused.

      If this works, then you could debug this further. You know then you’ve to look at the router.

      Disable the rule again like this, if you want:

      sudo iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

      Use ‘iptables-save’ to make the rule persistent.

      Let me know! 🙂

  17. 

    Hi Remi
    My router is a Netgear DG834GT. I couldn’t find anything specific in the settings around 192.168.0.0/24. I have got a static route set up to 192.168.0.111 and firewall ports open for VPN (port1194) and SSH (port 57474).
    However your suggestion above worked if I flushed the iptables first – I can now browse websites when connected via VPN 🙂

    The last thing I would like to do would be to get this working without flushing IP tables and losing all my existing rules. My /etc/iptables.firewall.rules (prior to dropping the rules and running your masquerade line above) looks like this :-

    *filter
    
    #  Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
    -A INPUT -i lo -j ACCEPT
    -A INPUT -d 127.0.0.0/8 -j REJECT
    
    #  Accept all established inbound connections
    -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    
    #  Allow all outbound traffic - you can modify this to only allow certain traffic
    -A OUTPUT -j ACCEPT
    
    #  Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
    -A INPUT -p tcp --dport 80 -j ACCEPT
    -A INPUT -p tcp --dport 443 -j ACCEPT
    -A INPUT -p udp --dport 1194 -j ACCEPT
    
    #  Allow SSH connections
    #
    #  The -dport number should be the same port number you set in sshd_config
    #
    -A INPUT -p tcp -m state --state NEW --dport 57474 -j ACCEPT
    
    # Allow VPN connections
    -A INPUT -p udp -m state --state NEW --dport 1194 -j ACCEPT
    
    #  Allow ping
    -A INPUT -p icmp -j ACCEPT
    
    #  Log iptables denied calls
    -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
    
    #  Drop all other inbound - default deny unless explicitly allowed policy
    -A INPUT -j DROP
    -A FORWARD -j DROP
    COMMIT
    

    Please advise what changes I would need to make here to finish things off ?

    • 

      Hi Sam,

      This is because the line is entered after your reject and drop lines.

      Try this:
      Enable firewall, then run the iptables cmd I sent you but replace -A with -I (capital I).

      When this works, add it to the script (using -A) but above the reject and drop settings at the bottom. This should then also work.

  18. 

    Hi Remi

    Think I’m nearly there .. I modified my iptables file so that the drop and reject commands were at the bottom. I also added the lines for the nat at the bottom but above the drop and reject lines. Unfortunately this means at reboot the iptables isn’t correctly loaded (i.e. if I uncomment the nat lines at the bottom #*nat to #commit). I’ve tried uncommenting the block and just the -A POSTROUTING line. So I suspect its invalid formatting in the file that is now the problem. I also tried to Google an example file but with no luck.

    Thanks
    Sam

    *filter
    #  Allow all loopback (lo0) traffic
    -A INPUT -i lo -j ACCEPT
    
    #  Accept all established inbound connections
    -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    
    #  Allow all outbound traffic - you can modify this to only allow certain traffic
    -A OUTPUT -j ACCEPT
    
    #  Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
    -A INPUT -p tcp --dport 80 -j ACCEPT
    -A INPUT -p tcp --dport 443 -j ACCEPT
    -A INPUT -p udp --dport 1194 -j ACCEPT
    
    #  Allow SSH connections
    #
    #  The -dport number should be the same port number you set in sshd_config
    #
    -A INPUT -p tcp -m state --state NEW --dport 57474 -j ACCEPT
    
    # Allow VPN connections
    -A INPUT -p udp -m state --state NEW --dport 1194 -j ACCEPT
    
    #  Allow ping
    -A INPUT -p icmp -j ACCEPT
    
    #  Log iptables denied calls
    -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
    
    #*nat
    #:PREROUTING ACCEPT [10:1030]
    #:INPUT ACCEPT [0:0]
    #:OUTPUT ACCEPT [0:0]
    #:POSTROUTING ACCEPT [0:0]
    #-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
    #COMMIT
    
    # reject all traffic to 127/8 that doesn't use lo0
    -A INPUT -d 127.0.0.0/8 -j REJECT
    
    #  Drop all other inbound - default deny unless explicitly allowed policy
    -A INPUT -j DROP
    -A FORWARD -j DROP
    COMMIT
    
    • 

      Hi Sam,
      How did you notice it didn’t work? Did you test it, or didn’t the MASQUERADE rule show up when you run ‘iptables -L’?

      It seems you generated the output using ‘iptables-save’ so that’s the right way to do it. Your output looks similar to when I try to create it.

      Maybe you can add the rule by hand again and see at what positon of the file ‘iptables-save’ writes it. Then edit your own firewall file accordingly.

      BTW: MASQUERADE rules are put in the NAT table. You can display its content with:

      iptables -L -t nat
      • 

        Hi Remi
        I noticed that with my own edits that the iptables wasn’t loading correctly when I rebooted the Pi and looked at iptables -L (probably because the file was no longer valid). What I’ve done now is

        1. Have my original firewall rules loaded
        2. Run your line above to add the nat rule
        3. iptables-save > a new firewall rules file, reboot
        4. On boot up verified that filter and nat rules are in place.
        5. However I’m still unable to have firewall rules and the NAT in place. Flushing the filter rules with iptables -F allows me to browse web pages (thanks to your masquerade tip), so I guess there’s a restriction in there still that is impacting the routing.

        This is what iptables-save generated for my new firewall rules :

        # Generated by iptables-save v1.4.14 on Sun Feb  3 20:45:29 2013
        *nat
        :PREROUTING ACCEPT [6:840]
        :INPUT ACCEPT [0:0]
        :OUTPUT ACCEPT [2:135]
        :POSTROUTING ACCEPT [2:135]
        -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
        COMMIT
        # Completed on Sun Feb  3 20:45:29 2013
        # Generated by iptables-save v1.4.14 on Sun Feb  3 20:45:29 2013
        *filter
        :INPUT ACCEPT [0:0]
        :FORWARD ACCEPT [0:0]
        :OUTPUT ACCEPT [0:0]
        -A INPUT -i lo -j ACCEPT
        -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
        -A INPUT -d 127.0.0.0/8 -j REJECT --reject-with icmp-port-unreachable
        -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
        -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
        -A INPUT -p udp -m udp --dport 1194 -j ACCEPT
        -A INPUT -p tcp -m state --state NEW -m tcp --dport 57474 -j ACCEPT
        -A INPUT -p udp -m state --state NEW -m udp --dport 1194 -j ACCEPT
        -A INPUT -p icmp -j ACCEPT
        -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
        -A INPUT -j DROP
        -A FORWARD -j DROP
        -A OUTPUT -j ACCEPT
        COMMIT
        # Completed on Sun Feb  3 20:45:29 2013
        

        Thanks
        Sam

      • 

        Hi Sam, thanks for the explanation. Remember we were talking about DNS before? I don’t see rules allowing DNS so that might be the reason why it isn’t working for you. I’d recommend adding a rule to allow DNS port 53/udp and then try again!

  19. 

    Hi Remi
    No luck unfortunately, still getting the same DNS error (unless I flush iptables). Is there another port that I need to open ?

    I ran the following commands to open up port 53 (for both tcp and udp). I also tried this with only the udp rules in place but still got the same error.

    sudo iptables -A INPUT -p udp -m udp –dport 53 -j ACCEPT
    sudo iptables -A INPUT -p tcp -m tcp –dport 53 -j ACCEPT
    sudo iptables -A INPUT -p udp -m state –state NEW -m udp –dport 53 -j ACCEPT
    sudo iptables -A INPUT -p tcp -m state –state NEW -m tcp –dport 53 -j ACCEPT

    and then did iptables-save again. This produced the following file :-

    # Generated by iptables-save v1.4.14 on Mon Feb 4 21:13:59 2013
    *filter
    :INPUT ACCEPT [0:0]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [0:0]
    -A INPUT -i lo -j ACCEPT
    -A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
    -A INPUT -d 127.0.0.0/8 -j REJECT –reject-with icmp-port-unreachable
    -A INPUT -p tcp -m tcp –dport 80 -j ACCEPT
    -A INPUT -p tcp -m tcp –dport 443 -j ACCEPT
    -A INPUT -p udp -m udp –dport 1194 -j ACCEPT
    -A INPUT -p tcp -m state –state NEW -m tcp –dport 57474 -j ACCEPT
    -A INPUT -p udp -m state –state NEW -m udp –dport 1194 -j ACCEPT
    -A INPUT -p icmp -j ACCEPT
    -A INPUT -m limit –limit 5/min -j LOG –log-prefix “iptables denied: ” –log-level 7
    -A INPUT -j DROP
    -A INPUT -p udp -m udp –dport 53 -j ACCEPT
    -A INPUT -p tcp -m tcp –dport 53 -j ACCEPT
    -A INPUT -p udp -m state –state NEW -m udp –dport 53 -j ACCEPT
    -A INPUT -p tcp -m state –state NEW -m tcp –dport 53 -j ACCEPT
    -A FORWARD -j DROP
    -A OUTPUT -j ACCEPT
    COMMIT
    # Completed on Mon Feb 4 21:13:59 2013
    # Generated by iptables-save v1.4.14 on Mon Feb 4 21:13:59 2013
    *nat
    :PREROUTING ACCEPT [25:3912]
    :INPUT ACCEPT [2:197]
    :OUTPUT ACCEPT [14:972]
    :POSTROUTING ACCEPT [14:972]
    -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
    COMMIT
    # Completed on Mon Feb 4 21:13:59 2013

    Thanks again
    Sam

    • 

      Hi Sam,

      The DNS iptables rules are below the DROP line and will therefore not work. Please move them up and try again.

      In general: use iptables -I when there’s already a DROP statement on place or it will never match.

      Also, have a look at the logs since you log what it drops (nice!). That should give some more hints on what’s going on 🙂

  20. 

    Thanks for the tip! I regenerated iptables with -I and now have the file below. The lines have now all been generated above the drop commands. Unfortunately I still get the same error.
    I grepped /etc/syslog for “iptables denied” and saw this a few times, implying that iptables is blocking the router from getting to the Pi (?) Do I need a new rule to allow this ?


    Feb 4 22:43:43 raspberrypi kernel: [ 26.921008] iptables denied: IN=eth0 OUT= MAC=b8:27:eb:e1:d3:6b:00:1b:2f:7b:e9:0a:08:00:45:00:00:4e:00:14:40:00:40:11:b8:ca SRC=192.168.0.1 DST=192.168.0.111 LEN=78 TOS=0x00 PREC=0x00 TTL=64 ID=20 DF PROTO=UDP SPT=3118 DPT=137 LEN=58

    # Generated by iptables-save v1.4.14 on Mon Feb  4 22:04:53 2013
    *filter
    :INPUT ACCEPT [0:0]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [0:0]
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 53 -j ACCEPT
    -A INPUT -p udp -m state --state NEW -m udp --dport 53 -j ACCEPT
    -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
    -A INPUT -p udp -m udp --dport 53 -j ACCEPT
    -A INPUT -i lo -j ACCEPT
    -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    -A INPUT -d 127.0.0.0/8 -j REJECT --reject-with icmp-port-unreachable
    -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
    -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
    -A INPUT -p udp -m udp --dport 1194 -j ACCEPT
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 57474 -j ACCEPT
    -A INPUT -p udp -m state --state NEW -m udp --dport 1194 -j ACCEPT
    -A INPUT -p icmp -j ACCEPT
    -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
    -A INPUT -j DROP
    -A FORWARD -j DROP
    -A OUTPUT -j ACCEPT
    COMMIT
    # Completed on Mon Feb  4 22:04:53 2013
    # Generated by iptables-save v1.4.14 on Mon Feb  4 22:04:53 2013
    *nat
    :PREROUTING ACCEPT [115:10051]
    :INPUT ACCEPT [2:94]
    :OUTPUT ACCEPT [13:904]
    :POSTROUTING ACCEPT [13:904]
    -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
    COMMIT
    # Completed on Mon Feb  4 22:04:53 2013
    

    Thanks
    Sam

    • 

      Hi Sam,

      UDP port 137 is NETBIOS Name Service; you wouldn’t normally need this. But you can try to allow all traffic between the router and the Pi. You’d probably already trust that network anyway.

      sudo iptables -I INPUT -d 192.168.0.0/24 -j ACCEPT

      Instead of the whole /24 you can also add the router’s ip address with /32.

      Alternatively, try changing the ‘-A INPUT -j DROP’ line to ‘-A INPUT -j ACCEPT’ while leaving the rest in place. This disables the firewall, but violations will still be logged. This way you can do everything you want and later inspect the logfiles for violations. Add rules to allow them, do some more test work, and when no more violations are logged, you change it back to DROP. Then it should work. If you want to firewall this, you need to be very sure what traffic needs to pass and allow that. Another way to see what passess by is to use tcpdump and wireshark on the Pi. But that’s too complicated to explain for now 😉

      Have fun, debugging always makes you learn new stuff 🙂

  21. 

    No luck unfortunately and I’ve run out of time as I fly abroad tomorrow and need to do some packing 🙂
    Nethertheless I feel that I’ve learned a lot (and have a lot still to learn – especially iptables !). I’ll have another go at this when I get back in a couple of weeks.

    Thanks a lot for your help over the past few weeks Remi, really appreciate your patience and help!

    Thanks
    Sam

    • 

      Hi Sam,

      You’re welcome! Have a nice trip and we’ll fix it later 🙂

      If you need the VPN abroad, I’d disable the Pi’s firewall for now (if that’s possible) since it isn’t very much exposed to the Internet anyway. It at least works then.

      Take care,
      Remi

  22. 

    I get this error:

    @raspberrypi:/etc/openvpn/easy-rsa/2.0# cp ca.crt ca.key dh1024.pem server.crt server.key /etc/openvpn
    cp: cannot stat `ca.crt’: No such file or directory
    cp: cannot stat `ca.key’: No such file or directory
    cp: cannot stat `dh1024.pem’: No such file or directory
    cp: cannot stat `server.crt’: No such file or directory
    cp: cannot stat `server.key’: No such file or directory

    Any idea?

    • 

      It seems like the build commands did not finish properly. Did you run all the ‘./build-*’ commands? Any errors?

      • 

        I experienced the same problem. I ran all the ‘./build-*’ commands without issue. Looking for suggestions. Thanks for sharing your expertise!

      • 

        Hi Kirk,

        Did you run these commands as root or prefixed with sudo? Have a look in the directory where you build the certs. They should be there (if you have write permissions). Please provide some more info otherwise and I’ll have a look!

      • 

        I think as root, but I’m honestly not sure. I’ll go back and give that a try. Thanks!

    • 

      take a look at the keys folder.
      @Remi thx for the extensive coverage 🙂

      • 

        You’re welcome and.. I overlooked that indeed.. they are of course in the /etc/openvpn/easy-rsa/2.0/keys folder 🙂 Thx!

        PS: Updated the blogpost to make this clear.

  23. 

    Hi Remi,

    Great stuff, even for a beginner like myself this is easy to setup. I have one question left though. For security reasons, which of the generated files do I remove from the Raspberry Pi and store somewhere else? I’m guessing the client key and certificate, correct?

    Regards,
    Marcel

    • 

      Hi Marcel,

      Glad you like it! The OpenVPN server does not need the certificates you generated for clients, so you can indeed safely remove them from the Pi. You need them on the client side only. You can always later revoke the client certificate on the Pi to disallow access if you want to.

  24. 

    Hi Remi
    I think I’ve finally sorted this out. There were no further “iptables denied” messages from the iptables INPUT chain but I still had problems – so I added some further logging for FORWARD chain. From this I could see denied messages in /var/log/syslog, which I resolved by allowing forwarding to 10.8.0.0/24 (source and destination)

    So my final iptables config (for anyone who reads this far 🙂 looks like this :-

    # Generated by iptables-save v1.4.14 on Fri Feb 22 00:14:25 2013
    *filter
    :INPUT ACCEPT [0:0]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [0:0]
    -A INPUT -d 192.168.0.0/24 -j ACCEPT
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 53 -j ACCEPT
    -A INPUT -p udp -m state --state NEW -m udp --dport 53 -j ACCEPT
    -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
    -A INPUT -p udp -m udp --dport 53 -j ACCEPT
    -A INPUT -i lo -j ACCEPT
    -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    -A INPUT -d 127.0.0.0/8 -j REJECT --reject-with icmp-port-unreachable
    -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
    -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
    -A INPUT -p udp -m udp --dport 1194 -j ACCEPT
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 57474 -j ACCEPT
    -A INPUT -p udp -m state --state NEW -m udp --dport 1194 -j ACCEPT
    -A INPUT -p icmp -j ACCEPT
    -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
    -A INPUT -j DROP
    -A FORWARD -s 10.8.0.0/24 -j ACCEPT
    -A FORWARD -d 10.8.0.0/24 -j ACCEPT
    -A FORWARD -m limit --limit 5/min -j LOG --log-prefix "iptables forward denied: " --log-level 7
    -A FORWARD -j DROP
    -A OUTPUT -j ACCEPT
    COMMIT
    # Completed on Fri Feb 22 00:14:25 2013
    # Generated by iptables-save v1.4.14 on Fri Feb 22 00:14:25 2013
    *nat
    :PREROUTING ACCEPT [313:24501]
    :INPUT ACCEPT [10:1245]
    :OUTPUT ACCEPT [23:1586]
    :POSTROUTING ACCEPT [23:1586]
    -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
    COMMIT
    # Completed on Fri Feb 22 00:14:25 2013

    So assuming this hasn’t left a gaping hole in my firewall I now have a fully working VPN server I can use when I’m next on public wifi 🙂
    Many thanks for your patience and help with all this Remi !

  25. 
    mikael.johansson.lc 9 March 2013 at 22:48

    For a little more explicit guide, go to http://raspberrypi.host56.com/index.php/tutorials/1-openvpn-server-tutorial . That one did the job for me.

    • 

      Thanks for sharing, that seems like a nice guide. Especially if you need an exact step-by-step tutorial.

      Be warned though: setting the keys directory to 777 might not what you want since it allows anyone to write in the directory. 755 should be enough, if you don’t look at ownership. Only the openvpn user and root needs access.

      Second note: by specifying the ‘client-to-client’ option in the server config, you allow VPN users to communicate to each other. This is normally not needed and probably not what you want. So, remove it if you don’t need it.

      Just my little advice 🙂

  26. 

    I have done

    sudo bash
    apt-get update
    apt-get install openvpn
    cp -R /usr/share/doc/openvpn/examples/easy-rsa /etc/openvp
    cd /etc/openvpn/easy-rsa/2.0
    vi vars –> change the line at the end export KEY_COUNTRY to export KEY_EMAIL
    . ./vars

    and obtain the following:
    ================================================================================
    /etc/openvpn/easy-rsa/2.0/whichopensslcnf: 6: /etc/openvpn/easy-rsa/2.0/whichopensslcnf: openssl: not found
    /etc/openvpn/easy-rsa/2.0/whichopensslcnf: 8: /etc/openvpn/easy-rsa/2.0/whichopensslcnf: openssl: not found
    /etc/openvpn/easy-rsa/2.0/whichopensslcnf: 10: /etc/openvpn/easy-rsa/2.0/whichopensslcnf: openssl: not found
    NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/2.0/keys
    ================================================================================

    ./clean-all
    ./build-ca
    and obtain the following:
    ================================================================================
    /etc/openvpn/easy-rsa/2.0/pkitool: 325: /etc/openvpn/easy-rsa/2.0/pkitool: openssl: not found
    ================================================================================

    ./build-key-server server
    and obtain the following:
    ================================================================================
    pkitool: Need a readable ca.crt and ca.key in /etc/openvpn/easy-rsa/2.0/keys
    Try pkitool –initca to build a root certificate/key.
    ================================================================================

    ./build-key client-name
    and obtain the following:
    ================================================================================
    pkitool: Need a readable ca.crt and ca.key in /etc/openvpn/easy-rsa/2.0/keys
    Try pkitool –initca to build a root certificate/key.
    ================================================================================

    ./build-key bruno
    and obtain the following:
    ================================================================================
    pkitool: Need a readable ca.crt and ca.key in /etc/openvpn/easy-rsa/2.0/keys
    Try pkitool –initca to build a root certificate/key.
    ================================================================================

    ./build-dh
    and obtain the following:
    ================================================================================
    ./build-dh: 7: ./build-dh: openssl: not found
    ================================================================================

    ls /etc/openvpn/easy-rsa/2.0/keys
    ================================================================================
    index.txt serial
    ================================================================================
    no keys where generated … do I miss something ???
    My raspberry running RaspBmc up to date ( version of the 26 of march)

  27. 
    Remi, I was wondering if you could help as you’ve helped so many others. I’m not using a Pi but premise is similar. I’ve also tried a second server.config to match similar to yours where all traffic is going over VPN. This wasn’t what I wanted but to get the issues worked out I figured I would try. I’d also like to use my remote dns servers rather than Google’s but my “newserver.config” does both of these things in order to at least try to get this to work properly. Here is a gist of all the configs, some routing tables, etc. Let me know what else I can provide to help with fixing my issue. .gist table { margin-bottom: 0; } This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters ~% netstat -rn -f inet Routing tables Internet: Destination Gateway Flags Refs Use Netif Expire default 192.168.3.1 UGSc 74 144 en1 10.8/24 10.8.0.5 UGSc 1 0 tun0 10.8.0.5 10.8.0.6 UH 5 0 tun0 25 link#10 UC 2 0 ham0 25.255.255.255 ff:ff:ff:ff:ff:ff UHLWbI 0 4 ham0 127 127.0.0.1 UCS 0 0 lo0 127.0.0.1 127.0.0.1 UH 11 1054980 lo0 169.254 link#5 UCS 0 0 en1 192.168.1 10.8.0.5 UGSc 2 0 tun0 192.168.3 link#5 UCS 2 0 en1 192.168.3.1 54:9b:12:cb:77:c3 UHLWIir 76 2046 en1 1091 192.168.3.2 127.0.0.1 UHS 0 0 lo0 192.168.3.255 ff:ff:ff:ff:ff:ff UHLWbI 0 4 en1 192.168.55 link#9 UC 2 0 vnic1 192.168.55.2 0:1c:42:0:0:9 UHLWIi 1 2 lo0 192.168.55.255 ff:ff:ff:ff:ff:ff UHLWbI 0 4 vnic1 192.168.56 link#8 UC 2 0 vnic0 192.168.56.2 0:1c:42:0:0:8 UHLWIi 1 2 lo0 192.168.56.255 ff:ff:ff:ff:ff:ff UHLWbI 0 4 vnic0 view raw Client Routes when connected to VPN without gateway forced hosted with ❤ by GitHub This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters Routing tables Internet: Destination Gateway Flags Refs Use Netif Expire 0/1 10.8.0.5 UGSc 9 0 tun0 default 192.168.3.1 UGSc 2 2 en1 10.8.0.1/32 10.8.0.5 UGSc 0 0 tun0 10.8.0.5 10.8.0.6 UHr 19 0 tun0 25 link#10 UC 2 0 ham0 25.255.255.255 ff:ff:ff:ff:ff:ff UHLWbI 0 1 ham0 76.15.21.242/32 192.168.3.1 UGSc 1 0 en1 127 127.0.0.1 UCS 0 0 lo0 127.0.0.1 127.0.0.1 UH 13 1100846 lo0 128.0/1 10.8.0.5 UGSc 6 0 tun0 169.254 link#5 UCS 0 0 en1 192.168.1 10.8.0.5 UGSc 0 0 tun0 192.168.3 link#5 UCS 2 0 en1 192.168.3.1 54:9b:12:cb:77:c3 UHLWIir 4 411 en1 830 192.168.3.2 127.0.0.1 UHS 0 0 lo0 192.168.3.255 ff:ff:ff:ff:ff:ff UHLWbI 0 1 en1 192.168.55 link#9 UC 2 0 vnic1 192.168.55.2 0:1c:42:0:0:9 UHLWIi 1 2 lo0 192.168.55.255 ff:ff:ff:ff:ff:ff UHLWbI 0 1 vnic1 192.168.56 link#8 UC 2 0 vnic0 192.168.56.2 0:1c:42:0:0:8 UHLWIi 1 2 lo0 192.168.56.255 ff:ff:ff:ff:ff:ff UHLWbI 0 1 vnic0 view raw Client routes when connecting over VPN with gateway forced hosted with ❤ by GitHub This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters ############################################## # Sample client-side OpenVPN 2.0 config file # # for connecting to multi-client server. # # # # This configuration can be used by multiple # # clients, however each client should have # # its own cert and key files. # # # # On Windows, you might want to rename this # # file so it has a .ovpn extension # ############################################## # Specify that we are a client and that we # will be pulling certain config file directives # from the server. client # Use the same setting as you are using on # the server. # On most systems, the VPN will not function # unless you partially or fully disable # the firewall for the TUN/TAP interface. ;dev tap dev tun # Windows needs the TAP-Win32 adapter name # from the Network Connections panel # if you have more than one. On XP SP2, # you may need to disable the firewall # for the TAP adapter. ;dev-node MyTap # Are we connecting to a TCP or # UDP server? Use the same setting as # on the server. ;proto tcp proto udp # The hostname/IP and port of the server. # You can have multiple remote entries # to load balance between the servers. ;remote my-server-1 1194 ;remote my-server-2 1194 remote myvpn.dyndns.org 1194 # Choose a random host from the remote # list for load-balancing. Otherwise # try hosts in the order specified. ;remote-random # Keep trying indefinitely to resolve the # host name of the OpenVPN server. Very useful # on machines which are not permanently connected # to the internet such as laptops. resolv-retry infinite # Most clients don't need to bind to # a specific local port number. nobind # Downgrade privileges after initialization (non-Windows only) ;user nobody ;group nobody # Try to preserve some state across restarts. persist-key persist-tun # If you are connecting through an # HTTP proxy to reach the actual OpenVPN # server, put the proxy server/IP and # port number here. See the man page # if your proxy server requires # authentication. ;http-proxy-retry # retry on connection failures ;http-proxy [proxy server] [proxy port #] # Wireless networks often produce a lot # of duplicate packets. Set this flag # to silence duplicate packet warnings. ;mute-replay-warnings # SSL/TLS parms. # See the server config file for more # description. It's best to use # a separate .crt/.key file pair # for each client. A single ca # file can be used for all clients. ca ca.crt cert client01.crt key client01.key # Verify server certificate by checking # that the certicate has the nsCertType # field set to "server". This is an # important precaution to protect against # a potential attack discussed here: # http://openvpn.net/howto.html#mitm # # To use this feature, you will need to generate # your server certificates with the nsCertType # field set to "server". The build-key-server # script in the easy-rsa folder will do this. ns-cert-type server # If a tls-auth key is used on the server # then every client must also have the key. ;tls-auth ta.key 1 # Select a cryptographic cipher. # If the cipher option is used on the server # then you must also specify it here. ;cipher x cipher BF-CBC # Enable compression on the VPN link. # Don't enable this unless it is also # enabled in the server config file. comp-lzo # Set log file verbosity. verb 3 # Silence repeating messages ;mute 20 view raw Client.config hosted with ❤ by GitHub This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters port 1194 proto udp #mssfix 1400 # Supposedly this fixes errors with RDP dev tun ca ca.crt cert MyVPNServer.crt key MyVPNServer.key # This file should be kept secret dh dh1024.pem server 10.8.0.0 255.255.255.0 ifconfig-pool-persist ipp.txt push "route 192.168.1.0 255.255.255.0" push "dhcp-option DNS 8.8.8.8" push "dhcp-option DNS 8.8.4.4" ;client-to-client keepalive 10 120 comp-lzo user openvpn group openvpn persist-key persist-tun status openvpn-status.log verb 3 view raw newserver.config hosted with ❤ by GitHub This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters ~% ping heroku.com ping: cannot resolve heroku.com: Unknown host ~% nslookup heroku.com Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: Name: heroku.com Address: 50.19.85.156 Name: heroku.com Address: 50.19.85.132 Name: heroku.com Address: 50.19.85.154 ~% ping 50.19.85.156 PING 50.19.85.156 (50.19.85.156): 56 data bytes 64 bytes from 50.19.85.156: icmp_seq=0 ttl=42 time=57.997 ms 64 bytes from 50.19.85.156: icmp_seq=1 ttl=42 time=64.985 ms ^C — 50.19.85.156 ping statistics — 2 packets transmitted, 2 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 57.997/61.491/64.985/3.494 ms ~% scutil –dns DNS configuration resolver #1 search domain[0] : denneen.local nameserver[0] : 192.168.1.1 if_index : 5 (en1) reach : Reachable resolver #2 domain : 53510353.members.btmm.icloud.com options : pdns timeout : 5 order : 150000 resolver #3 domain : local options : mdns timeout : 5 order : 300000 resolver #4 domain : 254.169.in-addr.arpa options : mdns timeout : 5 order : 300200 resolver #5 domain : 8.e.f.ip6.arpa options : mdns timeout : 5 order : 300400 resolver #6 domain : 9.e.f.ip6.arpa options : mdns timeout : 5 order : 300600 resolver #7 domain : a.e.f.ip6.arpa options : mdns timeout : 5 order : 300800 resolver #8 domain : b.e.f.ip6.arpa options : mdns timeout : 5 order : 301000 resolver #9 domain : dev nameserver[0] : 127.0.0.1 DNS configuration (for scoped queries) resolver #1 search domain[0] : denneen.local nameserver[0] : 192.168.1.1 if_index : 5 (en1) flags : Scoped reach : Reachable ~% more /etc/resolv.conf # # Mac OS X Notice # # This file is not used by the host name and address resolution # or the DNS query routing mechanisms used by most processes on # this Mac OS X system. # # This file is automatically generated. # search denneen.local nameserver 192.168.1.1 view raw Resolving Issues hosted with ❤ by GitHub This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 76.15.20.1 0.0.0.0 255.255.255.255 UH 0 0 0 vlan2 10.8.0.0 192.168.1.200 255.255.255.0 UG 0 0 0 br0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 br0 76.15.20.0 0.0.0.0 255.255.254.0 U 0 0 0 vlan2 169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br0 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo 0.0.0.0 76.15.20.1 0.0.0.0 UG 0 0 0 vlan2 view raw Router Routes hosted with ❤ by GitHub This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters ################################################# # Sample OpenVPN 2.0 config file for # # multi-client server. # # # # This file is for the server side # # of a many-clients <-> one-server # # OpenVPN configuration. # # # # OpenVPN also supports # # single-machine <-> single-machine # # configurations (See the Examples page # # on the web site for more info). # # # # This config should work on Windows # # or Linux/BSD systems. Remember on # # Windows to quote pathnames and use # # double backslashes, e.g.: # # "C:\\Program Files\\OpenVPN\\config\\foo.key" # # # # Comments are preceded with '#' or ';' # ################################################# # Which local IP address should OpenVPN # listen on? (optional) ;local a.b.c.d # Which TCP/UDP port should OpenVPN listen on? # If you want to run multiple OpenVPN instances # on the same machine, use a different port # number for each one. You will need to # open up this port on your firewall. port 1194 # TCP or UDP server? ;proto tcp proto udp mssfix 1400 # Supposedly this fixes errors with RDP # "dev tun" will create a routed IP tunnel, # "dev tap" will create an ethernet tunnel. # Use "dev tap0" if you are ethernet bridging # and have precreated a tap0 virtual interface # and bridged it with your ethernet interface. # If you want to control access policies # over the VPN, you must create firewall # rules for the the TUN/TAP interface. # On non-Windows systems, you can give # an explicit unit number, such as tun0. # On Windows, use "dev-node" for this. # On most systems, the VPN will not function # unless you partially or fully disable # the firewall for the TUN/TAP interface. ;dev tap dev tun # Windows needs the TAP-Win32 adapter name # from the Network Connections panel if you # have more than one. On XP SP2 or higher, # you may need to selectively disable the # Windows firewall for the TAP adapter. # Non-Windows systems usually don't need this. ;dev-node MyTap # SSL/TLS root certificate (ca), certificate # (cert), and private key (key). Each client # and the server must have their own cert and # key file. The server and all clients will # use the same ca file. # # See the "easy-rsa" directory for a series # of scripts for generating RSA certificates # and private keys. Remember to use # a unique Common Name for the server # and each of the client certificates. # # Any X509 key management system can be used. # OpenVPN can also use a PKCS #12 formatted key file # (see "pkcs12" directive in man page). ca ca.crt cert MyVPNServer.crt key MyVPNServer.key # This file should be kept secret # Diffie hellman parameters. # Generate your own with: # openssl dhparam -out dh1024.pem 1024 # Substitute 2048 for 1024 if you are using # 2048 bit keys. dh dh1024.pem # Configure server mode and supply a VPN subnet # for OpenVPN to draw client addresses from. # The server will take 10.8.0.1 for itself, # the rest will be made available to clients. # Each client will be able to reach the server # on 10.8.0.1. Comment this line out if you are # ethernet bridging. See the man page for more info. server 10.8.0.0 255.255.255.0 # Maintain a record of client <-> virtual IP address # associations in this file. If OpenVPN goes down or # is restarted, reconnecting clients can be assigned # the same virtual IP address from the pool that was # previously assigned. ifconfig-pool-persist ipp.txt # Configure server mode for ethernet bridging. # You must first use your OS's bridging capability # to bridge the TAP interface with the ethernet # NIC interface. Then you must manually set the # IP/netmask on the bridge interface, here we # assume 10.8.0.4/255.255.255.0. Finally we # must set aside an IP range in this subnet # (start=10.8.0.50 end=10.8.0.100) to allocate # to connecting clients. Leave this line commented # out unless you are ethernet bridging. ;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 # Configure server mode for ethernet bridging # using a DHCP-proxy, where clients talk # to the OpenVPN server-side DHCP server # to receive their IP address allocation # and DNS server addresses. You must first use # your OS's bridging capability to bridge the TAP # interface with the ethernet NIC interface. # Note: this mode only works on clients (such as # Windows), where the client-side TAP adapter is # bound to a DHCP client. ;server-bridge # Push routes to the client to allow it # to reach other private subnets behind # the server. Remember that these # private subnets will also need # to know to route the OpenVPN client # address pool (10.8.0.0/255.255.255.0) # back to the OpenVPN server. ;push "route 192.168.10.0 255.255.255.0" ;push "route 192.168.20.0 255.255.255.0" push "route 192.168.1.0 255.255.255.0" # To assign specific IP addresses to specific # clients or if a connecting client has a private # subnet behind it that should also have VPN access, # use the subdirectory "ccd" for client-specific # configuration files (see man page for more info). # EXAMPLE: Suppose the client # having the certificate common name "Thelonious" # also has a small subnet behind his connecting # machine, such as 192.168.40.128/255.255.255.248. # First, uncomment out these lines: ;client-config-dir ccd ;route 192.168.40.128 255.255.255.248 # Then create a file ccd/Thelonious with this line: # iroute 192.168.40.128 255.255.255.248 # This will allow Thelonious' private subnet to # access the VPN. This example will only work # if you are routing, not bridging, i.e. you are # using "dev tun" and "server" directives. # EXAMPLE: Suppose you want to give # Thelonious a fixed VPN IP address of 10.9.0.1. # First uncomment out these lines: ;client-config-dir ccd ;route 10.9.0.0 255.255.255.252 # Then add this line to ccd/Thelonious: # ifconfig-push 10.9.0.1 10.9.0.2 # Suppose that you want to enable different # firewall access policies for different groups # of clients. There are two methods: # (1) Run multiple OpenVPN daemons, one for each # group, and firewall the TUN/TAP interface # for each group/daemon appropriately. # (2) (Advanced) Create a script to dynamically # modify the firewall in response to access # from different clients. See man # page for more info on learn-address script. ;learn-address ./script # If enabled, this directive will configure # all clients to redirect their default # network gateway through the VPN, causing # all IP traffic such as web browsing and # and DNS lookups to go through the VPN # (The OpenVPN server machine may need to NAT # or bridge the TUN/TAP interface to the internet # in order for this to work properly). ;push "redirect-gateway def1 bypass-dhcp" # Certain Windows-specific network settings # can be pushed to clients, such as DNS # or WINS server addresses. CAVEAT: # http://openvpn.net/faq.html#dhcpcaveats # The addresses below refer to the public # DNS servers provided by opendns.com. ;push "dhcp-option DNS 208.67.222.222" ;push "dhcp-option DNS 208.67.220.220" push "dhcp-option DNS 192.168.1.1" push "dhcp-option DOMAIN domain.local" ;push "dhcp-option DOMAIN-SEARCH domain.local" # Uncomment this directive to allow different # clients to be able to "see" each other. # By default, clients will only see the server. # To force clients to only see the server, you # will also need to appropriately firewall the # server's TUN/TAP interface. client-to-client # Uncomment this directive if multiple clients # might connect with the same certificate/key # files or common names. This is recommended # only for testing purposes. For production use, # each client should have its own certificate/key # pair. # # IF YOU HAVE NOT GENERATED INDIVIDUAL # CERTIFICATE/KEY PAIRS FOR EACH CLIENT, # EACH HAVING ITS OWN UNIQUE "COMMON NAME", # UNCOMMENT THIS LINE OUT. ;duplicate-cn # The keepalive directive causes ping-like # messages to be sent back and forth over # the link so that each side knows when # the other side has gone down. # Ping every 10 seconds, assume that remote # peer is down if no ping received during # a 120 second time period. keepalive 10 120 # For extra security beyond that provided # by SSL/TLS, create an "HMAC firewall" # to help block DoS attacks and UDP port flooding. # # Generate with: # openvpn –genkey –secret ta.key # # The server and each client must have # a copy of this key. # The second parameter should be '0' # on the server and '1' on the clients. ;tls-auth ta.key 0 # This file is secret # Select a cryptographic cipher. # This config item must be copied to # the client config file as well. ;cipher BF-CBC # Blowfish (default) ;cipher AES-128-CBC # AES ;cipher DES-EDE3-CBC # Triple-DES # Enable compression on the VPN link. # If you enable it here, you must also # enable it in the client config file. comp-lzo # The maximum number of concurrently connected # clients we want to allow. max-clients 100 # It's a good idea to reduce the OpenVPN # daemon's privileges after initialization. # # You can uncomment this out on # non-Windows systems. ;user nobody ;group nogroup user openvpn group openvpn # The persist options will try to avoid # accessing certain resources on restart # that may no longer be accessible because # of the privilege downgrade. persist-key persist-tun # Output a short status file showing # current connections, truncated # and rewritten every minute. status openvpn-status.log # By default, log messages will go to the syslog (or # on Windows, if running as a service, they will go to # the "Program FilesOpenVPNlog" directory). # Use log or log-append to override this default. # "log" will truncate the log file on OpenVPN startup, # while "log-append" will append to it. Use one # or the other (but not both). ;log openvpn.log ;log-append openvpn.log # Set the appropriate level of log # file verbosity. # # 0 is silent, except for fatal errors # 4 is reasonable for general usage # 5 and 6 can help to debug connection problems # 9 is extremely verbose verb 3 # Silence repeating messages. At most 20 # sequential messages of the same message # category will be output to the log. ;mute 20 view raw Server.config hosted with ❤ by GitHub This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters 2013-04-06 01:14:20 Initialization Sequence Completed 2013-04-06 01:14:20 MANAGEMENT: >STATE:1365225260,CONNECTED,SUCCESS,10.8.0.6,76.15.21.242 2013-04-06 01:14:20 *Tunnelblick client.up.tunnelblick.sh: Retrieved name server(s) [ 192.168.1.1 ], domain name [ domain.local ], and WINS server(s) [ ] 2013-04-06 01:14:20 *Tunnelblick client.up.tunnelblick.sh: Up to two 'No such key' warnings are normal and may be ignored 2013-04-06 01:14:20 *Tunnelblick client.up.tunnelblick.sh: Saved the DNS and WINS configurations for later use 2013-04-06 01:14:20 *Tunnelblick client.up.tunnelblick.sh: Set up to monitor system configuration with process-network-changes 2013-04-06 01:14:56 *Tunnelblick process-network-changes: SearchDomains changed from * * to * <array> { * 0 : domain.local * } * pre-VPN was * 2013-04-06 01:14:56 *Tunnelblick process-network-changes: SearchDomains changed; sending USR1 to OpenVPN (process ID 8061) to restart the connection. 2013-04-06 01:14:57 event_wait : Interrupted system call (code=4) 2013-04-06 01:14:57 TCP/UDP: Closing socket 2013-04-06 01:14:57 /Applications/Tunnelblick.app/Contents/Resources/client.down.tunnelblick.sh -m -w -d -atDASNGWrdasngw tun0 1500 1542 10.8.0.6 10.8.0.5 restart 2013-04-06 01:14:57 SIGUSR1[hard,] received, process restarting 2013-04-06 01:14:57 MANAGEMENT: >STATE:1365225297,RECONNECTING,SIGUSR1,, 2013-04-06 01:14:57 MANAGEMENT: CMD 'hold release' 2013-04-06 01:14:57 NOTE: the current –script-security setting may allow this configuration to call user-defined scripts 2013-04-06 01:14:57 Re-using SSL/TLS context 2013-04-06 01:14:57 LZO compression initialized view raw tunnelblick.log hosted with ❤ by GitHub This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 10.8.0.2 0.0.0.0 255.255.255.255 UH 0 0 0 tun0 10.8.0.0 10.8.0.2 255.255.255.0 UG 0 0 0 tun0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 bond0 5.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 LeafNets 0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 bond0 view raw VPN Server Routes hosted with ❤ by GitHub Remote Router – 192.168.1.1 Remote VPN Server – 192.168.1.200/10.8.0.1 Issues I’m having are that when connected to vpn I can ping 192.168.1.0/24 range and 10.8.0.1. Before I switched to using Google’s Nameservers I could nslookup without an issue but when I ping or try to browse any external host I get a DNS issue saying it can’t resolve: Unknown host. After switching to Google’s DNS I can’t nslookup or ping or browse. (Sounds like a routing issue to me but I have the 10.8.0.0/24 route on the router as you can see from the gist pointing back to the VPN server) – And yes ip_forward is turned on the VPN server. What I’m guessing is that somehow the traffic is getting over the VPN to my network and somehow getting lost. The weird part about that is when using remote DNS I could nslookup, ping, ssh without issue… so the routing must be working somehow. And even when using remote DNS without forcing gateway it seemed like they must have been going over VPN anyway because its very similar behavior. Thanks Chris
    • 

      Hi Chris,
      Sorry for not getting back to you any sooner. Did you solve your problem already or do you still need help?
      If so, I’m wondering from what network are you testing your setup? Are you by any chance on the internal network, or on an external one?
      Let me know!

      • 

        Still having issues. I have a MiFi that I can test with. (192.168.3.0/24) Home network is 192.168.1.0/24… VPN network is 10.8.0/24

      • 

        Hi Chris,

        To be sure: Mifi is a device that turns a mobile (like 3G) internet connection into a Wifi hotspot?
        So, your client is connected to Mifi and has access to internet (are you sure it is _only_ connected to this network?). It is probably using NAT to share the mobile public ip I guess. When you check its public ip address it returns something different compared to a pc connected directly to you home network, right? The client then connects to the public ip address of your VPN server and you want to access the network behind it.

        If I understand your problem correctly, this actually works except for DNS resolution? If so, your routes etc are all OK and we’ll have to find out why DNS is not working. If not, we will check the routes.

        Let me know!

  28. 

    Any chance you can do a follow up showing a client setup for a raspberry pi?

    • 

      Hi Steve,

      So you want the Raspberry Pi to connect to another OpenVPN server?

      I’ll think about it and write something down when I find the time. It shouldn’t be too hard.

      Thanks for letting me know 🙂

  29. 

    Hi Remi,

    Firstly, nice entry! but I´m getting this while starting openvpn: [FAIL] Starting virtual private network daemon: openvpn failed!

    I don´t if you could / would help me with this but thank you in advance and keep posting!

    Regard

    • 

      Hi MarcusDo,

      Glad you like it! Could you have a look at the log files and post any entries regarding openVPN? That usually brings in some hints.

      /var/log/messages
      /var/log/daemon.log

      I’ll then have a look at what is wrong.

      • 

        Hi!

        Thank you for your prompt response: This is what it’s saying:

        May 24 09:31:06 raspberrypi ovpn-server[3580]: Cannot load certificate file server.crt: error:0906D06C:PEM routines:PEM_read_bio:no start line: error:140AD009:SSL routines:SSL_CTX_use_certificate_file:PEM lib

        As you could noticed I quite n00b on these matters.

        Cheers!

      • 

        Hi,

        OpenVPN doesn’t start because it cannot load the ‘server.crt’ certificate file. Did you copy the certificates to the /etc/openvpn folder?

        Please review this part:

        We need to copy the keys to the OpenVPN folder:
        cd /etc/openvpn/easy-rsa/2.0/keys
        cp ca.crt ca.key dh1024.pem server.crt server.key /etc/openvpn

        If you make sure the server.crt file is there, OpenVPN will start fine. Let me know if it works 🙂

  30. 

    Hi,

    It is there, but it’s goddamn empty.

    • 

      I’d suggest generating the keys again. Watch for any errors. Then let me know if it works, and, if it does not work, what exact you did including the results you got.

      Once you have the right keys generated OpenVPN will start.

      Good luck and have fun!

  31. 

    Hey,
    Thanks for the nice tutorial. I set up the openvpn on backtrack5 running on virtual machine. I don’t get any errors and i can connect using Viscocity but when i try to load a page on broswer nothing happens. It keeps on loading… Can u help me?

    Thanks in advance

    • 

      Hi Dinos,

      This sounds like either a routing or a DNS problem. Did you enable routing and are you able to resolve domain names on the connected clients?
      Have a look at this page, as it walks through most of it. Let me know if you need any more help.

      Bye,
      Remi

      • 

        Thank you for your reply.

        I did what you send me in the link but still nothing. I have some questions. How can i find out which DNS is open? You say “Just enter some DNS servers that work on the network of your OpenVPN server and that you are allowed to use”.

        I want also to tell you that i am trying it on a virtual machine with bridged network. When i disconnect from home wifi on pc the virtual machine loses internet connection so i cannot connect to another network to test it.

  32. 

    Hi Remi,

    Like this blog. But still not able to start openvpn on raspberry pi.

    Jun 24 21:37:09 juno ovpn-server[3202]: Options error: –server directive network/netmask combination is invalid
    Jun 24 21:37:09 juno ovpn-server[3202]: Use –help for more information.

    Any clue what can be wrong?

    openvpn.conf files contains:
    dev tun
    proto udp
    port 1194

    ca /etc/openvpn/easy-rsa/keys/ca.crt
    cert /etc/openvpn/easy-rsa/keys/server.crt
    key /etc/openvpn/easy-rsa/keys/server.key
    dh /etc/openvpn/easy-rsa/keys/dh1024.pem

    user nobody
    group nogroup

    server 192.168.2.82 255.255.255.0

    persist-key
    persist-tun

    status /var/log/openvpn-status.log
    verb 3
    push “redirect-gateway def1”
    #set the dns servers
    push “dhcp-option DNS 8.8.8.8”
    push “dhcp-option DNS 8.8.4.4”
    log-append /var/log/openvpn
    comp-lzo

    thx in advance.
    Erik

    • 

      Hi Erik,

      This line in your config:
      server 192.168.2.82 255.255.255.0

      Should be:
      server 192.168.2.0 255.255.255.0

      Or the default:
      server 10.8.0.0 255.255.255.0

      It’s the network used to assign ip addresses to clients, not the
      server ip address.

      You need a separate, unused range so if 192.168.2.x is already in use
      on your network you cannot use it here. Start with the default unless
      you already use that range.

      Let me know if this works!

  33. 
    Excel Master 1 August 2013 at 00:57

    Hello Remi,

    Thanks for this great write-up….which as others have correctly pointed out, is one of the best on the web.

    That being said, I’m a noob to Linux and VPNs (in general) and OpenVPN (in particular), and I find the conclusion of your post to be rather abrupt/incomplete (for lack of a better word). What I mean by that is that I have no clue what to do next, i.e.once I have both the server (on a Raspberry Pi), and a client (on a Win XP machine) setup, and even connected (which is where I’ve reached, and have no idea what to do next).

    What I’m trying to achieve is this:

    1. I’d like to have the R-Pi be an “always-on” VPN server, which will allow me to (from anywhere outside the home) tunnel-in to my home network and access files from any machine.

    2. If possible, I’d also like to be able to access my home internet, while in a coffee shop, library etc. .

    The questions/doubts I have are:

    1. Once connected, what do I need to do, or what else is required in order for me to be able to view files from my other machines (be it Windoze or Linux machines)?

    2. Do I have to be outside the house (or using a friendly neighbours’ free-for-all WiFi connection) in order to have this work, or can I be inside the house using my own network?

    Thanks,

    Gerard

    • 

      I’ll answer for you Gerard,

      I believe from your above post that you have created an openVPN server and are able to connect without problems, from a remote internet location such as a 3G mobile phone or public wifi spots. if not you will need to create a dyndns name at with a service like No-IP and forward traffic from you internet modem on port 1194 udp to the servers internal IP address. Also the client config will now have to be directed at the No-IP dns name.

      Once you are able to access the vpn from outside your network, you will be able to create a samba share on the raspberry pi, which will be accessible both on the local network or over the VPN link using the Pi’s IP address. Google has heaps of guides for setting up a samba shares and accessing them.

      To force all internet traffic over the vpn you can either follow the guide on this blog:

      If you follow that guide all traffic of all the connected cleints to the vpn server will have their traffic redirected over your home network , which is less than ideal when working on files over the VPN or using internal resources whilst still happy to use the local location for web browsing.I which case you can do the method listed below, however it is slightly more complex

      add this lines to server.conf (sudo nano /etc/openvpn/server.conf) the DNS sever has to be pushed to the clients because the local DNS server that they are using though DHCP will no longer be assessable, the push “dhcp-option DNS 8.8.8.8” can be added here or in the ccd files later on, I recommend here unless you will be connecting from a point that uses in house dns servers such as a corporate network. In that case only push to specific clients that are for secure browsing using the CCD files.
      client-config-dir ccd
      push “dhcp-option DNS 8.8.8.8”

      next set of commands

      sudo su (Change to Root)

      cd /etc/openvpn

      mkdir ccd (make client config dir)

      cd ccd

      Add the individual client config file the file name is exactly what the certficate common name is based upon this tutorial it would be client-name, add the line push “redirect-gateway def1” to the client config file. This command forces all traffic over the gateway.

      nano client-name
      push “redirect-gateway def1”

      restart the VPN process and you are complete provide the vpn server has be previously configured to allow vpn access to the entire home network.

      I generally have two certificates per machine like my laptop has one certificate for general usage and remote access to the network and one for secure browsing. This allows my VPN server to be used by my laptop 24/7 without the internet speeds being affected by my slow upload speeds at home and access the intranet at work, whilst still being able to securely browse the net at public WiFi spots at a click of a button.

      Regards,

      Cole

  34. 

    Hey, you need to change the DH parameters to 2048 bits in the ./vars file. 1024 bits is widely regarded as insecure and crackable. Its use was recommended to cease after 2010.

  35. 

    Remi,

    Thank you for making this how to series. Everything works great! I would like to ask you when we can expect the next how to in which you will explain how to connect two LAN segments – seperated through a WAN – by using OpenVPN and 2 RPI’s.

    Best regards,

    B

    • 

      Hi,

      Thanks for your feedback. I’m quite busy at the moment so it will probably take some time. But it is interesting so I might dive into it again 🙂

  36. 

    Hi, I’m trying to setup a vpn to connect from home to the office network. I’ve used an open vpn access server which is hosted on aws amazon cloud. So in theory, right now I should be able to connect from home to the vpn server on the cloud, but I’m not sure how the vpn server will then make the rest of the connection to the office lan. I should add a route on the office lan router that point to the vpn server on the cloud? Can you help me figuring this up? I’m new working on vpn.. Thanks

Trackbacks and Pingbacks:

  1. HOWTO connect to hosts on a remote network using OpenVPN and some routing « Remi Bergsma's blog - January 13, 2013

    […] network in a secure and easy way. But while it’s quite easy to set it up (see my post about OpenVPN on Raspberry Pi), getting all the pieces together takes some more network understanding and configuration. I […]

  2. Secure browsing via untrusted wifi networks using OpenVPN and the Raspberry Pi « Remi Bergsma's blog - January 27, 2013

    […] Raspberry Pi can easily be setup as an OpenVPN server. One common feature is to access servers or services on the remote network. Another use case is to […]

  3. Improving OpenVPN security by revoking unneeded certificates « Remi Bergsma's blog - February 27, 2013

    […] you can connect to the OpenVPN server using this certificate. Refer to my earlier post for more info. Now that this works, I’ll show you how to revoke this certificate so you will […]

  4. Secure browsing on iOS (iPhone/iPad) using OpenVPN and the Raspberry Pi « Remi Bergsma's blog - March 13, 2013

    […] lot of people seem interested in safe browsing over untrusted wifi and using a Raspberry Pi with an OpenVPN server to accomplish that. In this blog post, I’ll continue the series and explain how to set up […]

  5. Raspberry Pi – The Perfect Home Server | LW Apps - March 24, 2013

    […] installed OpenVPN on the pi using this guide. With a bit of tweaking, I can now access my home network and route my internet traffic […]

  6. Building an economical OpenVPN server using the Raspberry Pi | University of Wales, Newport: Information Security and Privacy - March 27, 2013

    […] Building an economical OpenVPN server using the Raspberry Pi. […]

  7. Mike Harris How to use a Raspberry Pi as a server - mjrharris.co.uk - May 29, 2013

    […] OpenVPN (from Remi Bergsma’s blog) or private VPN – perfect to create a secure connection to […]

Leave a reply to O Cancel reply