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
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:
- Open NetworkManager setting and click to
Edit Connections
- Click on
Wired
tab. - Select or create a new wired connection you want to share. Let's call it
ShareEth
, you can use another name. - Click on new connection & you will be redirected to its properties, next pick
IPv4
. - Click on
Method
then selectShared to other computers
. - Enable
Available for all users
if this connection should be useful for another users on this device. - Click
Save
, back to connection list and enableShareEth
.
On client device which receive your connection:
- Create a NetworkManager wired connection using
Wired
tab - In method option select
Automatic
and click toSave
. - 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
, Cloudflare1.1.1.1
should work too) or useManual
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.
- Open NetworkManager setting and click to
Edit Connections
- Click on
Wireless
tab. - Select or create a new wired connection you want to share. Let's call it
ShareWifiVPN
this time, all up to you. - Click on new connection & you will be redirected to its properties, select
WPA2
orWPA3
and the password with 8 characters or more. - Click on
Wi-fi mode
then selectHotspot
orAd-hoc
for non-Android devices. - Enable
Available for all users
if this connection should be useful for another users on this device. - Click
Save
, back to connection list and enableShareWifi
.
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 physicalwlp3s0
interface to WireGuard interfacewg0
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.