Console Login

Container Security in 2021: Hardening Strategies for Norwegian DevOps

The Illusion of Isolation: Why Your Containers Are Leaking Data

Let’s be honest. Most of you are treating containers like lightweight Virtual Machines. You pull node:latest, map port 80, mount a volume, and go to lunch. It works on your machine, it works in staging, and then it gets deployed to production.

This is negligence.

In the wake of the Codecov breach earlier this year and the SolarWinds fallout, the "it works" mentality is a liability. If you are running containers in 2021 without specific hardening, you aren't just deploying an application; you are deploying a root-access welcome mat. I’ve spent the last month auditing clusters from Oslo to Trondheim, and the pattern is terrifyingly consistent: default settings, privileged containers, and zero egress filtering.

Here is how we lock this down. No fluff, just the configs that stop you from getting paged at 3 AM.

1. The Root Problem (Literally)

By default, a process inside a Docker container runs as root. If an attacker compromises that process and finds a kernel vulnerability (hello, Dirty Pipe precursors), they break out. Suddenly, they aren't just in the container; they own the host node.

You must enforce the Principle of Least Privilege. Create a specific user for your application.

The Fix: Update Your Dockerfile

Stop using the default user. Here is a production-ready snippet for a Node.js application that I implement on every CoolVDS instance I provision:

FROM node:14-alpine

# Install dependencies required for the app
RUN apk add --no-cache python3 make g++

# Create a group and user so we aren't running as root
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .

# Switch to the non-root user
USER appuser

EXPOSE 3000
CMD ["node", "server.js"]
Pro Tip: Alpine Linux is great for size, but verify your dependencies. If you need standard glibc, consider Google's distroless images. They contain only your application and its runtime dependencies. No shell, no package manager, no noise. It makes an attacker's life miserable because there is no /bin/bash to leverage.

2. Immutable Infrastructure: Read-Only Filesystems

If an attacker manages to inject a shell script into your container, their next step is usually to write a persistence mechanism or download a crypto-miner. Make their job impossible by making the container filesystem read-only.

Your application should only write to specific, mounted volumes—never the container layer itself. This enforces statelessness, a core tenet we preach for scalable architecture on CoolVDS.

Docker Implementation

docker run --read-only -v /my/data:/data my-app

Kubernetes Implementation

In your deployment YAML, you need to set the securityContext. This is non-negotiable for high-security environments, especially if you are handling financial data or GDPR-sensitive info.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: secure-app
spec:
  template:
    spec:
      containers:
      - name: my-app
        image: my-registry/app:v1.2
        securityContext:
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 1001
          capabilities:
            drop:
              - ALL
        volumeMounts:
        - name: tmp-volume
          mountPath: /tmp
      volumes:
      - name: tmp-volume
        emptyDir: {}

Note the capabilities: drop: - ALL line. Linux capabilities break down root privileges into granular units. Most web apps don't need NET_ADMIN or SYS_TIME. Drop everything, then add back only what you strictly need.

3. The "Schrems II" Reality: Data Sovereignty

This is where the "Pragmatic CTO" side of me comes out. Since the Schrems II ruling last year, relying on US-based cloud providers (even their EU regions) is legally risky for Norwegian companies. The transfer of personal data to jurisdictions subject to FISA 702 is a compliance minefield.

This is why physical location and ownership matter. When you deploy on CoolVDS, your data sits on NVMe storage physically located in Oslo or nearby European hubs, governed by local laws. We don't just offer VPS Norway solutions for latency (though < 3ms pings to NIX are nice); we offer them for compliance safety.

Using a KVM-based VPS like CoolVDS adds a hard layer of isolation. Unlike shared container platforms where kernel exploits can bleed across tenants, a KVM hypervisor ensures your kernel is yours alone. It’s a necessary defense-in-depth strategy.

4. Scan Before You Ship

You cannot secure what you don't know exists. Vulnerabilities in base images are discovered daily. Integrating a scanner into your CI/CD pipeline is mandatory in 2021.

I recommend Trivy by Aqua Security. It’s fast, stateless, and integrates easily. Don't wait for the security team to audit you; audit yourself.

# Install Trivy (v0.18.3 - current stable)
apt-get install wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | apt-key add -
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | tee -a /etc/apt/sources.list.d/trivy.list
apt-get update
apt-get install trivy

# Run the scan and fail the build if CRITICAL issues are found
trivy image --severity CRITICAL --exit-code 1 my-app:latest

5. Comparison: Isolation Levels

Not all isolation is created equal. Here is how the stack looks when you peel back the layers.

Technology Isolation Mechanism Risk Profile CoolVDS Verdict
Containers (Docker/LXC) Namespaces & cgroups Shared Kernel. High risk of escape. Good for app packaging, not security boundaries.
Virtual Machines (KVM) Hypervisor Hardware virtualization. Very high isolation. Standard. We use this to wrap your environment.
Bare Metal Physical Air Gap Maximum. No noisy neighbors. Overkill for most web apps, high TCO.

6. Network Policies: The Silent Killer

By default, in a Kubernetes cluster, every pod can talk to every other pod. If your frontend gets popped, the attacker has a direct line to your database pod. Use NetworkPolicies to whitelist traffic.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: db-access
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: database
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: backend
    ports:
    - protocol: TCP
      port: 5432

Final Thoughts

Security is not a product; it is a process of reducing the attack surface until the cost of entry exceeds the value of the data. By stripping root privileges, locking file systems, and hosting on a KVM-backed infrastructure like CoolVDS with strict Norwegian data protections, you aren't just "doing DevOps." You are building a fortress.

The threats in 2021 are sophisticated. Your infrastructure needs to be smarter. Don't let slow I/O or shared kernels be your downfall.

Ready to harden your stack? Deploy a secure, high-performance NVMe KVM instance on CoolVDS today and get full root control—so you can make sure your containers don't have it.