Download the Raspberry Pi image from https://en.opensuse.org/Portal:MicroOS/Downloads and copy it the MicsoSD card.
# xz -d openSUSE-MicroOS.aarch64-ContainerHost-RaspberryPi.raw.xz
# dd bs=4M if=openSUSE-MicroOS.aarch64-ContainerHost-RaspberryPi.raw of=/dev/mmcblk0 iflag=fullblock oflag=direct status=progress; sync
In the past it was necessary to use ignition or combustion to set a root password or add an ssh key to .ssh/authorized_keys. You can still do that - see https://en.opensuse.org/Portal:MicroOS/Combustion - but today the "Jeos First Boot" will be presented if a USB drive with label "iginition" is not found, and it allows you to set the root password.
After the dd/sync is done, insert the SD card into the Pi, attach monitor, keyboard and network cable and power it up. The screen goes black after about 40sec and stays like that for another few minutes (maybe a serial console would show more?). Then the "Jeos First Boot" prompts you to set the language, timezone and root password. After that you should be able to login at the console as root. You can curl your ssh public key from somewhere and add it to authorized_keys.
This package provides the wg
tool and qg-quick
. With MicroOS you need to use transactional-update
to install packages and reboot after. Note reboot can take a few minutes because selinux relabeling is slow on microSD storage.
# transactional-update pkg install wireguard-tools
# reboot
There are many possible topologies - this doc just shows a simple point-to-point example between a laptop and the Pi. Also there are different ways to configure/persist WireGuard. This guide uses wg-quick
. See https://www.wireguard.com/ for other ways.
For Pi:
laptop # TTY=$(tty); wg genkey | tee $TTY | wg pubkey
6FAsBgy1OmGRzCMOoXJK5tz2esx0ElfArAhvaTX800k=
1INU+lEE6Jo0XxqENneInEqgjctXQZQj6dX1y1OJZgE=
For laptop:
laptop# TTY=$(tty); wg genkey | tee $TTY | wg pubkey
aAtkn8TfFA5+cm/YVoC0gV1RsFThz997dpaPKe2eMls=
DZwInXs4evwwR0EzZKU7Dhn2Y/wToraT4t2GCrrZFGU=
The latop's eth0
ip is 192.168.0.31
and the pi's is 192.168.0.234
. The port 51871
was choosen for the laptop, so that port will need to be opened on the firewall for UDP.
For Pi:
[Interface]
ListenPort = 51872
PrivateKey = 6FAsBgy1OmGRzCMOoXJK5tz2esx0ElfArAhvaTX800k=
Address = 172.31.0.2/30
[Peer]
PublicKey = DZwInXs4evwwR0EzZKU7Dhn2Y/wToraT4t2GCrrZFGU=
AllowedIPs = 172.31.0.1/32
Endpoint = 192.168.0.31:51871
For latop:
[Interface]
ListenPort = 51871
PrivateKey = aAtkn8TfFA5+cm/YVoC0gV1RsFThz997dpaPKe2eMls=
Address = 172.31.0.1/30
[Peer]
PublicKey = 1INU+lEE6Jo0XxqENneInEqgjctXQZQj6dX1y1OJZgE=
AllowedIPs = 172.31.0.2/32
Endpoint = 192.168.0.234:51872
pi# chmod 0600 /etc/wireguard/wg0.conf
laptop# chmod 0600 /etc/wireguard/wg0.conf
pi # systemctl enable [email protected] --now
latop # systemctl enable [email protected] --now
pi# ping -c1 172.31.0.1
PING 172.31.0.1 (172.31.0.1) 56(84) bytes of data.
64 bytes from 172.31.0.1: icmp_seq=1 ttl=64 time=5.09 ms
--- 172.31.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 5.089/5.089/5.089/0.000 ms
pi# wg
interface: wg0
public key: 1INU+lEE6Jo0XxqENneInEqgjctXQZQj6dX1y1OJZgE=
private key: (hidden)
listening port: 51872
peer: DZwInXs4evwwR0EzZKU7Dhn2Y/wToraT4t2GCrrZFGU=
endpoint: 192.168.0.31:51871
allowed ips: 172.31.0.1/32
latest handshake: 23 seconds ago
transfer: 476 B received, 564 B sent
pi# ip -4 address show dev wg0
6: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
inet 172.31.0.2/30 scope global wg0
valid_lft forever preferred_lft forever
Instead of installing iperf
on the pi we can build and run it as a container.
pi# mkdir iperf; cd iperf
pi# cat > Containerfile <<EOF
FROM registry.opensuse.org/opensuse/tumbleweed
RUN zypper --non-interactive install iperf && zypper clean --all
EOF
pi# podman build -t iperf .
pi# podman run -it --rm --net=host localhost/iperf iperf3 -s
These tests were done on a Model B Rev 1.2
# cat /sys/firmware/devicetree/base/model
Raspberry Pi 3 Model B Rev 1.2
laptop# iperf3 --omit 5 --time 25 -c 192.168.0.234
...
[ 5] 0.00-25.01 sec 278 MBytes 93.2 Mbits/sec receiver
laptop# iperf3 --omit 5 --time 25 -c 172.31.0.2
...
[ 5] 0.00-25.01 sec 263 MBytes 88.3 Mbits/sec receiver
latop# # iperf3 --reverse --omit 5 --time 25 -c 192.168.0.234
...
[ 5] 0.00-25.01 sec 282 MBytes 94.5 Mbits/sec 0 sender
laptop# iperf3 --reverse --omit 5 --time 25 -c 172.31.0.2
...
[ 5] 0.00-25.01 sec 270 MBytes 90.5 Mbits/sec 0 sender
So it looks like a 4-5% performance drop.
On MicoOS you can use the toolbox container
pi # toolbox
Trying to pull registry.opensuse.org/opensuse/toolbox:latest...
...
Entering container. To exit, type 'exit'.
toolbox-root:/ #
toolbox-root:/ # tcpdump -c2 -ni eth0 udp port 51872
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:47:15.893910 IP 192.168.0.31.51871 > 192.168.0.234.51872: UDP, length 148
12:47:15.897386 IP 192.168.0.234.51872 > 192.168.0.31.51871: UDP, length 92
2 packets captured
4 packets received by filter
0 packets dropped by kernel
The systemd timer transactional-update.timer
runs transactional-update once per day by default, and the schedule can be changed. When transactional-update installs updates it informs rebootmgr that a reboot is needed and rebootmgr will do the reboot within the set maintenance window.
pi# rebootmgrctl get-window
Maintenance window is set to *-*-* 03:30:00, lasting 01h30m.
To change the maintenance window:
pi# cp /usr/etc/rebootmgr.conf /etc/rebootmgr.conf
pi# vi /etc/rebootmgr.conf
pi# systemctl restart rebootmgr
pi# rebootmgrctl get-window