Skip to content

Instantly share code, notes, and snippets.

@popey
Last active March 21, 2023 00:22
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save popey/b3ac7c148d7b74308a2363453481283f to your computer and use it in GitHub Desktop.
Save popey/b3ac7c148d7b74308a2363453481283f to your computer and use it in GitHub Desktop.
#!/bin/bash
# Automatically setup routing and DNS for a PiZero connected over a USB-network
# Based off https://gist.github.com/lurch/ad939bbce48064cffdb215268eac9f62
# Need to have booted PI Zero with config.txt option "dtoverlay=dwc2"
# and cmdline.txt parameter "modules-load=dwc2,g_ether"
# TODO
# Force PI to have fixed MAC address like e6:45:88:d0:85:46
# For now, edit cmdline.txt in the boot partition on the pi SD card, add:-
# g_ether.dev_addr=e6:45:88:d0:85:46
# Enable ip forwarding
sudo sysctl -w net.ipv4.ip_forward=1
# The Avahi-discovered hostname
ZERO_HOSTNAME=raspberrypi.local
# The SSH user
ZERO_USERNAME=pi
# The USB network device on the Zero-side (will typically be usb0)
ZERO_DEV=usb0
# The USB network device on the PC-side (will probably be usb0 on older kernels)
# Should maybe get this from dmesg, looking for "renamed from usb0"
#PC_ZERO_DEV=enp0s20u2i1
#PC_ZERO_DEV=enp0s20u1
PC_ZERO_DEV=`dmesg | grep "renamed from usb0" | awk '{ print $4}' | tail -n 1 | tr -d ':'`
# The Connection name in Network Manager we will call the Pi USB Ethernet
PC_CONN_NAME=piusb
##### This part only needs doing once - we should check for piusb
# Check for piusb. If exists, delete and recreate
nmcli con show piusb
if [[ $? -eq 0 ]]; then
# For now we delete and recreate the piusb connection
nmcli con delete piusb
fi
# Create new named connection
nmcli con add autoconnect yes type ethernet con-name $PC_CONN_NAME ifname $PC_ZERO_DEV
# Set new connection to local-link
nmcli con modify $PC_CONN_NAME ipv4.method link-local
# Bring up the connection
nmcli con up piusb
##### This part only needs doing once
# Figure out the internet-connected network device on the PC
# (will probably be eth0 or wlan0 on older installs)
PC_INET_DEV=$(route | grep ^default | head -n 1| awk '{print $8}')
echo "PC_INET_DEV is $PC_INET_DEV"
sudo iptables -t nat -A POSTROUTING -s 169.254.0.0/16 -o $PC_INET_DEV -j MASQUERADE
ifconfig $PC_ZERO_DEV > /dev/null 2>&1
if [[ "$?" != "0" ]]; then
echo "PC_ZERO_DEV ($PC_ZERO_DEV) doesn't exist"
exit 1
fi
ifconfig $PC_INET_DEV > /dev/null 2>&1
if [[ "$?" != "0" ]]; then
echo "PC_INET_DEV ($PC_INET_DEV) doesn't exist"
exit 1
fi
DNS_SERVER=$(nmcli -t -f IP4 device show $PC_INET_DEV | grep DNS | head -1 | cut -d: -f2)
echo "DNS_SERVER is $DNS_SERVER"
# The IP address assigned to the PC-side of the USB network device
PC_ZERO_DEV_IP=$(ifconfig $PC_ZERO_DEV | grep 'inet addr:' | cut -d: -f2 | awk '{print $1}')
echo "PC_ZERO_DEV_IP is $PC_ZERO_DEV_IP"
if [[ "$PC_ZERO_DEV_IP" != 169.254.* ]]; then
echo "PC_ZERO_DEV_IP isn't in the link-local range"
exit 1
fi
# The IP address assigned to Zero-side of the USB network device
ZERO_IP=$(ping -c1 $ZERO_HOSTNAME | grep $ZERO_HOSTNAME | head -1 | cut -d'(' -f2 | cut -d')' -f1)
echo "ZERO_IP is $ZERO_IP"
if [[ "$ZERO_IP" != 169.254.* ]]; then
echo "ZERO_IP isn't in the link-local range"
exit 1
fi
# Copy SSH key
ssh-copy-id -f $ZERO_USERNAME@$ZERO_HOSTNAME
if [[ "$?" != "0" ]]; then
echo "Failed to copy ssh key"
exit 2
fi
# Setup default route and DNS server on Zero
ssh $ZERO_USERNAME@$ZERO_HOSTNAME "sudo route add default gw $PC_ZERO_DEV_IP $ZERO_DEV; echo \"nameserver $DNS_SERVER\" | sudo resolvconf -a $ZERO_DEV"
if [[ "$?" != "0" ]]; then
echo "Failed to setup route"
exit 3
fi
# Done
echo "ssh $ZERO_USERNAME@$ZERO_HOSTNAME"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment