Console Login

Compliance as Code: Automating Linux Security Standards for Norwegian Fintechs (2025 Edition)

Compliance as Code: Automating Linux Security Standards for Norwegian Fintechs (2025 Edition)

I still remember the silence in the boardroom three years ago when a compliance officer asked a Junior Admin, "Can you prove nobody accessed the production database on Tuesday night?" The answer wasn't a log file; it was a shrug. That shrug cost the company a contract worth 4 million NOK.

In 2025, manual hardening is professional negligence. If you are typing commands into a terminal to secure a server, you have already failed. Security must be immutable, automated, and auditable. Specifically, for those of us operating out of Oslo or serving European clients, Datatilsynet (The Norwegian Data Protection Authority) does not care about your "best efforts." They care about evidence.

This guide ignores the fluff. We are going to build a self-healing, compliant VPS baseline on Ubuntu 24.04 LTS that adheres to CIS Level 2 benchmarks. We will use Ansible for the setup and Wazuh for the ongoing audit, all running on high-performance CoolVDS infrastructure where hardware isolation prevents the side-channel attacks plaguing shared container environments.

The "Trust No One" Baseline

Security starts at the kernel level. Most default VPS templates are designed for compatibility, not security. They leave IPv6 redirect acceptance on, allow ICMP redirects, and have loose memory allocation. This is convenient for hobbyists but fatal for production.

We need to lock down the sysctl.conf. Do not just copy-paste this; understand that we are disabling packet forwarding to prevent the server from being used as a pivot point in a network attack.

Code Snippet 1: Kernel Hardening via Sysctl

# /etc/sysctl.d/99-security.conf

# IP Spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Ignore ICMP broadcast requests
net.ipv4.icmp_echo_ignore_broadcasts = 1

# Disable source packet routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0

# Disable send redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

# Block SYN attacks
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2

# Log Martians
net.ipv4.conf.all.log_martians = 1

# Disable IPv6 if not used (optional, but recommended for internal nodes)
# net.ipv6.conf.all.disable_ipv6 = 1

Apply this immediately without rebooting:

sysctl -p /etc/sysctl.d/99-security.conf

Automating the Hardening with Ansible

I see too many engineers writing Bash scripts to harden servers. Bash is fragile. It is not idempotent. If you run a hardening script twice, you might break your SSH config or duplicate firewall rules.

We use Ansible. It ensures the state of the machine matches your definition. Below is a production-grade playbook snippet we use to enforce SSH security. Note the PermitRootLogin no directive. On CoolVDS, you have VNC console access via the portal, so you don't need to fear locking yourself out completely—but for SSH, root must die.

Code Snippet 2: Idempotent SSH Hardening Playbook

---
- name: Harden SSH Configuration
  hosts: all
  become: yes
  tasks:
    - name: Ensure SSH protocol 2 is used
      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'
        state: present
      notify: Restart SSH

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

    - name: Ensure MaxAuthTries is set to 3
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^MaxAuthTries'
        line: 'MaxAuthTries 3'
        state: present

    - name: Allow specific users only
      lineinfile:
        path: /etc/ssh/sshd_config
        line: 'AllowUsers deployer_user admin_user'
        state: present
        
  handlers:
    - name: Restart SSH
      service:
        name: sshd
        state: restarted
Pro Tip: When running this against a fresh CoolVDS instance, ensure you have added your public key to the deployer_user first. If you disable password auth before keys are synced, you will have a bad afternoon.

File Integrity Monitoring (FIM)

Compliance isn't just about closing ports; it's about knowing when a file changes. If /bin/ls is modified, you have been compromised. Tools like Tripwire are ancient history. In 2025, we use Wazuh or Auditd integrated with ELK.

Here is a configuration for auditd that tracks changes to the system time—a common tactic malware uses to mess with logs.

auditctl -w /etc/localtime -p wa -k time-change

But let's go deeper. Here is a robust audit.rules configuration that satisfies most banking compliance requirements in the Nordics.

Code Snippet 3: Comprehensive Audit Rules

## /etc/audit/rules.d/audit.rules

# First rule - Remove any existing rules
-D

# Buffer Size
-b 8192

# Failure Mode (2=shutdown, 1=printk, 0=silent)
-f 1

# Watch critical network configuration
-w /etc/issue -p wa -k system-locale
-w /etc/issue.net -p wa -k system-locale
-w /etc/hosts -p wa -k system-locale
-w /etc/network/ -p wa -k system-locale

# Watch user/group modification
-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

# Log sudo usage
-w /bin/su -p x -k priv_escalation
-w /usr/bin/sudo -p x -k priv_escalation
-w /etc/sudoers -p wa -k scope

# Make the configuration immutable (must be last rule)
-e 2

The Hardware Sovereignty Factor

You can have the most hardened OS in the world, but if your host is over-provisioned or legally compromised, software won't save you. This is the Schrems II reality we still live with.

Many "cheap" VPS providers overload their hypervisors. This leads to "CPU Steal," where your neighbor's intense crypto-mining operation slows down your SSL handshakes. In a compliance audit, erratic latency is a red flag for availability standards.

This is where architecture matters. CoolVDS uses KVM (Kernel-based Virtual Machine) virtualization. Unlike OpenVZ or LXC containers used by budget hosts, KVM provides a higher degree of isolation. Your kernel is your kernel.

Feature Typical Cloud Container CoolVDS KVM Instance
Kernel Access Shared with Host Dedicated
IOPS Consistency Fluctuates (Noisy Neighbor) Reserved NVMe Limits
Data Residency Often vague "EU Region" Strictly Oslo/Norway
Custom Modules Restricted Full Loadable Support

Final Checks

Before you sign off on the deployment, verify your firewall. We prefer nftables in modern Debian/Ubuntu systems, but ufw is acceptable for simple setups. Ensure you limit SSH (port 22) rate limits to prevent brute force.

ufw limit 22/tcp

And verify that no unnecessary services are listening:

ss -tulpn | grep LISTEN

If you see anything you don't recognize, kill it. Remove the package. Minimalism is security.

Conclusion

Compliance is not a document; it is a state of your infrastructure. By automating your hardening with Ansible and monitoring with Auditd/Wazuh, you turn a quarterly headache into a daily routine. And by deploying on CoolVDS, you ensure that the physical layer respects the same high standards as your code.

Don't let legacy infrastructure compromise your audit. Spin up a secure, compliant KVM instance in Oslo on CoolVDS today and see the difference dedicated NVMe performance makes.