Skip to content

Instantly share code, notes, and snippets.

@superjamie
Last active March 8, 2024 13:18
Star You must be signed in to star a gist
Save superjamie/ac55b6d2c080582a3e64 to your computer and use it in GitHub Desktop.
Raspberry Pi VPN Router

Raspberry Pi VPN Router

This is a quick-and-dirty guide to setting up a Raspberry Pi as a "router on a stick" to PrivateInternetAccess VPN.

Requirements

Install Raspbian Jessie (2016-05-27-raspbian-jessie.img) to your Pi's sdcard.

Use the Raspberry Pi Configuration tool or sudo raspi-config to:

  • Expand the root filesystem and reboot
  • Boot to commandline, not to GUI
  • Configure the right keyboard map and timezone
  • Configure the Memory Split to give 16Mb (the minimum) to the GPU
  • Consider overclocking to the Medium (900MHz) setting on Pi 1, or High (1000MHz) setting on Pi 2

IP Addressing

My home network is setup as follows:

  • Internet Router: 192.168.1.1
  • Subnet Mask: 255.255.255.0
  • Router gives out DHCP range: 192.168.100-200

If your network range is different, that's fine, use your network range instead of mine.

I'm going to give my Raspberry Pi a static IP address of 192.168.1.2 by configuring /etc/network/interfaces like so:

auto lo
iface lo inet loopback

auto eth0
allow-hotplug eth0
iface eth0 inet static
    address 192.168.1.2
    netmask 255.255.255.0
    gateway 192.168.1.1
    dns-nameservers 8.8.8.8 8.8.4.4

You can use WiFi if you like, there are plenty tutorials around the internet for setting that up, but this should do:

auto lo
iface lo inet loopback

auto eth0
allow-hotplug eth0
iface eth0 inet manual

auto wlan0
allow-hotplug wlan0
iface wlan0 inet static
    wpa-ssid "Your SSID"
    wpa-psk  "Your Password"
    address 192.168.1.2
    netmask 255.255.255.0
    gateway 192.168.1.1
    dns-nameservers 8.8.8.8 8.8.4.4

You only need one connection into your local network, don't connect both Ethernet and WiFi. I recommend Ethernet if possible.

NTP

Accurate time is important for the VPN encryption to work. If the VPN client's clock is too far off, the VPN server will reject the client.

You shouldn't have to do anything to set this up, the ntp service is installed and enabled by default.

Double-check your Pi is getting the correct time from internet time servers with ntpq -p, you should see at least one peer with a + or a * or an o, for example:

$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
-0.time.xxxx.com 104.21.137.30    2 u   47   64    3  240.416    0.366   0.239
+node01.jp.xxxxx 226.252.532.9    2 u   39   64    7  241.030   -3.071   0.852
*t.time.xxxx.net 104.1.306.769    2 u   38   64    7  127.126   -2.728   0.514
+node02.jp.xxxxx 250.9.592.830    2 u    8   64   17  241.212   -4.784   1.398

Setup VPN Client

Install the OpenVPN client:

sudo apt-get install openvpn

Download and uncompress the PIA OpenVPN profiles:

wget https://www.privateinternetaccess.com/openvpn/openvpn.zip
sudo apt-get install unzip
unzip openvpn.zip -d openvpn

Copy the PIA OpenVPN certificates and profile to the OpenVPN client:

sudo cp openvpn/ca.rsa.2048.crt openvpn/crl.rsa.2048.pem /etc/openvpn/
sudo cp openvpn/Japan.ovpn /etc/openvpn/Japan.conf

You can use a diffrent VPN endpoint if you like. Note the extension change from ovpn to conf.

Create /etc/openvpn/login containing only your username and password, one per line, for example:

user12345678
MyGreatPassword

Change the permissions on this file so only the root user can read it:

sudo chmod 600 /etc/openvpn/login

Setup OpenVPN to use your stored username and password by editing the the config file for the VPN endpoint:

sudo nano /etc/openvpn/Japan.conf

Change the following lines so they go from this:

ca ca.rsa.2048.crt
auth-user-pass
crl-verify crl.rsa.2048.pem

To this:

ca /etc/openvpn/ca.rsa.2048.crt
auth-user-pass /etc/openvpn/login
crl-verify /etc/openvpn/crl.rsa.2048.pem

Test VPN

At this point you should be able to test the VPN actually works:

sudo openvpn --config /etc/openvpn/Japan.conf

If all is well, you'll see something like:

$ sudo openvpn --config /etc/openvpn/Japan.conf 
Sat Oct 24 12:10:54 2015 OpenVPN 2.3.4 arm-unknown-linux-gnueabihf [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [MH] [IPv6] built on Dec  5 2014
Sat Oct 24 12:10:54 2015 library versions: OpenSSL 1.0.1k 8 Jan 2015, LZO 2.08
Sat Oct 24 12:10:54 2015 UDPv4 link local: [undef]
Sat Oct 24 12:10:54 2015 UDPv4 link remote: [AF_INET]123.123.123.123:1194
Sat Oct 24 12:10:54 2015 WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
Sat Oct 24 12:10:56 2015 [Private Internet Access] Peer Connection Initiated with [AF_INET]123.123.123.123:1194
Sat Oct 24 12:10:58 2015 TUN/TAP device tun0 opened
Sat Oct 24 12:10:58 2015 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Sat Oct 24 12:10:58 2015 /sbin/ip link set dev tun0 up mtu 1500
Sat Oct 24 12:10:58 2015 /sbin/ip addr add dev tun0 local 10.10.10.6 peer 10.10.10.5
Sat Oct 24 12:10:59 2015 Initialization Sequence Completed

Exit this with Ctrl+c

Enable VPN at boot

sudo systemctl enable openvpn@Japan

Setup Routing and NAT

Enable IP Forwarding:

echo -e '\n#Enable IP Routing\nnet.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Setup NAT fron the local LAN down the VPN tunnel:

sudo iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
sudo iptables -A FORWARD -i tun0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o tun0 -j ACCEPT

Make the NAT rules persistent across reboot:

sudo apt-get install iptables-persistent

The installer will ask if you want to save current rules, select Yes

If you don't select yes, that's fine, you can save the rules later with sudo netfilter-persistent save

Make the rules apply at startup:

sudo systemctl enable netfilter-persistent

VPN Kill Switch

This will block outbound traffic from the Pi so that only the VPN and related services are allowed.

Once this is done, the only way the Pi can get to the internet is over the VPN.

This means if the VPN goes down, your traffic will just stop working, rather than end up routing over your regular internet connection where it could become visible.

sudo iptables -A OUTPUT -o tun0 -m comment --comment "vpn" -j ACCEPT
sudo iptables -A OUTPUT -o eth0 -p icmp -m comment --comment "icmp" -j ACCEPT
sudo iptables -A OUTPUT -d 192.168.1.0/24 -o eth0 -m comment --comment "lan" -j ACCEPT
sudo iptables -A OUTPUT -o eth0 -p udp -m udp --dport 1198 -m comment --comment "openvpn" -j ACCEPT
sudo iptables -A OUTPUT -o eth0 -p tcp -m tcp --sport 22 -m comment --comment "ssh" -j ACCEPT
sudo iptables -A OUTPUT -o eth0 -p udp -m udp --dport 123 -m comment --comment "ntp" -j ACCEPT
sudo iptables -A OUTPUT -o eth0 -p udp -m udp --dport 53 -m comment --comment "dns" -j ACCEPT
sudo iptables -A OUTPUT -o eth0 -p tcp -m tcp --dport 53 -m comment --comment "dns" -j ACCEPT
sudo iptables -A OUTPUT -o eth0 -j DROP

And save so they apply at reboot:

sudo netfilter-persistent save

If you find traffic on your other systems stops, then look on the Pi to see if the VPN is up or not.

You can check the status and logs of the VPN client with:

sudo systemctl status openvpn@Japan
sudo journalctl -u openvpn@Japan

Configure Other Systems on the LAN

Now we're ready to tell other systems to send their traffic through the Raspberry Pi.

Configure other systems' network so they are like:

  • Default Gateway: Pi's static IP address (eg: 192.168.1.2)
  • DNS: Something public like Google DNS (8.8.8.8 and 8.8.4.4)

Don't use your existing internet router (eg: 192.168.1.1) as DNS, or your DNS queries will be visible to your ISP and hence may be visible to organizations who wish to see your internet traffic.

Optional: DNS on the Pi

To ensure all your DNS goes through the VPN, you could install dnsmasq on the Pi to accept DNS requests from the local LAN and forward requests to external DNS servers.

sudo apt-get install dnsmasq

You may now configure the other systems on the LAN to use the Pi (192.168.1.2) as their DNS server as well as their gateway.

@KuraiKitsune
Copy link

Had this working on a Pi2. Upgraded to a Pi3A+, worked fine for a while until sector corruption. Now trying to re-create it on the Pi3A+ with Raspbian Stretch instead of Jessie, and i can't get it working right... connects to VPN as far as i can see but not getting any net access.
Tried again with Jessie, but Wifi doesn't want to connect...
Any tips for doing this process on Stretch?

@winedog
Copy link

winedog commented Aug 19, 2019

anyone have luck getting this work on Buster? I was eventually able to get the vpn to come up by adding the client switch
tls-version-min 1.0
However, I'm running into some issues after trying to use the killswitch. Not sure how I undo those changes because now I can't get the vpn to even come up again.

@winedog
Copy link

winedog commented Aug 21, 2019

Well - I've ignored the killswitch and this all seems to work on buster with an rpi3, but as soon as I added the routing and NAT setup portion of this guide, the vpn throughput performance just fell through the floor. With just the openvpn connection up and running I could get about 30mbps. After the IPfowarding and local NAT forwarding it dropped down to 5mbps. This leads me to believe buster is just too heavy for the rpi3 to support openvpn at reasonable speeds? Reverting to back to Jessie and I get 40-50mbps. Was running full install of buster so perhaps buster lite will be more friendly, but I'm skeptical

@winedog
Copy link

winedog commented Aug 25, 2019

I've tested this now on an rpi3 and odroid c2 in both stretch and buster lite installations and performance is hugely degraded from jessie. I suspect the issue is openvpn >2.4 as the jessie install I use still has openvpn2.3. I haven't managed to locate a repository to install older openvpn 2.3 into a stretch or buster build to confirm and can't devote any more time to this since the jessie has good throughput. Would love to hear if anyone tries setting this all up on an rpi4 with buster. Openvpn is notoriously resource hungry so an rpi4 might have enough power to effectively handle this job with openvpn >2.4

@racingpassion
Copy link

Hi I followed the instructions as you say and still get auth error , has anyone managed to get this done on the latest operating system and a Rpi4. Could do with some help getting this working.

@winedog
Copy link

winedog commented Sep 22, 2019

Hi I followed the instructions as you say and still get auth error , has anyone managed to get this done on the latest operating system and a Rpi4. Could do with some help getting this working.

Please post the output you get when doing the 'Test VPN' step listed above. That output should give some idea of where the failure is happening.

Did you try adding tls-version-min 1.0 to the .conf file?

@sg6
Copy link

sg6 commented Sep 23, 2019

2 years ago, I set my network up like this and it worked like a charm. Now my Raspian was a little bit damaged, so I had to make a new install and I am glad that I found your gist again. It's awesome - thank you. Works like a charm once again.

@ashleyw
Copy link

ashleyw commented Sep 26, 2019

If you're having trouble with DNS leaking… don't overlook the same thing I did! 😅

I'm running Pi-Hole alongside my OpenVPN server, but whether I set the DNS on my computer, or via a local cache like dnsmasq on the Raspberry Pi itself, or with OpenVPN's push "dhcp-option DNS 123.123.123.123" config… I was still leaking! How?!

OpenVPN-client sets up a route when it boots, like 123.123.123.123 via 10.0.0.1 dev eth0, meaning traffic to the Pi-hole/OpenVPN server's IP in particular was being singled out to explicitly bypass the the VPN tunnel and to be resolved by my standard router and network… out in the open, right next to the encrypted VPN traffic heading to the exact same destination (at least in theory — I suppose my ISP was sniffing packets and responding to DNS requests themselves!!)

$ ip route
  0.0.0.0/1 via 10.8.0.1 dev tun0
  default via 10.0.0.1 dev eth0 src 10.0.0.6 metric 202
  10.0.0.0/24 dev eth0 proto dhcp scope link src 10.0.0.6 metric 202
  10.8.0.0/24 dev tun0 proto kernel scope link src 10.8.0.5
  123.123.123.123 via 10.0.0.1 dev eth0
  128.0.0.0/1 via 10.8.0.1 dev tun0

I just needed to specify OpenVPN's gateway IP (10.8.0.1) in dnsmasq's config and the DNS traffic would get routed correctly, via the tunnel. No more leaking! 👌🏼

@shoxcorp
Copy link

My kill switch - keeping local stuff from leaving outside the tunnel
iptables -I FORWARD -i eth0 -s 192.168.0.0/16 -o eth0 ! -d 192.168.0.0/16 -j REJECT

This is exactly what was missing to make the killswitch work for any client using the raspi as the gateway. THANKS!

@TokyoM1ke
Copy link

Thanks so much for this!

I would really like to get this working with two ethernet ports:
eth0 - onto my local LAN for management (and external access)
eth1 - a separate network so that I can attach devices to it and have them route through the VPN only

So routing from eth1<>tun0
And no connection between eth1 and eth0

The main reason is to allow devices to connect without configuration and potentially run a Pi for each country endpoint that I want.

I think that I'm just getting myself tied up in knots after umpteenth reinstall.

Thanks!

@MrSco
Copy link

MrSco commented Jan 10, 2020

Love this tutorial! Thanks for writing this up. I have it all working but was wondering what modifications to the iptables rules would need to be made to make it so only a specific destination external IP address (or set of addresses or domains) uses the vpn tun and the rest just get forwarded through as normal.

My senario is i need to use my appletv and other devices behind a vpn for some apps/servers/domains/IPs but not everything because things like Netflix and Hulu don't like vpn's.

Anyone doing something similar?

@winedog
Copy link

winedog commented Jan 12, 2020

Love this tutorial! Thanks for writing this up. I have it all working but was wondering what modifications to the iptables rules would need to be made to make it so only a specific destination external IP address (or set of addresses or domains) uses the vpn tun and the rest just get forwarded through as normal.

My senario is i need to use my appletv and other devices behind a vpn for some apps/servers/domains/IPs but not everything because things like Netflix and Hulu don't like vpn's.

Anyone doing something similar?

So I'm not sure what you are asking? If you want your AppleTV to go completely through the Pi/VPN just follow the directions. When you point the AppleTV's gateway to the Pi only the AppleTV will go through the Pi/VPN.

However, if you are trying to have only certain apps on the AppleTV go through the Pi/VPN (e.g. Netflix) and other apps use your main internet connection, that is going to be very very tricky and I would advise against it. You'd have to know exactly all the correct IP addresses/domain names for all the services and all of their servers and create some very detailed and customized IPTables rules. And if there are any changes to those servers it will stop working.

Instead, what I do is simply change the gateway IP on my AppleTV depending on the service/app I'm using. It's a minor annoyance, but it's pretty easy to go into Network and change the gateway from 192.168.1.1 to 192.168.1.2. That way when I want to bypass the VPN and use my regular internet connection for a local/non-vpn connection I only have to increment/decrement the Gateway IP to change where it's all going. I just leave the DNS permanently set to use cloudflare 1.1.1.1 regardless of whether I use the Pi or my main router as the gateway.

It's about as good as you can get. The only other option is to get something like the GL.net travel routers where they have a hardware switch to turn the VPN on/off. However, that is still a manual invoked task.

@blockloop
Copy link

blockloop commented Mar 2, 2020

I took the liberty of turning this into an ansible playbook. I could have turned the iptables blocks into ansible iptables blocks but I didn't because I got lazy and this works well enough for me.

Changes from the original (all configurable in vars section):

  1. added the ability to disable ipv6 (default yes)
  2. use Cloudflare DNS by default instead of Google
---
- hosts: raspberrypi
  become: yes
  vars:
    # put these somewhere secure like vault or just type them in here and uncomment if you like to live dangerously 
    # piavpn_user: ??????
    # piavpn_pw: ??????
    vpn_kill_switch: yes
    disable_ipv6: yes
    static_ip: 192.168.1.163
    netmask: 255.255.255.0
    gateway: 192.168.1.254
    ip_range: 192.168.1.0/24
    dns_nameservers: 1.1.1.1 1.0.0.1
    pia_server: US Texas
    # probably don't change these unless you really care
    pia_conf_name: "{{ pia_server | replace(' ','-') }}"
    conf_file: "/etc/openvpn/{{ pia_conf_name }}.conf"
  tasks:
    - name: install packages
      apt:
        name:
          - dnsmasq
          - iptables-persistent
          - ntp
          - openvpn
          - unzip

    - name: configure static ip
      copy:
        dest: /etc/network/interfaces
        mode: '0600'
        owner: root
        group: root
        content: |
          auto lo
          iface lo inet loopback

          auto eth0
          allow-hotplug eth0
          iface eth0 inet static
              address {{ static_ip }}
              netmask {{ netmask }}
              gateway {{ gateway }}
              dns-nameservers {{ dns_nameservers }}

    - name: create pia configs dir
      file:
        state: directory
        owner: root
        path: /etc/openvpn/pia

    - name: download PIA configs
      unarchive:
        remote_src: yes
        src: https://www.privateinternetaccess.com/openvpn/openvpn.zip
        dest: /etc/openvpn/pia
        mode: '0600'
        owner: root

    - name: copy PIA certs
      copy:
        src: "/etc/openvpn/pia/{{ item }}"
        dest: "/etc/openvpn/{{ item }}"
        remote_src: yes
        mode: '0600'
        owner: root
        group: root
      loop:
        - ca.rsa.2048.crt
        - crl.rsa.2048.pem

    - name: copy PIA conf
      copy:
        src: "/etc/openvpn/pia/{{ pia_server }}.ovpn"
        dest: "{{ conf_file }}"
        remote_src: yes
        mode: '0600'
        owner: root
        group: root

    - name: create PIA login credentials
      copy:
        dest: /etc/openvpn/pia_login
        mode: '0600'
        owner: root
        group: root
        content: |
          {{ piavpn_user }}
          {{ piavpn_pw }}


    - name: fullpath certs and login in conf
      become: yes
      replace:
        path: /etc/openvpn/{{ pia_conf_name }}.conf
        regexp: '{{ item.regexp }}'
        replace: '{{ item.replace }}'
      loop:
        - { regexp: '^auth-user-pass',              replace: 'auth-user-pass /etc/openvpn/pia_login' }
        - { regexp: '^ca ca.rsa.2048.crt',          replace: 'ca /etc/openvpn/ca.rsa.2048.crt' }
        - { regexp: '^crl-verify crl.rsa.2048.pem', replace: 'crl-verify /etc/openvpn/crl.rsa.2048.pem' }


    - name: enable ip forwarding
      sysctl:
        name: net.ipv4.ip_forward
        value: '1'
        reload: yes

    - name: disable ipv6
      when: disable_ipv6
      sysctl:
        name: '{{ item }}'
        value: '1'
        reload: yes
      loop:
      - net.ipv6.conf.all.disable_ipv6
      - net.ipv6.conf.default.disable_ipv6

    # this could/should probably be converted into native iptables ansible
    # modules but I am lazy right now and this just works
    - name: Setup NAT fron the local LAN down the VPN tunnel
      shell:
        cmd: |
          iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE && \
          iptables -A FORWARD -i tun0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT && \
          iptables -A FORWARD -i eth0 -o tun0 -j ACCEPT

    - name: Make the NAT rules persistent across reboot
      command: "netfilter-persistent save"

    - name: Make the rules apply at startup
      systemd:
        name: netfilter-persistent
        enabled: yes

    - name: enable VPN
      systemd:
        name: openvpn@{{ pia_conf_name }}
        state: started
        enabled: yes

    - name: enable dnsmasq
      systemd:
        name: dnsmasq
        state: started
        enabled: yes

    - name: Enable kill switch
      when: vpn_kill_switch
      block:
        # this could/should probably be converted into native iptables ansible
        # modules but I am lazy right now and this just works
        - shell:
            cmd: |
              iptables -A OUTPUT -o tun0 -m comment --comment "vpn" -j ACCEPT && \
              iptables -A OUTPUT -o eth0 -p icmp -m comment --comment "icmp" -j ACCEPT && \
              iptables -A OUTPUT -d {{ ip_range }} -o eth0 -m comment --comment "lan" -j ACCEPT && \
              iptables -A OUTPUT -o eth0 -p udp -m udp --dport 1198 -m comment --comment "openvpn" -j ACCEPT && \
              iptables -A OUTPUT -o eth0 -p tcp -m tcp --sport 22 -m comment --comment "ssh" -j ACCEPT && \
              iptables -A OUTPUT -o eth0 -p udp -m udp --dport 123 -m comment --comment "ntp" -j ACCEPT && \
              iptables -A OUTPUT -o eth0 -p udp -m udp --dport 53 -m comment --comment "dns" -j ACCEPT && \
              iptables -A OUTPUT -o eth0 -p tcp -m tcp --dport 53 -m comment --comment "dns" -j ACCEPT && \
              iptables -A OUTPUT -o eth0 -j DROP
        - name: persist iptables
          command: "netfilter-persistent save"

@resos1
Copy link

resos1 commented Mar 13, 2020

I'm trying to use openconnect instead of openvpn but i think i'm missing something, my clients can't get access to the internet
can some please help me to make this done?
ps i have created a topic here please take a look
thanks

@NicksMacLife
Copy link

I am going to try this tutorial tomorrow but can any tell me how i can make it work with 2 ethernet port on a Rpi. I am going to use a Rpi4 and a USB 3.0 gigabit ethernet adapter. I would like it to use 1 ethernet port for the pi's access to the internet and then the clients whos traffic is to be routed over the VPN to be connected to the 2nd Ethernet port.

@mondo2020
Copy link

Hi everyone! First of all also many thanks to superjamie! Very competent and effective.
I set up a raspi4 as vpn router and !IT WORKS!
But, like in some other posts above, I do not manage to get the "Kill Switch" working.
When I put in these IPTABLES commands, I cannot access the internet any longer. Not with the devices connected to the raspberry and neither directly with the system.
The log shows: Mon May 25 23:42:55 2020 write UDP: Operation not permitted (code=1)
Anyone an idea?
Thanks in advance

@jdfrey1
Copy link

jdfrey1 commented Jul 7, 2020

Thanks for this superjamie! I've been working on this issue for days and I've tried so many different configurations. I finally was able to use this tutorial to setup my IPTables to get the gateway to properly work. The problem I'm having now is that I would like to still be able to ping/remote desktop into the computer that is using the PI as it's gateway.

Here's my setup:
Raspberry Pi setup as VPN Gateway. Can ping this from both PC1 (Not on VPN) and PC2 (using the Pi as Gateway)
PC2 can ping PC1, but PC1 can't ping PC2
All on the same subnet

I really need PCs not connected to the VPN to be able to connect to a PC using the Gateway as the router?
Is there a rule that I'm missing to not allow this on the LAN?

@sberrevoets
Copy link

Is there some ipv4/ipv6 difference that needs to be accounted for? When I go to ipinfo.io/json it gives me the IP (v4) of the VPN server, but whatismyip.com can still see my ISP and location and shows an IPV6 address. If I connect to the VPN directly (by-passing the RPi), whatismyip.com now also shows the VPN IP. Any tips?

@rallegade
Copy link

Speaking from experience here.

A good idea is to disable ipv6 using:
sudo nano /etc/sysctl.d/70-disable-ipv6.conf
net.ipv6.conf.all.disable_ipv6 = 1
sudo sysctl -p -f /etc/sysctl.d/70-disable-ipv6.conf

Then after disabling ipv6 I would get problems with openvpn service once in a while not being able to pick either ipv4 or ipv6.
This is fixed by going into the config file used, for example Sweden.conf, find the part that says proto udp and change this to proto udp4

@sberrevoets
Copy link

Thanks, that did the trick for me!

@sberrevoets
Copy link

Well, once ¯\_(ツ)_/¯ Tried with the same setting just now and it seems like it just ignores it altogether or something, as websites/services still see the ipv6 address.

@PantelisIoannou
Copy link

Hello, I am trying to setup my Rasberry Pi Vpn Router but i am getting:

t Nov 7 08:57:00 2020 UDP link remote: [AF_INET]103.208.220.132:1198
Sat Nov 7 08:58:00 2020 TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
Sat Nov 7 08:58:00 2020 TLS Error: TLS handshake failed
Sat Nov 7 08:58:00 2020 SIGUSR1[soft,tls-error] received, process restarting
Sat Nov 7 08:58:05 2020 TCP/UDP: Preserving recently used remote address: [AF_INET]103.208.220.139:1198
Sat Nov 7 08:58:05 2020 UDP link local: (not bound)
Sat Nov 7 08:58:05 2020 UDP link remote: [AF_INET]103.208.220.139:1198
Sat Nov 7 08:59:05 2020 TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
Sat Nov 7 08:59:05 2020 TLS Error: TLS handshake failed
Sat Nov 7 08:59:05 2020 SIGUSR1[soft,tls-error] received, process restarting
Sat Nov 7 08:59:05 2020 SIGUSR1[soft,tls-error] received, process restarting
Sat Nov 7 08:59:10 2020 TCP/UDP: Preserving recently used remote address: [AF_INET]103.208.220.131:1198
Sat Nov 7 08:59:10 2020 UDP link local: (not bound)

@PantelisIoannou
Copy link

ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=116 time=26.5 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=116 time=29.8 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=116 time=26.4 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=116 time=26.5 ms
^C
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 8ms
rtt min/avg/max/mdev = 26.442/27.311/29.799/1.436 ms

@syrusfem
Copy link

syrusfem commented Nov 22, 2020

Hello, this is a great tutorial.
I followed the istructions including the dsnmasq setup and it works great but i can't block call to hard coded DNS from clients.
If from a client i call this command : nslookup example.com 208.67.222.222 i have a response from the remote DNS server.
I tried to use : sudo iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 53 -j DNAT --to 127.0.0.1 but it does not reroute hard coded DNS calls from clients to the raspberry dnsmasq.
Any idea of how i could block or better reroute to local dnsmasq these calls?
Thanks!

@AaronDavidSchneider
Copy link

Thank you for this awesome guide! Is it possible to still run an openvpn server simultaneously on the same device?
E.g: Use this method to connect all network devices to the VPN on a VCS and have a vpn server (using pivpn) to be able to connect from outside to the home network.

@yalopov
Copy link

yalopov commented Dec 3, 2020

I tried this with both ExpressVPN and Surfshark using Arch Linux with no success.

I was able to connect other devices through this "router" host by setting them router host's IP as gateway IP and DNS servers manually, it worked but I was getting DNS leaks.

After doing some research I found this info (https://wiki.archlinux.org/index.php/OpenVPN#DNS), it says it's necessary to use a script to let OpenVPN to update DNS name servers after establish or finalize a connection, I tried openvpn-update-resolv-conf-git, it updated my /etc/resolv.conf file and fixed the DNS leaks in the router host but other hosts connecting through would still have that issue.

It seems that script works locally, but it's needed to set up a DNS server to let other devices know the current VPN's DNS nameservers (as DNS servers could change as VPN connects to different servers), so I tried to set up a BIND DNS server on the router host and configured it to retrieve /etc/resolv.conf name servers using openresolv.
That way the openvpn-update-resolv-conf script would try to update DNS nameservers using openresolv's resolvconf and that would update the BIND server config to resolve DNS queries to other devices.

It tried to work but other devices DNS queries would hang out after a few seconds, I tried to debug BIND but didn't have any luck.

It didn't work but It was fun at least.

@syrusfem
Copy link

syrusfem commented Dec 6, 2020

A thing i noticed in my setup is that sometimes under heavy traffic for long time (say a week) sometimes clients lost internet connection .
I have setup a reboot once a week: with this line in crontab: 0 5 * * 1 sudo shutdown -r now for a refresh of the system .
UPDATE
As an alternative and upgrate to the weekly reboot now i use the following script :

#!/bin/bash

ping -c2 google.com  > /dev/null

if [ $? -ne 0 ]
    then
        echo "No network connection , restarting"
        reboot
       
    else
        echo "ok"
fi

saved as file executable (using chmod +x) and started every 5 minutes with crontab.
The script check if the system could reach google.com, if not start a reboot of the system.
The script i use is discussed in these pages:
https://www.raspberrypi.org/forums/viewtopic.php?t=265337
https://superuser.com/questions/378549/can-i-automatically-reboot-if-disconnected-from-the-internet

For DNS leakage i have problems only for hard coded DNS of clients (clients that connect using a DNS IP ignoring the fixed VPN DNS i set up on them) other than that i have no other leaks.

@squeeeb
Copy link

squeeeb commented Dec 20, 2020

Beautiful - thanks!

@JeisonSanches
Copy link

Thank you for this awesome guide! Is it possible to still run an openvpn server simultaneously on the same device?
E.g: Use this method to connect all network devices to the VPN on a VCS and have a vpn server (using pivpn) to be able to connect from outside to the home network.

Any news? I'm trying the exact same thing.

@kinduff
Copy link

kinduff commented Dec 14, 2021

@JeisonSanches Should be possible, since the server will route clients through the device, they should connect through the VPN.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment