For simply ssh'ing to the USB attached Raspberry Pi Zero running in USB device / peripheral / gadget mode we just need a few 'simple' things:
- dwc2 and g_ether to enable ethernet gadget mode
- ssh enabled by putting a file named ssh in the boot partition of the SD card
- a couple of IP addresses in the same subnet, one for the Pi and one for the host computer
- name resolution so you don't have to know the IP address
Using a Zeroconf based IP addresses here seems ideal. We don't need to know what the Pi's address is as long as we can use a name to reach it, and it doesn't care what the host computer's is as long as they are on the same subnet. Ideally a system uses some form of Dynamic Configuration of IPv4 Link-Local Addresses (RFC 3927) to self-assign a link-local IPv4 address after determining that another method like DHCP is not available.
Unfortunately it seems some current Linux based hosts, like Ubuntu for example, default to DHCP and disable the interface instead of falling back to link local addressing when it fails. I am not yet sure how raspbian handles this, it is likely the same. The guides by gbman have you hard code a link-local address, 169.254.64.64, into the Pi.
So you can SSH into the Pi and start doing some stuff, but as soon as you try to do anything that requires an Internet connection you're stuck. To get past this hurdle we need a few more things.
- The host computer's IP address at the other end of our USB network to use as a default route gateway.
- DNS server address(es) to resolve names with.
- An advertised routable IP address or to have the host NAT us.
If so, that could provide to the Raspberry Pi some DNS server addresses and the default route IP address. If not, we've glossed over another detail for people to stumble over. Also, even if it does those things, your Zero had better be configured to use DHCP instead of that hard-coded link local address or, better yet, be configured to automatically switch to DHCP from link local addressing.
At the moment I only have a Ubuntu Linux host to test against, and it's not configured to send DHCP to a random (dev enp0s26f0u1i1) USB network connection when it appears. I'd really rather do as little as possible to the host system. If Ubuntu has an internet sharing button or checkbox that enables NAT and starts a DHCP service on that interface, perfect.
If Mac, Windows, and Linux don't start a DHCP server on the interface they are sharing the Internet connection with then we need to solve the DNS and routing issue on the Zero. It seems the simplest way to do this would be to install and configure dnsmasq for the usb0 interface. It would do this just to give the host computer's end a fixed IP address that we could hard-code as the default route. We could also hard-code some stable public DNS servers, like Google's 188.8.131.52 & 184.108.40.206.
Using dnsmasq provides a chicken and the egg problem. We have to discover the auto-assigned IP at least once to configure our default route. Maybe some scripts wrapping the arp tool would be sufficient. Then the host's IP could be random but we could discover what it is and configure the route.
Once all those pieces are in place it seems you could not only ssh into the Zero over the USB connection, but you could then use the host's Internet connection from the Zero.
Am I on track or up in the night?
Is there already a comprehensive guide that does this?
I would like help finding and writing up the most reliable steps to get this kind of setup working as close to automagically as possible. I would love a solution that works across as many host systems as is reasonable. I'd like to plug into a chromebook and have http://raspberrypi.local/ work, if I were running a webserver on port 80 of the Pi.