Networking - Wifi to Ethernet Bridge

Networking - Wifi to Ethernet Bridge

August 23, 2024

Raspberry Pi: Wifi Bridge

Inspired by the awsome work of William Halley in his blog, where I was able to follow succesfully and to share Wifi through Ethernet on a separated subnet with a Raspberry Pi 4 2GB

Let’s learn a little bit about Networking by doing!

CV with a RPI4

Option 1 - Wifi to Ethernet with Separated subnet 📌

The script that is provided is this one (again, credits to William):

#!/usr/bin/env bash

set -e

[ $EUID -ne 0 ] && echo "run as root" >&2 && exit 1

apt update && \
  DEBIAN_FRONTEND=noninteractive apt install -y \
    dnsmasq netfilter-persistent iptables-persistent

# Create and persist iptables rule.
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
netfilter-persistent save

# Enable ipv4 forwarding.
sed -i'' s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/ /etc/sysctl.conf

# The Ethernet adapter will use a static IP of 10.1.1.1 on this new subnet.
cat <<'EOF' >/etc/network/interfaces.d/eth0
auto eth0
allow-hotplug eth0
iface eth0 inet static
  address 10.1.1.1
  netmask 255.255.255.0
  gateway 10.1.1.1
EOF

# Create a dnsmasq DHCP config at /etc/dnsmasq.d/bridge.conf. The Raspberry Pi
# will act as a DHCP server to the client connected over ethernet.
cat <<'EOF' >/etc/dnsmasq.d/bridge.conf
interface=eth0
bind-interfaces
server=8.8.8.8
domain-needed
bogus-priv
dhcp-range=10.1.1.2,10.1.1.254,12h
EOF

systemctl mask networking.service
ℹ️
Remember, the names of wlan0 and eth0 used, can be different in other devices, check it with:
ifconfig

The end result is that the Raspberry Pi will act as a bridge between the WiFi connection and the Ethernet connection, providing Internet access to devices connected via Ethernet- to the RPi.

Raspberry Pi Bridge: Wifi to Ethernet (With wireguard)

That was really great and I was really impressed and happy that it worked perfectly the first time I tried.

Then, I wondered…if the Raspberry Pi would be having a VPN connection, could we provide to the ethernet connected device that same connection?

I decided to try with Wireguard (you will need a working VPN server that generates Wireguard config) and surprisingly it worked with some modification:

Pre-Requisite - We need to have wireguard installed: 📌
sudo apt install wireguard
cp /home/Downloads/your_vpn_wireguard_configuration.conf /etc/wireguard #download the wireguard config: account-wireguard configuration
sudo wg-quick your_vpn_wireguard_configuration #the name of the .conf file that you have downloaded

This will make your wireguard client to be connected to the server.

Do you want to check your public IP?

curl -sS https://ipinfo.io/json #the command to use

And if you need, to disconnect from Wireguard, just:

wg-quick down <name>
sudo wg-quick down your_vpn_wireguard_configuration
#sudo nano /etc/resolv.conf #to check/adapt DNS name (optional)
#sudo reboot (optional)

Check network interface for wireguard VPN

ifconfig

Create new bridge_wireguard.sh script

It routes the WIFI to ethernet and provide VPN connection at the same time:

sudo nano bridge_wireguard.sh
Wifi to Ethernet Bridge (Wireguard) Script 📌
#!/usr/bin/env bash

set -e

[ $EUID -ne 0 ] && echo "run as root" >&2 && exit 1

apt update && \
  DEBIAN_FRONTEND=noninteractive apt install -y \
    dnsmasq netfilter-persistent iptables-persistent

# Create and persist iptables rule.
# Here's the change: we're using the WireGuard interface (your_vpn_wireguard_netw_interface) instead of the WiFi interface (wlan0).
iptables -t nat -A POSTROUTING -o your_vpn_wireguard_netw_interface -j MASQUERADE
netfilter-persistent save

# Enable ipv4 forwarding.
sed -i'' s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/ /etc/sysctl.conf

# The Ethernet adapter will use a static IP of 10.1.1.1 on this new subnet.
cat <<'EOF' >/etc/network/interfaces.d/eth0
auto eth0
allow-hotplug eth0
iface eth0 inet static
  address 10.1.1.1
  netmask 255.255.255.0
  gateway 10.1.1.1
EOF

# Create a dnsmasq DHCP config at /etc/dnsmasq.d/bridge.conf. The Raspberry Pi
# will act as a DHCP server to the client connected over ethernet.
cat <<'EOF' >/etc/dnsmasq.d/bridge.conf
interface=eth0
bind-interfaces
server=8.8.8.8
domain-needed
bogus-priv
dhcp-range=10.1.1.2,10.1.1.254,12h
EOF

systemctl mask networking.service
sudo bash bridge_wireguard.sh
sudo reboot
ℹ️
with this version, you can route the traffic through any Wireguard Traffic (from your custom VPS or a provider like Mullvad, ProtonVPN,…)

FAQ

  • Portable Router (Alternative to RPi) - GL.iNet GL-SFT1200 or the GL.iNet GL-MT300N-V2 (which should be powered via the usb port of a laptop).
Which WIFI is the raspberry pi connected to?
nano /etc/wpa_supplicant/wpa_supplicant.conf
What’s the ping and internet speed?
apt-get install -y iputils-ping
sudo apt-get install speedtest-cli
speedtest-cli
Is the VPN Working?

In addition to ipinfo.io, you can use:

curl https://ipapi.co/json/
#curl -sS https://ipinfo.io/json
curl -sS http://ip-api.com/json/ #provides info about country, ISP, ...
curl -sS https://am.i.mullvad.net/json #https://whatismyipaddress.com/
curl -6 ifconfig.me #ipv6 info 
#https://porkbun.com/tools/whats_my_ip_address
What about DNS?
nmcli device show | grep DNS #check which DNS the device is using
#ip a #get netwk interface to check, something like eth0, wlan...
#nmcli device show <your_netwk_interface> | grep IP4.DNS
##sudo nmcli connection modify <your_connection_name> ipv4.dns "192.168.3.200 9.9.9.9"

Is port 67 free?

netstat -tuln | grep :67
#sudo systemctl stop a_conflicting_service #for now
##sudo systemctl stop a_conflicting_service #prevent it to run on boot
How to Block ads with the Raspberry Pi
  1. You can use PiHole with a RPi
  2. You can also use RaspAP ad-blocking capabilities

VPS for the Experiment

Provider NameComments
Skillhost.pl Hosting VPS PolskaPolish-based VPS provider with a focus on local services and support.
HetznerWell-known European hosting provider with a wide range of server options. / ISP will appear as Hetzner.
GCP

How to Setup WG-Easy

Step 1

Get your VPS public IP

ip -4 -brief a #you will need to use it

Step 2

Install Docker and use the stack below.

How to Setup Wireguard with WG-Easy and Docker 📌
version: '3'
services:
  wg-easy:
    container_name: wg-easy
    #env_file: .env
    environment:
      - WG_HOST= your-vps-ip-address #${WG_HOST}
      - WG_PORT=51820
      - PASSWORD= someamazingpassword #${WG_PASSWORD} # It's recommended to keep sensitive data in an .env file
      #- WG_PEER_DEFAULT_DNS=9.9.9.9
      - LANG=en
    volumes:
      - ./wg-easy:/etc/wireguard
      #- wg_data:/etc/wireguard
    ports:
      - 51820:51820/udp # VPN traffic
      - 51821:51821/tcp # Web interface
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
      - net.ipv4.ip_forward=1
    restart: unless-stopped
    image: ghcr.io/wg-easy/wg-easy
#     networks:
#       - nginx_default #https for wg-easy UI  
  
# networks:
#   nginx_default:
#     external: true    

# volumes:
#   wg_data:
#     name: wg_data    
ℹ️
You can also try with PiVPN
How to Setup TailScale with Docker 📌
version: '3' #https://tailscale.com/blog/getting-started-with-docker-and-tailscale
services: #https://www.youtube.com/watch?v=YTjYXii4WzI
  tailscale-authkey1: #https://github.com/tailscale-dev/docker-guide-code-examples/blob/main/06-quickstart-vid/01-nginx-basic/docker-compose.yaml
    container_name: ts-authkey-test
    restart: unless-stopped
    image: tailscale/tailscale:latest #https://tailscale.com/kb/1282/docker
    hostname: coolurl
    environment:
      - TS_AUTHKEY=tskey-auth-get-the-string #use tailscale admin console for this
      - TS_STATE_DIR=/var/lib/tailscale
      - TS_USERSPACE=false
    volumes:
      - ts-authkey-test:/var/lib/tailscale
      - /dev/net/tun:/dev/net/tun
    cap_add:
      - net_admin
      - sys_module
    restart: unless-stopped
  nginx-authkey-test:
    image: nginx
    network_mode: service:tailscale-authkey1 #the name of the service above
  # metube-authkey-test:
  #   #image: nginx
  #   network_mode: service:tailscale-authkey1 #the name of the service above
  #   image: ghcr.io/alexta69/metube
  #   container_name: metube
  #   restart: unless-stopped
  #   # ports:
  #   #   - "8081:8081"
  #   volumes:
  #     - "/home/user/Downloads:/downloads"    
volumes:
  ts-authkey-test:
    driver: local

Deploying containers directly onto your tailnet transforms each one into a fully operational node, equivalent to any other node in the network.

Tailscale eliminates the need for intricate firewall configurations or port forwarding.

Tailscale efficiently handles even the most complex NAT setups, ensuring smooth connectivity.

  • Settings -> OAuth Clients -> Generate OAuth Client
version: '3' #https://tailscale.com/blog/getting-started-with-docker-and-tailscale
services: #https://www.youtube.com/watch?v=YTjYXii4WzI
  tailscale-authkey1: #https://github.com/tailscale-dev/docker-guide-code-examples/blob/main/06-quickstart-vid/02-stirlingpdf/docker-compose.yaml
    container_name: ts-authkey-test
    restart: unless-stopped
    image: tailscale/tailscale:latest #https://tailscale.com/kb/1282/docker
    hostname: pdf
    environment:
      - TS_AUTHKEY=tskey-auth-get-the-string #use tailscale admin console for this
      - TS_STATE_DIR=/var/lib/tailscale
      - TS_USERSPACE=false
    volumes:
      - ts-authkey-test:/var/lib/tailscale
      - /dev/net/tun:/dev/net/tun
    cap_add:
      - net_admin
      - sys_module
    restart: unless-stopped

  metube-authkey-test:
    network_mode: service:tailscale-authkey1 #the name of the service above
    image: ghcr.io/alexta69/metube
    container_name: metube
    restart: unless-stopped
    # ports:
    #   - "8081:8081"
    volumes:
      - "/home/user/Downloads:/downloads"    
volumes:
  ts-authkey-test:
    driver: local

How to Setup RaspAP

curl -sL https://install.raspap.com | bash #https://docs.raspap.com/

Go to http://raspberrypi.local and access it with admin/secret. You will see a network called raspi-webgui, pass ChangeMe

RaspAP with NordVPN 📌
RaspAP with ProtonVPN 📌
[Interface]
# Bouncing = 2
# NAT-PMP (Port Forwarding) = off
# VPN Accelerator = on
PrivateKey = +some/pri/key=
Address = address/32
DNS = 10.2.0.1

[Peer]
# NL-FREE#103073
PublicKey = +some/string=
AllowedIPs = 0.0.0.0/0
Endpoint = ipaddress:51820
RaspAP with Mullvad 📌

Software for Routers

VyOS

OpenWRT

TailScale and More