Project 5: Container SELinux Sandbox Lab

A lab environment demonstrating container SELinux confinement, including breaking out of containers without SELinux, showing protection with SELinux, and generating custom container policies with udica.

Quick Reference

Attribute Value
Primary Language Bash/Python
Alternative Languages Go, Rust
Difficulty Level 3: Advanced
Time Estimate 2-3 weeks
Knowledge Area Container Security / SELinux Integration
Tooling Podman, Docker, udica, container-selinux
Prerequisites Podman/Docker experience, Projects 1-3 completed

What You Will Build

A lab environment demonstrating container SELinux confinement, including breaking out of containers without SELinux, showing protection with SELinux, and generating custom container policies with udica.

Why It Matters

This project builds core skills that appear repeatedly in real-world systems and tooling.

Core Challenges

  • Understanding container_t and svirt_lxc_net_t → maps to container type enforcement
  • Demonstrating protection against breakout attempts → maps to MAC vs namespaces
  • Using udica to generate custom policies → maps to automated policy generation
  • MCS separation between containers → maps to multi-category security

Key Concepts

  • Container SELinux Types: container-selinux documentation
  • MCS Isolation: RHEL Container Security Guide
  • udica Tool: Fedora Magazine “Custom SELinux Policies for Containers”
  • Container Escapes: Container Security Ch. 9 - Liz Rice

Real-World Outcome

# Lab 1: See SELinux container types
$ podman run --rm fedora cat /proc/self/attr/current
system_u:system_r:container_t:s0:c123,c456

# Lab 2: Attempt host filesystem access (blocked by SELinux)
$ podman run --rm -v /etc:/host-etc:ro fedora cat /host-etc/shadow
cat: /host-etc/shadow: Permission denied

$ ausearch -m avc -ts recent
type=AVC msg=audit(1705123456.789:1234): avc:  denied  { read }
  for pid=12345 comm="cat" name="shadow"
  scontext=system_u:system_r:container_t:s0:c123,c456
  tcontext=system_u:object_r:shadow_t:s0
  tclass=file permissive=0

# Lab 3: MCS isolation between containers
$ podman run -d --name db redis
$ podman run -d --name web nginx

$ ps -eZ | grep -E "(redis|nginx)"
system_u:system_r:container_t:s0:c100,c200  redis-server
system_u:system_r:container_t:s0:c300,c400  nginx

# Different MCS categories = can't access each other's data!

# Lab 4: Generate custom policy with udica
$ podman inspect myapp | udica myapp_container
Policy myapp_container created!

$ cat myapp_container.cil
(block myapp_container
  (type process)
  (roletype system_r process)
  (typeattributeset container_domain (process))
  (allow process container_file_t (file (read open getattr)))
  ...
)

$ semodule -i myapp_container.cil
$ podman run --security-opt label=type:myapp_container.process myapp

Implementation Guide

  1. Reproduce the simplest happy-path scenario.
  2. Build the smallest working version of the core feature.
  3. Add input validation and error handling.
  4. Add instrumentation/logging to confirm behavior.
  5. Refactor into clean modules with tests.

Milestones

  • Milestone 1: Minimal working program that runs end-to-end.
  • Milestone 2: Correct outputs for typical inputs.
  • Milestone 3: Robust handling of edge cases.
  • Milestone 4: Clean structure and documented usage.

Validation Checklist

  • Output matches the real-world outcome example
  • Handles invalid inputs safely
  • Provides clear errors and exit codes
  • Repeatable results across runs

References

  • Main guide: SELINUX_DEEP_DIVE_LEARNING_PROJECTS.md
  • “Container Security” by Liz Rice