releases

VPN Works 0.5.0: Ledger Seals Each Run's Record and Names the Line Anyone Changed

VPN Works 0.5.0 brings Ledger back, as plugins. One seals every event of a run into a file as it happens. The other checks that file and names the line anyone changed.

After an incident, the record of where a program connected is the evidence. A plain log file can be edited by anyone who reaches it, and a careful edit leaves no mark. Ledger makes every edit leave one:

vpnw guard --plugin ledger --policy agent.toml -- ./my-agent
vpnw verify ~/.local/state/vpnw/ledger/r-3f9a1c.ledger

Ledger: the run’s events sealed into a hash-chained file as they happen, checkpoint copies kept in the trace, and vpnw verify naming the line that was changed

Sealed as It Happens

Each event goes into the ledger the moment it arrives, exactly as vpnw recorded it, with a SHA-256 hash that covers the line before it. Checkpoints every 100 events and an end line are links in the same chain. Change one byte, remove a line, add one, swap two, and the chain breaks at that line.

Ledger also copies each checkpoint into the run’s trace and prints the last hash when the run ends. Those copies, kept somewhere else, catch the one edit a chain alone can’t: a whole ledger written again from scratch.

A run killed halfway leaves a ledger that stops where the run did. Writes go straight to the file, so everything before that point is there, and still checks out.

Checked Line by Line

vpnw verify answers intact, CHANGED with the file and the line, or cut short when the ledger ends without its end line. The tests made 22 kinds of edit to a ledger, and 21 were reported as changes. 18 were named at the line where they were made. The other 3 cut off the end or wrote the whole ledger again, and the copies kept elsewhere caught them. The 22nd, removing only the end line with nothing kept elsewhere, looks the same as a run that was killed, and verify says it was cut short. With the trace beside it, that edit is a change too.

Before release, an independent review tried to slip edits past verify, and found four that got through: bytes added after the end line, a checkpoint removed, one added, and one removed with the rest renumbered. They’re fixed, mostly by making checkpoints and the end line links in the chain, and each is now a case in the tests. The review also caught one edit blamed on the wrong line, and lost events marked too early; both are fixed too.

A Permission Every Plugin Gets

Ledger has no way in that other plugins don’t. It writes its file through file.write, a new permission any plugin can ask for: vpnw creates one new file for it, and the plugin can only add to it. It can’t read the file, move around in it, or reach any other.

The checker uses another addition every Advisor can use: it’s handed the lines of its files exactly as they are on disk. And an Observer that falls behind the run is now told where events were lost, so Ledger marks the gap in its chain instead of skipping it.

Measured

What 0.5.0
Kinds of edit to a ledger 22, all reported: 21 as changes (18 named at their line), 1 as a run cut short
One event sealed by the Ledger plugin 0.13 ms
Test functions 144 of 144 passed
Ways out of the sealed sandbox 17 of 17 blocked, IPv6 included
Statements covered 83.1%
Fuzz targets 11, all clean

How it was measured: test/results

What It Doesn’t Do Yet

The 0.2.0 Ledger signed its checkpoints with Ed25519. This one doesn’t: signing needs a key a plugin can use without reading it, and the plugin interface has no such thing yet. And vpnw limits the network, not files, so the program being watched could rewrite its own ledger while it runs. Keep the last hash where it can’t reach.

Next is 0.6.0, Lab. Ledger · Roadmap · Download