Console Login

Automating Compliance: How to Survive Datatilsynet Audits with Ansible & OpenSCAP in 2023

Automating Compliance: How to Survive Datatilsynet Audits with Ansible & OpenSCAP

It’s 3:00 AM on a Tuesday. Your monitoring dashboard is green, but a cold sweat is building on your neck. Why? Because you just remembered that Datatilsynet (the Norwegian Data Protection Authority) has ramped up its random audit frequency for tech companies handling consumer data. If they knocked on your digital door tomorrow, could you prove—timestamped and verified—that every single server in your fleet is hardened against the latest CVEs?

If your answer involves SSH-ing into a box and running history | grep iptables, you have already lost. In the post-Schrems II era, manual security is not just inefficient; it is negligence.

I have spent the last decade fighting entropy in infrastructure. I’ve seen “secure” environments drift into vulnerability because a junior dev temporarily opened port 22 for a vendor and forgot to close it. The only fix is ruthlessness: Infrastructure as Code (IaC) applied to security compliance.

The Residency Trap: Why Geography is a Security Feature

Before we touch a single config file, we must address the physical layer. In 2023, where your data sits is as critical as how it is encrypted. For Norwegian businesses, or European entities serving Nordic customers, hosting data on US-owned hyperscalers introduces complex legal exposure regarding data transfer mechanisms.

This is where the architecture of CoolVDS becomes a strategic asset rather than just a utility. By ensuring your KVM instances are physically located in Oslo-area data centers, you bypass the headache of Trans-Atlantic Data Privacy Framework uncertainties. You aren't just buying NVMe storage; you are buying legal insulation. Plus, the latency to NIX (Norwegian Internet Exchange) is negligible, often sub-2ms, which makes real-time log shipping feasible without choking your bandwidth.

Phase 1: Hardening the Kernel with Ansible

Compliance is not a state; it is a continuous loop. We rely on Ansible to enforce the Center for Internet Security (CIS) benchmarks. Unlike shell scripts, Ansible is idempotent—run it once or a thousand times, the result is the same.

Here is a snippet from a production playbook I use to lock down the Linux kernel networking stack. This prevents common attacks like IP spoofing and man-in-the-middle redirects.

- name: Harden Network Stack (sysctl)
  ansible.builtin.sysctl:
    name: "{{ item.key }}"
    value: "{{ item.value }}"
    state: present
    sysctl_file: /etc/sysctl.d/99-security.conf
    reload: yes
  loop:
    - { key: 'net.ipv4.conf.all.accept_redirects', value: '0' }
    - { key: 'net.ipv4.conf.default.accept_redirects', value: '0' }
    - { key: 'net.ipv4.conf.all.secure_redirects', value: '0' }
    - { key: 'net.ipv4.conf.default.secure_redirects', value: '0' }
    - { key: 'net.ipv4.ip_forward', value: '0' }
    - { key: 'net.ipv4.conf.all.send_redirects', value: '0' }
    - { key: 'net.ipv4.conf.default.send_redirects', value: '0' }
    - { key: 'net.ipv4.icmp_echo_ignore_broadcasts', value: '1' }
Pro Tip: Never apply net.ipv4.ip_forward = 0 blindly on a server acting as a Kubernetes node or a VPN gateway. You will break your routing. Context matters. On a standard CoolVDS web worker, however, shut it down.

Phase 2: Immutable SSH Configurations

The second biggest vector is remote access. Password authentication should have been dead to you in 2015. Today, we enforce Ed25519 keys and ban root login entirely.

Check your /etc/ssh/sshd_config. If it doesn't look like this, fix it:

PermitRootLogin no
PasswordAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
X11Forwarding no
AllowAgentForwarding no
Protocol 2
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2

While standard VPS providers might give you a generic image, a true DevOps approach involves baking these configs into your base image or applying them via cloud-init immediately upon provisioning. The goal is to minimize the "Time to Insecurity"—the gap between a server booting and it being fully hardened.

Phase 3: Continuous Auditing with OpenSCAP

You have hardened the server. Great. How do you prove it? This is where OpenSCAP shines. It scans your system against the XCCDF (Extensible Configuration Checklist Description Format) profiles provided by security organizations.

Install the scanner (on Ubuntu 22.04 LTS):

sudo apt-get install libopenscap8 scap-security-guide -y

Now, run a scan against the standard SSG profile. This operation is CPU intensive. On cheaper, shared-core hosting, this will steal cycles from your application or, worse, get your instance throttled. Because CoolVDS offers dedicated resource allocation on KVM, you can run these heavy audit threads without degrading your web server's TTFB (Time to First Byte).

oscap xccdf eval \
  --profile xccdf_org.ssgproject.content_profile_cis_level1_server \
  --results scan-results.xml \
  --report scan-report.html \
  /usr/share/xml/scap/ssg/content/ssg-ubuntu2204-ds.xml

This command generates an HTML report showing exactly where you pass and fail. Attach this report to your compliance Jira tickets. The auditors love it.

Phase 4: Real-time File Integrity Monitoring (FIM)

If an attacker bypasses your firewall, they will try to modify binaries or configuration files. auditd is the kernel-level answer to "who touched that file?"

Here is a robust set of audit rules. Place these in /etc/audit/rules.d/audit.rules to monitor changes to the shadow file, network config, and system time.

## Identity Tracking
-w /etc/group -p wa -k identity
-w /etc/passwd -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/security/opasswd -p wa -k identity

## Network Configuration
-w /etc/hosts -p wa -k system-locale
-w /etc/network/ -p wa -k system-locale

## System 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
-w /etc/localtime -p wa -k time-change

Once loaded (augenrules --load), any modification triggers a log entry. Pipe these logs to a centralized Wazuh manager or an ELK stack.

Phase 5: Web Server Headers

Finally, do not expose your backend version to the world. A simple Nginx snippet in your server block can mitigate XSS and clickjacking attempts.

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
server_tokens off;

The Infrastructure Trade-off

Automation is powerful, but it relies on a predictable substrate. I have seen compliance scripts fail because a noisy neighbor on a budget VPS spiked disk I/O, causing timeouts during package verification. Security automation requires stability.

This is why serious professionals in the Nordic market gravitate towards KVM-based solutions like CoolVDS. The isolation is not just a performance perk; it is a security boundary. When you are running heavy encryption for transit and storage, or compiling OpenSCAP reports, you need raw CPU cycles that aren't being stolen by a Minecraft server next door.

Your Next Move

Don't wait for the audit letter to land in your inbox. Start by auditing your current setup.

  1. Spin up a fresh instance.
  2. Run the OpenSCAP scan command provided above.
  3. Check your score.

If you are scoring below 80%, your current infrastructure is a risk. Deploy a high-performance CoolVDS instance today and build your fortress on solid ground.