Automating Security Compliance: Surviving the Datatilsynet Audit with Infrastructure as Code
Most sysadmins lie. When the auditor asks if every single server has the latest kernel patch or if root login is disabled across the entire fleet, the answer is usually a confident "yes," followed by a frantic check of the inventory spreadsheets. In 2023, with the Datatilsynet (Norwegian Data Protection Authority) tightening the screws on GDPR enforcement and the Schrems II ruling making data transfers a legal minefield, relying on manual checklists is professional suicide.
Compliance isn't a PDF you sign once a year. It is a technical state of being. If you cannot prove your infrastructure's security posture via code, you are already non-compliant.
I recently inherited a chaotic infrastructure for a fintech client based in Oslo. They had data scattered across three different cloud providers, root keys circulating in Slack, and a pending audit. The solution wasn't a consulting firm; it was Compliance as Code. Here is how we automated the hardening process to meet CIS Benchmarks, strictly on Norwegian soil.
The Foundation: Isolation Matters
Before writing a single line of code, look at your virtualization. Many "cheap" VPS providers use container-based virtualization (like OpenVZ or LXC) where you share the kernel with neighbors. From a security compliance perspective, this is a nightmare. A kernel panic or a container escape vulnerability affects everyone on the node.
For strict compliance, you need KVM (Kernel-based Virtual Machine). This provides hardware-level isolation. At CoolVDS, we enforce KVM on all instances. It means your memory, CPU instructions, and kernel modules are yours. No noisy neighbors, no shared vulnerabilities. When an auditor asks about tenant isolation, "We use KVM" is the only acceptable answer.
Step 1: The Automated Hardening Pipeline
We don't manually edit /etc/ssh/sshd_config anymore. We use Ansible. This ensures that every node, from the load balancer to the database replica, adheres to the exact same standard.
Here is a production-ready Ansible task snippet that enforces SSH hardening standards compatible with CIS benchmarks. This disables empty passwords, root login, and enforces protocol 2.
- name: Harden SSH Configuration
hosts: all
become: yes
tasks:
- name: Update SSHD configuration
lineinfile:
path: /etc/ssh/sshd_config
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
state: present
validate: '/usr/sbin/sshd -t -f %s'
loop:
- { regexp: '^PermitRootLogin', line: 'PermitRootLogin no' }
- { regexp: '^PasswordAuthentication', line: 'PasswordAuthentication no' }
- { regexp: '^PermitEmptyPasswords', line: 'PermitEmptyPasswords no' }
- { regexp: '^Protocol', line: 'Protocol 2' }
- { regexp: '^MaxAuthTries', line: 'MaxAuthTries 3' }
notify: restart sshd
handlers:
- name: restart sshd
service:
name: sshd
state: restarted
This script does two critical things: it applies the config and validates it before restarting the service. If you break the config, SSH doesn't restart, and you don't get locked out. That is operational maturity.
Step 2: Kernel & Network Tuning
Default Linux network stacks are tuned for compatibility, not security. To prevent IP spoofing and Man-in-the-Middle attacks, we need to manipulate the sysctl settings. Doing this manually on 50 servers is impossible. Doing it via an initialization script is reliable.
Use this configuration to prevent source routing and redirect acceptance:
# /etc/sysctl.d/99-security.conf
# IP Spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Ignore ICMP broadcast requests
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Disable source packet routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
# Disable send redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
Apply these immediately without rebooting using:
sysctl -p /etc/sysctl.d/99-security.conf
Pro Tip: On CoolVDS NVMe instances, tweaking vm.swappiness down to 10 often improves database performance significantly because our I/O throughput is high enough that we want to avoid swap unless absolutely necessary.
Step 3: Auditing with OpenSCAP
How do you prove to the auditor that the above settings are active? You scan. OpenSCAP is the industry standard for verifying compliance against CIS profiles.
First, install the scanner and the security guides (on RHEL/CentOS/AlmaLinux systems):
yum install openscap-scanner scap-security-guide
Now, run a scan against the "Standard" profile and generate an HTML report. This report is what you hand to the Datatilsynet auditors.
oscap xccdf eval \
--profile xccdf_org.ssgproject.content_profile_standard \
--results scan-results.xml \
--report report.html \
/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml
If you see red on that report, you fix the Ansible playbook, run it again, and re-scan. This is the loop. Scan, Patch, Verify.
Step 4: File Integrity Monitoring (FIM)
Compliance requires knowing when a critical file changed. auditd is the Linux kernel's audit subsystem. It logs system calls. It is verbose, but necessary.
To monitor changes to the /etc/passwd file (where users are defined), add this rule:
-w /etc/passwd -p wa -k identity_changes
This command breaks down as follows:
-w: Watch this file.-p wa: Trigger on write or attribute change.-k: Key name for searching logs later.
To search for these events later:
ausearch -k identity_changes | aureport -f -i
The Data Sovereignty Factor
Technical hardening is useless if the legal framework of the data center fails. Under GDPR and Schrems II, storing personal data of Norwegian citizens on US-controlled cloud infrastructure is risky. Even with "European Regions," the US CLOUD Act can compel data access.
This is where local hosting becomes a compliance feature. CoolVDS infrastructure is physically located in Europe, often leveraging low-latency connections to NIX (Norwegian Internet Exchange). When we say your data is in Norway/Europe, it stays there. The latency benefits (often sub-10ms to Oslo) are just a bonus on top of the legal safety.
Summary
Security compliance automation reduces the "bus factor" risk. If your lead engineer leaves, the security posture shouldn't leave with them. By defining your infrastructure in Ansible and verifying it with OpenSCAP, you turn compliance into a deployable asset.
Your Checklist for Monday:
- Migrate off container-based VPS to KVM-based CoolVDS instances.
- Write an Ansible role for basic SSH hardening.
- Run an initial OpenSCAP scan to see how bad the baseline is.
- Disable root login. Seriously. Do it now.
Don't wait for the audit letter to arrive. Deploy a compliant, hardened KVM instance on CoolVDS today and secure your infrastructure before the logs start growing.