Automating Compliance: Why Manual Security Audits Are a Liability in 2020
If you are still manually editing /etc/ssh/sshd_config on your production servers, you are already in breach. That might sound harsh, but with the Datatilsynet (Norwegian Data Protection Authority) ramping up audits this year and the uncertainty surrounding the EU-US Privacy Shield, reliance on manual intervention is a risk no CTO should accept.
We are past the point where "security through obscurity" works. In 2020, security is about consistency and provenance. I've seen too many sophisticated setups crumble because a junior dev enabled password authentication on a jump host for "just five minutes" to debug a script.
This guide isn't about buying expensive security appliances. It's about using open-source toolsâspecifically Ansible and OpenSCAPâto enforce 'Compliance as Code' on your infrastructure. Whether you are running a single node or a cluster, the principles remain the same: automate the audit, automate the fix, and keep the data in Norway.
The Myth of the "Secure" Image
Many hosting providers claim their OS images are secure out of the box. They aren't. They are optimized for compatibility, not compliance. A standard Ubuntu 20.04 LTS installation is designed to be user-friendly, which usually means it's too permissive for a fintech or healthcare workload.
I recall a project last winter where we migrated a payment processor from a legacy dedicated server to a cloud environment. We thought the base image was solid. A simple OpenSCAP scan revealed a 43% compliance score against the CIS (Center for Internet Security) benchmark. We were missing audit rules, we had unowned files, and legacy services were listening on public interfaces.
To fix this, we stopped treating servers as pets. We started treating them as immutable targets for our compliance code.
Step 1: The Tooling (OpenSCAP & Ansible)
We use the Security Content Automation Protocol (SCAP). It provides a standardized approach to maintaining the security of enterprise systems. Combined with Ansible, we can not only check for compliance but enforce it.
First, let's install the necessary tools on a control node. We are assuming you are targeting Ubuntu 20.04 (Focal Fossa), which was released a few months ago and is rapidly becoming the standard for LTS deployments.
sudo apt-get update
sudo apt-get install scap-security-guide openscap-scanner ansible -y
The scap-security-guide package contains the XCCDF checklistsâessentially XML files that define what a "secure" system looks like according to various standards (PCI-DSS, STIG, CIS).
Step 2: Assessing the Baseline
Before you apply fixes, you need to know where you stand. Run this on your target CoolVDS instance to generate a report. Note that scanning consumes CPU; on our NVMe instances, this takes about 40 seconds, but on slower spinning rust storage, this can take minutes.
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-ubuntu2004-ds.xml
This command checks your system against the CIS Level 1 Server profile. You will likely see a lot of red "fail" messages. Don't panic. That is the baseline.
Step 3: Automating Remediation with Ansible
Here is where the magic happens. Instead of manually fixing each failure, we use an Ansible playbook. This ensures that every server you spin upâwhether it's for a staging environment or productionâhas the exact same security posture.
Below is a snippet of a hardening playbook that addresses common failures: SSH configuration and filesystem permissions.
---
- name: Hardening CoolVDS Instance
hosts: all
become: yes
tasks:
- name: Ensure SSH Protocol 2 is enforced
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^Protocol'
line: 'Protocol 2'
state: present
validate: '/usr/sbin/sshd -t -f %s'
- name: Disable Root Login
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PermitRootLogin'
line: 'PermitRootLogin no'
state: present
notify: Restart SSH
- name: Set sticky bit on all world-writable directories
shell: |
df --local -P | awk {'if (NR!=1) print $6'} | xargs -I '{}' find '{}' -xdev -type d -perm -0002 2>/dev/null | xargs chmod a+t
args:
warn: false
tags: filesystem
handlers:
- name: Restart SSH
service:
name: sshd
state: restarted
This is basic, but it illustrates the point. You define the state you want, and Ansible ensures the server matches it. If a sysadmin accidentally changes PermitRootLogin to yes manually, the next Ansible run reverts it.
Pro Tip: When using Ansible for hardening, always use thevalidateparameter when editing configuration files likesshd_configorsudoers. This prevents you from locking yourself out of the server if you make a syntax error in the config file. The service won't restart if validation fails.
Step 4: Advanced Audit Rules (The "Big Brother" Configuration)
For high-compliance environments (like those handling GDPR-sensitive data), you need to log everything. The Linux Audit daemon (auditd) is your friend here. However, auditd can be heavy on disk I/O if not configured correctly. This is one area where the underlying infrastructure matters significantly.
We recommend CoolVDS NVMe instances for this reason. High I/O throughput prevents the audit queue from filling up and dropping logs, which is an automatic failure in many compliance audits.
Here is a robust configuration snippet for /etc/audit/rules.d/audit.rules to track unauthorized file access:
# Delete all existing rules
-D
# Buffer Size
-b 8192
# Failure Mode (2 = shutdown if audit fails to log. Use 1 for production to avoid downtime)
-f 1
# Monitor changes to the shadow file (passwords)
-w /etc/shadow -p wa -k identity
-w /etc/passwd -p wa -k identity
-w /etc/gshadow -p wa -k identity
# Monitor system calls for file truncation or deletion
-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete
-a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete
Data Sovereignty and The "Schrems II" Anxiety
We are currently in a strange limbo regarding data transfers to the US. While Privacy Shield is technically still in effect, the legal winds in Europe are shifting. If you are a Norwegian business, storing your data in US-owned clouds (even if the datacenter is in Frankfurt) exposes you to the US CLOUD Act.
From a pragmatic perspective, the safest bet for compliance right now is strict data residency. This is why we built CoolVDS on infrastructure physically located in Oslo, directly peering with NIX (Norwegian Internet Exchange).
Comparison: Public Cloud vs. Regional Compliant Hosting
| Feature | Hyperscale Public Cloud | CoolVDS (Oslo) |
|---|---|---|
| Jurisdiction | US Law (CLOUD Act applies) | Norwegian/EEA Law |
| Latency to Oslo | 15-30ms (via Stockholm/Frankfurt) | < 3ms (Local Peering) |
| Audit Access | Limited / Shared Responsibility | Full Kernel Control (KVM) |
| Storage I/O | Throttled (unless paying premium) | Unmetered NVMe Standard |
Conclusion
Compliance isn't a checkbox; it's an operational habit. By utilizing tools like Ansible and OpenSCAP, you move from a reactive "panic before the audit" model to a proactive "always compliant" stance.
However, software automation only solves half the puzzle. If your underlying hardware is in a jurisdiction that conflicts with your legal obligations, no amount of Ansible playbooks will save you. Ensure your foundation is as solid as your code.
Ready to harden your stack? Deploy a fresh Ubuntu 20.04 LTS instance on CoolVDS today and get full KVM isolation for your compliance workloads.