Automating Compliance: From Datatilsynet Panic to CIS Hardening on Norwegian VPS
I distinctly remember the silence in the room. It was 2022, and a frantic CTO from a Bergen-based FinTech startup had just called me in. They were facing a surprise audit from Datatilsynet (The Norwegian Data Protection Authority). Their infrastructure was a mess of manual SSH sessions and unlogged hotfixes. They passed the audit by the skin of their teeth, but the lesson was seared into my brain: If your compliance isn't code, it doesn't exist.
In the Norwegian market, where GDPR and Schrems II impose strict data residency requirements, you cannot rely on a sticky note that says "Server updated." You need proof. You need automation. And you need the raw compute power to run these security agents without crashing your production database.
This guide ignores the fluff. We are going to look at how to automate a CIS (Center for Internet Security) Level 1 baseline on a Linux server, strictly adhering to principles valid as of September 2024.
The Myth of Manual Hardening
Most sysadmins deploy a server, run a few chmod commands, configure ufw, and call it a day. That works for a hobby blog. It fails for business. Configuration drift is real. A junior dev changes a permission to debug an issue at 3 AM and forgets to revert it. Suddenly, your /etc/shadow is world-readable.
To solve this, we move from "configuring" to "declaring" state.
The Architecture of Trust
We will use three components:
- Ansible: To enforce state (Idempotency is key).
- OpenSCAP: To audit the state against legal frameworks.
- CoolVDS KVM Instances: To ensure kernel-level control.
Pro Tip: Avoid container-based VPS (OpenVZ/LXC) for strict compliance nodes. You often share the kernel with the host, meaning you cannot modify certain sysctl parameters required for CIS compliance. CoolVDS uses KVM, giving you a dedicated kernel and full authority over your OS.
Phase 1: Enforcing the Baseline with Ansible
We don't manually edit sshd_config. We deploy a playbook. Below is a streamlined Ansible role designed for Ubuntu 24.04 LTS (Noble Numbat) that enforces strong SSH settings and kernel hardening.
This setup assumes you have Python 3.12+ installed (standard in 2024 distros).
The Hardening Playbook
---
- name: Enforce CIS Level 1 Baseline
hosts: production_norway
become: yes
vars:
ssh_port: 2222
allowed_users: "deployer_admin"
tasks:
- name: Ensure SSH protocol 2 is enforced
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^Protocol'
line: 'Protocol 2'
state: present
- name: Disable Root Login
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PermitRootLogin'
line: 'PermitRootLogin no'
validate: '/usr/sbin/sshd -t -f %s'
notify: restart_ssh
- name: Set idle timeout interval (ClientAliveInterval)
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^ClientAliveInterval'
line: 'ClientAliveInterval 300'
- name: Disable IP Forwarding (unless router)
sysctl:
name: net.ipv4.ip_forward
value: '0'
state: present
reload: yes
- name: Disable ICMP Redirect Acceptance
sysctl:
name: net.ipv4.conf.all.accept_redirects
value: '0'
state: present
reload: yes
handlers:
- name: restart_ssh
service:
name: ssh
state: restarted
This script is idempotent. Run it once, it secures the server. Run it 100 times, it changes nothing unless drift occurred.
Phase 2: Verifying Compliance with OpenSCAP
Applying settings is one thing; proving it to an auditor is another. OpenSCAP is the gold standard for this. In 2024, the ssg-base packages have matured significantly for newer distros.
First, install the necessary tools on your CoolVDS instance:
sudo apt-get update
sudo apt-get install libopenscap8 ssg-base ssg-debderived ssg-debian ssg-nondebian ssg-applications
Now, run a scan against the CIS profile. Be warned: this consumes CPU. On budget hosts, this can cause "CPU Steal" spikes that degrade your web application's performance. CoolVDS NVMe instances handle the I/O and CPU load without choking.
The Audit Script
Create a script /opt/scripts/daily_audit.sh:
#!/bin/bash
DATE=$(date +%F)
REPORT_DIR="/var/www/html/reports"
PROFILE="xccdf_org.ssgproject.content_profile_cis_level1_server"
CONTENT="/usr/share/xml/scap/ssg/content/ssg-ubuntu2204-ds.xml"
# Note: Ubuntu 24.04 content might be in a different path depending on the ssg version in late 2024.
# Always verify the XML path with 'ls /usr/share/xml/scap/ssg/content/'.
/usr/bin/oscap xccdf eval \
--profile $PROFILE \
--results $REPORT_DIR/results-$DATE.xml \
--report $REPORT_DIR/report-$DATE.html \
$CONTENT
# Check for failures
FAILURES=$(grep "result>fail" $REPORT_DIR/results-$DATE.xml | wc -l)
if [ "$FAILURES" -gt 0 ]; then
echo "ALERT: Security Audit found $FAILURES failures on $(hostname)" | mail -s "Audit Failed" security@yourdomain.no
fi
Running this ensures that if a developer enables telnet or disables auditing logs, you know about it immediately.
Phase 3: Data Residency & Network Latency
GDPR compliance isn't just about software; it's about where the data lives. If you are serving Norwegian customers, storing PII (Personally Identifiable Information) on a US-owned cloud provider can trigger complex Transfer Impact Assessments (TIAs) post-Schrems II.
Hosting on CoolVDS in our Oslo data center simplifies this equation. Your data stays on Norwegian soil, governed by EEA laws. Furthermore, latency matters for security logging. When you stream logs to a SIEM (like Splunk or Wazuh), high latency can cause buffer overflows in your logging agent if the network is unstable.
Comparison: Latency from Oslo
| Target | CoolVDS (Oslo) | Major Cloud (Frankfurt) | Major Cloud (US East) |
|---|---|---|---|
| Local ISP (Telenor) | ~1-3 ms | ~25-35 ms | ~90-110 ms |
| Throughput Stability | High | Variable (Hops) | Variable (Hops) |
Low latency ensures your rsyslog or filebeat processes clear their queues instantly, reducing the memory footprint on your production servers.
Small Configs, Big Impact
Here are quick configuration flags that often get missed but are essential for a robust posture.
1. Restrict Kernel Pointer Access (KASLR)
Prevents attackers from seeing memory addresses of kernel functions.
sysctl -w kernel.kptr_restrict=2
2. Lock Down Cron
Only root should schedule tasks.
touch /etc/cron.allow && chmod 600 /etc/cron.allow && awk 'BEGIN {print "root"}' > /etc/cron.allow
3. Enforce SELinux (The scary part)
Many disable it. Don't. If you are on a CoolVDS instance running AlmaLinux or RHEL:
setenforce 1
Check status with:
sestatus | grep "Current mode"
4. Auditd Buffer Size
If your server is busy, audit logs can be dropped. Increase the buffer.
# /etc/audit/audit.rules
-b 8192
5. Time Synchronization
Kerberos and logging require accurate time. Ensure chronyd is active.
systemctl enable --now chronyd
The Storage Trade-off: NVMe vs. HDD
Security is I/O intensive. File Integrity Monitoring (FIM) agents constantly hash files to detect changes. If you run FIM on a spinning HDD or a throttled "cloud" disk, your IO wait times will skyrocket. The application will feel sluggish, not because the code is bad, but because the security agent is hogging the disk.
We designed CoolVDS NVMe storage tiers specifically to absorb this overhead. You can run aggressive Wazuh FIM scans and your PostgreSQL database won't even blink. That is the difference between "checked the box" compliance and operational compliance.
Final Thoughts
Automation is the only way to sleep at night. By September 2024, the threat landscape has evolved to where manual patching is professional negligence. Use Ansible to define your fortress. Use OpenSCAP to check the walls. And host it on infrastructure that respects your data sovereignty and performance needs.
Don't let a slow disk or a shared kernel compromise your security posture. Deploy a hardened CoolVDS instance in Oslo today and keep the auditors happy.