Automating Regulatory Sanity: Why Manual Hardening is a Liability
If you are still manually editing /etc/ssh/sshd_config every time you spin up a new VPS, you are already non-compliant. In the time it took you to read that sentence, a script-kiddie scanned your IP block, and a new vulnerability was likely published to the CVE database.
For CTOs operating in the European Economic Area—specifically Norway—the stakes are financial, not just technical. The Datatilsynet (Norwegian Data Protection Authority) does not hand out participation trophies for trying hard. They hand out fines calculated on global turnover. With the Schrems II ruling effectively complicating data transfers to US-owned hyperscalers, the "Pragmatic CTO" has two choices: build a compliance army or automate the entire process on local, sovereign infrastructure.
This is not a theoretical discussion about "best practices." This is a blueprint for automating CIS (Center for Internet Security) benchmarks using OpenSCAP and Ansible, deployed on infrastructure that doesn't leak your data across the Atlantic.
The Foundation: Isolation is Non-Negotiable
Before we touch a single line of code, we must address the substrate. Compliance requires isolation. Many budget hosting providers pack users into containers (LXC/OpenVZ) sharing a single kernel. From a security perspective, this is a nightmare. A kernel panic triggered by a neighbor brings you down; a kernel exploit exposes your memory.
Pro Tip: Always verify your virtualization technology. Runvirt-whaton your instance. If it doesn't returnkvmorvmware, you lack the hardware-level isolation often required for strict PCI-DSS or HIPAA compliance.
We built CoolVDS exclusively on KVM (Kernel-based Virtual Machine) architectures. When you provision an instance in our Oslo datacenter, you aren't just getting a slice of an OS; you are getting a dedicated kernel environment. This is the only way to ensure that your automated hardening actually sticks without the host node overriding your sysctl settings.
Step 1: Baserelining with OpenSCAP
You cannot improve what you cannot measure. OpenSCAP is the industry standard for verifying the configuration of Linux systems against the SCAP (Security Content Automation Protocol) standard. It allows you to scan a server against the CIS Benchmark profile without manual intervention.
First, install the necessary tools. On an Enterprise Linux 9 system (common in 2024 corporate environments):
sudo dnf install openscap-scanner scap-security-guideNow, run a scan. Don't rely on default settings. We want to check against the CIS Level 2 Server profile—this is for environments where security is prioritized over some usability convenience.
oscap xccdf eval
--profile xccdf_org.ssgproject.content_profile_cis_workstation_l2
--results /var/log/openscap/results.xml
--report /var/log/openscap/report.html
/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xmlThe output will be a sea of red "FAIL" flags. Don't panic. That is the baseline. The report generated at report.html gives you the exact remediation steps. However, manually fixing 200+ failures is inefficient.
Step 2: Remediation via Ansible
Infrastructure as Code (IaC) allows us to turn those remediation steps into a repeatable playbook. Instead of manually editing config files, we define the desired state.
Here is a concise Ansible task structure to handle one of the most common failures: SSH Root Login and Protocol versions. This snippet ensures that even if a junior dev spins up a server, it snaps back to a compliant state immediately.
---
- name: Harden SSH Configuration
hosts: all
become: yes
tasks:
- name: Ensure SSH Protocol is set to 2
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^Protocol'
line: 'Protocol 2'
state: present
notify: Restart SSH
- name: Disable Root Login
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PermitRootLogin'
line: 'PermitRootLogin no'
state: present
notify: Restart SSH
- name: Ensure SSH MaxAuthTries is set to 4 or less
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^MaxAuthTries'
line: 'MaxAuthTries 4'
state: present
notify: Restart SSH
handlers:
- name: Restart SSH
service:
name: sshd
state: restartedThis is basic hygiene. Real compliance goes deeper. You need to configure the kernel runtime parameters to prevent IP spoofing and man-in-the-middle attacks. These changes are volatile unless written to sysctl.conf.
| Parameter | Value | Why it matters for GDPR/Security |
|---|---|---|
net.ipv4.conf.all.accept_redirects | 0 | Prevents malicious routing alteration. |
kernel.randomize_va_space | 2 | Enables ASLR to make buffer overflows harder. |
fs.suid_dumpable | 0 | Prevents core dumps from leaking sensitive memory data. |
Step 3: Immutable Audit Logs
In Norway, if you suffer a breach, the burden of proof is on you. If an attacker wipes your logs, you cannot prove the scope of the breach, and the fines increase. You need to configure auditd to be immutable. This means that once the rules are loaded, they cannot be changed without a reboot.
Add this to your /etc/audit/audit.rules file. Note the -e 2 flag at the end—that is the "lock" command.
# Record attempts to alter time
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change
-a always,exit -F arch=b32 -S adjtimex -S settimeofday -k time-change
# Record attempts to alter user IDs
-w /etc/group -p wa -k identity
-w /etc/passwd -p wa -k identity
-w /etc/gshadow -p wa -k identity
# Make the configuration immutable
-e 2Once this is applied, even the root user cannot stop the logging service without rebooting the machine. This brings us back to infrastructure choice. Rebooting a VPS on a slow spinning-disk array can take minutes—minutes where your service is offline.
On CoolVDS, our storage backend uses enterprise NVMe arrays. A full reboot cycle of a hardened AlmaLinux node typically takes less than 12 seconds. This allows you to apply immutable kernel updates during micro-maintenance windows without disrupting service level agreements (SLAs).
The "Data Sovereignty" Variable
Automation solves the configuration problem, but it doesn't solve the location problem. As of late 2024, the legal landscape regarding US Cloud Act vs. GDPR is still hostile. If your automated, perfectly hardened server resides on a hypervisor owned by a US entity, you are technically subject to extra-territorial data requests.
Hosting locally in Norway removes layers of legal complexity. It reduces the latency for your Oslo and Bergen based users to sub-5ms, but more importantly, it simplifies your "Record of Processing Activities" (ROPA) for the GDPR.
The Check-Loop
Compliance is not a destination; it is a loop. Set up a cron job to run your OpenSCAP scan weekly and pipe the results to your monitoring dashboard.
0 3 * * 0 /usr/bin/oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_cis_server_l1 --report /var/www/html/compliance/$(date +\%F)-report.html /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xmlSecurity is difficult. It requires vigilance, technical debt repayment, and robust infrastructure. Don't let slow I/O or noisy neighbors compromise your compliance posture. Automate the hardening, lock the logs, and keep the data on Norwegian soil.
Ready to audit your infrastructure? Deploy a KVM-isolated, NVMe-powered instance on CoolVDS in 55 seconds and run your first OpenSCAP scan today.