jiml8
Posts: 25
Joined: Wed Aug 05, 2020 6:27 pm

pi as a vpn proxy on a vlan

Wed Aug 05, 2020 6:46 pm

I have decided to deploy a smart TV. Because I won't tolerate the spying, I have configured my network to give it its very own VLAN, where it can sit and not see anything else on the network.

I have also set up a pi-hole DNS server which is providing network-wide DNS with ad and tracker blocking.

Now, I am setting up a dedicated pi vpn proxy on that VLAN, so that traffic from the TV will all be forced out through a VPN.

For this configuration, the eth0 address on the raspberry pi is not set, but an IP address is set on vlan0. I am using Proton VPN (a service that I highly recommend, btw). IP forwarding is enabled, and some appropriate iptables rules are in place, and the device is doing exactly what I want; traffic arriving on the vlan is passing into the VPN without trouble.

The problem I am having is that, with this configuration, traffic that originates on the pi itself is not being routed anywhere. This, of course, means trouble when getting updates and so forth; I would prefer to not have to stop the vlan in order to do updates.

Here is my current iptables setup.

Code: Select all

#!/usr/bin/env bash

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

# Clear all rules
iptables -F
iptables -t nat -F

# Default drop incoming
iptables -P INPUT DROP

# Don't forward traffic
/sbin/iptables -P FORWARD DROP 

# Allow outgoing traffic
iptables -P OUTPUT ACCEPT

# Allow localhost traffic
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -i eth0 -j ACCEPT
iptables -A OUTPUT -o eth0 -j ACCEPT

# block any traffic that does not belong to our vlan
iptables -A INPUT  -i vlan0  -j ACCEPT
iptables -A INPUT -j DROP

# enable traffic from the vlan to the vpn tunnel
iptables -t nat -A POSTROUTING  -o proton0 -j MASQUERADE
iptables -A FORWARD -i vlan0 -o proton0 -j ACCEPT
iptables -A FORWARD -i proton0  -m state --state ESTABLISHED,RELATED -j ACCEPT
Here is the ifconfig:

Code: Select all

root@raspberrypi:/usr/local/bin# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::dea6:32ff:feb6:9f59  prefixlen 64  scopeid 0x20<link>
        ether dc:a6:32:b6:9f:59  txqueuelen 1000  (Ethernet)
        RX packets 4014  bytes 1197168 (1.1 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2057  bytes 304843 (297.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

proton0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 10.50.0.13  netmask 255.255.0.0  destination 10.50.0.13
        inet6 fe80::a6ca:78e7:33a9:26e6  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 100  (UNSPEC)
        RX packets 318  bytes 65021 (63.4 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 471  bytes 61248 (59.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

vlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.24.49  netmask 255.255.255.0  broadcast 192.168.24.255
        inet6 fe80::dea6:32ff:feb6:9f59  prefixlen 64  scopeid 0x20<link>
        ether dc:a6:32:b6:9f:59  txqueuelen 1000  (Ethernet)
        RX packets 2594  bytes 298335 (291.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2034  bytes 294095 (287.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
And here is the routing table:

Code: Select all

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.50.0.1       128.0.0.0       UG    0      0        0 proton0
default         simplewan-vlan1 0.0.0.0         UG    0      0        0 vlan0
10.50.0.0       0.0.0.0         255.255.0.0     U     0      0        0 proton0
128.0.0.0       10.50.0.1       128.0.0.0       UG    0      0        0 proton0
192.168.24.0    0.0.0.0         255.255.255.0   U     0      0        0 vlan0
199.187.209.30  simplewan-vlan1 255.255.255.255 UGH   0      0        0 vlan0
Here is the result when I do an apt update:

Code: Select all

root@raspberrypi:/usr/local/bin# apt update
Err:1 http://raspbian.raspberrypi.org/raspbian buster InRelease                                                                        
  Cannot initiate the connection to raspbian.raspberrypi.org:80 (2a00:1098:0:80:1000:75:0:3). - connect (101: Network is unreachable) Could not connect to raspbian.raspberrypi.org:80 (93.93.128.193), connection timed out
Err:2 http://archive.raspberrypi.org/debian buster InRelease                                                                           
  Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:80:56::1:1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:80:56::2:1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:80:56::3:1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:82:47::1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:82:47::1:1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:82:47::2:1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:84:1e0::1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:84:1e0::2). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:84:1e0::3). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:88:26::1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:88:26::1:1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:88:26::2:1). - connect (101: Network is unreachable) Could not connect to archive.raspberrypi.org:80 (46.235.227.39), connection timed out Could not connect to archive.raspberrypi.org:80 (46.235.230.122), connection timed out Could not connect to archive.raspberrypi.org:80 (46.235.231.111), connection timed out Could not connect to archive.raspberrypi.org:80 (46.235.231.145), connection timed out Could not connect to archive.raspberrypi.org:80 (176.126.240.167), connection timed out Could not connect to archive.raspberrypi.org:80 (93.93.130.212), connection timed out Could not connect to archive.raspberrypi.org:80 (93.93.135.117), connection timed out Could not connect to archive.raspberrypi.org:80 (93.93.135.118), connection timed out Could not connect to archive.raspberrypi.org:80 (93.93.135.141), connection timed out Could not connect to archive.raspberrypi.org:80 (176.126.240.84), connection timed out Could not connect to archive.raspberrypi.org:80 (176.126.240.86), connection timed out Could not connect to archive.raspberrypi.org:80 (46.235.231.151), connection timed out
Reading package lists... Done                                    
Building dependency tree       
Reading state information... Done
All packages are up to date.
W: Failed to fetch http://raspbian.raspberrypi.org/raspbian/dists/buster/InRelease  Cannot initiate the connection to raspbian.raspberrypi.org:80 (2a00:1098:0:80:1000:75:0:3). - connect (101: Network is unreachable) Could not connect to raspbian.raspberrypi.org:80 (93.93.128.193), connection timed out
W: Failed to fetch http://archive.raspberrypi.org/debian/dists/buster/InRelease  Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:80:56::1:1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:80:56::2:1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:80:56::3:1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:82:47::1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:82:47::1:1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:82:47::2:1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:84:1e0::1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:84:1e0::2). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:84:1e0::3). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:88:26::1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:88:26::1:1). - connect (101: Network is unreachable) Cannot initiate the connection to archive.raspberrypi.org:80 (2a00:1098:88:26::2:1). - connect (101: Network is unreachable) Could not connect to archive.raspberrypi.org:80 (46.235.227.39), connection timed out Could not connect to archive.raspberrypi.org:80 (46.235.230.122), connection timed out Could not connect to archive.raspberrypi.org:80 (46.235.231.111), connection timed out Could not connect to archive.raspberrypi.org:80 (46.235.231.145), connection timed out Could not connect to archive.raspberrypi.org:80 (176.126.240.167), connection timed out Could not connect to archive.raspberrypi.org:80 (93.93.130.212), connection timed out Could not connect to archive.raspberrypi.org:80 (93.93.135.117), connection timed out Could not connect to archive.raspberrypi.org:80 (93.93.135.118), connection timed out Could not connect to archive.raspberrypi.org:80 (93.93.135.141), connection timed out Could not connect to archive.raspberrypi.org:80 (176.126.240.84), connection timed out Could not connect to archive.raspberrypi.org:80 (176.126.240.86), connection timed out Could not connect to archive.raspberrypi.org:80 (46.235.231.151), connection timed out
W: Some index files failed to download. They have been ignored, or old ones used instead.
Can anyone here tell me what is required to get traffic originating locally to pass through the VPN in this circumstance?

epoch1970
Posts: 5203
Joined: Thu May 05, 2016 9:33 am
Location: Paris, France

Re: pi as a vpn proxy on a vlan

Wed Aug 05, 2020 10:21 pm

I’m not sure what’s going on but I would use these to find out:
- ip route get <IP address> -> tells you how which route is chosen
- iptables -v -> shows counters, so you can identify which rule blocks in case routing is ok. (also mind the policies in case traffic doesn’t go through but no counter increases.)
"S'il n'y a pas de solution, c'est qu'il n'y a pas de problème." Les Shadoks, J. Rouxel

jiml8
Posts: 25
Joined: Wed Aug 05, 2020 6:27 pm

Re: pi as a vpn proxy on a vlan

Wed Aug 05, 2020 11:01 pm

ip route get is an interesting command. It said:

Code: Select all

ip route get 93.93.128.193
93.93.128.193 via 10.50.0.1 dev proton0 src 10.50.0.13 uid 0 
    cache 
...which is, of course, the route I want to have taken.

Here's an iptables -vnL. Doesn't show much other than traffic originating on the device does not show in the localhost rules. Which is why I put the eth0 rules in...just because. It is interesting that there is eth0 traffic. I wonder if the local traffic is being assigned to eth0 for routing purposes, though that seems odd.

Code: Select all

root@raspberrypi:/usr/local/bin# iptables -vnL
Chain INPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
 3809 3410K ACCEPT     all  --  eth0   *       0.0.0.0/0            0.0.0.0/0           
 4210  885K ACCEPT     all  --  vlan0  *       0.0.0.0/0            0.0.0.0/0           
  348 24276 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
 1651  371K ACCEPT     all  --  vlan0  proton0  0.0.0.0/0            0.0.0.0/0           
 1242  535K ACCEPT     all  --  proton0 *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  *      lo      0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  *      eth0    0.0.0.0/0            0.0.0.0/0 
The TV, by the way, is not yet here. It is scheduled to be delivered tomorrow. So the untrusted device I am testing with is a chinese-made android phone I picked up in Colombia a few months ago. It certainly deserves to be labeled "untrusted"; it wants to connect to all sorts of places. So the overall traffic rate on this vlan presently is not high.

jiml8
Posts: 25
Joined: Wed Aug 05, 2020 6:27 pm

Re: pi as a vpn proxy on a vlan

Thu Aug 06, 2020 5:09 am

I just opened a second ssh session to this vpn proxy, and started tcpdump on the proton0 interface.

I then pinged to yahoo.com.

The pings went out, the proper response came back. So the response is arriving at the proton0 interface, with the destination address specified as that interface. But that traffic is not reaching the console.

Must be something to do with the lo interface. Not sure what; the iptables rules look right. But I'm closer now....

jiml8
Posts: 25
Joined: Wed Aug 05, 2020 6:27 pm

Re: pi as a vpn proxy on a vlan

Thu Aug 06, 2020 5:20 am

And it is solved. I needed to add a rule: iptables -A INPUT -i proton0 -m state --state ESTABLISHED,RELATED -j ACCEPT

So the final iptables ruleset to make the pi a vpn proxy on a vlan is this:

Code: Select all

#!/usr/bin/env bash

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

# Clear all rules
iptables -F
iptables -t nat -F

# Default drop incoming
iptables -P INPUT DROP

# Don't forward traffic
iptables -P FORWARD DROP 

# Allow outgoing traffic
iptables -P OUTPUT ACCEPT

# Allow localhost traffic
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# block any traffic that does not belong to our vlan
iptables -A INPUT -i vlan0  -j ACCEPT
iptables -A INPUT -i proton0  -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -j DROP

# enable traffic from the vlan to the vpn tunnel
iptables -t nat -A POSTROUTING  -o proton0 -j MASQUERADE
iptables -A FORWARD -i vlan0 -o proton0 -j ACCEPT
iptables -A FORWARD -i proton0  -m state --state ESTABLISHED,RELATED -j ACCEPT
Other than this missing rule, I found this job to be very straightforward, presenting no difficulties.

I actually like this proxy well enough that I am going to deploy another one (separate raspberry pi) on my LAN for use by my trusted devices. Presently, I have individual instances of VPNs running on various systems, but this will be more efficient and easier to maintain while also providing me visibility into the DNS traffic.

Is there any interest in having me write a howto about setting this up? It includes a few scripts and the creation of a couple of systemd services, as well as some basic hardening of the pi for this purpose.

Return to “Networking and servers”