NIS2, ISO 27001 & bewijsbeginner8 min lezen

NIS2-checklist voor de Belgische KMO: de tien maatregelen van artikel 21 vertaald naar concrete servertaken

NIS2 art. 21 §2 somt tien maatregelen op in juridisch Nederlands. Dit is de vertaling naar wat je maandag op je servers doet — per maatregel het commando, het bestand of het script dat het bewijs oplevert. Met de Belgische context: wet van 26 april 2024, CCB, CyberFundamentals en de registratieplicht.

Inhoud
  1. Eerst: de Belgische context in vijf punten
  2. De tien maatregelen, vertaald
  3. De checklist (om af te vinken)
  4. Valkuilen
  5. Wat je hiermee nog niet hebt
  6. Zo doet monsys het
  7. FAQ

De NIS2-richtlijn is in België omgezet door de wet van 26 april 2024, van kracht sinds 18 oktober 2024. Het Centrum voor Cybersecurity België (CCB) is de bevoegde autoriteit, en organisaties die onder de wet vallen moesten zich registreren op Safeonweb@Work. Sindsdien is de vraag in elke IT-afdeling van een "belangrijke" of "essentiële" entiteit dezelfde: wat moet ik nu concreet doen?

Dit artikel beantwoordt dat voor het serverpark. Het is geen juridisch advies en geen compliance-verklaring — of je entiteit onder de wet valt, in welke categorie, en of je maatregelen "passend en evenredig" zijn (de woorden van de wet), beoordeelt een jurist of een CyFun-geaccrediteerde auditor. Wat hier staat, is hoe je het technische bewijs klaarlegt zodat die beoordeling snel gaat.

Eerst: de Belgische context in vijf punten

  1. Twee categorieën. Essentiële entiteiten (grote bedrijven in sectoren als energie, transport, gezondheid, digitale infrastructuur) en belangrijke entiteiten (middelgrote in dezelfde sectoren, plus sectoren als post, afval, chemie, voeding, industrie, digitale diensten). De drempels zijn 50 medewerkers of € 10 miljoen omzet — dus veel KMO's vallen erónder, maar niet allemaal.
  2. CyberFundamentals (CyFun). Het CCB heeft een eigen raamwerk met drie niveaus: Basic, Important, Essential. Belangrijke entiteiten kunnen conformiteit aantonen via CyFun Important; essentiële via CyFun Essential of ISO 27001. Een CyFun-attest van een geaccrediteerde instelling geldt als vermoeden van conformiteit.
  3. Meldplicht. Een significant incident: early warning binnen 24 uur, incidentmelding binnen 72 uur, eindverslag binnen een maand. Via het CCB-meldplatform.
  4. Bestuurdersaansprakelijkheid. Het bestuur moet de maatregelen goedkeuren en toezien op de uitvoering, en opleiding volgen. Dat is nieuw en het is persoonlijk.
  5. Toezicht. Het CCB kan inspecteren, audits vragen en boetes opleggen (tot € 10 miljoen of 2 % omzet voor essentiële; € 7 miljoen of 1,4 % voor belangrijke).

De tien maatregelen, vertaald

Artikel 21 §2 van de richtlijn (overgenomen in de Belgische wet) noemt tien domeinen, (a) tot (j). Per domein: wat de wet zegt, wat dat op een server betekent, en het commando of bestand dat het bewijs is.

(a) Risicoanalyse en beveiligingsbeleid

Wet: beleid inzake risicoanalyse en beveiliging van informatiesystemen. Server: je kunt geen risico analyseren van wat je niet kent. Begin met een inventaris die je kunt reproduceren.

# Per host, wekelijks, in git of een gedeelde map:
{
  echo "host=$(hostname -f) date=$(date -Is)"
  echo "os=$(. /etc/os-release; echo "$PRETTY_NAME") kernel=$(uname -r)"
  echo "ip=$(hostname -I)"
  echo "--- listening"; ss -tulnH | awk '{print $1, $5}' | sort -u
  echo "--- services"; systemctl list-units --type=service --state=running --no-legend | awk '{print $1}'
  echo "--- packages"; dpkg-query -W -f='${Package} ${Version}\n' | wc -l
  echo "--- users"; awk -F: '$3>=1000 && $7!~/nologin|false/{print $1}' /etc/passwd
} > "/srv/inventory/$(hostname -s)-$(date +%F).txt"

De risicoanalyse zelf is een document (welke systemen, welke dreigingen, welke impact, welke maatregel). Dat schrijf je niet in bash. Maar elke regel in dat document verwijst naar een asset uit deze inventaris — dat is de koppeling die een auditor zoekt.

(b) Incidentbehandeling

Wet: procedures voor het behandelen van incidenten. Server: je moet incidenten kunnen zien (detectie), reconstrueren (logs die lang genoeg bewaard blijven) en melden (binnen 24 u).

# Logs lang genoeg bewaren (journald): minstens 90 dagen, liefst 12 maanden voor auth
sudo mkdir -p /etc/systemd/journald.conf.d
sudo tee /etc/systemd/journald.conf.d/retention.conf >/dev/null <<'EOF'
[Journal]
Storage=persistent
SystemMaxUse=2G
MaxRetentionSec=365day
EOF
sudo systemctl restart systemd-journald

# Tijd moet kloppen, anders is elke tijdlijn waardeloos
timedatectl show -p NTPSynchronized -p Timezone

Detectie: zie de how-to's over SSH brute-force en honeypot-bestanden. De procedure (wie belt wie, wie meldt bij het CCB, waar staat het formulier) is een A4 dat aan de muur hangt — en dat je één keer per jaar oefent.

(c) Bedrijfscontinuïteit: back-up, herstel, crisisbeheer

Wet: bedrijfscontinuïteit, zoals back-upbeheer en noodvoorzieningenplannen. Server: een back-up die je nooit hebt teruggezet, is een hypothese.

# Bewijs 1: back-up is recent
restic -r /srv/backup snapshots --latest 1 --json | jq -r '.[0].time'
# Bewijs 2: back-up is leesbaar (steekproef 5 % van de data)
restic -r /srv/backup check --read-data-subset=5%
# Bewijs 3: restore-test, met datum en resultaat gelogd
restic -r /srv/backup restore latest --target /tmp/restore-test --include /etc/nginx \
  && echo "$(date -Is) restore-test OK nginx-config" >> /srv/inventory/restore-tests.log

Kwartaal-ritme: één volledige restore-test van een echte service naar een testomgeving. Zie back-ups controleren die "geslaagd" zeggen.

(d) Beveiliging van de toeleveringsketen

Wet: beveiliging van de toeleveringsketen, inclusief de relatie met directe leveranciers. Server: weet welke software van derden je draait en welke kwetsbaarheden die meebrengt — OS-packages én applicatie-dependencies.

# OS-laag: zie de OSV-how-to; kort samengevat
dpkg-query -W -f='${source:Package} ${source:Version}\n' | sort -u > /srv/inventory/$(hostname -s)-packages.txt
# Applicatie-laag: lockfiles zijn je SBOM-light
find /srv /var/www /opt -maxdepth 4 \( -name package-lock.json -o -name requirements.txt -o -name composer.lock -o -name go.sum \) 2>/dev/null

De contractuele kant (welke eisen stel je aan je leveranciers, hebben ze zelf een NIS2- of ISO-verklaring) is een lijst in je leveranciersregister. De technische kant is een CVE-scan met datum.

(e) Verwerving, ontwikkeling en onderhoud; kwetsbaarheidsbeheer

Wet: beveiliging bij verwerving, ontwikkeling en onderhoud, met inbegrip van de respons op kwetsbaarheden en de openbaarmaking ervan. Server: patchen, met een aantoonbare doorlooptijd.

# Automatische security-updates aan
sudo apt install -y unattended-upgrades
grep -E '^Unattended-Upgrade::Allowed-Origins|security' /etc/apt/apt.conf.d/50unattended-upgrades | head -3
# Bewijs: wanneer werd wat geïnstalleerd
grep -h 'status installed' /var/log/dpkg.log* | awk '{print $1, $5, $6}' | sort | tail -20
# Openstaande updates en reboot-status
apt list --upgradable 2>/dev/null | wc -l; [ -f /var/run/reboot-required ] && echo REBOOT-REQUIRED

Zie unattended-upgrades goed configureren. Een auditor vraagt naar de tijd tussen publicatie van een fix en installatie. dpkg.log geeft de installatiedatum; de USN geeft de publicatiedatum.

(f) Beoordeling van de doeltreffendheid

Wet: beleid en procedures om de doeltreffendheid van de maatregelen te beoordelen. Server: meet. Een maatregel zonder metriek is een intentie.

MaatregelMetriekBron
Patchingdagen tussen USN en installatie, p50 en p95dpkg.log + USN-datum
Back-up% dagen met geslaagde back-up; laatste restore-testrestic snapshots + restore-log
Detectieaantal detecties per maand; % binnen 1 u bekekenntfy-log / ticketsysteem
Toegangaantal accounts; % met MFA; datum laatste review/etc/passwd, IdP, review-log

Eén pagina, elk kwartaal bijgewerkt, ondertekend door de verantwoordelijke. Dat is "beoordeling van de doeltreffendheid".

(g) Cyberhygiëne en opleiding

Wet: basispraktijken inzake cyberhygiëne en opleiding. Server: de basis is niet spannend, en precies daarom wordt ze overgeslagen.

# Geen wachtwoord-SSH, geen root-login
sshd -T | grep -E '^(passwordauthentication|permitrootlogin) '
# Firewall aan, default deny
sudo ufw status verbose | head -4
# Geen accounts zonder wachtwoord of met lege shell-restricties
sudo awk -F: '($2=="" || $2=="!") {print "no-password:", $1}' /etc/shadow
# Screen-lock / sessietime-out op servers: TMOUT in /etc/profile.d
grep -rh TMOUT /etc/profile.d/ 2>/dev/null

Opleiding: de wet vraagt dat ook het bestuur wordt opgeleid. Bewaar de aanwezigheidslijst.

(h) Cryptografie en encryptie

Wet: beleid inzake het gebruik van cryptografie en, waar passend, encryptie. Server: TLS overal, geen verlopen certificaten, versleutelde back-ups en schijven.

# Welke certificaten draaien er, en wanneer verlopen ze? (elke TLS-poort die luistert)
for port in $(ss -tlnH | awk '{sub(/.*:/,"",$4); print $4}' | sort -un); do
  end=$(echo | timeout 3 openssl s_client -connect "localhost:$port" -servername "$(hostname)" 2>/dev/null \
        | openssl x509 -noout -enddate 2>/dev/null) && echo "port $port: $end"
done
# TLS-configuratie: geen TLS 1.0/1.1
nmap --script ssl-enum-ciphers -p 443 localhost 2>/dev/null | grep -E 'TLSv1\.[01]' && echo "OUD PROTOCOL ACTIEF"
# Back-up versleuteld? (restic: altijd; rsync: niet)
restic -r /srv/backup cat config >/dev/null 2>&1 && echo "restic repo: versleuteld"
# Schijfencryptie
lsblk -o NAME,TYPE,FSTYPE | grep -i crypt

Zie TLS-certificaten die stil verlopen voor de fleet-brede versie.

(i) Personeelsbeveiliging, toegangsbeleid en activabeheer

Wet: beveiligingsaspecten ten aanzien van personeel, toegangsbeleid en beheer van activa. Server: wie heeft toegang, waarom, en sinds wanneer — en wordt dat elk kwartaal nagekeken?

# Alle interactieve accounts, met laatste SSH-login uit de journal
# (lastlog/wtmp zijn op Ubuntu ≥ 24.04 niet meer betrouwbaar; de journal wel)
for u in $(awk -F: '$3>=1000 && $7!~/nologin|false/{print $1}' /etc/passwd); do
  last=$(journalctl -u ssh --since "365 days ago" --no-pager -o short-iso 2>/dev/null \
         | grep -E "Accepted (publickey|password) for $u " | tail -1 | awk '{print $1}')
  printf '%-16s last=%s\n' "$u" "${last:-never}"
done
# Wie mag sudo?
getent group sudo admin wheel 2>/dev/null
grep -rhE '^[^#].*ALL' /etc/sudoers /etc/sudoers.d/ 2>/dev/null
# Welke SSH-keys zijn geautoriseerd, en van wie?
for d in /root /home/*; do [ -f "$d/.ssh/authorized_keys" ] && { echo "== $d"; awk '{print $NF}' "$d/.ssh/authorized_keys"; }; done

Elk kwartaal: deze output naast de personeelslijst leggen, elke afwijking verklaren of verwijderen, en het resultaat met datum en handtekening bewaren. Dat is een access review, en het is het bewijsstuk dat het vaakst ontbreekt.

(j) Multifactorauthenticatie en beveiligde communicatie

Wet: gebruik van MFA of continue authenticatie, beveiligde spraak-, video- en tekstcommunicatie, en beveiligde noodcommunicatie. Server: SSH met keys is één factor (iets dat je hebt). Voor beheer-toegang wil je er twee.

# Optie 1: key + TOTP via PAM (google-authenticator-libpam, geen Google-dienst nodig)
sudo apt install -y libpam-google-authenticator
# per beheerder: google-authenticator -t -d -f -r 3 -R 30 -W
# in /etc/pam.d/sshd:  auth required pam_google_authenticator.so
# in sshd_config.d:    KbdInteractiveAuthentication yes
#                      AuthenticationMethods publickey,keyboard-interactive
# Optie 2: SSH-certificaten met korte TTL vanuit een CA achter je IdP (MFA gebeurt bij de IdP)
# Bewijs: welke methode is afgedwongen?
sshd -T | grep -iE '^authenticationmethods'

Beveiligde noodcommunicatie: als je e-mail en Teams plat liggen door het incident, hoe bereik je elkaar? Een Signal-groep met de nummers op papier is een geldig antwoord. Schrijf het op.

De checklist (om af te vinken)

#MaatregelServer-bewijs klaar?Frequentie
aInventaris per host, gekoppeld aan risicoanalyse☐wekelijks automatisch
bLogretentie ≥ 90 d, NTP gesynchroniseerd, detectie actief, meldprocedure op A4☐continu / jaarlijkse oefening
cBack-up recent + check + restore-test gelogd☐dagelijks / kwartaal
dPackage-inventaris + CVE-scan met datum; leveranciersregister☐wekelijks
eunattended-upgrades aan; dpkg.log bewaard; reboot-required bewaakt☐continu
fMetriek-pagina met vier KPI's, ondertekend☐kwartaal
gKey-only SSH, firewall default-deny, geen lege wachtwoorden; opleidingslijst☐continu / jaarlijks
hCert-inventaris + verloopalert; TLS ≥ 1.2; versleutelde back-ups☐continu
iAccess review: accounts, sudo, SSH-keys naast personeelslijst☐kwartaal
jMFA op beheer-toegang afgedwongen; noodcommunicatie beschreven☐continu

Valkuilen

  • Denken dat CyFun Basic genoeg is. Basic is voor micro-organisaties en niet-NIS2-entiteiten. Belangrijke entiteiten zitten op Important, en dat niveau vraagt expliciet om logging, kwetsbaarheidsbeheer en MFA.
  • Beleid zonder bewijs. Een prachtig informatiebeveiligingsbeleid in Word is stap één. De auditor vraagt: "laat me zien dat het draait". Elk commando in dit artikel is dat "laten zien".
  • Bewijs zonder datum. Een screenshot van apt list --upgradable zonder timestamp bewijst niets. Alles wat je bewaart, krijgt een date -Is erbij en gaat in een map die je niet meer aanpast.
  • De 24-uursmelding vergeten te oefenen. Wie belt het CCB als de IT-verantwoordelijke op vakantie is? Als het antwoord "euh" is, is de procedure niet af.
  • Leveranciers vergeten. Je cloudhoster, je MSP, je SaaS-boekhouding: NIS2 vraagt dat je hun beveiliging beoordeelt. Vraag hun verklaring op en bewaar ze.

Wat je hiermee nog niet hebt

Elk commando hierboven werkt op één server. Bij tien servers heb je tien inventarissen, tien package-lijsten, tien access-review-outputs — en de vraag "is alles gedekt?" is een spreadsheet die iemand bijhoudt. Bij dertig servers houdt niemand die spreadsheet bij. En het bewijs dat je verzamelt, is pas bewijs als je kunt aantonen dat het niet achteraf is aangepast — een map met tekstbestanden is dat niet.

Zo doet monsys het

monsys mapt elke NIS2-maatregel (en de ISO 27001- en CRA-controls) op een evidence query die continu over alle hosts draait: inventaris, patchstatus, CVE's, back-up-versheid, certificaten, accounts, MFA-status, detecties. Het resultaat is per control een dekkingspercentage en een maandelijks audit pack — Ed25519-ondertekend, byte-stabiel, offline verifieerbaar — dat je aan een CyFun-auditor of het CCB geeft. Een control die bewijs verliest (een host waar unattended-upgrades uitvalt) geeft een compliance erosion-alert vóór de auditor het ziet. monsys beoordeelt niet of je conform bent; het zorgt dat het bewijs er is als iemand het vraagt.

FAQ

Valt mijn KMO onder NIS2?

Dat hangt af van sector en grootte (vanaf 50 medewerkers of € 10 miljoen omzet in een NIS2-sector, met uitzonderingen naar beneden voor sommige sectoren zoals DNS en trust services). Het CCB heeft een zelftest op Safeonweb@Work. Bij twijfel: vraag het een jurist; de registratieplicht ligt bij jou.

Is ISO 27001 hetzelfde als NIS2-conform?

Nee, maar het helpt. Voor essentiële entiteiten aanvaardt het CCB een ISO 27001-certificaat als vermoeden van conformiteit, mits de scope klopt. Voor belangrijke entiteiten is CyFun Important de referentie. De technische maatregelen overlappen grotendeels; de meldplicht en de bestuurdersverplichtingen komen er bovenop.

Hoe snel moet ik een incident melden?

Early warning binnen 24 uur nadat je kennis hebt van een significant incident, volledige melding binnen 72 uur, eindverslag binnen een maand. Wat "significant" is, staat in de wet (ernstige operationele verstoring of financieel verlies, of aanzienlijke schade aan anderen). Bij twijfel: melden.

Geschreven door het monsys-team — sysadmins die dit dagelijks doen.

Zelf gedaan? Laat monsys het bijhouden.

Alles uit deze how-to draait in monsys als doorlopende check, met historie, alerts en audit-bewijs. 5 servers gratis, EU-gehost in België, geïnstalleerd in 60 seconden.