OTG PiZero

I dug out this old step by step I used to use for setting up Raspberry Pi Zeros as OTG devices. I had lost this for a while, so rather than filing it away somewhere that I may lose track of it again, I figured I’d share it here. This may be a bit dated as I think I wrote this a couple years back. This was pieced together from other guides, but I don’t recall where from. I can’t take full credit for all of this.

1) Flash Raspbian to SD card

2) Mount SD card

3) vim /boot/config.txt add dtoverlay=dwc2 on a new line at the end.

4) touch /boot/ssh

5) vim /boot/cmdline.txt (Be careful with this file, it is very picky with its formatting! Each parameter is seperated by a single space not newlines) Insert ‘modules-load=dwc2,g_ether’after rootwait

6) Unmount SD card and power on Pi

7) sudo dmesg
[ 1943.306812] usb 1-12: new high-speed USB device number 14 using xhci_hcd
[ 1943.494324] cdc_ether 1-12:1.0 usb0: register 'cdc_ether' at usb-0000:00:14.0-12, CDC Ethernet Device, 2e:2f:d7:3d:10:88
[ 1943.526965] cdc_ether 1-12:1.0 enp0s20f0u12: renamed from usb0

8) sudo avahi-autoipd -D enp0s20f0u12

9) avahi-resolve -n raspberrypi.local

10) ip a (Note the inet6 address of the device)

11) ssh -6 -o BindAddress=fe80::ccf3:3fff:3ff3:ccc1%enp0s20f0u12 pi@raspberrypi.local

12) sudo vim /etc/network/interfaces

# Start of file (you don't need to include this line)
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
    address 10.2.2.3 # IP you want to assign to the RPi
    gateway 10.2.2.2 # IP you want to assign to the ethernet port
    network 10.2.2.0
    netmask 255.255.255.0
    broadcast 10.2.2.255
13) sudo vim /etc/resolv.conf
nameserver 10.2.2.2
nameserver 8.8.8.8
nameserver 8.8.4.4

14) sudo reboot

Part III: Seting up forwarding to the pi (from Arch)
1) First make sure your pi is still the same name as before, and also note the name of the device you intend to share internet from (for me its my ethernet adapter enp3s0) by running:

ifconfig

and checking to see if the device name shows up
2) Lets make sure our device is up by running:

sudo ip link set up dev enp0s20f0u12

(NOTE: make sure to change the enp020f0u12 to your device name)
3) Lets add the IPv4 address for the device by running

sudo ip addr add 10.2.2.2 dev enp0s20f0u12

(NOTE: again the device name…)
4) Lets enable packet forwarding to the device by running

sudo sysctl net.ipv4.ip_forward=1

5) Enable the NAT for the device by running the following 3 commands, making sure to use your device id, and changing enp3s0 to be the ethernet device id that you want to share with your pi!

sudo iptables -t nat -A POSTROUTING -o enp3s0 -j MASQUERADE
sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i enp0s20f0u12 -o enp3s0 -j ACCEPT

6) Lets assign the ip addresses to the Pi zero by running the following 3 commands, making sure to use your device id, and changing enp3s0 to be the ethernet device id that you want to share with your pi!

sudo iptables -I INPUT -p udp --dport 67 -i enp0s20f0u12 -j ACCEPT
sudo iptables -I INPUT -p udp --dport 53 -s 10.2.2.0/24 -j ACCEPT
sudo iptables -I INPUT -p tcp --dport 53 -s 10.2.2.0/24 -j ACCEPT

Part IV: Setup a network bridge to the pi so we can effectively share our internet with the pi zero
1) Lets use netctl to create a network bridge by copying the example network bridge file included in the netctl package by running

sudo cp /etc/netctl/examples/bridge /etc/netctl/bridge
cd /etc/netctl/

2) Lets modify the example network bridge to share internet between our devices, making sure to replace enp3s0 with the device id you want to share internet from and enp0s20f0u12 with the device id of your pi by running

sudo vim bridge

and changing the file to:

# Start of file (you don't need to include this line)

Description="Example Bridge connection"
Interface=br0
Connection=bridge
BindsToInterfaces=(enp3s0 enp0s20f0u12 )
IP=dhcp
## Ignore (R)STP and immediately activate the bridge
#SkipForwardingDelay=yes

# End of file (you don't need to include this line)

Save the changes to the file…

3) Now test the bridge connection using netctl by running:

sudo netctl start bridge

4) Now when we run

ifconfig

we should see our our bridge connection br0 in the output like so:

br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.104  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::3490:aff:f37f:fdf3  prefixlen 64  scopeid 0x20<link>
        ether 01:20:3f:27:1f:ff  txqueuelen 1000  (Ethernet)
        RX packets 34442  bytes 47881180 (45.6 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 29738  bytes 4640292 (4.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

If you don’t see this, something went wrong, so try hunting it down, or if you really can’t find it on your own, as a question and be sure to post exactly what you did. Please don’t waste my time without first really looking into it on your own first (at least spend a few hours debugging on your own…).

5) Let’s try ssh’ing into that ipv4 address (inet):

ssh pi@192.168.0.104

Note: replace the 192.168.0.104 with whatever your inet address is.

6) If you can, then your pi now also has whatever internet connection your ethernet device has. Congrats! Now to ensure we can ssh into raspberrypi.local instead of having to specify the ip, run:

sudo avahi-resolve -n raspberrypi.local

Note: this may not always be necessary

7) Now we can ssh like normal:

ssh pi@raspberrypi.local

8) Now if you intend on leaving your pizero plugged into the same usb port and want to be able to ssh into it without having to do any setup when you reconnect or reboot, run:

sudo netctl enable bridge

Otherwise, if you intend on reconnecting the same pi device with the same operating system periodically, just run the

sudo netctl start bridge