Console Login

Automating Compliance: Surviving Datatilsynet with Ansible and Hardened KVM

Stop Manual Hardening: Automating Compliance for the Nordic Cloud

I recently watched a competent sysadmin in Oslo nearly weep during a preliminary audit. His infrastructure was solid, but his documentation was a mess of spreadsheets and "I think we patched that last Tuesday." With the General Data Protection Regulation (GDPR) looming over us for 2018 implementation, and Datatilsynet sharpening their enforcement tools, the era of "security by obscurity" is dead. If you cannot prove your security posture via code, you are not compliant.

Manual hardening guides are failure points. Humans forget steps. Scripts break. The only path forward for serious infrastructure in Norway is Infrastructure as Code (IaC). We treat compliance not as a checklist, but as a state of convergence.

The Jurisdiction Trap

Before we touch a single config file, acknowledge the physical layer. You can encrypt data at rest, but if your physical host is in a jurisdiction subject to the US PATRIOT Act, your legal footing in Europe is shaky. This is why we deploy strictly on CoolVDS instances in Norwegian data centers. Data sovereignty isn't a buzzword; it's risk management. When your bits live in Oslo, you are playing by Norwegian rules, which significantly simplifies the legal overhead of data export agreements.

Step 1: The Ansible Baseline

We don't SSH into servers to run commands anymore. We write playbooks. Here is a standard Ansible task structure we use to enforce SSH security across our CentOS 7 and Ubuntu 16.04 fleets. This ensures that even if a junior dev spins up a new VPS, it converges to a secure state immediately.

- name: Secure SSH configuration
  hosts: all
  become: yes
  tasks:
    - name: Disable Root Login
      lineinfile:
        dest: /etc/ssh/sshd_config
        regexp: '^PermitRootLogin'
        line: 'PermitRootLogin no'
        state: present
      notify: restart ssh

    - name: Disable Password Authentication
      lineinfile:
        dest: /etc/ssh/sshd_config
        regexp: '^PasswordAuthentication'
        line: 'PasswordAuthentication no'
        state: present
      notify: restart ssh

    - name: Ensure Protocol 2 only
      lineinfile:
        dest: /etc/ssh/sshd_config
        regexp: '^Protocol'
        line: 'Protocol 2'
        state: present
      notify: restart ssh

  handlers:
    - name: restart ssh
      service:
        name: sshd
        state: restarted
Pro Tip: On CoolVDS KVM instances, you have full kernel control. Use this to enable selinux in enforcing mode. Unlike container-based hosting (OpenVZ/LXC), KVM allows true isolation, which is critical when proving to auditors that "Neighbor A" cannot access "Neighbor B's" memory segments.

Step 2: Automated Vulnerability Scanning with OpenSCAP

How do you know you are compliant? You ask the machine. OpenSCAP is the gold standard for automated auditing against the XCCDF (Extensible Configuration Checklist Description Format) standard.

Install the scanner on your Red Hat or CentOS 7 systems:

yum install openscap-scanner scap-security-guide

Run a scan against the PCI-DSS profile (often a good baseline even if you aren't processing cards):

oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_pci-dss \
  --results /var/www/html/scan-report.xml \
  --report /var/www/html/scan-report.html \
  /usr/share/xml/scap/ssg/content/ssg-centos7-ds.xml

This generates a human-readable HTML report. We script this via cron to run weekly. If the compliance score drops below 90%, our monitoring system (Nagios) pages the on-call engineer.

Step 3: The SSL/TLS Mandate

With Let's Encrypt leaving beta earlier this year, there is no financial excuse for unencrypted traffic. However, a certificate alone isn't enough. You must configure Nginx to reject weak ciphers. The default configs in many repos are outdated and support SSLv3, which is vulnerable to POODLE.

Here is the CoolVDS reference configuration for Nginx on Ubuntu 16.04, optimized for an A+ rating on SSLLabs:

server {
    listen 443 ssl http2;
    server_name secure.example.no;

    ssl_certificate /etc/letsencrypt/live/secure.example.no/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/secure.example.no/privkey.pem;

    # Diffie-Hellman parameter for DHE ciphersuites
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    # Mozilla Intermediate configuration (2016)
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;
}

Step 4: Immutable Logging

In a forensic analysis, logs are your only source of truth. Attackers will try to wipe /var/log. To prevent this, we use the chattr command on log rotation archives, but for real-time protection, we stream logs off-site.

However, you first need to capture the right data. auditd is the Linux Audit Daemon. It hooks into the kernel and watches system calls. Here is a snippet for /etc/audit/audit.rules to watch for unauthorized changes to the /etc/passwd file:

# Watch for changes to user database
-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

Why Infrastructure Choice Matters

You can script all the security in the world, but if the underlying hypervisor is over-provisioned or insecure, you are building a fortress on a swamp. We see this constantly with budget providers who oversell RAM, leading to unpredictable OOM (Out of Memory) kills that crash security daemons.

CoolVDS takes a different approach. We don't over-provision. When you buy a slice of a node, that RAM is reserved for you. This stability is essential for compliance services like ClamAV or Snort, which are memory-hungry and prone to crashing on unstable "burstable" instances. Furthermore, our NVMe storage arrays ensure that logging I/O never becomes a bottleneck during a DDoS attack.

The Final Check

Automation is not a "set and forget" activity. It is a discipline. With the regulatory landscape in Europe tightening, the cost of non-compliance is far higher than the cost of a proper server architecture.

Start your compliance journey with a clean slate. Deploy a fresh CentOS 7 or Ubuntu 16.04 instance on CoolVDS today, clone your Ansible repo, and watch your infrastructure build itself securely in minutes.