User guide · Chapter 1 of 8 · Deutschnullos.de

Try NULLos in QEMU and connect via SSH

NULLos runs on the Mac in a virtual machine (QEMU). You then connect from your Mac with ssh, just like with any other computer.

Status: All steps on this page were checked on 30 Oct 2026 with the finished image nullos-0.3-x86_64.img: Mac with Apple chip, QEMU 11.1.2, OpenSSH 10.3p1. Where something does not work yet, it says so.

What you need

If you do not have an Ed25519 key yet, create one:

ssh-keygen -t ed25519

All commands on the Mac run in the folder where the image is, for example cd ~/Downloads.

1. Check the image

shasum -a 256 --ignore-missing -c SHA256SUMS
nullos-0.3-x86_64.img: OK

If it says OK, the file is complete and unchanged. --ignore-missing skips the ISO if you did not download it.

2. Prepare the keys

First create the keys for the SSH server ssd in a folder on the Mac:

mkdir nullos-ssh
ssh-keygen -y -f ~/.ssh/id_ed25519 > nullos-ssh/authorized_keys
ssh-keygen -t ed25519 -N '' -f nullos-ssh/hostkey
echo 'erlaube ein tcp port 2222' > nullos-ssh/ssh.fw

3. Put the keys into the image

The image contains the boot partition of NULLos. In NULLos it is called /boot. That is where ssd looks for the keys. You attach it on the Mac and copy the folder into it:

cp nullos-0.3-x86_64.img nullos.img
diskutil image attach --noMount nullos.img

The copy nullos.img is your working copy. The original stays unchanged, so you can start over at any time. diskutil shows the name under which the image is attached:

/dev/disk8  	GUID_partition_scheme
/dev/disk8s1	EFI

The number (here 8) may be different for you. Use your number in the following lines:

diskutil mount disk8s1
cp -R nullos-ssh /Volumes/NULLOS/ssh
diskutil eject disk8

In NULLos the folder is then called /boot/ssh/. In NULLos itself, /boot is read-only. If you want to change something later, attach the image on the Mac again while NULLos is off.

Double-clicking the image in the Finder does not work: macOS reports „Möglicherweise gibt es ein Problem mit diesem Image“ ("There may be a problem with this image") and does not mount the partition.

4. Start NULLos

This command starts NULLos without a window. It forwards two ports to your Mac:

qemu-system-x86_64 -machine q35 -m 256M \
  -drive if=pflash,format=raw,readonly=on,file=/opt/homebrew/share/qemu/edk2-x86_64-code.fd \
  -drive format=raw,file=nullos.img \
  -netdev user,id=n0,hostfwd=tcp:127.0.0.1:2222-:2222 -device virtio-net-pci,netdev=n0 \
  -serial tcp:127.0.0.1:4555,server,nowait -display none

The first three lines are also shown like this on nullos.de. The firmware file is where Homebrew puts it on a Mac with Apple chip. Keep the terminal open as long as NULLos should run.

Both ports listen only on 127.0.0.1, that is, only on your Mac itself. Other computers on the network cannot reach NULLos this way.

5. Start the SSH server in NULLos

Open a second terminal and connect to the serial console:

nc 127.0.0.1 4555

Press Enter once. Then you see the prompt of the shell s: root@nullos:~ $. Now start the SSH server:

ssd -p 2222 -u max -k /boot/ssh/hostkey -a /boot/ssh/authorized_keys -s s &
PartMeaning
-p 2222wait on port 2222
-u maxonly the user name max may log in – put your own name here
-k /boot/ssh/hostkeythe fixed host key from step 2
-a /boot/ssh/authorized_keysthe allowed keys from step 2
-s safter login the shell s runs
&run in the background, the console stays free

Unless you say otherwise, ssh sends along your user name from the Mac. whoami on the Mac shows it to you. A name other than the one given with -u is rejected („Permission denied“).

ssd reports with a line like this:

ssd: lauscht auf [::]:2222, Hostschlüssel SHA256:/RqW/KjFiOPj4aRooyyoHZ1i7gfRtdfwl8sRzIVVTvo

6. Open the firewall

The NULLos firewall is on by default: nothing gets in from outside. Without opening it, ssh gives up after a while with „Connection timed out during banner exchange“.

The easiest way is to load the rule from step 2:

fw laden /boot/ssh/ssh.fw
geladen: 1 Regeln

Or the firewall asks you itself:

fw dienste frage
Port 2222 (tcp, Prozess 5): lauscht, aber die Firewall lässt von außen nichts durch
  Von außen freigeben (erlaube ein tcp port 2222)? [j/N]

Type j and Enter. After that, fw zeigen shows the new rule:

standard ein sperre
standard aus erlaube
zustand an
erlaube ein tcp port 2222

It also works without a file: echo 'erlaube ein tcp port 2222' | fw laden -. The - means "read from the input". Careful: fw laden replaces all rules that were loaded before. More about the firewall: Network and firewall.

7. Connect

On the Mac, in a third terminal:

ssh -p 2222 127.0.0.1

The first time, ssh asks whether you trust the host key. The fingerprint must be the one that ssd reported in step 5. You can also see it on the Mac like this:

ssh-keygen -lf nullos-ssh/hostkey.pub

After that comes a warning „connection is not using a post-quantum key exchange algorithm“. This is known: ssd cannot do the new method mlkem768x25519-sha256 yet. The connection is encrypted anyway.

Then ssd shows its banner, the greeting from /etc/motd and the prompt:

 _   _ _   _ _     _
| \ | | | | | |   | |    ___  ___
|  \| | | | | |   | |   / _ \/ __|
| |\  | |_| | |___| |__| (_) \__ \
|_| \_|\___/|_____|_____\___/|___/

Zugriff nur mit Erlaubnis. Unbefugter Zugriff und Änderungen sind verboten; Aktivitäten können protokolliert werden.
Authorized access only. Unauthorized access or changes are prohibited; activity may be logged.

Willkommen bei nullos.
max@nullos:/ $

Now you type commands just like at the console. The shell's line editing also works over SSH, for example the arrow keys. Ctrl-C stops a running command; the session stays open.

You can also run a command directly, without a session:

ssh -p 2222 127.0.0.1 'l /boot/ssh'

ssd -b DATEI shows a different text instead of the banner, ssd -b - shows none at all.

Getting out again

Without a terminal: ssh -T

With ssh -T the shell gets no pseudo-terminal. Then there is no prompt and no line editing, and the keys ~. do not work. You get out with exit or Ctrl-D.

8. Shorter with an entry in the SSH configuration

Add this to the file ~/.ssh/config on your Mac:

Host nullos
  HostName 127.0.0.1
  Port 2222

If your key is not called id_ed25519, add one more line:

  IdentityFile ~/.ssh/dein-schluessel

Then this is enough:

ssh nullos
ssh nullos 'l /boot/ssh'

After a restart

NULLos does not remember running programs or firewall rules. After every restart of the VM:

  1. nc 127.0.0.1 4555 and Enter
  2. ssd … as in step 5
  3. Open the firewall as in step 6 (fw laden /boot/ssh/ssh.fw or fw dienste frage)

The files in /boot/ssh/ are kept. After all, they are in your working copy nullos.img.

If it does not work

MessageCauseFix
FAILED from shasumfile incomplete or changeddownload the image again
Connection timed out during banner exchangefirewall closed, or ssd is not runningsteps 5 and 6
Permission denied (publickey)wrong user name, or key not in authorized_keyscompare the name given with -u and whoami, step 2
Hostschlüssel fehlt und lässt sich nicht anlegenfolder ssh not in the image, or the ISO was startedstep 3, start with nullos.img
Umlauts in the banner shown as \303\204terminal on the Mac without UTF-8set LANG=de_DE.UTF-8