Once and for All: iptables and udev rules
I hope I can remember it now
Time for another Once-And-For-All - tasks I do periodically (but not weekly) and keep forgetting the command syntax. I got myself a brand-new BeagleBone Black A6. When you attach the device via usb (and have a correctly configured kernel) it will appear as USB Gadget device with 3 classes a usb-uart serial device (CDC), a mass-storage device (MSC) and a usb-networking adapter (rndis_host). Magic™ will take care that it already has an ipaddress (192.168.7.2) and can communicate with your host. To allow access to the Internet via this usb-networking connection will require your host machine to route the traffic to its gateway. Once-and-for-all: add a NAT-table, enable forwarding, enable forwarding globally:
iptables --table nat -A POSTROUTING -o wlan0 -j MASQUERADE
iptables -A FORWARD -i usbeth0 -j ACCEPT
sysctl net.ipv4.ip_forward=1
Just for completeness, some distributions come with iptables with restrictive rules. No need to flush them all, you can inspect them with line-numbers and delete single rules:
iptables -vnL --line-numbers # List with line numbers
iptables -D default_input_chain 16 # delete line #16 from default_input_chain
iptables -A INPUT -j ACCEPT # you probably trust your beagleboard
Udev is part of the above Magic™ it does most stuff on its own but sometimes I
want it do do more or different stuff. For instance whenever you plug in a new
(usb-)network device you get a new number - great. Udev simply adds a new line
to the /etc/udev/rules.d/70-persistent-net.rules
incrementing the counter on
the name. If you don’t like the name - change it! So far so good, you probably
knew that already. The fancy thing about these rules is you can let udev call
arbitrary commands when executing these rules. You just add as many , RUN+="
parameter" actions to the line. Once-and-for-all: use an absolute path!!
If no absolute path is given, the program is expected to live in /usr/lib/udev, otherwise the absolute path must be specified!" man (7) udev
The complete rule that lets your usb-network connection access the internet looks like this:
# USB device 0x:0x (rndis_host)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="usbnet%n" ,\
RUN+="/sbin/iptables --table nat -A POSTROUTING -o wlan0 -j MASQUERADE",\
RUN+="/sbin/iptables -A FORWARD -i usbeth%n -j ACCEPT",\
RUN+="/sbin/sysctl net.ipv4.ip_forward=1"
Note: It seems that at least my beagleboard came with a bug. Dropbear the ssh server didn’t let me connect.
ssh root@192.168.7.2 ssh_exchange_identification:
read: Connection reset by peer
The problem was /etc/dropbear/dropbear_rsa_host_key was an empty file, so it couldn’t read the host key…. duh!. Deleting the file and restarting dropbear solved the issue.