How to share VPN connection using Ethernet and Wi-Fi on Linux

This setup can be helpful _if_: - part of your or your friend network equipment is broken or badly configured - for developer purposes like debug or microservices development - your VPN plan supports only one connection to server - share wired connection to your smartphone over Wi-Fi

How to share VPN connection using Ethernet and Wi-Fi on Linux
Photo by Nick Fewings / Unsplash

This setup can be helpful if:

  • part of your or your friend network equipment is broken or badly configured
  • for developer purposes like debug or microservices development
  • your VPN plan supports only one connection to server
  • share wired connection to your smartphone over Wi-Fi

The most popular case why you're here is probably money saving: you don't need to pay more to buy a costly plan from your current VPN provider.

Wirequard was picked by us as a faster and lower-latency solution, but should say OpenVPN setup is quite similar. We recommend NetworkManager 'cause popular network setup tool on both sides: desktop and server.

First step - connect to VPN

Yeah, if you need to share your VPN connection - your device should be connected first. Of course 99% of our readers know it, but we're trying to highlight all hot corners. Also check your firewall for blocking of forwarding connections - you probably need to use this command: echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf && sysctl -p.

Ethernet connection

On server device which share your connection:

  1. Open NetworkManager setting and click to Edit Connections
  2. Click on Wired tab.
  3. Select or create a new wired connection you want to share. Let's call it ShareEth, you can use another name.
  4. Click on new connection & you will be redirected to its properties, next pick IPv4.
  5. Click on Method then select Shared to other computers.
  6. Enable Available for all users if this connection should be useful for another users on this device.
  7. Click Save, back to connection list and enable ShareEth.

On client device which receive your connection:

  1. Create a NetworkManager wired connection using Wired tab
  2. In method option select Automatic and click to Save.
  3. If it doesn't work you should install dnsmasq on server or add the optional DNS server IP in the same menu (for example, 192.168.0.1 or 192.168.1.1, Cloudflare 1.1.1.1 should work too) or use Manual and choose an IP range from the same subnet (for example, 192.168.0.2 or 192.168.1.2).

Wireless connection

Let's share our wired connection over Wi-Fi using a laptop with Linux and same time get more privacy with VPN. For wireless connection the setup is quite similar 'cause NetworkManager will do the most of hard work for us.

  1. Open NetworkManager setting and click to Edit Connections
  2. Click on Wireless tab.
  3. Select or create a new wired connection you want to share. Let's call it ShareWifiVPN this time, all up to you.
  4. Click on new connection & you will be redirected to its properties, select WPA2 or WPA3 and the password with 8 characters or more.
  5. Click on Wi-fi mode then select Hotspot or Ad-hoc for non-Android devices.
  6. Enable Available for all users if this connection should be useful for another users on this device.
  7. Click Save, back to connection list and enable ShareWifi.

Then your client device should see your new access point. If problems with DNS happened - check the end of Ethernet connection guide.

IPv6

If you have a working IPv6 connectivity, make sense to share it to your downstream devices too. NetworkManager supports it since long time ago. IPv6 address can be assigned in two ways: classic DHCP request or RA (Router Advertisement). Let's use heavy lifting from NetworkManager:

nmcli connection modify ShareWifi ipv6.method shared

Be sure your VPN provider supports IPv6, instead you will get error in logs like policy: ipv6-pd: none of 0 prefixes of wlp1s0 can be shared on enp1s0.

Routing

VPN ←→ server ←→ client

Let's say our server has local IP 10.0.0.1 and client - 10.0.0.2.
On the client, we need to route all traffic from the destination network to server, let it be 192.168.0.0/24.

  • Add route on client:
ip r a 192.168.0.0/24 via 10.0.0.1 dev eth0
  • Now routing works and all client packages will go to server network 192.168.0.0/24. We need also to allow forwarding from physical wlp3s0 interface to WireGuard interface wg0 on server.
sysctl -w net.ipv4.conf.all.forwarding=1
iptables -I FORWARD -i wlp3s0 -d 192.168.0.0/24 -j ACCEPT
iptables -I FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
the RELATED,ESTABLISHED
  • Finally, all packages will be sent into the WireGuard tunnel. But hey, Houston, we got a problem: remote network does not know our local topology. We need to set up NAT for all packages forwarded from local network to VPN address of wg0 interface.

Let's do it with the MASQUERADE rule on server:

iptables -t nat -I POSTROUTING -o wg0 -j MASQUERADE

Voilà! All should work fine now.

Read more