Repository navigation
Releases: woffko/Hardened-BliKVM
Release list
Hardened BliKVM 0.1.0-beta.10
Tenth beta of Hardened BliKVM, a security-focused KVM-over-IP for the BliKVM v4 (Allwinner H616). It replaces 0.1.0-beta.9's application, card image and RAW system update. It is made of the work on remote control from a phone that the operator reported on 2026-10-24 and 25: control that turned itself off, a cursor that drifted, a picture that blinked when a QUIC session opened again, and the board's own display upside down. Beside the files is the target agent's program for Windows.
Every menu and settings page, on a desktop and a phone: docs/screenshots.md.
The project's page: https://woffko.github.io/Hardened-BliKVM/
What changed since beta.9
- Remote control.
- It is taken by the first click, tap or key on the screen, after a confirmation; that press reaches nothing. The toolbar's button is gone, and Release remote control is in the Mouse menu. A click that only closes a menu asks nothing.
- A window that loses focus gives the keyboard and mouse back and keeps the confirmation: its next input takes them again without asking.
- No key or move is dropped on the way. A report that meets a lease that ended is sent again with a new one, or control turns off with "Remote control was lost". A lost relative move used to put the phone's trackpad cursor apart from the target's for good.
- A QUIC session that opens again keeps the lease the page uses: the server no longer releases it when the gateway closes the earlier session. A socket of the page that opens again within 10 s keeps it too.
- QUIC transport.
- While a lost session opens again, the last frame stays on the screen instead of a dimmed wait, which blinked on the phone.
- The path's MTU is searched up to 1360 bytes instead of 1452, as RustAdmin's QUIC transport does for paths through a VPN.
- The board's journal says why each session ended: the gateway's reason with the path it measured (round trip, MTU, congestion window, losses, black holes), and the page's own (no answer to its pings, the connection closed, what the browser said) with its next session. The lines are in memory and cost about 250 bytes each.
- The desktop layout from the target agent. One monitor, or monitors duplicated, is the whole desktop, whichever is the board's. The page keeps the agent's layout on the board, so the absolute mouse stays right when the agent is not running. While the agent's layout applies, the Mouse menu's Desktop entry says so and offers no layout of its own.
- The board's display shows its status screen the vendor's way up. It was upside down: its MADCTL came from code the vendor's program carries but never calls.
- Dependencies.
rustls-webpki0.103.16 (RUSTSEC-2026-0382) andtokio1.53.3 (RUSTSEC-2026-0386); the board owner registers the target agent's device withAsyncFd::register. - Documentation. The README describes the present system; screenshots of every menu.
The record, with the commit and the test of each change and what was shown on the test board: audit-20261025-remote-control.md.
Update a running board
From beta.9, do the two steps in this order.
- The application. Upload
hardened-blikvm-application-0.1.0-beta.10-seq106.tarin Settings > Update. It brings the server, the board owner and the web interface. After it, the target agent on the target says it is not the board's version: "Update the agent on the target" in Settings > Device replaces it. - The system. In Settings > Update > System Update, turn on "Allow raw system updates", upload
hardened-blikvm-system-0.1.0-beta.10-seq10.tar(Upload and Verify), then Install. It brings the update runtime0.1.0~dev45(the QUIC gateway and the update supervisor of this release). The board saves its settings, reboots, keeps the current system as a backup on the data partition, writes the new one and starts it. On the test board that took about 5 minutes to upload and verify and 35 to write and start. Keep power and the network connected: a board that loses power while its root is written does not start until the root is written back from that backup (tools/image/restore_raw_backup.py, with the card in a reader of another Linux computer). Then confirm the new system in the same section. Until it is confirmed, Rollback writes the old one back, and a new system that does not start within two boots is written back by itself.
The RAW update is written by beta.9's boot step, which keeps the board's application, update journal and anti-rollback floor besides what earlier ones kept (accounts, root's password, the TLS certificate and SSH host keys, root's SSH keys, the machine id and host name, the network and Wi-Fi settings, the firewall mode, the administration features, the video settings, the display's sleep time, Tailscale's state and the switches).
From beta.8, the same two steps. The RAW update is then written by beta.4's boot step, as beta.9's notes describe: it carries the settings above but not the application, so the board runs the image's (slot 106) afterwards, which is why the application step comes first.
Write the card
The image needs a card of at least 32 GB. Check the download against SHA256SUMS first.
Linux or macOS:
zstd -dc hardened-blikvm-h616-sd.img.zst | sudo dd of=/dev/sdX bs=4M conv=fsync status=progress
Windows: unpack it with zstd -d hardened-blikvm-h616-sd.img.zst, then write hardened-blikvm-h616-sd.img with balenaEtcher or Rufus.
First boot
- Insert the card, connect Ethernet, power the board. The first boot creates the board's own SSH host keys, TLS certificate and identifiers, and gives the virtual media store the rest of the card; it takes about a minute.
- Open
https://<board address>/(the certificate is self-signed) and create the administrator account in First Setup. The password you choose there also becomes root's password (SSH); changing it later in Settings > Account changes both. - Until First Setup, root's password is
1234and an SSH login must change it. Whoever reaches the board first can complete First Setup, so do it on a trusted network.
The image starts clean: every administration feature off (QUIC among them), the firewall in Baseline, no Wi-Fi profiles, an empty image store, H.264 HW chosen, upscaling Auto. Card layout: 12 GiB system, 8 GiB data, the rest for virtual media images.
Checked
On the test board, at each step, the board's settings and switches were read before and after and compared.
- As the work went on, slots 102 to 105 and update runtimes dev43 and dev44 were installed at the operator's word. The operator confirmed the display the right way up, the agent working with the mouse on duplicated monitors, and used the phone while its sessions' endings were read from the journal.
- Slot 106 was installed and confirmed on beta.9's system, with this release's update runtime (dev45) put in by hand. Then these passed: the walks of the GUI at a desktop's and a phone's size (each menu, dialog and settings page, without asking for remote control), H.264 and VP8 over WebRTC, the H.264 picture over QUIC, and the phone's touch reach.
- The RAW system update of sequence 10 was installed from beta.9's system (sequence 9) and confirmed. It kept the certificate, the host keys, the account, slot 106, the host name, the session lock and SSH. The board's state after it differed from before only in its temporary IPv6 addresses, the system's version and sequence, and an encoder not started yet.
- Not run: the update from beta.8's system to this one.
scripts/check.sh passed on the source (the Rust tests and the page's contracts). For cargo audit, see the known limitations.
Known limitations
- On the operator's phone the page sometimes heard no answer to its pings for 6 to 7 s while it was shown, and the next connection opened within one or two seconds; the cause is not proven. The page now shows the last frame meanwhile, and the journal lines above are there to find it.
- RUSTSEC-2026-0385 (
ctutils0.4.2) is in the lock through the diagnostic journal's crates, which no program on the board carries (docs/third-party-rust.md). - When a page closes while it reads the update status, the status worker's instance can be left marked failed in systemd (
systemctl --failed); it has no other effect.
Everything else is as in beta.9 and beta.4: the capture's 1920x1080, the browsers upscaling was tried with, QUIC's requirements, the agent for Windows only, and the start line typed at the US layout's keys.
Files
hardened-blikvm-application-0.1.0-beta.10-seq106.tar: the signed application bundle (slot 106, commit3adbe43).hardened-blikvm-system-0.1.0-beta.10-seq10.tar: the signed RAW system update, sequence 10 (update runtime0.1.0~dev45, commit3adbe43).hardened-blikvm-h616-sd.img.zst: the card image of the same system, with slot 106;IMAGE-INFO.txtdescribes it.hardened-blikvm-agent.exe: the target agent for Windows x86-64, the same bytes as on the board's drive.SHA256SUMS: their checksums, and the unpacked image's.
The commits after these and the tag add only documents.
Keywords: BliKVM, BliKVM v4, Allwinner H616, KVM over IP, IP-KVM, IPKVM, KVM switch over the network, open-source KVM, hardware KVM, remote KVM, PiKVM alternative, NanoKVM, Hardened NanoKVM, Rust, web K...
Hardened BliKVM 0.1.0-beta.9
Superseded by 0.1.0-beta.10, which keeps remote control from a phone through QUIC reconnects without dropping input, shows the last frame while a session opens again, keeps the target agent's desktop layout on the board, turns the board's display the right way up and takes
rustls-webpki0.103.16 andtokio1.53.3. Use beta.10 for new cards and updates.
Ninth beta of Hardened BliKVM for the BliKVM v4 (Allwinner H616). It replaces 0.1.0-beta.8's application and 0.1.0-beta.4's card image and RAW system update. It is made of the fixes of a security review of beta.8 (2026-10-18) and of a code audit (2026-10-20), each verified against the device's model, in which the operator has full rights to the board; each fix comes with a test that failed before it. Beside the files is the target agent's program for Windows.
What changed since beta.8
- Logins and sessions.
- The login limiter counts every source whatever account name is tried, and a table full of lockouts still locks (before, it stopped counting).
- A new password needs the current one, and root's password follows the account's.
- Tightening the session lock caps every live session, a QUIC page's too.
- The terminal's password check cannot be raced past its lockout, and its password has a length cap.
- Two password changes at once can no longer leave the account and root with different passwords.
- Behind nginx. nginx reaches the web server through a Unix socket that serves nginx alone, and the server believes the forwarded client address only there. Before, a local process on the loopback port (the QUIC gateway, Janus, an encoder, PicoClaw's runtime) could guess passwords from a fresh address each time or lock the operator's out. Before every start of nginx the system puts its own nginx configuration back, with the HTTPS redirect the board's file has. nginx also takes only TLS 1.2 suites with forward secrecy.
- Virtual media.
- A link in the image store is refused, and the target is given the checked file itself.
- The store is sticky, and its catalog changes under a lock.
- An empty upload, or one refused after its file was replaced, no longer destroys the image of its name.
- An image swapped for a FIFO is refused at once.
- Remote ISO download. It runs as an account of its own that can write only the file the server prepared for it. It refuses glob characters, hostnames with a hyphen at a label's edge and redirects into private or special ranges. It ends within its transfer budget, and a file still being written is not taken.
- PicoClaw. It is installed by an installer with an account and a socket of its own; no image download writes its files. Its unit starts only a copy that root checked against the pinned release's size and SHA-256.
- The board's services.
- The board owner and the platform broker serve only their own peers.
- No root service reads a configuration from a directory another account may write.
- boardd survives a damaged status image, and keeps the fan cooling when the clock goes back.
- A network change made inside a confirmation window keeps the state the window opened with (IPv4 and Wi-Fi).
- A slow system setting (video, host name, SSH, QUIC, Tailscale) no longer holds up the keyboard and mouse.
- A firewall mode that cannot be stored is not applied.
- Shortcuts and Wake-on-LAN entries added at once are all kept.
- A mouse button released after a restart is released on both pointer devices.
- Video and QUIC.
- Janus has a loopback address of its own that no other service reaches.
- A QUIC session that ends hands back its keyboard lease, and a second connection of one session is refused.
- A key frame the encoder did not make is asked for again.
- A certificate set while the QUIC link comes up reaches the server.
- A certificate made while the clock was months behind is replaced.
- Target agent (Windows).
- While Windows is locked, it refuses the clipboard, the layout and the monitors.
- It loads
hid.dllfrom the system folder only and opens its channel unshared. - "Start the agent" runs only a file with the board's agent's SHA-256.
- Updates.
- A RAW update keeps the board's own application, journal and anti-rollback floor (from the RAW update after this one: see below).
- It checks the staged files' digests and the carried accounts both ways, takes one request at a time, and keeps the new image's nginx configuration.
- The running root's system sequence counts in the update checks.
- An interrupted copy or deletion no longer stops the application at every boot.
- The update journal is fitted by size.
- A failed start of the application at boot is tried again (at most four attempts in ten minutes).
- If a board loses power while a RAW update writes its root,
tools/image/restore_raw_backup.pywrites the root back from the backup on the card, with the card in a reader of another Linux computer.
The records, with the commit and the test of each fix and what was shown on the test board: audit-20261018-security-review.md and audit-20261020-code-review.md.
Update a running board
From beta.8 (beta.4's system), do the two steps in this order.
- The application. Upload
hardened-blikvm-application-0.1.0-beta.9-seq101.tarin Settings > Update. It brings the server, the board owner and the web interface. Until the next step, what needs the new system keeps beta.8's behaviour: nginx reaches the server over loopback TCP, PicoClaw is installed as before. - The system. In Settings > Update > System Update, turn on "Allow raw system updates", upload
hardened-blikvm-system-0.1.0-beta.9-seq9.tar(Upload and Verify), then Install. It brings the update runtime0.1.0~dev42. The board saves its settings, reboots, keeps the current system as a backup on the data partition, writes the new one and starts it. On the test board that took about 5 minutes to upload and verify and 34 to write and start. Keep power and the network connected: a board that loses power while its root is written does not start until the root is written back from that backup (see above). Then confirm the new system in the same section. Until it is confirmed, Rollback writes the old one back, and a new system that does not start within two boots is written back by itself.
The RAW update is written by the board's own boot step, which on beta.4's system is beta.4's. So this update carries what beta.4's carried: the accounts, root's password, the TLS certificate and SSH host keys, root's SSH keys, the machine id and host name, the network and Wi-Fi settings, the firewall mode, the administration features, the video and WebRTC settings and the engine choice, the display's sleep time, Tailscale's state, and the SSH, QUIC, Tailscale and mDNS switches. The board then runs the application the image carries (slot 101), which is why the application step comes first. This system's own boot step acts from the next RAW update: it also keeps the board's application, journal and floor, and checks more. nginx's configuration is the new system's after this update too: the system puts it back before nginx starts.
Write the card
The image needs a card of at least 32 GB. Check the download against SHA256SUMS first.
Linux or macOS:
zstd -dc hardened-blikvm-h616-sd.img.zst | sudo dd of=/dev/sdX bs=4M conv=fsync status=progress
Windows: unpack it with zstd -d hardened-blikvm-h616-sd.img.zst, then write hardened-blikvm-h616-sd.img with balenaEtcher or Rufus.
First boot
As in beta.4:
- Insert the card, connect Ethernet, power the board. The first boot creates the board's own SSH host keys, TLS certificate and identifiers, and gives the virtual media store the rest of the card; it takes about a minute.
- Open
https://<board address>/(the certificate is self-signed) and create the administrator account in First Setup. The password you choose there also becomes root's password (SSH); changing it later in Settings > Account changes both. - Until First Setup, root's password is
1234and an SSH login must change it. Whoever reaches the board first can complete First Setup, so do it on a trusted network.
The image starts clean: every administration feature off (QUIC among them), the firewall in Baseline, no Wi-Fi profiles, an empty image store, H.264 HW chosen, upscaling Auto. Card layout as in beta.1: 12 GiB system, 8 GiB data, the rest for virtual media images.
Checked
On the test board, at each step, the operator's settings and switches were compared before and after. The checks included the GUI at a desktop's and a phone's size, H.264 and VP8 over WebRTC, the H.264 picture over QUIC, the phone's touch reach, and nginx reaching the server only through its socket.
- Slot 101 was installed and confirmed on the system of the 2026-10-18 review (sequence 7, not published).
- That system's update runtime was then replaced by hand with this release's packages and the board rebooted. The first start of the application at that boot failed while the board was still starting; that is why a failed start is now tried again.
- RAW system updates of sequence 8 and then of this release's 9 were installed and confirmed. Each kept the certificate, the host keys, the account, the slot, the host name, the session lock and SSH.
- beta.8's nginx configuration (what beta.4's boot step carries) was put back on the board, and nginx's next start replaced it with the system's.
- Not run: slot 10...
Hardened BliKVM 0.1.0-beta.8
Superseded by 0.1.0-beta.9, which adds the fixes of a security review of beta.8 and of a code audit, with a new card image and RAW system update. Use beta.9 for new cards and updates.
An application release of Hardened BliKVM for the BliKVM v4 (Allwinner H616), for boards that run 0.1.0-beta.4's system (its card image, or its RAW system update). It has no card image: for a new card, write beta.4's image and upload this bundle in Settings > Update. Beside the bundle is the target agent's program for Windows. It fixes what a code review of beta.7 found, most of it in the target agent; each fix comes with a test that failed before it.
What changed since beta.7
- Updating the target agent. An agent of another version, started while an older one runs, takes its place, and the copy kept for the sign-in start is refreshed to the agent started last. Settings > Device and the agent's menu say when the agent is not the board's version, and "Update the agent on the target" starts the board's agent over it. Before, the older agent kept running and kept starting at sign-in, and the board's agent could not replace it.
- The target agent on Windows:
- the clipboard's text is read only within the block Windows hands over: a program on the target could leave text without its end on the clipboard, which crashed the agent or sent what followed it to the board;
- a monitors' change made just as an earlier one was being undone could make the earlier change permanent, a choice without a picture included; a change and its undo now wait for each other;
- only the agent of the session at the console serves the board: an agent left in a switched-away or remote session lets go of it;
- Keep, when nothing waits to be kept, is refused rather than answered as done.
- The page:
- the monitors' Keep waits for the agent's answer and says a failure while the countdown goes on, rather than closing at once; a change may take up to 10 s (it had 3 s), and the dialog says how long it took;
- the on-screen keyboard's switch of the target's layout takes remote control first, says a refusal and is asked again when control is taken again;
- "Start the agent on the target" times the Run box from when Win+R is sent, not from when it was queued, so a slow start no longer types the line into another window;
- the periodic read of the target's layouts no longer undoes a switch the page has just made.
- The board owner:
- a target agent's switch that fails to turn off leaves the channel as the switch says, and one that fails to turn on can no longer bring the agent's channel to the target later with the switch off;
- the agent's drive follows the switch also after a board update while the target had ejected the image, a medium the target ejected is not put back, and the drive goes at the owner's stop even when the virtual media cannot be rebuilt (a slot from before the agent, restored after a failed update, could not remove it and left the target without keyboard, mouse and media);
- a refusal from the target with an unexpected reason no longer leaves the agent's state unreadable (the page showed the switch off and disabled);
- a call to the agent that cannot be sent fails at once rather than after its time;
- a change of the virtual media that fails binds the USB device again.
Update from beta.7
Upload hardened-blikvm-application-0.1.0-beta.8-seq96.tar in Settings > Update. It brings the server, the board owner and the web interface; the system stays beta.4's.
The agent from beta.7 keeps running; connected to this slot, Settings > Device says it is not the board's version. Enable remote control, with the English layout in front on the target, and press "Update the agent on the target": the board's agent takes its place and, while the sign-in start is on, refreshes its copy. The program is not signed; its SHA-256 is in SHA256SUMS and on the drive, and it is built reproducibly from this source (scripts/build-target-agent.sh).
Checked
On the test board (beta.4's system) with this slot: every setting and switch as before the update, the board naming its commit to the agent, the agent's drive; the GUI at a desktop's and a phone's size without an API error, H.264 and VP8 over WebRTC, the H.264 picture over QUIC, the phone's touch reach. On the operator's target, Windows 11 Pro for Workstations 26H2: an agent of an older slot replaced through "Update the agent on the target" and its sign-in copy refreshed, "Start the agent on the target" connecting within 10 s, the on-screen keyboard's Russian after remote control was off and on, Keep after a click outside the window, a monitors' change taking about 3 s. Not checked on the target: an agent in a switched-away session (it needs a second Windows user) and the sign-in start across a restart. Records with their evidence: docs/baselines/audit-20261017-review.md. scripts/check.sh passed on the source. cargo audit reports beta.4's advisory RUSTSEC-2026-0009 in time 0.3.45 and four newer ones in rustls 0.23.45 (RUSTSEC-2026-0346 to 0349); both crates are linked only into the QUIC gateway, which is part of the system, not of this bundle nor of the agent, and none of the four in rustls is reachable there (docs/third-party-rust.md).
Known limitations
- The agent is for Windows; other systems come later.
- "Start the agent on the target" and "Update the agent on the target" type at the US layout's keys: the target's layout in front must be English.
- The on-screen keyboard does not follow a layout switched on the target itself (as by Alt+Shift): its keys then type what the target's layout has at them. Choose the keyboard's language as the target's, or switch the target's layout back.
Everything else, the card image, the RAW system update and the other known limitations, is as in beta.4.
Files
hardened-blikvm-application-0.1.0-beta.8-seq96.tar: the signed application bundle (slot 96, commitcc60094; the commits after it and the tag add only documents).hardened-blikvm-agent.exe: the target agent for Windows x86-64, the same bytes as on the board's drive.SHA256SUMS: their checksums.
Hardened BliKVM 0.1.0-beta.7
Superseded by 0.1.0-beta.8, which fixes what a code review of beta.7 found: updating the target agent and its sign-in copy, the agent's clipboard read and monitors' changes, the monitors' Keep, and the board owner's agent switch and drive. Use beta.8 for updates.
An application release of Hardened BliKVM for the BliKVM v4 (Allwinner H616), for boards that run 0.1.0-beta.4's system (its card image, or its RAW system update). It has no card image: for a new card, write beta.4's image and upload this bundle in Settings > Update. Beside the bundle is the target agent's program for Windows. (0.1.0-beta.6 was a development build of the test board and was not published.)
What changed since beta.5
- The target agent, for a Windows target (off by default). With the switch in Settings > Device, the board's mouse device also carries a channel to a small program on the target, and a read-only drive labelled
BLIKVMAGENTcarries that program. "Start the agent on the target" (Settings > Device) types its start line into the target; its icon's menu can start it at every sign-in. While it is connected and you control the target, the page knows:- the target's Windows, its monitors and its keyboard layouts;
- the Monitors menu on the toolbar says the mode the monitors are in and changes it as Windows does (duplicate, extend, only the board's monitor, only the others); a change is undone by itself after 15 s unless you keep it, so a choice that leaves the KVM without a picture comes back. Say there once which monitor is the board's: many captures give the target a copy of another monitor's EDID, which no program can tell apart. The absolute mouse then keeps to that monitor, extended, duplicated or alone, with no layout set by hand;
- the keyboard: the target's layout shown and switched from the Keyboard menu, and, as an option, switched to the letters you type, the phone's own keyboard included (English, Russian and Estonian);
- the clipboard's text both ways, and locking the session, each at your action.
The quality monitor's last row says the agent's state. The agent runs with the user's rights, opens no network connection and runs no command; every read and action is made under your remote control. Seedocs/design/target-agent-v1.md.
- The absolute mouse on a desktop of several monitors without the agent: the Mouse menu keeps the target's desktop layout on the board (
docs/design/screen-area-v1.md). - The on-screen keyboard sends a tapped modifier with the next key as a keyboard does: Ctrl+V and other shortcuts reached the target as a report the board refused, which also turned remote control off. A pressed modifier and, on a phone with the dark theme, every key were white on white; the Russian layout's letters were not sent.
- The board owner, started again with an image attached (as after an update), named the image as the kernel showed it from the former process and could not reconnect it.
Update from beta.5
Upload hardened-blikvm-application-0.1.0-beta.7-seq95.tar in Settings > Update. It brings the server, the board owner and the web interface; the system stays beta.4's.
To use the agent: turn on Settings > Device > Target agent (the board's USB device leaves the target and comes back), enable remote control, then "Start the agent on the target" (with the English layout in front on the target), or run hardened-blikvm-agent.exe from the BLIKVMAGENT drive. The program is not signed; its SHA-256 is in SHA256SUMS and on the drive, and it is built reproducibly from this source (scripts/build-target-agent.sh). Started from the board's drive it carries no mark of the web; downloaded from this page it does, and Windows SmartScreen may ask before it runs.
Checked
On the test board (beta.4's system) with this slot: the GUI at a desktop's and a phone's size without an API error, H.264 and VP8 over WebRTC, the H.264 picture over QUIC, the phone's screen layout. On the operator's target, Windows 11 Pro for Workstations 26H2 with two monitors of one EDID: the channel (round trip 2 ms; back within a second after a virtual media change), the agent's reads matching Windows' settings, the mouse on the board's monitor at its corners and middle from a desktop and a phone, the layouts, the monitors' modes with a change undone by itself, the clipboard both ways, locking, the drive appearing and "Start the agent" connecting within 10 s. The sign-in start was set and not checked across a restart of the target. Records with their evidence: docs/baselines/audit-20261014-target-agent.md. scripts/check.sh passed on the source; cargo audit reports beta.4's one advisory (RUSTSEC-2026-0009 in time 0.3.45, in the QUIC gateway, which is part of the system; docs/third-party-rust.md).
Known limitations
- The agent is for Windows; other systems come later.
- "Start the agent" types at the US layout's keys: the target's layout in front must be English.
- The sign-in start keeps a copy of the program that started it; turn it off and on again to keep a newer one.
Everything else, the card image, the RAW system update and the other known limitations, is as in beta.4.
Files
hardened-blikvm-application-0.1.0-beta.7-seq95.tar: the signed application bundle (slot 95, commit8dfb152; the commits after it and the tag add only documents and device probes).hardened-blikvm-agent.exe: the target agent for Windows x86-64, the same bytes as on the board's drive.SHA256SUMS: their checksums.
Hardened BliKVM 0.1.0-beta.5
Superseded by 0.1.0-beta.7, which adds the target agent for Windows (the Monitors menu, the mouse kept on the board's monitor, the target's keyboard layouts and clipboard), the absolute mouse on a desktop of several monitors and fixes of the on-screen keyboard. Use beta.7 for updates.
An application release of Hardened BliKVM for the BliKVM v4 (Allwinner H616), for boards that run 0.1.0-beta.4 (its card image, or its RAW system update). It has no card image: for a new card, write beta.4's image and upload this bundle in Settings > Update.
What changed since beta.4
- The quality monitor tells a QUIC frame's age right on every computer. The page answers the transport's pings on its own thread and draws the picture in a worker, and handed the times over by each context's time origin, which is the wall clock when that context began. Where the wall clock was stepped between the page's start and the picture's (a virtual machine, a clock corrected at once), every frame's age was off by that much for the page's life: on the virtual machine beta.4 was tested from, four seconds for a picture 60 ms old. The page now hands its times over by its monotonic clock. The picture itself was never late.
Nothing else changed: the upscaling, QUIC protocol 2, the bitrate share, the display's sleep and the rest are beta.4's.
Update from beta.4
Upload hardened-blikvm-application-0.1.0-beta.5-seq85.tar in Settings > Update. It brings the web interface.
A board on beta.3 or older takes beta.4's two steps first (its application and its RAW system update, which brings the QUIC gateway of protocol 2), then this bundle.
Checked
On the test board (beta.4's system) with this slot: the GUI at a desktop's and a phone's size with the quality monitor open, without an API error; H.264 and VP8 over WebRTC; the H.264 picture over QUIC for 30 s, frames 57 ms old when drawn from the same virtual machine that read four seconds with beta.4; the phone's screen layout. The operator looked at it on an Android phone (Chrome) and a desktop: every view upscaled smooth and without freezes, the pinch and the touches where they were made, the monitor fitting the phone. The page's contracts give the picture's worker a time origin 4 s off the page's: 6 ms with this release, 4006 ms without. scripts/check.sh passed on the source; cargo audit reports beta.4's one advisory (RUSTSEC-2026-0009 in time 0.3.45, in the QUIC gateway, which is part of the system; docs/third-party-rust.md).
Everything else, the card image, the RAW system update and the known limitations, is as in beta.4.
Files
hardened-blikvm-application-0.1.0-beta.5-seq85.tar: the signed application bundle (slot 85, commit04745b0; the tag adds only documents).SHA256SUMS: its checksum.
Hardened BliKVM 0.1.0-beta.4
Superseded by 0.1.0-beta.9, whose card image, RAW system update and application replace this release's. Use beta.9 for new cards and updates.
Fourth beta of Hardened BliKVM for the BliKVM v4 (Allwinner H616). It replaces 0.1.0-beta.3: the application, the card image and the RAW system update. It sharpens the picture where the browser enlarges it, by upscaling in the page (Auto by default where the browser draws with a GPU), moves the QUIC transport to its protocol 2 with the bitrate fitted to the slowest QUIC path, and lets the board's display go dark after a time without activity.
What changed since beta.3
- Sharp upscaling of the screen. Where the picture is shown larger than the capture's 1920x1080 (a 2560x1440 display, a pixel ratio of 2, a zoom), the browser stretched it, and the capture bridge's JPEG ringing grew with it. The page now draws it through a deringing pass and SGSR 1 (Snapdragon Game Super Resolution, BSD-3) in WebGL2, in every view: H.264 over QUIC, H.264 and VP8 over WebRTC, and MJPEG. On the real capture: SSIM 0.938 against bilinear's 0.906, edges rising in 1.78 px against 2.34, the halo one level above bilinear's; 0.27 ms a 2560x1440 frame on an RTX 3080 Ti and 1.09 ms on an Adreno 830, no frame lost over 30 s at 30 frames a second on either. The Screen menu has Upscaling: Auto (the default) upscales where the browser draws with a GPU and the picture is enlarged by more than 1.1, with a sharpness of low, medium or high, and shows the picture as large as the window or at a size you type (a 2560x1440 desktop's); Off draws as before. A watchdog switches it off for the page load, with a notice, when fewer than 90 % of the frames of five seconds were drawn; a browser that draws in software, has no WebGL2 or loses its context draws as before. Upscaling changes no colour: on the test board every view at 133 and 200 % came within a quarter of a level of its plain picture. The quality monitor's Extended view shows how the picture is drawn and the watchdog's count. Pointer and touch land where they are on the picture at 100, 150 and 200 % and pixel ratios 1 and 2.
- QUIC protocol 2. Each group of pictures travels on a QUIC stream of its own and every frame arrives (beta.3 sent delta frames as datagrams that were never sent again, so one lost packet broke the picture until the next key frame); congestion control is BBR; the page says each frame as it arrives, and the gateway judges by that what is still on its way. Through a relay on the host: 30 frames a second with 40 ms each way and 3 % or 10 % of the packets lost, the 95th percentile of the frames' age 151 and 197 ms, nothing given up and no key frame asked for (protocol 1: 7.5 frames a second at 3 %). The gateway is part of the system (the update runtime
0.1.0~dev38), so QUIC needs the system step below. - The H.264 bitrate follows the slowest QUIC path. Each QUIC session measures the queue in front of its page and asks for the share of the chosen bitrate its path carries; the board's one H.264 encoder runs at the chosen bitrate times the least share of the sessions that watch, never below a quarter, and comes back up by a fifth every 10 s once the page keeps up. Nothing is stored, the Screen menu's choice stays, and VP8 is not touched. A page frozen in the background (a phone with another app in front) holds nobody back. The quality monitor shows the share.
- The board's display goes dark after a time without activity, as in Hardened NanoKVM: Settings > Device > Display, never (the default, as before), 15 or 30 seconds, 1, 3, 5, 10 or 30 minutes, or an hour. Its backlight goes off and nothing is drawn; the board's button lights it again, held for two to three seconds.
- The quality monitor fits a phone. Its Extended view takes the phone's width and scrolls when its rows are more than the screen holds, wraps long values instead of cutting them, and shows the packets lost and how much of a second the page's own picture code took on its thread and in the QUIC worker.
- An enlarged picture opens at its middle. A plain view enlarged beyond the window opened at its left edge when its first frame came after the page had laid it out (also in beta.3), and the watchdog's switch to the plain path moved it there.
- The phone's cursor puts its tip where the target's cursor is, not its box's corner.
Update a running board
Do the two steps in this order.
- The application. Upload
hardened-blikvm-application-0.1.0-beta.4-seq84.tarin Settings > Update. It brings the web interface (upscaling, the monitor, the display's setting) and the board's services (the bitrate share, the display's sleep). Until the next step the board's QUIC gateway speaks the transport's older protocol: QUIC is unavailable and the page uses Standard (WebRTC). - The system. In Settings > Update > System Update, turn on "Allow raw system updates", upload
hardened-blikvm-system-0.1.0-beta.4-seq6.tar(Upload and Verify), then Install. It brings the update runtime0.1.0~dev38with the QUIC gateway of protocol 2. The board saves its settings, reboots, keeps the current system as a backup on the data partition, writes the new one and starts it: on the test board that took 7 minutes to upload and verify and 36 to write and start. Keep power and the network connected. Then confirm the new system in the same section; until it is confirmed, Rollback writes the old one back, and a new system that does not start within two boots is written back by itself.
What the RAW update carries: the accounts, root's password, the TLS certificate and the SSH host keys, root's SSH keys, the machine id and host name, the network and Wi-Fi settings, the firewall mode, the administration features, the video and WebRTC settings and the engine choice, the display's sleep time, Tailscale's state, and the SSH, QUIC, Tailscale and mDNS switches. The virtual media images are on their own partition, which it does not touch. It does not carry anything else of the old system: files in root's home other than .ssh, packages installed or files changed by hand.
The application step comes first because the RAW update of the published systems does not yet carry the application update's own records: after it the board runs the application this system carries (slot 84), with the board's own protected copies, which agree only when the board already ran that application.
Write the card
The image needs a card of at least 32 GB. Check the download against SHA256SUMS first.
Linux or macOS:
zstd -dc hardened-blikvm-h616-sd.img.zst | sudo dd of=/dev/sdX bs=4M conv=fsync status=progress
Windows: unpack it with zstd -d hardened-blikvm-h616-sd.img.zst, then write hardened-blikvm-h616-sd.img with balenaEtcher or Rufus.
First boot
- Insert the card, connect Ethernet, power the board. The first boot creates the board's own SSH host keys, TLS certificate and identifiers, and gives the virtual media store the rest of the card; it takes about a minute.
- Open
https://<board address>/(the certificate is self-signed) and create the administrator account in First Setup. The password you choose there also becomes root's password (SSH), as in Hardened NanoKVM; changing it later in Settings > Account changes both. - Until First Setup, root's password is
1234and an SSH login must change it. Whoever reaches the board first can complete First Setup, so do it on a trusted network.
The image starts clean: every administration feature off (QUIC among them), the firewall in Baseline, no Wi-Fi profiles, an empty image store, the capture at its defaults (30 frames/s), the bitrate at 2.5 Mbit/s, H.264 HW chosen, upscaling Auto in every browser, and the display never going dark.
Card layout
As in beta.1: 12 GiB system, 8 GiB data (update staging and the RAW update's backup), and the rest of the card for virtual media images; one image may have up to 64 GiB.
Checked
On the test board with this release's slot 84: the GUI at a desktop's and a phone's size with the quality monitor open, without an API error; H.264 and VP8 over WebRTC; the H.264 picture over QUIC for 30 s (no frame dropped, no packet lost); the phone's screen layout; the engine switched from the Screen menu each way over QUIC and over WebRTC; the display going dark and the button lighting it (by the operator). The picture of every video mode at 133 and 200 % with upscaling on against the MJPEG frame it shows, read at the same moment with the target's screen still: the upscaled picture within 0.22 levels of the plain one in every view and colour, and nowhere further from MJPEG than the plain path. On the operator's desktop (RTX 3080 Ti) and Android phone (Adreno 830, Chrome) every view upscaled without freezes, the pinch smooth and touches where they were made at 100, 200 and 400 %; on the phone the page's own picture code took about 1 % of a core with upscaling or without.
The RAW system update was installed on that board from this bundle, onto beta.3's system with slot 84, and confirmed: it came back with the same account, settings, switches, host keys, TLS certificate, machine id, network identity, image store, slots and the display's sleep time, and the QUIC picture 56 ms old when drawn. scripts/check.sh passed on the source (the Rust tests and the page's contracts); cargo audit reports the one advisory below.
Known limitations
- The capture is at most 1920x1080: the board's HDMI capture bridge, a MacroSilicon USB 2.0 device (the H616 has no USB 3), offers no larger mode, so a 2560x1440 desktop reaches the board as 1920x1080 at best. Upscaling sharpens what the browser enlarges; it does not bring back detail the capture did not take.
- Upscaling was tried with Chrome and Edge on a desktop and Chrome on an Android phone; Firefox a...
Hardened BliKVM 0.1.0-beta.3
Superseded by 0.1.0-beta.4, which adds sharp upscaling of the screen, QUIC protocol 2 with the H.264 bitrate fitted to the slowest QUIC path, and the board's display going dark after a time without activity. Use 0.1.0-beta.4 for new cards and updates.
Third beta of Hardened BliKVM for the BliKVM v4 (Allwinner H616). It replaces 0.1.0-beta.2, an application release, and the card image of 0.1.0-beta.1. It brings the encoders that say what their samples mean, so that every video mode is drawn as MJPEG is, as a new card image and, for the first time, as a RAW system update for a running board; and it fixes reboots from the page, which since beta.1 could lock the board out of every later reboot and RAW update.
What changed since beta.2
The video modes were drawn darker than MJPEG: the capture's JPEG frames are YCbCr of the full range (0 to 255) with the BT.601 matrix, the encoders pass them on unchanged, and browsers read them as the narrow range (16 to 235) and stretched them (docs/baselines/audit-20261006-colour-range.md). beta.2 fixed the QUIC picture in the page; this release fixes the rest.
- H.264 over WebRTC is drawn as MJPEG is. The video engine and x264 say the colour space in their streams. These encoders are part of the system: they come with this card image or this RAW system update, not with the application bundle. On the test board the picture was within half a level of the JPEG on average in each colour, against 5 to 10 levels darker before.
- VP8 is drawn as MJPEG is, where the browser draws with a GPU. VP8 cannot say what its samples mean, so the page undoes the browser's stretch with a table per colour channel as it draws the picture; black and white stay black and white, and colours come out 2 % less saturated than MJPEG's. On the test board: -0.96 / +0.16 / -0.55 levels in red, green and blue against the JPEG, -9.0 / -0.8 / -10.4 without the table. A browser that draws in software (no WebGL, or a software WebGL renderer such as SwiftShader or llvmpipe) is left drawing VP8 as before: there any filter on the picture cost Chromium about one processor core more at 1920x1080 and 30 frames a second, and frames. This is in the application bundle.
- A reboot from the page no longer locks out the next one. The board keeps a record of every reboot made from the page (Settings > Device > Reboot, a RAW update's install or rollback) until it is confirmed after the boot, and refuses another action while one is open. Nothing in beta.1 or beta.2 could confirm it while the board ran, so after one reboot from the page every later one, and every RAW install or rollback, was refused with
pending_unreconciled, power cycles included. Worse, beta.1's card image carried such an open record from the test board, so a beta.1 card refused even its first reboot from the page. Now the board's control service confirms the open record when you confirm the next action, if the board has started since; the record makes room for new entries instead of refusing everything after its sixteenth; and this card image starts with an empty one (docs/design/system-actions-v1.md). The first two are in the application bundle. - The SSH, QUIC, Tailscale and mDNS switches survive a RAW system update. They are held in system files, which a RAW update replaces, and the update of the published systems does not carry them: after it the switches were as the new image has them (SSH and Tailscale on, QUIC and mDNS off). The board's control service, which comes with the application bundle, now records them in its state, which the update carries, and sets them again at the first start of a new system. The page's System Update section said that switches are carried over: with this release's application that is true of these four too.
Update a running board
Do the two steps in this order.
- The application. Upload
hardened-blikvm-application-0.1.0-beta.3-seq78.tarin Settings > Update, as for beta.2. It brings the web interface (the VP8 table) and the board's services (the reboot fix and the switches' record). Without it a board that was ever rebooted from the page, and every beta.1 card, refuses the RAW install. - The system, if you want the fixed encoders without writing a new card. In Settings > Update > System Update, turn on "Allow raw system updates", upload
hardened-blikvm-system-0.1.0-beta.3-seq4.tar(Upload and Verify), then Install. The board saves its settings, reboots, keeps the current system as a backup on the data partition, writes the new one and starts it: on the test board that took 6.5 minutes to upload and verify and 36 to write and start. Keep power and the network connected. Then confirm the new system in the same section; until it is confirmed, Rollback writes the old one back, and a new system that does not start within two boots is written back by itself.
What the RAW update carries: the accounts, root's password, the TLS certificate and the SSH host keys, root's SSH keys, the machine id and host name, the network and Wi-Fi settings, the firewall mode, the administration features, the video and WebRTC settings and the engine choice, Tailscale's state, and (with this release's application) the SSH, QUIC, Tailscale and mDNS switches. The virtual media images are on their own partition, which it does not touch. It does not carry anything else of the old system: files in root's home other than .ssh, packages installed or files changed by hand.
The application step comes first also because the RAW update of the published systems does not yet carry the application update's own records: after it the board runs the application this system carries (slot 78), with the board's own protected copies, which agree only when the board already ran that application.
Write the card
The image needs a card of at least 32 GB. Check the download against SHA256SUMS first.
Linux or macOS:
zstd -dc hardened-blikvm-h616-sd.img.zst | sudo dd of=/dev/sdX bs=4M conv=fsync status=progress
Windows: unpack it with zstd -d hardened-blikvm-h616-sd.img.zst, then write hardened-blikvm-h616-sd.img with balenaEtcher or Rufus.
First boot
- Insert the card, connect Ethernet, power the board. The first boot creates the board's own SSH host keys, TLS certificate and identifiers, and gives the virtual media store the rest of the card; it takes about a minute.
- Open
https://<board address>/(the certificate is self-signed) and create the administrator account in First Setup. The password you choose there also becomes root's password (SSH), as in Hardened NanoKVM; changing it later in Settings > Account changes both. - Until First Setup, root's password is
1234and an SSH login must change it. Whoever reaches the board first can complete First Setup, so do it on a trusted network.
The image starts clean: every administration feature off (QUIC among them), the firewall in Baseline, no Wi-Fi profiles, an empty image store, the capture at its defaults (30 frames/s), the bitrate at 2.5 Mbit/s, and H.264 HW chosen.
Card layout
As in beta.1: 12 GiB system, 8 GiB data (update staging and the RAW update's backup), and the rest of the card for virtual media images; one image may have up to 64 GiB.
Checked
On the test board with this release's slot 78: the GUI at a desktop's and a phone's size (the desktop also with the quality monitor open) without an API error; H.264 and VP8 over WebRTC; the H.264 picture over QUIC; the phone's screen layout; the engine switched from the Screen menu each way over QUIC and over WebRTC; a reboot from the page's action, and the RAW install, each with an earlier reboot still open (refused before this release). The picture of every video mode against the MJPEG frame it shows, with the same page: H.264 over WebRTC +0.46 / -0.29 / +0.26 levels, over QUIC +0.25 / -0.33 / +0.10, VP8 with the table -0.96 / +0.16 / -0.55.
The RAW system update was installed on that board twice, each time from the card image made from it: an earlier build of this release onto beta.2's application, then this bundle onto slot 78. Both came back with the same account, settings, host keys, TLS certificate, machine id, network identity, image store and slots, and were confirmed. The first also set QUIC on again where the image has it off; the second, given a build of the release the board already ran, left it off (see the limitations), and it was switched back on in Settings. scripts/check.sh passed on the source (3321 Rust tests and the page's contracts); cargo audit reports the one advisory below.
Known limitations
- The capture is at most 1920x1080: the board's HDMI capture bridge, a MacroSilicon USB 2.0 device (the H616 has no USB 3), offers no larger mode, so a 2560x1440 desktop reaches the board as 1920x1080 at best.
- A RAW update knows a new system by its image's name, the release and the day of its build: installing the bundle of the release a board already runs leaves the SSH, QUIC, Tailscale and mDNS switches as the image has them. Going from one release to another is not affected.
- A moving picture reaches about 20 frames a second over WebRTC or QUIC, not the encoders' limit of 30: their frame gate admits a frame no sooner than a full interval after the one before (unchanged).
- To hold 1.5 or 2.5 Mbit/s on a fast-moving picture, the engine leaves frames out. The engine choice is the board's: H.264 SW makes x264 encode for every viewer.
- The encoder driver is built for the kernel the image boots (5.19.4-sunxi64); under another kernel x264 encodes.
- VP8 is drawn as MJPEG only where the browser draws with a GPU (tried with Chromium; Firefox and Safari not tried). Levels up to 16 are still drawn black and from 235 white.
- QUIC: lost fram...
Hardened BliKVM 0.1.0-beta.2
Superseded by 0.1.0-beta.3, which brings the fixed encoders as a card image and a RAW system update, draws VP8 as MJPEG is, and fixes reboots from the page, which could lock the board out of every later reboot and RAW update. Use beta.3 for new cards and updates.
An application release of Hardened BliKVM for the BliKVM v4 (Allwinner H616), for boards that run 0.1.0-beta.1. It has no card image: for a new card, write beta.1's image and upload this bundle in Settings > Update.
What changed since beta.1
The video modes were drawn darker than MJPEG, with crushed shadows and slightly other colours. The cause: the capture's JPEG frames are YCbCr of the full range (0 to 255) with the BT.601 matrix, the encoders pass them on unchanged, and no stream said so, so the browser read them as the narrow range (16 to 235) with the BT.709 matrix and stretched them. The encoders themselves are exact: the hardware encoder's decoded picture is its input within 0.04 levels on average (docs/baselines/audit-20261006-colour-range.md).
- H.264 over QUIC is drawn as MJPEG is. The page tells its decoder the board's colour space, so this works with beta.1's encoders too. On the test board with beta.1's encoder: the picture minus the JPEG was -4.8 / -5.2 / -10.0 levels in red, green and blue before, and +0.04 / -0.13 / +0.06 with this release.
- H.264 over WebRTC needs the fixed encoder, which is part of the system, not of this bundle (see below). The encoders of the next card image say the colour space in their streams (both the video engine and x264); with them the board's WebRTC H.264 picture was within 0.25 levels of the JPEG.
- VP8 has no way to say it and is still drawn darker.
Update from beta.1
Upload hardened-blikvm-application-0.1.0-beta.2-seq75.tar in Settings > Update. It brings the web interface and the web server.
The encoders, their units and the encoder driver belong to the system: a beta.1 card keeps its encoders after this update, so H.264 over WebRTC and VP8 stay darker than MJPEG on it until the next card image. QUIC is right at once; on a beta.1 board, QUIC with H.264 is the way to see the true picture.
Checked
On the test board with this slot: the GUI at a desktop's and a phone's size (the desktop also with the quality monitor open) without an API error, H.264 and VP8 over WebRTC, the H.264 picture over QUIC, the phone's screen layout, the engine switched from the Screen menu each way over QUIC and over WebRTC, and the picture of every video mode against the MJPEG frame it shows, with beta.1's encoder and with the fixed one. cargo audit on the lock reports the one advisory of beta.1 (RUSTSEC-2026-0009 in time 0.3.45, not reachable; docs/third-party-rust.md).
Everything else, the card image and the known limitations, is as in beta.1.
Files
hardened-blikvm-application-0.1.0-beta.2-seq75.tar: the signed application bundle (slot 75, commit3d0d118; the tag adds only documents).SHA256SUMS: its checksum.
Hardened BliKVM 0.1.0-beta.1
Superseded by 0.1.0-beta.3, whose card image and bundles replace this release's. A card written from this image refuses its first reboot from the page, and the RAW system update, until beta.3's application bundle is uploaded in Settings > Update: the image carried a record of the test board's that nothing could close (fixed in beta.3).
First beta of Hardened BliKVM for the BliKVM v4 (Allwinner H616). It replaces 0.1.0-alpha.10. The versions between, alpha.11 to alpha.17, were slots on the test board and were not published. It brings H.264 encoded by the H616's own video engine, a choice between the engine and x264 in the Screen menu, a quality monitor, and the fixes of a review of that work.
What changed since alpha.10
H.264 by the video engine (new):
- The H616's video engine encodes H.264 for WebRTC and for the QUIC transport, through a driver of this project (
hardened-blikvm-ve-enc, a kernel module under GPL-2.0-only, loaded by its own unit;docs/design/h616-ve-encoder-driver-v1.md). Where the engine is not there or fails three frames in a row, x264 encodes, as before. - Measured on the test board: the engine encodes a 1920x1080 frame in about 7 ms. At 30 frames a second of a moving 1920x1080 picture the H.264 encoder used 1.56 and 1.70 of the board's four cores with the engine; with x264 it used 3.07 and 3.27 and made only 18.8 and 12.5 of the 30 frames. Twelve hours on the engine passed without an encoder error or a line in the kernel's log from the driver or the engine.
- At 2.5 and 8 Mbit/s its picture is at most 0.2 dB (PSNR) below x264's on moving content, and well above it on text and a still desktop, where it spends the rate x264 leaves unused (
docs/design/h616-ve-h264-encoder.md).
The choice of the engine (new):
- The Screen menu has two H.264 entries, H.264 HW (the video engine) and H.264 SW (x264), for WebRTC and for QUIC. The choice is the board's, for every viewer, and kept across restarts; a viewer sees the switch within a second, and the stream goes on from a key frame.
- Where the engine cannot be had (busy, missing, or given up after failures), the menu says "x264 encodes" beside H.264 HW and its tooltip gives the reason; choosing H.264 HW again asks the encoder to try the engine again.
Quality monitor (new):
- QM on the toolbar opens a window over the picture, on the desktop and on a phone, that can be moved, resized, made opaque and hidden, and remembers its place. Basic shows what arrives: speed, delay (measured by the board's clock over QUIC, estimated over WebRTC and marked
~), the path, frames a second against the capture's, bitrate, codec with the engine, chroma. Extended adds the transport's counters, the board's capture and encoder (the stages' times, the engine's passes, the frame gate) with the encoder's share of the processors and the SoC's temperature, and the browser's decoder. - It asks the board (
GET /api/vm/quality) once a second and only while it is open. Its rows are drawn in a worker: the open monitor cost the page 0.1 to 0.4 ms a second, and the board half a percent of a core. - It needs a browser with workers and OffscreenCanvas; in another one the window says so in one line.
Fixes from a review of the above (docs/baselines/audit-20261004-review.md):
- A still picture gets a key frame every two seconds, as designed; before, about a third of them were delta frames, so the next key frame could be four seconds away.
- The quality monitor no longer loops, or takes the page down, in a browser without OffscreenCanvas or with workers refused; it is drawn again when the display's pixel ratio changes; the H.264 Direct path no longer shows another viewer's encoder; no rate is shown across a pause.
- The engine choice is offered only where the board's encoder takes it; two choices made at once can no longer leave the board's setting and the encoders apart; a refused choice is told in the page's own words.
- The encoder's demand socket skips an overlong line only up to 4 KiB, then closes the connection.
Update from alpha.10
- Upload
hardened-blikvm-application-0.1.0-beta.1-seq74.tarin Settings > Update. It brings the web interface and the web server: the quality monitor, and the Screen menu's engine choice where the system has this release's encoder. - The encoder driver, the encoders with the engine and their reports, their units and the web server's settings for them belong to the system, not the application: they come with the new card image. On an alpha.10 system, after the upload, x264 encodes as before, the Screen menu keeps one H.264 entry, and the quality monitor shows the page's own numbers and the capture's, not the encoder's.
Write the card
The image needs a card of at least 32 GB. Check the download against SHA256SUMS first.
Linux or macOS:
zstd -dc hardened-blikvm-h616-sd.img.zst | sudo dd of=/dev/sdX bs=4M conv=fsync status=progress
Windows: unpack it with zstd -d hardened-blikvm-h616-sd.img.zst, then write hardened-blikvm-h616-sd.img with balenaEtcher or Rufus.
First boot
- Insert the card, connect Ethernet, power the board. The first boot creates the board's own SSH host keys, TLS certificate and identifiers, and gives the virtual media store the rest of the card; it takes about a minute.
- Open
https://<board address>/(the certificate is self-signed) and create the administrator account in First Setup. The password you choose there also becomes root's password (SSH), as in Hardened NanoKVM; changing it later in Settings > Account changes both. - Until First Setup, root's password is
1234and an SSH login must change it. Whoever reaches the board first can complete First Setup, so do it on a trusted network.
The image starts clean: every administration feature off (QUIC among them), the firewall in Baseline, no Wi-Fi profiles, an empty image store, the capture at its defaults (30 frames/s), the bitrate at 2.5 Mbit/s, and H.264 HW chosen.
Card layout and uploads
- 12 GiB system, 8 GiB data (update staging), and the rest of the card for virtual media images: about 9 GiB on a 32 GB card, about 39 GiB on a 64 GB card.
- One image may have up to 64 GiB and a name of up to 128 characters (letters, digits, dots, dashes, underscores). The Download menu shows the free space and refuses a file that does not fit, or a name the board would refuse, before sending it; Cancel stops an upload.
Known limitations
- A moving picture reaches about 20 frames a second over WebRTC or QUIC, not the encoders' limit of 30: their frame gate admits a frame no sooner than a full interval after the one before, and with the capture running faster than that limit about twenty a second get through (found in the hardware work, not changed yet).
- To hold 1.5 or 2.5 Mbit/s on a fast-moving picture, the engine leaves frames out.
- The engine choice is the board's: H.264 SW makes x264 encode for every viewer, with more of the processors for fewer frames.
- The driver is built for the kernel the image boots (5.19.4-sunxi64, held by the package manager); under another kernel the engine is not there and x264 encodes.
- QUIC: lost frames are not sent again (on a path that loses 1% of its packets a moving picture of 30 frames a second keeps 23, with 3% lost 18; use Standard on a lossy path); it needs a browser with WebTransport that accepts a certificate by its hash and decodes H.264 in WebCodecs (Chrome, Edge, Firefox 156 were seen to); VP8 and MJPEG keep their own paths; control over QUIC with a real keyboard lease was tested on the development host against the real server and gateway, not on the board. After a boot with QUIC switched on, sessions can be refused with "clock" if the gateway started before the board's clock was set; switching QUIC off and on in Settings starts it again.
- The quality monitor needs workers and OffscreenCanvas. Its rows are drawn on a canvas: a screen reader gets the window's name and not the numbers.
- Time, NTP servers, the remote system log, autostart scripts and the OLED settings are shown read-only.
- No audio.
- H.264 needs a browser with an H.264 decoder (Chrome, Edge, Safari, Firefox); a Chromium build without one shows no picture in that mode, so use VP8 there.
- Tailscale peers reach the board through
tailscale0, which the Moderate, Restricted and Paranoid firewall modes block, as in the reference. WebRTC video is off in Restricted and Paranoid. - Updates are uploaded, not fetched from a feed. The application bundle updates the application only; the system's update runtime, the encoder driver, the QUIC gateway, the video encoders and their configuration change with a RAW system update or a new card.
- No HSTS header: the certificate is self-signed and changes with every new card.
- The web interface's npm dependencies have not been audited yet. The Rust dependencies have one RustSec advisory, RUSTSEC-2026-0009 in
time0.3.45 (a stack exhaustion when RFC 2822 dates from outside are parsed); it comes with the QUIC gateway's certificate code, which parses no such input (docs/third-party-rust.md). alpha.10 expected the fixed version with the next system build; this one still carries 0.3.45, because moving the lock needs the crate registry, which this build did not use. H.264 is covered by patent pools; VP8 is royalty-free. - This beta was verified on one board. On its own slot: the GUI at a desktop's and a phone's size, also with the quality monitor open, without an API error; H.264 and VP8 over WebRTC; the H.264 picture over QUIC; the phone's screen layout with the extra keys; the quality answer. On the test slot before it, with the same program code: the engine switched from the menu five times each way over QUIC and over WebRTC, each time within 0.7 s; a busy engine left to x264 with its reason and taken back with one click; ...
Hardened BliKVM 0.1.0-alpha.10
Superseded by 0.1.0-beta.1, which adds H.264 encoded by the H616's video engine, a choice between it and x264 in the Screen menu, a quality monitor, and the fixes of their review. Use beta.1 for new cards and updates.
Third published alpha of Hardened BliKVM for the BliKVM v4 (Allwinner H616). It replaces 0.1.0-alpha.2. The versions between, alpha.3 to alpha.9, were slots on the test board and were not published. This is an intermediate release: it brings a second transport, a faster picture and the changes to the interface since alpha.2.
What changed since alpha.2
QUIC transport (new, off by default):
- Beside the standard transport (HTTPS, and WebRTC for H.264 and VP8) the board can serve one WebTransport session over QUIC on UDP 443, which carries control, keyboard and mouse, and the H.264 picture. Turn on "QUIC on this device" in Settings > System > Network > Transport, then choose QUIC under "This browser uses"; the status line shows the transport in use with its round trip and counters, and the Screen menu says "H.264 (QUIC)". Standard stays the default, and the page falls back to it, with the reason shown, whenever the session cannot be made.
- What it changes, measured on the test board on the local network: a keyboard or mouse report and its answer take 2.2 to 2.5 ms instead of 15.3 to 15.7 ms (measured with reports the board refuses, because the probes take no control); a frame is drawn 1 ms after its first packet arrives instead of 28 ms (WebRTC keeps it in a jitter buffer); a key frame comes when the page asks for one. One UDP port is all it needs.
- Its limit: frames that are lost are not sent again. On a path that loses 1% of its packets a moving picture of 30 frames a second keeps 23, with 3% lost 18. Use Standard on a lossy path.
- The session is bound to the web login, uses TLS 1.3 with a certificate made in memory at every start (its hash reaches the page over HTTPS), and ends with the web session. The gateway is a process of its own under its own user.
- Firewall: Baseline and Moderate admit the port from the sources they admit. Restricted now admits it from the local ranges, so H.264 is available there over QUIC although WebRTC stays closed; Paranoid keeps it closed, and the page says why.
- Checked with Chromium 149 and Firefox 156 on the desktop. Safari and phones have not been checked by probes.
Video:
- The Screen menu's Quality sets the bitrate of H.264 and VP8 (1.5, 2.5, 5 or 8 Mbit/s) while the picture runs.
- Capture frames are decoded with libjpeg-turbo: preparing a 1920x1080 frame takes 25 ms instead of 45, and H.264 at that size reaches about 36 frames a second at 2.5 Mbit/s.
- The H.264 encoder no longer ends when the capture size changes under load, the picture comes back by itself after the encoder was started again, and a new viewer of a still screen gets its first picture at once instead of up to two seconds late.
Interface:
- Settings > Appearance: Dark, Light or the system's theme, and eight accent colours.
- On touch screens the menu bar hides after five seconds and returns from a tab at the top edge; the screen is laid out below it and above any keyboard, so every edge of a zoomed picture can be reached.
- A row of extra keys above the phone keyboard: Shift, Ctrl, Alt and Win (a tap holds one for the next key, a double tap keeps it), Esc, Tab, Enter, arrows, the navigation keys, F1 to F12, Ctrl+Alt+Del and more.
Documentation: the README describes the system as it is now (what it does, its processes and users, where the design notes are).
Update from alpha.2
- Upload
hardened-blikvm-application-0.1.0-alpha.10-seq65.tarin Settings > Update. It brings the web interface, the web server and the board owner: the themes, the phone keys, the menu bar and the firewall's rule for QUIC. - The QUIC gateway, the encoders with libjpeg-turbo and the live bitrate, and their units belong to the system, not the application: they come with the new card image. On an alpha.2 system the Transport section is not shown and the Screen menu's Quality changes nothing; everything else works.
Write the card
The image needs a card of at least 32 GB. Check the download against SHA256SUMS first.
Linux or macOS:
zstd -dc hardened-blikvm-h616-sd.img.zst | sudo dd of=/dev/sdX bs=4M conv=fsync status=progress
Windows: unpack it with zstd -d hardened-blikvm-h616-sd.img.zst, then write hardened-blikvm-h616-sd.img with balenaEtcher or Rufus.
First boot
- Insert the card, connect Ethernet, power the board. The first boot creates the board's own SSH host keys, TLS certificate and identifiers, and gives the virtual media store the rest of the card; it takes about a minute.
- Open
https://<board address>/(the certificate is self-signed) and create the administrator account in First Setup. The password you choose there also becomes root's password (SSH), as in Hardened NanoKVM; changing it later in Settings > Account changes both. - Until First Setup, root's password is
1234and an SSH login must change it. Whoever reaches the board first can complete First Setup, so do it on a trusted network.
The image starts clean: every administration feature off (QUIC among them), the firewall in Baseline, no Wi-Fi profiles, an empty image store, the capture at its defaults (30 frames/s), the bitrate at 2.5 Mbit/s.
Card layout and uploads
- 12 GiB system, 8 GiB data (update staging), and the rest of the card for virtual media images: about 9 GiB on a 32 GB card, about 39 GiB on a 64 GB card.
- One image may have up to 64 GiB and a name of up to 128 characters (letters, digits, dots, dashes, underscores). The Download menu shows the free space and refuses a file that does not fit, or a name the board would refuse, before sending it; Cancel stops an upload.
Known limitations
- QUIC: lost frames are not sent again (above); it needs a browser with WebTransport that accepts a certificate by its hash and decodes H.264 in WebCodecs (Chrome, Edge, Firefox 156 were seen to); VP8 and MJPEG keep their own paths; control over QUIC with a real keyboard lease was tested on the development host against the real server and gateway, not on the board.
- Time, NTP servers, the remote system log, autostart scripts and the OLED settings are shown read-only.
- No audio.
- H.264 and VP8 are encoded in software. At 1920x1080 H.264 reaches about 36 frames a second at 2.5 Mbit/s and about 20 at 8 Mbit/s, VP8 about 25; MJPEG passes on what the capture gives.
- H.264 needs a browser with an H.264 decoder (Chrome, Edge, Safari, Firefox); a Chromium build without one shows no picture in that mode, so use VP8 there.
- Tailscale peers reach the board through
tailscale0, which the Moderate, Restricted and Paranoid firewall modes block, as in the reference. WebRTC video is off in Restricted and Paranoid. - Updates are uploaded, not fetched from a feed. The application bundle updates the application only; the system's update runtime, the QUIC gateway, the video encoders and their configuration change with a RAW system update or a new card.
- No HSTS header: the certificate is self-signed and changes with every new card.
- The web interface's npm dependencies have not been audited yet. The Rust dependencies have one RustSec advisory, RUSTSEC-2026-0009 in
time0.3.45 (a stack exhaustion when RFC 2822 dates from outside are parsed); it comes with the QUIC gateway's certificate code, which parses no such input, and the fixed version follows with the next system build (docs/third-party-rust.md). H.264 (x264) is covered by patent pools; VP8 is royalty-free. - This alpha was verified on one board (the QUIC session in the Baseline, Restricted and Paranoid firewall modes, the H.264 picture over QUIC, H.264 and VP8 over WebRTC, the GUI at a desktop's and a phone's size without an API error). The image was built from that board after resetting its state and has not been booted from a new card yet.
Files
hardened-blikvm-h616-sd.img.zst: the SD card image (28 GiB unpacked), with slot 65.SHA256SUMS,IMAGE-INFO.txt: checksums and the image's layout.hardened-blikvm-application-0.1.0-alpha.10-seq65.tar: the signed application bundle (slot 65, commit4602d68; the tag adds only documents) for Settings > Update on an alpha.2 board.
