@@PRODUCT@@

Het auditlog controleren, exporteren en bewaken

Het auditlog is het bewijsstuk van dit paneel: wie wat deed, wanneer, en of het mocht. Deze pagina gaat over de drie dingen die daar omheen staan en die je tot nu toe alleen over SSH kon bereiken:

Geschreven voor: Beheerder

Het auditlog is het bewijsstuk van dit paneel: wie wat deed, wanneer, en of het mocht. Deze pagina gaat over de drie dingen die daar omheen staan en die je tot nu toe alleen over SSH kon bereiken:

  1. de keten — de controle die zegt of er iets in dat log is bijgewerkt;
  2. de export — het log als bestand, precies zo gefilterd als je het op het scherm hebt staan;
  3. de detectie — de nepgegevens (canaries) die verraden dat iemand met gestolen sleutels rondkijkt, en het alarmkanaal dat je daarover wekt.

De keten, de canaries en het alarmkanaal zijn beheerderswerk: je ziet ze alleen als Global admin. De export niet — die hoort bij het scherm en werkt voor iedereen die het auditlog mag lezen, altijd binnen het eigen bereik.

1. De auditketen

Ga naar Inzicht → Auditlog. Boven de tabel staat het blok Auditketen.

Elke regel in het log wordt bij het schrijven aan de vorige vastgehasht. Wie achteraf één regel bijwerkt, breekt de hash van die regel; wie er één weghaalt, laat de regel erna naar iets wijzen dat niet meer bestaat. Dat is wat "de keten verifiëren" nakijkt.

Wat de drie tegels zeggen

TegelBetekenis
GebeurtenissenHoeveel regels de keten dekt, en welk nummer de kop heeft.
Achterstand off-boxHoeveel regels de kopie op de buildserver nog niet gelezen heeft. Elke minuut haalt die machine op wat erbij kwam. Staat de teller stil, dan staat er staat stil bij — en dan is de kopie geen kopie meer.
Laatst geverifieerdHet antwoord van de vorige controle (intact of gebroken), met datum, aantal regels en hoeveel milliseconden het kostte.

Daaronder staat de kop-hash: de hash van de nieuwste regel. Die waarde wordt elke minuut naar de buildserver geschreven, op een machine waar dit paneel niet bij kan. Wie de hele keten herschrijft, maakt intern een kloppend geheel — maar verandert die waarde. Vergelijk hem daarom af en toe met de kopie:

# op panel1: wat het paneel zegt dat de kop is
ssh root@panel1.corecp.dev 'corecp-panel audit status'

# op de buildserver: wat er vanaf panel1 is aangeleverd
ssh root@build.corecp.dev 'tail -1 /srv/corecp/audit/panel1.corecp.dev/head.txt'

Verifiëren

Klik op Verifiëren. Het paneel vraagt eerst om een verse bevestiging van wie je bent (je authenticator-app of je passkey): een oordeel over bewijsmateriaal hoort van een sessie te komen die net heeft laten zien van wie hij is.

Daarna rekent de server de hele keten opnieuw uit en antwoordt in één zin:

  • De keten is intact — geen regel is bewerkt of verwijderd, en de kop hoort bij de nieuwste regel. Er staat bij hoeveel regels het waren en hoe lang het duurde (op een log van vijftigduizend regels is dat ongeveer twee seconden).
  • De keten klopt niet — er staat een tabel onder met elke regel die niet past: het nummer, wanneer hij geschreven is, welke handeling het was, en of hij bewerkt is (zijn eigen hash klopt niet meer) of dat de schakel weg is (zijn voorganger bestaat niet meer).

Krijg je dat tweede antwoord, ga dan niet verder werken op dit paneel: neem een kopie van de database, vergelijk de kop-hash met de buildserver, en volg docs/dr-runbook.md.

Hetzelfde vanaf de opdrachtregel, bijvoorbeeld in een cronjob:

ssh root@panel1.corecp.dev 'corecp-panel audit verify'
# exit 0 = intact, exit 1 = er is iets mis (en dan noemt hij het regelnummer)

Wie dit oordeel nog meer velt, en waarom dat dezelfde uitkomst geeft

De knop is niet de enige die deze vraag stelt. De maandelijkse hersteloefening op de buildserver zet de backup echt terug en controleert de keten in die kopie — dat is het bewijs dat het log ook ná een herstel nog klopt.

Belangrijk daarbij: beide stellen letterlijk dezelfde vraag. Het oordeel "past deze regel in de keten" staat in de database zelf, naast de hashfunctie waar het over gaat, en de knop en de oefening roepen allebei dát aan. Zo kan het niet gebeuren dat het paneel "intact" zegt terwijl de oefening dezelfde regels afkeurt.

Dat is niet theoretisch: precies dat gebeurde, omdat de oefening een oudere versie van de vraag had onthouden waarin regels op volgnummer werden vergeleken. Op een druk paneel is de volgorde van de nummers niet de volgorde van de keten — twee gelijktijdige handelingen krijgen hun nummer eerder dan hun plek in de keten — en dan noemt zo'n vergelijking gezonde regels kapot.

1b. Eén aanvraag terugvinden met het support-ID

Als het paneel iemand iets weigert, staat er onder de melding een support-ID: een kort kenmerk dat precies die ene aanvraag benoemt (zie Het support-ID bij een foutmelding). Wie een probleem meldt, wordt gevraagd dat door te geven. Hier gebruik je het.

Ga naar Inzicht → Auditlog en plak het kenmerk in het zoekveld. Er wordt ook op het support-ID gezocht, naast de operatie, de persoon en de reden, dus je krijgt de regel over precies die aanvraag: wat er werd geprobeerd, door wie, vanaf welk adres, en of het mocht.

Twee dingen zijn goed om te weten.

Het blijft binnen je eigen bereik. Zoeken op een kenmerk dat iemand je gaf, verbreedt niet wat je mag lezen. Een reseller die een kenmerk zoekt dat bij een aanvraag in een andere groep hoort, vindt niets — het zoekveld versmalt, het opent nooit iets.

Een tweede poging heeft een tweede kenmerk. Elke aanvraag krijgt een eigen kenmerk, dus wie twee keer op de knop drukte heeft er twee. Vraag om het kenmerk van de poging die diegene voor zich zag.

Is die ene regel niet genoeg, dan kan de paneelmachine de auditregels én de logregels van die ene aanvraag in één bestand verzamelen:

corecp-panel support bundle --config /etc/corecp-panel/panel.yaml \
    --request-id <kenmerk> --out /root/support-<kenmerk>.tar.gz

Wat er in dat bestand zit en waarom het veilig te versturen is, staat in Diagnosegegevens opsturen.

1c. Zoeken en filteren op het scherm

Boven de tabel staan twee dingen waarmee je het log kleiner maakt: een zoekveld en een keuzelijst met de uitkomst.

  • Het zoekveld kijkt naar de handeling, het onderwerp en de aanvrager. Typ je account.create, dan houd je alleen het aanmaken van accounts over; typ je een domeinnaam, dan houd je alles over wat aan dat domein is gedaan, door wie dan ook.
  • De keuzelijst heet Filter op uitkomst en heeft vier standen: alle uitkomsten, gelukt, geweigerd en mislukt. "Geweigerd" is de interessantste van de drie: dat zijn de handelingen die iemand probeerde en niet mocht.
Zoekveld:  account.create        Filter op uitkomst:  Geweigerd
→ elke poging tot het aanmaken van een account die is tegengehouden

Twee dingen die je hierbij moet weten. De filters gelden binnen je eigen bereik — je maakt de lijst kleiner, nooit groter, en een reseller ziet ook met een leeg filter alleen zijn eigen groep. En de export van de volgende paragraaf volgt exact deze twee instellingen, dus filteren vóór je exporteert scheelt je het werk achteraf.

Sinds ronde 5 zeggen beide bedieningselementen ook hardop waarop ze filteren. Dat is niet zichtbaar op het scherm — de naam staat er al boven — maar wél voor wie het paneel met een schermlezer bedient: die hoorde eerder alleen de gekozen waarde ("Alle uitkomsten") en nu ook waar die waarde bij hoort.

2. Het log als bestand

Rechtsboven op het auditscherm staan Exporteren als CSV en Exporteren als JSONL (op een telefoon onder het "…"-knopje).

Twee dingen zijn hier het vermelden waard.

Wat je downloadt is wat je op het scherm hebt staan. De zoekterm en het uitkomst-filter gaan mee in de download. Zoek je op account.create en exporteer je dan, dan zitten alleen die regels in het bestand.

En het is jouw bereik, niet dat van iemand anders. De server past dezelfde filter toe als op het scherm: een reseller krijgt de regels van zijn eigen groep, en niets daarbuiten. Een aangepaste link levert daar niets extra's mee op.

Het bestand is oudste-eerst geschreven, zodat je het kunt doorlopen of aanvullen. Bij heel grote logs stopt de export bij vijftigduizend regels; het zijn dan de nieuwste vijftigduizend, en op de laatste regel van het bestand staat dat het er meer waren. Voor het hele log gebruik je de opdrachtregel:

# alles vanaf gebeurtenis 0, als JSONL, in stukken van 5000
ssh root@panel1.corecp.dev 'corecp-panel audit export --since 0 --limit 5000' > audit.jsonl

Elke export schrijft zelf een auditregel (audit.export) met het aantal regels, het formaat en het gebruikte filter. Een kopie van het log die deze machine verlaat, hoort een spoor achter te laten.

3. Canaries en het alarmkanaal

Ga naar Instellingen → Platformbeveiliging. Onder het aanmeldbeleid staan twee blokken.

Canaries

Op drie plekken staat iets dat er echt uitziet en dat niets legitiems ooit gebruikt: een server die geen server is, een bootstrap-gegeven dat nooit aan een server is uitgegeven, en een API-token in panel.yaml waar niets aan is toegekend. Wie ze probeert, heeft ze ergens gevonden — en dat is meteen een alarm.

Het blok toont per canary waar hij ligt, hoe vaak hij is aangeraakt en wanneer dat het laatst was. Wat er nooit staat, is de waarde zelf: een canary werkt alleen zolang alleen een indringer hem tegenkomt. Ontbreekt het API-token-lokaas, dan zegt het scherm dat, met het commando erbij — dat lokaas moet in panel.yaml staan om gevonden te kúnnen worden, en een webverzoek mag dat bestand niet bewerken:

# op panel1, als root: plant wat er nog niet staat
corecp-panel canary ensure
corecp-panel canary status

Het alarmkanaal, en de test die het bewijst

Het tweede blok is het kanaal dat je wekt: waar een alarm heen gaat, hoe ver de classificatie door het auditlog is, wat er in de wachtrij staat en — de belangrijkste en saaiste van de drie — hoeveel berichten er niet afgeleverd in het spoolbestand liggen. Een groeiend spoolbestand betekent dat het kanaal stuk is en dat niemand dat te horen heeft gekregen, want het ding dat dat zou melden ís het kanaal.

Daarom staat er een knop Testalarm sturen. Die stuurt één bericht met TEST in het onderwerp naar de adressen uit panel.yaml, en het scherm zegt daarna of het is afgeleverd en waar. Ook hier vraagt het paneel eerst om een verse bevestiging: de knop maakt iemands telefoon aan het piepen, ook 's nachts.

Staat alarmering uit (alerting.enabled: false), dan weigert de knop met die reden in plaats van iets in een wachtrij te zetten dat toch niemand krijgt.

Hetzelfde vanaf de opdrachtregel:

ssh root@panel1.corecp.dev 'corecp-panel alert status'   # kanaal, wachtrij, spool
ssh root@panel1.corecp.dev 'corecp-panel alert test'     # één testbericht
ssh root@panel1.corecp.dev 'corecp-panel alert kinds --lang nl'  # wat er alarmeert, en waarom

Wat hier bewust niet staat

Noodtoegang (break-glass), de hoofdsleutel (KEK), de SSO-clients en de certificaatautoriteit hebben géén knop in het paneel — en dat blijft zo. Een noodsleutel die via het paneel loopt, werkt niet als het paneel het probleem is, en een sleutel die het vertrouwen van de hele vloot tekent, hoort niet vanuit een browsersessie bereikbaar te zijn. Wat het paneel daarvan wél toont is de stand van zaken, met het commando erbij; zie Beveiliging → Noodtoegang.

Een server die tijdens onderhoud wegviel

Zet je een server in onderhoudsmodus, dan gaan de meldingen over die server uit: er wordt niemand gebeld en er komt geen pushbericht als hij wegvalt. In het logboek staat het gewoon.

Dat is met opzet zo, en het is de reden om na een onderhoudsnacht juist hier te kijken. "Er is niemand gebeld" betekent niet "er is niets gebeurd": de regel dat de server om 04:12 niet meer antwoordde staat er, met dezelfde tijd en dezelfde reden als anders. Wat ontbreekt is het alarm, niet het feit.

Zoek op de server en op de tijd van de onderhoudsronde. Zie je daar meer dan je had verwacht — een dienst die wegviel en niet terugkwam, bijvoorbeeld — dan is dat precies wat een onderhoudsmodus voor je heeft opgevangen.