Console Login

Automating Security Compliance: Surviving Schrems II with Infrastructure as Code

Automating Security Compliance: Surviving Schrems II with Infrastructure as Code

July 2020 changed the hosting landscape in Europe overnight. When the Court of Justice of the European Union (CJEU) invalidated the Privacy Shield framework (Schrems II), the comfortable reliance many Norwegian CTOs had on US-based hyperscalers evaporated. If you are storing customer PII on servers owned by a US company, even if those servers are located in Frankfurt or Stockholm, you are now operating in a legal grey zone regarding the US CLOUD Act.

Compliance is no longer just a box to check; it is an architectural requirement. But here is the friction point: security usually slows down development. We cannot afford that. The solution is not more paperwork, but Compliance as Code. By treating your security posture as software, we can automate adherence to CIS benchmarks and GDPR requirements while keeping deployment pipelines green.

This guide explores how to implement automated security hardening on Ubuntu 20.04 LTS (Focal Fossa) using Ansible and OpenSCAP, specifically tailored for infrastructure hosted within Norwegian jurisdiction.

The Architecture of Trust

Before we touch the terminal, let’s address the infrastructure layer. Compliance automation is useless if the underlying virtualization is leaky. In a recent audit for a purely Norwegian fintech client, we migrated their workload from a shared container environment to strict KVM-based isolation. Containers share the host kernel; if a neighbor breaks out, your data is exposed. KVM (Kernel-based Virtual Machine) provides hardware-level virtualization.

At CoolVDS, we strictly enforce KVM virtualization. This isn't just for performance; it's for the segregation of duties required by ISO 27001. When you couple strict isolation with data residency in Oslo, you solve the physical layer of GDPR instantly. Latency drops to under 3ms for local users, and data never crosses the border.

Step 1: Baseling with OpenSCAP

You cannot secure what you cannot measure. OpenSCAP is the industry standard for verifying the configuration of systems. It compares your current state against the Security Content Automation Protocol (SCAP) standards, including the CIS (Center for Internet Security) benchmarks.

First, install the toolset on your target server (Ubuntu 20.04 in this example):

sudo apt-get update
sudo apt-get install libopenscap8 scap-workbench ssg-base ssg-deb ssg-applications ssg-gtK

Once installed, you can view the available security profiles. We are interested in the standard profile for general-purpose servers, which covers the basics like partition mounting options, SSH configurations, and package integrity.

Run the following to verify your profile availability:

oscap info /usr/share/xml/scap/ssg/content/ssg-ubuntu2004-ds.xml

Now, let's run a scan. This command generates an HTML report showing exactly where your vanilla OS installation fails compliance.

oscap xccdf eval \
  --profile xccdf_org.ssgproject.content_profile_standard \
  --report /tmp/report.html \
  /usr/share/xml/scap/ssg/content/ssg-ubuntu2004-ds.xml

If you run this on a standard cloud image, you will likely see a failure score of around 60%. Critical failures often include /tmp partition mounting options, SSH root login permissions, and unrestricted kernel network parameters.

Step 2: Remediation with Ansible

Manual remediation is a recipe for drift. If you fix a setting manually, a system update might revert it next month. We use Ansible to enforce the state. Below is a production-grade playbook structure we use to align servers with the CIS Level 1 benchmark.

Create a file named harden_sysctl.yml. This handles the network stack hardening to prevent IP spoofing and Man-in-the-Middle attacks.

---
- name: Harden Network Stack (Sysctl)
  hosts: all
  become: yes
  tasks:
    - name: Disable IP forwarding
      sysctl:
        name: net.ipv4.ip_forward
        value: '0'
        state: present
        reload: yes

    - name: Disable ICMP redirects
      sysctl:
        name: net.ipv4.conf.all.accept_redirects
        value: '0'
        state: present
        reload: yes

    - name: Enable RFC 1337 - Protect against time-wait assassination
      sysctl:
        name: net.ipv4.tcp_rfc1337
        value: '1'
        state: present
        reload: yes

    - name: Log Martians (Spoofed Packets)
      sysctl:
        name: net.ipv4.conf.all.log_martians
        value: '1'
        state: present
        reload: yes

This playbook modifies /etc/sysctl.conf and reloads the values immediately. Specifically, log_martians is crucial for audit trails—it logs packets with impossible source addresses, often a sign of a probing attack.

Hardening SSH Access

The number one entry vector for compromised VPS instances is weak SSH configuration. We disable password authentication entirely and enforce SSH protocol 2. Here is the sshd_config template approach.

Pro Tip: Never edit `/etc/ssh/sshd_config` directly with sed or echo. Use Ansible's lineinfile or, better yet, deploy a full template to ensure no rogue configurations persist.
# /etc/ssh/sshd_config snippet for CoolVDS instances

# Network
Port 22
Protocol 2

# Authentication
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no

# Optimization & Security
UseDNS no
X11Forwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
MaxAuthTries 3

Deploying this configuration automatically ensures that every new instance you spin up is inaccessible to brute-force password attacks from the start. Combined with CoolVDS's DDoS protection, your attack surface shrinks dramatically.

Step 3: Kernel Tuning for I/O Performance and Security

Security often kills performance, specifically I/O throughput when encryption is involved. Since CoolVDS runs on NVMe storage, we want to ensure the kernel scheduler takes full advantage of the speed without compromising isolation.

We recommend the mq-deadline or none (for NVMe) I/O scheduler inside your guest VM to reduce CPU overhead. While not strictly a security setting, high load averages caused by I/O waits can trigger false positives in availability monitoring, which is an availability risk.

Check your current scheduler:

cat /sys/block/vda/queue/scheduler

To set it permanently in GRUB (for Ubuntu 20.04):

# Edit /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash elevator=none"

# Apply changes
sudo update-grub

The