Data publikacji: Nov 21, 2019 8:21:29 AM
Po wykonaniu poniższych kroków RaspberryPI Zero podłaczone poprzez USB z komputerem:
- będzie widziane jako karta ethernet
- będzie do niego dostęp poprzez SSH
- będzie miało dostęp do internetu
- będzie widziane jako pamięć masowa
- jako bonus również jako klawiatura
Na samym początku należy skonfigurować maskaradę:
# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -t nat -A POSTROUTING -o enp3s0 -j MASQUERADE
Interfejs enp3s0 to mój interfejs poprzez który mam dostęp do Internetu.
Mam też inny sposób:
# cat <<EOT >/etc/NetworkManager/dispatcher.d/02-raspberrypi
#!/bin/bash
INTERFACE=$1
EVENT=$2
IFACEGW=`ip route show 0.0.0.0/0 | cut -d\ -f5`
if [ "$IP4_ADDRESS_0" == "10.33.0.2/30 0.0.0.0" ]; then
if [ "$EVENT" == "up" ]; then
iptables -t nat -A POSTROUTING -s 10.33.0.0/24 -o $IFACEGW -j MASQUERADE
fi
fi
EOT
I dodanie do /etc/sysctl.conf:
net.ipv4.ip_forward=1
Zaczynamy od pobrania obrazu Raspbiana ze strony https://www.raspberrypi.org/downloads/raspbian/
Ja skorzystałem z obrazu Raspbian Buster with desktop and recommended software (datowanego na 2019-09-26).
Po pobraniu plik rozpakowujemy i kopiujemy na kartę SD:
# unzip 2019-09-26-raspbian-buster-full.zip
# dd if=2019-09-26-raspbian-buster-full.img /dev/mmcblk0
# sync
Obraz jest tak przygotowany, że po uruchomieniu pierwszy raz systemu rozszerzy się na całą kartę SD
Kartę wyjmujemy i wkładamy ponownie. Mój system automatycznie podmountował partycję boot i rootfs.
Na partycji boot dokonujemy zmian w pliku cmdline.txt zmieniając linię z:
... rootwait quiet ...
na
... rootwait modules-load=dwc2 quiet ...
Dodatkowo tworzymy pusty plik ssh. To sygnał dla syste
Następnie przechodzimy na partycję rootfs i tworzymy katalog /usbgadget a w nim plik konfiguracyjny init.sh o następującej zawartości:
#!/bin/bash
cd /sys/kernel/config/usb_gadget/
mkdir -p gadget
cd gadget
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
mkdir -p strings/0x409
# Poniżej można wypełnić te zmienne wg. uznania
echo "deadbeef3735928559" > strings/0x409/serialnumber
echo "Anonymous creator" > strings/0x409/manufacturer
echo "Smart USB Device" > strings/0x409/product
mkdir -p configs/c.1/strings/0x409
echo "Config 1: ECM network" > configs/c.1/strings/0x409/configuration
echo 250 > configs/c.1/MaxPower
# Start functions
# Ethernet
mkdir -p functions/ecm.usb0
# Ważne, aby pierwszy bajt był parzysty
HOST="48:6f:73:74:50:43" # "HostPC"
SELF="42:61:64:55:53:42" # "BadUSB"
echo $HOST > functions/ecm.usb0/host_addr
echo $SELF > functions/ecm.usb0/dev_addr
ln -s functions/ecm.usb0 configs/c.1/
# End functions
ls /sys/class/udc > UDC
Pamiętamy o nadaniu uprawnienia +x temu plikowi.
Jego wywołanie dospisujemy do /etc/rc.local - uwaga: przed exit 0 - dopisując tam:
/usbgadget/init.sh
Następnie konfigurujemy sieć tworząc plik /etc/network/interfaces.d/eth0:
auto usb0
allow-hotplug usb0
iface usb0 inet static
address 10.33.0.1
netmask 255.255.255.0
Do pliku /etc/dhcpcd.conf dopisujemy:
noipv4ll
Na tym etapie możemy przełożyć kartę SD do RaspberryPI, podpiąć kabel USB pod złącze opisane jako USB (nie PWR!) i wpiąć go do komputera. Migająca dioda będzie sygnałem, że system się bootuje.
Możemy śledzić /var/log/kern.log na komputerze. W logach powinniśmy widzieć:
Nov 22 18:55:13 io kernel: [ 2422.216214] usb 3-9: new high-speed USB device number 19 using xhci_hcd
Nov 22 18:55:20 io kernel: [ 2429.095745] usb 3-9: device descriptor read/64, error -110
Nov 22 18:55:21 io kernel: [ 2429.352529] usb 3-9: New USB device found, idVendor=1d6b, idProduct=0104, bcdDevice= 1.00
Nov 22 18:55:21 io kernel: [ 2429.352533] usb 3-9: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Nov 22 18:55:21 io kernel: [ 2429.352536] usb 3-9: Product: Smart USB Device
Nov 22 18:55:21 io kernel: [ 2429.352539] usb 3-9: Manufacturer: Anonymous creator
Nov 22 18:55:21 io kernel: [ 2429.352541] usb 3-9: SerialNumber: deadbeef3735928559
Nov 22 18:55:21 io kernel: [ 2429.356596] cdc_ether 3-9:1.0 eth0: register 'cdc_ether' at usb-0000:00:14.0-9, CDC Ethernet Device, 48:6f:73:74:50:43
Nov 22 18:55:21 io kernel: [ 2429.361598] input: Anonymous creator Smart USB Device as /devices/pci0000:00/0000:00:14.0/usb3/3-9/3-9:1.2/0003:1D6B:0104.0007/input/input23
Nov 22 18:55:21 io kernel: [ 2429.420051] hid-generic 0003:1D6B:0104.0007: input,hidraw3: USB HID v1.01 Keyboard [Piotr Gasidlo Smart USB Device] on usb-0000:00:14.0-9/input2
Nov 22 18:55:21 io kernel: [ 2429.420288] usb-storage 3-9:1.3: USB Mass Storage device detected
Nov 22 18:55:21 io kernel: [ 2429.420697] scsi host6: usb-storage 3-9:1.3
Nov 22 18:55:21 io kernel: [ 2429.445540] cdc_ether 3-9:1.0 enx486f73745043: renamed from eth0
Ostatnia linia mówi nam jaka karta sieciowa pojawiła się w systemie. Należy ustawić jej adres IP i podnieść:
# ip a a dev enx486f73745043 10.33.0.2/24 brd +
# ip l s dev enx486f73745043 up
Powinniśmy mieć możliwość pingnięcia 10.33.0.1. Dodatkowo powinno działać połączenie po SSH:
ssh -C pi@rasberrypi.local
lub
ssh -C pi@10.33.0.1
Hasło to domyślne raspberry, które najlepiej zmienić po zalogowaniu komendą passwd.
Jeżeli poprawnie zalogowaliśmy się na pi, przechodzimy na roota i konfigurujemy sieć:
$ sudo bash
# route add default gw 10.33.0.1 usb0
Sprawdzamy, czy ping 8.8.8.8 działa. Brak odpowiedzi może oznaczać problemy z maskaradą.
Do pliku /etc/resolv.conf dopisać (ew. zastąpić istniejący wpis):
nameserver 8.8.8.8
Sprawdzić czy ping www.google.pl odpowiada.
Teraz kończymy konfigurację. Instalujemy dnsmasq:
# apt install dnsmasq
Tworzymy plik /etc/dnsmasq.d/usbgadget.conf z następującą zawartością:
interface=usb0
dhcp-range=usb0,10.33.0.2,10.33.0.5,255.255.255.0,1h
dhcp-option=3
server=8.8.4.4
server=8.8.8.8
leasefile-ro
dhcp-script=/usbgadget/route.sh
Tworzymy plik /usbgadget/route.sh z następującą zawartością:
#!/bin/bash
op="${1:-op}"
mac="${2:-mac}"
ip="${3:-ip}"
host="${4}"
if [[ $op == "init" ]]; then
exit 0
fi
if [[ $op == "add" ]] || [[ $op == "old" ]]; then
route add default gw $ip usb0
fi
Pamiętamy o nadaniu uprawnienia +x temu plikowi.
Restartujemy PI wpisując restart. Jeżeli wszystko poszło OK powinien wystartować zaś wirtualna karta w naszym komputerze powinna automatycznie otrzymać adres IP.