Keeping Traffic Logs Is Not Enough — They Have to Be Provable
Summarising a logging obligation as "keep logs" is common and incomplete. The day a record is actually requested — an investigation, a court order, an audit — the file you hand over has to show two things: whose traffic it was, and that the record has not been altered since. In most organisations the first is missing and the second almost never exists.
Who is obliged to keep records, and for how long, is covered in guest WiFi and logging law. This post is about the next step: the technical structure that turns a record into evidence.
Gap one: an IP address is not an identity
Firewall logs produce lines like 10.20.4.37 → 93.184.x.x, 443/tcp, 21:14. On its own that line answers nothing, because who held 10.20.4.37 at 21:14 that evening is not recorded in it. On a guest network, addresses change hands constantly through DHCP; the same address is handed to dozens of people in a day.
To tie a record to a person, two data sets have to sit in the same place on the same timeline:
- Session records: which identity (phone number, room number, voucher, corporate account) was connected with which MAC address, holding which IP address, between which times.
- Traffic records: which IP address went where, and when.
Joined, they answer "at 21:14, 10.20.4.37 belonged to this identity". Kept in separate systems, that join is done by hand in a spreadsheet and usually takes hours — and if there is any clock drift between the two, it cannot be done at all.
Gap two: a file does not prove it was not edited
A text file in a folder cannot tell you whether it was edited later. Neither can the filesystem's modification time — that can be changed too. So a log you kept perfectly is still silent on the question that matters when it is offered as evidence: were these lines written that day, or added afterwards?
A daily hash chain
The answer is to seal the records day by day. A digest (SHA-256) is computed for each day's logs, and that digest is folded into the next day's computation. The days form a chain.
The consequence: anyone changing a single line in the past breaks that day's digest, and because the digest feeds the following day, every day after it breaks too. Quietly editing one line becomes impossible — the change takes the rest of the chain down with it and shows up the moment anything is verified.
Signature and trusted timestamp
The digest at the end of the chain is signed with a key (in Captivo, Ed25519). That proves who applied the seal.
One step further is having the time attested by an independent party. A timestamping authority does this under RFC 3161: you send the digest and receive a signed statement that this digest existed at that date and time. The record's date then rests on an official time source rather than on your server's clock.
What to watch when collecting syslog
- Synchronise clocks with NTP. If the firewall, the log server and the portal disagree on the time, the IP-to-identity join drifts. This is the hardest mistake to repair afterwards, because you cannot tell which record drifted by how much.
- Keep both pre-NAT and post-NAT addresses. With only the public address you cannot reach the internal user; with only the internal address you cannot match the external side.
- Plan retention and deletion together. Keeping records for the required period is one obligation; deleting them once the period passes is a separate one under data protection law. Doing either by hand does not last.
- Verify regularly. A hash chain first tried during an investigation, and found not to work, is no better than none. Verifying a random day once a month is a good habit.
With the Captivo Log Server
Captivo's 5651 Log Server module does all three jobs in one place: it collects and automatically parses syslog from pfSense, OPNsense, MikroTik, FortiGate, Cisco Meraki, UniFi and Ruijie, matches an IP address against the guest sessions held in the same system, and seals each day with a SHA-256 day chain and an Ed25519 signature. A TÜBİTAK KamuSM timestamp integration is available for those who need an official time source.
You can verify any day's signature from the panel in one click and download the archive. The module runs on a self-hosted (on-premise) installation, so the records never leave your own server — setup steps are on the On-Premise page.