Skip to content

Container Security

Campus WoL runs as a set of Docker containers, and each container is hardened to limit the damage that could result from a compromised component. This page explains the container-level security measures applied to the platform.

What is a container?

A container is a lightweight, isolated environment that runs a single application or service. Think of it as a sealed box: the application inside can only access what it has been explicitly given. Containers share the host operating system's kernel but have their own filesystem, processes, and network stack. If something goes wrong inside a container, it is isolated from other containers and the host system.

Privilege Separation

The Campus WoL platform is split into several containers, each responsible for a specific task. The main application (API server and web interface) runs in one container, while agents that interact with the network (sending wake packets, running scans) run in separate containers.

This separation means that a vulnerability in a network-facing agent does not automatically give an attacker access to the database, user credentials, or the web interface. Each container has only the permissions it needs for its specific job.

Capability Drops

Linux capabilities are fine-grained permissions that control what privileged operations a process can perform. By default, Docker grants containers a set of capabilities that most applications do not need. Campus WoL drops all capabilities and then adds back only the specific ones required.

What are Linux capabilities?

Traditional Linux security is all-or-nothing: a process either runs as root with full power, or as a regular user with limited power. Capabilities break root's power into small, specific permissions. For example, NET_RAW allows sending raw network packets (needed for wake-on-LAN magic packets), while NET_ADMIN allows configuring network interfaces (needed for network scanning). By dropping all capabilities except the ones strictly needed, each container runs with the absolute minimum power required.

The capability assignments are:

Container Capabilities Why
API server None Does not need any privileged operations
WoL agent NET_RAW Must send raw magic packets on the network
Scan agent NET_RAW, NET_ADMIN Must send raw packets and configure network interfaces for scanning

All other capabilities (including SYS_ADMIN, DAC_OVERRIDE, CHOWN, and dozens more) are dropped.

Read-Only Filesystems

Agent containers run with read-only root filesystems. This means the application inside the container cannot write to any files on disk. If an attacker gains code execution inside an agent container, they cannot install additional tools, modify configuration files, or write persistent backdoors.

Why read-only?

A read-only filesystem is one of the simplest and most effective container hardening measures. Most attack techniques -- installing malware, modifying system libraries, writing shell scripts -- require writing files. A read-only filesystem makes all of those techniques fail immediately, even if the attacker has root access inside the container.

No-New-Privileges

All containers run with the no-new-privileges security option. This prevents processes inside the container from gaining additional privileges through mechanisms like setuid binaries or capability escalation. Even if an attacker finds a setuid binary inside the container, they cannot use it to elevate their permissions.

Unix Socket IPC

Communication between the API server and the network agents uses Unix sockets rather than TCP network connections. The socket file is created with restrictive permissions (mode 0660, group ID 1337) so that only containers with the correct group membership can connect.

What is a Unix socket?

A Unix socket is a way for two programs on the same machine to communicate directly through the filesystem rather than over a network connection. Unlike a TCP port, a Unix socket is never exposed to the network -- it exists only as a file on disk. This means there is no way for a remote attacker to connect to the agent communication channel. File permissions on the socket control exactly which processes can use it.

This design eliminates an entire class of attacks: there is no TCP port for an attacker to scan, connect to, or exploit from outside the host.

Host Network Mode

The WoL and scan agents require host network mode to interact with the physical network. This is necessary because wake-on-LAN magic packets and ARP scans must operate at the Ethernet layer, which is not accessible from Docker's default bridge networking.

Host network mode is applied only to the agent containers that need raw network access. The API server container uses standard Docker networking and does not have direct access to the host network.

Why host network mode?

Docker normally gives each container its own virtual network, which is isolated from the physical network. However, Wake-on-LAN requires sending special Ethernet-layer broadcast packets that must reach the physical network segment where the target machines are connected. Host network mode gives the agent container direct access to the host's network interfaces, allowing it to send these packets. This mode is applied only to the agents that need it.

Next Steps