You Are Probably One Kernel Panic Away from a Breach
Let’s be honest with ourselves. Most of the Docker containers running in production today are security nightmares. We pull images from Docker Hub, slap a port mapping on them, and call it "isolated." It’s not. If you are running containers as root (UID 0) on a shared kernel, you aren't building infrastructure; you are building a house of cards.
I’ve cleaned up the mess after the runC vulnerability (CVE-2019-5736) hit a client’s staging environment last year. It wasn't pretty. The attacker broke out of the container, gained host root access, and the rest is history. In 2020, with container adoption skyrocketing across Europe, treating containers like lightweight Virtual Machines is negligence.
Here is how we lock things down. No fluff, just configurations that work.
1. The Root Problem (Literally)
By default, Docker containers run as root. If an attacker compromises your application code—say, via a Remote Code Execution (RCE) in your Node.js app—they are root inside the container. If they escape the container (which happens more often than we'd like to admit), they are root on your host.
Stop doing this. Create a user. It adds two lines to your Dockerfile.
FROM node:12.16.1-alpine
WORKDIR /app
COPY . .
# Create a group and user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Switch to this user
USER appuser
CMD ["npm", "start"]
Pro Tip: Never map the Docker socket (/var/run/docker.sock) inside a container unless you absolutely know what you are doing (e.g., CI/CD agents). Giving access to the socket is effectively giving root access to the host.
2. Minimizing the Attack Surface: Multi-Stage Builds
Why does your production container need gcc, curl, or wget? It doesn't. These tools are gifts to attackers trying to download payload scripts. Use multi-stage builds to compile your artifacts and copy only the binary or runtime files to the final image.
Here is a standard Go implementation we use for high-performance microservices:
# Stage 1: Build
FROM golang:1.14-alpine AS builder
WORKDIR /build
COPY . .
RUN go build -o main .
# Stage 2: Run
FROM alpine:3.11
WORKDIR /root/
COPY --from=builder /build/main .
# Drop privileges
RUN adduser -D -g '' appuser
USER appuser
CMD ["./main"]
This results in a 10MB image with zero build tools. Good luck running a shell script inside that.
3. Kernel Capabilities: The `cap-drop` Approach
The Linux kernel divides root privileges into distinct units called capabilities. By default, Docker grants a broad set of these. Your web server does not need NET_ADMIN (network manipulation) or SYS_MODULE (loading kernel modules).
The safest approach is whitelisting: drop everything, then add back only what is necessary.
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE --name web-server nginx
This command drops all capabilities but allows the container to bind to a port (like 80 or 443). If an attacker manages to exploit the process, their hands are tied by the kernel itself.
4. The Infrastructure Layer: Why KVM Matters
Container security is useless if the host itself is compromised. This is where your choice of VPS provider in Norway becomes critical. Many budget providers use OpenVZ or LXC to oversell resources. In those environments, you are sharing a kernel with the noisy neighbor next door who hasn't patched their WordPress since 2016.
This is a security risk.
At CoolVDS, we exclusively use KVM (Kernel-based Virtual Machine) virtualization. Each VPS instances runs its own isolated kernel. Even if a container breakout occurs within your VM, the attacker is trapped inside your specific KVM instance, not roaming the physical host. When we talk about "VPS Norway," we mean true hardware virtualization.
Comparison: Virtualization Isolation
| Feature | OpenVZ / LXC (Common) | KVM (CoolVDS Standard) |
|---|---|---|
| Kernel | Shared with Host | Dedicated / Isolated |
| Security | Low (Neighbor Risk) | High (Hardware Isolation) |
| Custom Modules | Impossible | Full Control (e.g., WireGuard) |
5. Read-Only Filesystems
If your application is stateless (which it should be), it has no business writing to the filesystem. Run your containers as read-only. This prevents attackers from downloading backdoors or modifying configuration files.
docker run --read-only -v /tmp_volume:/tmp:rw my-app
In this example, the root filesystem is immutable. We mount a temporary volume for /tmp because many frameworks still need to write temporary lock files. This setup is incredibly resilient.
6. Local Compliance: GDPR and Datatilsynet
We are operating in Europe. Compliance isn't optional. Under GDPR, you are the Data Controller. If you host on a US-based cloud, you are dealing with the complexities of the Privacy Shield (which is under heavy scrutiny right now).
Hosting locally in Norway solves two problems:
- Latency: CoolVDS peers directly at NIX (Norwegian Internet Exchange). Your packets don't need to route through Frankfurt to reach a user in Oslo. We are talking sub-5ms ping times.
- Sovereignty: Your data stays within Norwegian borders, simplifying your compliance with Datatilsynet requirements.
7. Secrets Management
Stop putting API keys in environment variables. Anyone with access to docker inspect can read them. In 2020, even basic orchestrators support secrets. If you are using Docker Swarm or Kubernetes:
# Docker Swarm Example
printf "my_super_secret_password" | docker secret create db_pass -
# In your compose file
services:
db:
image: mysql
secrets:
- db_pass
The secret is mounted as a file at /run/secrets/db_pass only in the container memory. It is never written to disk and is not visible in environment variables.
Conclusion
Security is not a product; it's a process of reducing risk. By dropping root privileges, using minimal images, and choosing a hosting provider that respects kernel isolation, you make your infrastructure a hard target.
Don't let your infrastructure be the low-hanging fruit for automated botnets. Start with a solid foundation.
Ready to lock down your stack? Deploy a secure, KVM-based instance on CoolVDS today. With NVMe storage and local Norwegian peering, you get security without sacrificing speed.