Skip to content

Instantly share code, notes, and snippets.

@steelbrain
Forked from glenselle/bridge-diff-subnet.sh
Created June 11, 2023 02:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steelbrain/7d84394e53c2ad6849a6078002609fd2 to your computer and use it in GitHub Desktop.
Save steelbrain/7d84394e53c2ad6849a6078002609fd2 to your computer and use it in GitHub Desktop.
Raspberry PI4 Wifi to Eth Bridge

How to use

First, install dnsmasq because it the backbone of most of the recipes.

sudo apt-get update && sudo apt-get install dnsmasq

Download a recipe to pi user's home directory. For example:

curl -O https://gist.githubusercontent.com/glenselle/880cedfe25490a6d3f9bf51756e4e4bd/raw/a4932ecb48a0108446553325be4f9adce0d27292/wifi-to-eth-bridge.sh

Make the file executable:

sudo chmod 755 wifi-to-eth-route.sh

If using LXDE desktop, edit /etc/xdg/lxsession/LXDE-pi/autostart:

nano /etc/xdg/lxsession/LXDE-pi/autostart

And add the last line to start the script automatically after reboot:

@lxpanel --profile LXDE-pi
@pcmanfm --desktop --profile LXDE-pi
@xscreensaver -no-splash
@point-rpi
sudo bash /home/pi/wifi-to-eth-route.sh

Without desktop (lite version), edit /etc/rc.local with root privilege:

sudo nano /etc/rc.local

And add the following before exit 0 to start script automatically after reboot:

bash /home/pi/wifi-to-eth-route.sh

Be sure to give full path to the file.
That's it! Reboot to see the changes.

sudo reboot

There are few things which can't be automated and has to be done manually. Below are some tips to help you get stuff done.

Tips

Enable SSH

When you have written the Image file on to the SD Card. Mount the boot partition and create a file named ssh. Eject the card. Start the Raspberry Pi. You will be able to have SSH connection to it. After boot the /boot/ssh file gets deleted automatically. So, type this to start ssh service on every boot.

sudo systemctl enable ssh

WiFi Connection

Connect to RPi through SSH by providing it Ethernet. If you don't any Lan cable lying around than plug the SD card into PC. Mount the second partition of the SD Card.

WiFi connections are stored at /etc/wpa_supplicant/wpa_supplicant.conf. Edit this file with root privilege:

sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

It should look like this after filling network details:

country=GB
ctrl_interface=/var/run/wpa_supplicant
update_config=1
network={
    ssid="Home WiFi"
    psk="password_goes_here"
}

Configuration for eap should look like this:

network={
        ssid="SSID_NAME"
        key_mgmt=WPA-EAP
        password="PASSWORD"
        eap=PEAP
        identity="USERNAME"
}

Suggestions and PRs are welcome to make these recipes more useful.

#!/usr/bin/env bash
set -e
[ $EUID -ne 0 ] && echo "run as root" >&2 && exit 1
apt-get update && apt install -y dnsmasq
# Create a directory where we will store our `iptables` forwarding rules.
mkdir -p /etc/iptables
# Create `iptables` rules by running this command to generate a `rules.v4` file
# [0:0] refers to counters, not port numbers - https://serverfault.com/questions/373871/dont-understand-00-iptable-syntax/373875#373875
cat <<'EOF' >/etc/iptables/rules.v4
# Generated by iptables-save v1.6.0
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o wlan0 -j MASQUERADE
COMMIT
# Generated by iptables-save v1.6.0
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A FORWARD -i wlan0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -o wlan0 -j ACCEPT
COMMIT
EOF
# Load our `iptables` forwarding rules at each boot
# https://major.io/2009/11/16/automatically-loading-iptables-on-debianubuntu/
cat <<'EOF' >/etc/network/if-up.d/iptables
#!/bin/sh
iptables-restore < /etc/iptables/rules.v4
EOF
chmod +x /etc/network/if-up.d/iptables
# Enable persistent `ipv4` forwarding for each system boot
# http://www.ducea.com/2006/08/01/how-to-enable-ip-forwarding-in-linux/
sed -i'' \
s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/ \
/etc/sysctl.conf
# Create a static IP address configuration. The `eth0` 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. The DNS server will be `8.8.8.8` (Google's DNS) and the
# range will start at `10.1.1.2`.
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
#!/usr/bin/env bash
set -e
[ $EUID -ne 0 ] && echo "run as root" >&2 && exit 1
##########################################################
# You should not need to update anything below this line #
##########################################################
# parprouted - Proxy ARP IP bridging daemon
# dhcp-helper - A DHCP/BOOTP relay agent
apt update && apt install -y parprouted dhcp-helper
systemctl stop dhcp-helper
systemctl enable dhcp-helper
# Prevent the networking and dhcpcd service from running. networking.service
# is a debian-specific package and not the same as systemd-network. Disable the
# dhcpcd service as well.
systemctl mask networking.service dhcpcd.service
# This tells resolvconf to ignore whenever some daemon tries to modify the
# resolv.conf file - https://wiki.debian.org/resolv.conf
sed -i '1i resolvconf=NO' /etc/resolvconf.conf
systemctl enable systemd-networkd.service systemd-resolved.service
# Use systemd-resolved to handle the /etc/resolf.conf config
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
cat > /etc/systemd/network/08-wlan0.network <<EOF
[Match]
Name=wlan0
[Network]
DHCP=yes
IPForward=yes
EOF
cat > /etc/default/dhcp-helper <<EOF
DHCPHELPER_OPTS="-b wlan0"
EOF
cat <<'EOF' >/etc/avahi/avahi-daemon.conf
[server]
use-ipv4=yes
use-ipv6=yes
ratelimit-interval-usec=1000000
ratelimit-burst=1000
[wide-area]
enable-wide-area=yes
[publish]
publish-hinfo=no
publish-workstation=no
[reflector]
enable-reflector=yes
[rlimits]
EOF
# Create a helper script to get an adapter's IP address
cat <<'EOF' >/usr/bin/get-adapter-ip
#!/usr/bin/env bash
/sbin/ip -4 -br addr show ${1} | /bin/grep -Po "\\d+\\.\\d+\\.\\d+\\.\\d+"
EOF
chmod +x /usr/bin/get-adapter-ip
# I have to admit, I do not understand ARP and IP forwarding enough to explain
# exactly what is happening here. I am building off the work of others. In short
# this is a service to forward traffic from wlan0 to eth0
cat <<'EOF' >/etc/systemd/system/parprouted.service
[Unit]
Description=proxy arp routing service
Documentation=https://raspberrypi.stackexchange.com/q/88954/79866
[Service]
Type=forking
# Restart until wlan0 gained carrier
Restart=on-failure
RestartSec=5
TimeoutStartSec=30
ExecStartPre=/lib/systemd/systemd-networkd-wait-online --interface=wlan0 --timeout=6 --quiet
ExecStartPre=/bin/echo 'systemd-networkd-wait-online: wlan0 is online'
# clone the dhcp-allocated IP to eth0 so dhcp-helper will relay for the correct subnet
ExecStartPre=/bin/bash -c '/sbin/ip addr add $(/usr/bin/get-adapter-ip wlan0)/32 dev eth0'
ExecStartPre=/sbin/ip link set dev eth0 up
ExecStartPre=/sbin/ip link set wlan0 promisc on
ExecStart=-/usr/sbin/parprouted eth0 wlan0
ExecStopPost=/sbin/ip link set wlan0 promisc off
ExecStopPost=/sbin/ip link set dev eth0 down
ExecStopPost=/bin/bash -c '/sbin/ip addr del $(/usr/bin/get-adapter-ip eth0)/32 dev eth0'
[Install]
WantedBy=wpa_supplicant@wlan0.service
EOF
systemctl daemon-reload
systemctl enable parprouted.service
systemctl start wpa_supplicant@wlan0 dhcp-helper systemd-networkd systemd-resolved
#!/bin/bash
# Derived from a script by @arpitjindal97 originally made for Raspbian stretch
# Original source: https://github.com/arpitjindal97/raspbian-recipes
#
# Bridge WiFi with Ethernet
# Internet source is wlan0
# wpa_supplicant will be running on wlan0
#
# This is Layer 3 proxy arp solution
#
# This script is made to work with Raspbian Buster
# but it can be used with most of the distributions
# by making few changes.
#
# Make sure you have already installed:
# avahi-daemon
# parprouted
# dhcp-helper
#
# Just install these packages and don't touch
# any configuration file. This script will handle
# required options dynamically.
#
# Configure your wpa_supplicant prior to this script
#
eth="eth0"
wlan="wlan0"
sudo systemctl start network-online.target &> /dev/null
sudo iptables -F
sudo iptables -t nat -F
sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
echo "Killing parprouted "
sudo killall parprouted &> /dev/null
echo "Stopping dhcp-helper service"
sudo systemctl stop dhcp-helper
echo "Killing dhcp-helper"
sudo killall dhcp-helper &> /dev/null
echo "Stopping avahi-daemon service"
sudo systemctl stop avahi-daemon
echo "Killing avahi-daemon"
sudo killall avahi-daemon &> /dev/null
echo "Creating temp avahi conf file"
cp /etc/avahi/avahi-daemon.conf /tmp/avahi-daemon.conf
sed -i s/^enable-reflector=no/enable-reflector=yes/ /tmp/avahi-daemon.conf
option=$(cat /tmp/avahi-daemon.conf | grep enable-reflector=yes)
if [ $option=="" ]; then
echo -e '\n[reflector]\nenable-reflector=yes\n' >> /tmp/avahi-daemon.conf
fi
echo "Starting parprouted ..."
sudo /usr/sbin/parprouted $eth $wlan &
echo "Starting dhcp-helper ..."
sudo /usr/sbin/dhcp-helper -r /var/run/dhcp-helper.pid -b $wlan &
echo "Flushing $eth IP addr"
sudo ip addr flush dev $eth
echo "Assigning IP to $eth from $wlan"
sudo /sbin/ip addr add $(/sbin/ip addr show $wlan | perl -wne 'm|^\s+inet (.*)/| && print $1')/32 dev $eth &
sleep 2
echo "Starting avahi-daemon ... "
avahi-daemon -f /tmp/avahi-daemon.conf &
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment