+
+
+
cosmos
+
+
<=
riot
lit
nim
+
prometheus
+
+
pip
#
nvim
+
vault
+
ubuntu
aws
+
tls
+
+
echo
+
+
+
+
+
+
+
+
+
fiber
+
fedora
nomad
spring
prettier
+
+
~
fortran
+
+
+
+
css
+
&&
+
abap
alpine
+
+
java
+
py
+
gcp
rb
+
groovy
vb
+
+
vscode
+
+
influxdb
+
+
protobuf
+
wasm
+
notepad++
cdn
dns
atom
+
+
play
+
Back to Blog
🔐 Setting Up Podman Security on Alpine Linux: Container Hardening Guide
Alpine Linux Podman Container Security

🔐 Setting Up Podman Security on Alpine Linux: Container Hardening Guide

Published Jun 18, 2025

Comprehensive tutorial for security engineers to implement advanced Podman container security on Alpine Linux. Perfect for secure containerization with SELinux, rootless containers, and security policies!

19 min read
0 views
Table of Contents

🔐 Setting Up Podman Security on Alpine Linux: Container Hardening Guide

Let’s implement enterprise-grade Podman container security on Alpine Linux! 🚀 This comprehensive tutorial shows you how to configure rootless containers, security contexts, network isolation, and advanced security policies. Perfect for DevSecOps teams and security-conscious deployments! 😊

🤔 What is Podman Security?

Podman security encompasses rootless container execution, advanced isolation mechanisms, security contexts, and policy enforcement that provides defense-in-depth for containerized applications without requiring a daemon!

Podman security is like:

  • 🛡️ Multi-layered fortress protecting each container with independent security boundaries
  • 🔒 Smart security guard that enforces strict access controls and resource limits
  • 🏰 Isolated kingdoms where each container runs with minimal necessary privileges

🎯 What You Need

Before we start, you need:

  • ✅ Alpine Linux system with container runtime support
  • ✅ Understanding of container security concepts and Linux namespaces
  • ✅ Knowledge of security policies and access controls
  • ✅ Root access for initial system configuration

📋 Step 1: Install and Configure Secure Podman

Install Podman with Security Features

Let’s install Podman with all security components! 😊

What we’re doing: Installing Podman with security tools, rootless support, and policy enforcement capabilities.

# Update package list
apk update

# Install Podman and container tools
apk add podman podman-bash-completion

# Install security and policy tools
apk add podman-compose
apk add fuse-overlayfs slirp4netns

# Install additional security tools
apk add runc crun containers-common

# Install policy and audit tools
apk add shadow coreutils util-linux

# Install networking tools for container isolation
apk add iptables netavark aardvark-dns

# Check Podman version and features
podman version
podman info

# Check security features
podman info | grep -A 10 "security"

echo "Podman with security features installed! 🔐"

What this does: 📖 Installs complete Podman ecosystem with advanced security capabilities.

Example output:

Client:       Podman Engine
Version:      4.7.2
API Version:  4.7.2
Go Version:   go1.19.13
Git Commit:   9f9fc23d44
Built:        Thu Nov 16 00:00:00 2023
OS/Arch:      linux/amd64

What this means: Podman is ready for secure container deployment! ✅

Configure Rootless Container Environment

Let’s set up secure rootless container execution! 🎯

What we’re doing: Configuring user namespaces, subUID/subGID mappings, and rootless container policies for maximum security.

# Configure subUID and subGID for rootless containers
echo "Configuring rootless container environment..."

# Create user for rootless containers if not exists
CONTAINER_USER="${1:-$USER}"

# Set up subUID and subGID mappings
echo "Setting up user namespace mappings for $CONTAINER_USER"

# Configure subUID ranges (100000 UIDs per user)
if ! grep -q "^$CONTAINER_USER:" /etc/subuid; then
    echo "$CONTAINER_USER:100000:65536" >> /etc/subuid
fi

# Configure subGID ranges
if ! grep -q "^$CONTAINER_USER:" /etc/subgid; then
    echo "$CONTAINER_USER:100000:65536" >> /etc/subgid
fi

# Create user-specific container configuration
mkdir -p ~/.config/containers

# Create containers.conf for rootless security
cat > ~/.config/containers/containers.conf << 'EOF'
# Podman Security Configuration for Rootless Containers

[containers]
# Default user namespace mode
userns = "auto"

# Enable user namespace for better isolation
userns_size = 65536

# Default security options
default_ulimits = [
  "nofile=65536:65536",
  "nproc=4096:4096"
]

# Security labels and options
label = true
seccomp_profile = "/usr/share/containers/seccomp.json"
apparmor_profile = "containers-default-0.44.1"

# Default capabilities (minimal set)
default_capabilities = [
  "CHOWN",
  "DAC_OVERRIDE", 
  "FOWNER",
  "FSETID",
  "KILL",
  "NET_BIND_SERVICE",
  "SETFCAP",
  "SETGID",
  "SETPCAP",
  "SETUID",
  "SYS_CHROOT"
]

# Remove dangerous capabilities
default_sysctls = [
  "net.ipv4.ping_group_range=0 0",
]

# Container engine settings
runtime = "crun"
events_logger = "journald"
log_driver = "journald"

# Rootless networking
netns = "slirp4netns"

[engine]
# Engine security configuration
cgroup_manager = "systemd"
events_logger = "journald"
runtime = "crun"

# Image security settings
pull_policy = "always"

# Remote connections (disabled for security)
remote = false

[secrets]
# Secrets driver configuration
driver = "file"

[network]
# Network security configuration
network_backend = "netavark"
default_network = "podman"
dns_bind_port = 53

[machine]
# Machine configuration (if using podman machine)
cpus = 2
disk_size = 10
memory = 2048
EOF

# Create secure storage configuration
cat > ~/.config/containers/storage.conf << 'EOF'
# Podman Storage Security Configuration

[storage]
# Storage driver for security
driver = "overlay"

# Rootless storage paths
runroot = "/run/user/1000/containers"
graphroot = "/home/$USER/.local/share/containers/storage"

[storage.options]
# Overlay storage options for security
additionalimagestores = [
]

# Security options for overlay
mount_program = "/usr/bin/fuse-overlayfs"
mountopt = "nodev,fsync=0"

[storage.options.overlay]
# Overlay security settings
mount_program = "/usr/bin/fuse-overlayfs"
mountopt = "nodev"

# Force mask for security
force_mask = "shared"
EOF

# Set proper permissions
chmod 644 ~/.config/containers/containers.conf
chmod 644 ~/.config/containers/storage.conf

# Create Podman security policy
mkdir -p ~/.config/containers/policy.d

cat > ~/.config/containers/policy.json << 'EOF'
{
  "default": [
    {
      "type": "reject"
    }
  ],
  "transports": {
    "docker": {
      "docker.io": [
        {
          "type": "insecureAcceptAnything"
        }
      ],
      "localhost": [
        {
          "type": "insecureAcceptAnything"
        }
      ],
      "quay.io": [
        {
          "type": "insecureAcceptAnything"
        }
      ]
    },
    "docker-daemon": {
      "": [
        {
          "type": "insecureAcceptAnything"
        }
      ]
    }
  }
}
EOF

# Initialize rootless Podman
echo "Initializing rootless Podman..."
podman system migrate

# Test rootless configuration
echo "Testing rootless container execution..."
podman run --rm alpine:latest echo "Rootless container security test successful!"

echo "Rootless container environment configured! 🔒"

What this creates: Secure rootless container environment with proper isolation! 🌟

🛡️ Step 2: Implement Advanced Security Policies

Configure Security Contexts and Profiles

Let’s implement comprehensive security contexts! 🛠️

What we’re doing: Creating custom security profiles, SELinux contexts, and seccomp filters for maximum container security.

# Create advanced security profiles directory
mkdir -p ~/.config/containers/security-profiles

# Create custom seccomp profile
cat > ~/.config/containers/security-profiles/strict-seccomp.json << 'EOF'
{
  "defaultAction": "SCMP_ACT_ERRNO",
  "archMap": [
    {
      "architecture": "SCMP_ARCH_X86_64",
      "subArchitectures": [
        "SCMP_ARCH_X86",
        "SCMP_ARCH_X32"
      ]
    },
    {
      "architecture": "SCMP_ARCH_AARCH64",
      "subArchitectures": [
        "SCMP_ARCH_ARM"
      ]
    }
  ],
  "syscalls": [
    {
      "names": [
        "accept",
        "accept4",
        "access",
        "adjtimex",
        "alarm",
        "bind",
        "brk",
        "capget",
        "capset",
        "chdir",
        "chmod",
        "chown",
        "chown32",
        "clock_getres",
        "clock_gettime",
        "clock_nanosleep",
        "close",
        "connect",
        "copy_file_range",
        "creat",
        "dup",
        "dup2",
        "dup3",
        "epoll_create",
        "epoll_create1",
        "epoll_ctl",
        "epoll_pwait",
        "epoll_wait",
        "eventfd",
        "eventfd2",
        "execve",
        "execveat",
        "exit",
        "exit_group",
        "faccessat",
        "fadvise64",
        "fallocate",
        "fanotify_mark",
        "fchdir",
        "fchmod",
        "fchmodat",
        "fchown",
        "fchown32",
        "fchownat",
        "fcntl",
        "fcntl64",
        "fdatasync",
        "fgetxattr",
        "flistxattr",
        "flock",
        "fork",
        "fremovexattr",
        "fsetxattr",
        "fstat",
        "fstat64",
        "fstatat64",
        "fstatfs",
        "fstatfs64",
        "fsync",
        "ftruncate",
        "ftruncate64",
        "futex",
        "getcwd",
        "getdents",
        "getdents64",
        "getegid",
        "getegid32",
        "geteuid",
        "geteuid32",
        "getgid",
        "getgid32",
        "getgroups",
        "getgroups32",
        "getitimer",
        "getpeername",
        "getpgid",
        "getpgrp",
        "getpid",
        "getppid",
        "getpriority",
        "getrandom",
        "getresgid",
        "getresgid32",
        "getresuid",
        "getresuid32",
        "getrlimit",
        "get_robust_list",
        "getrusage",
        "getsid",
        "getsockname",
        "getsockopt",
        "get_thread_area",
        "gettid",
        "gettimeofday",
        "getuid",
        "getuid32",
        "getxattr",
        "inotify_add_watch",
        "inotify_init",
        "inotify_init1",
        "inotify_rm_watch",
        "io_cancel",
        "ioctl",
        "io_destroy",
        "io_getevents",
        "ioprio_get",
        "ioprio_set",
        "io_setup",
        "io_submit",
        "ipc",
        "kill",
        "lchown",
        "lchown32",
        "lgetxattr",
        "link",
        "linkat",
        "listen",
        "listxattr",
        "llistxattr",
        "lremovexattr",
        "lseek",
        "lsetxattr",
        "lstat",
        "lstat64",
        "madvise",
        "memfd_create",
        "mincore",
        "mkdir",
        "mkdirat",
        "mknod",
        "mknodat",
        "mlock",
        "mlock2",
        "mlockall",
        "mmap",
        "mmap2",
        "mprotect",
        "mq_getsetattr",
        "mq_notify",
        "mq_open",
        "mq_timedreceive",
        "mq_timedsend",
        "mq_unlink",
        "mremap",
        "msgctl",
        "msgget",
        "msgrcv",
        "msgsnd",
        "msync",
        "munlock",
        "munlockall",
        "munmap",
        "nanosleep",
        "newfstatat",
        "open",
        "openat",
        "pause",
        "pipe",
        "pipe2",
        "poll",
        "ppoll",
        "prctl",
        "pread64",
        "prlimit64",
        "pselect6",
        "pwrite64",
        "read",
        "readahead",
        "readlink",
        "readlinkat",
        "readv",
        "recv",
        "recvfrom",
        "recvmmsg",
        "recvmsg",
        "rename",
        "renameat",
        "renameat2",
        "restart_syscall",
        "rmdir",
        "rt_sigaction",
        "rt_sigpending",
        "rt_sigprocmask",
        "rt_sigqueueinfo",
        "rt_sigreturn",
        "rt_sigsuspend",
        "rt_sigtimedwait",
        "rt_tgsigqueueinfo",
        "sched_getaffinity",
        "sched_getattr",
        "sched_getparam",
        "sched_get_priority_max",
        "sched_get_priority_min",
        "sched_getscheduler",
        "sched_setaffinity",
        "sched_setattr",
        "sched_setparam",
        "sched_setscheduler",
        "sched_yield",
        "seccomp",
        "select",
        "semctl",
        "semget",
        "semop",
        "semtimedop",
        "send",
        "sendfile",
        "sendfile64",
        "sendmmsg",
        "sendmsg",
        "sendto",
        "setfsgid",
        "setfsgid32",
        "setfsuid",
        "setfsuid32",
        "setgid",
        "setgid32",
        "setgroups",
        "setgroups32",
        "setitimer",
        "setpgid",
        "setpriority",
        "setregid",
        "setregid32",
        "setresgid",
        "setresgid32",
        "setresuid",
        "setresuid32",
        "setreuid",
        "setreuid32",
        "setrlimit",
        "set_robust_list",
        "setsid",
        "setsockopt",
        "set_thread_area",
        "set_tid_address",
        "setuid",
        "setuid32",
        "setxattr",
        "shmat",
        "shmctl",
        "shmdt",
        "shmget",
        "shutdown",
        "sigaltstack",
        "signalfd",
        "signalfd4",
        "sigpending",
        "sigprocmask",
        "sigreturn",
        "sigsuspend",
        "socket",
        "socketcall",
        "socketpair",
        "splice",
        "stat",
        "stat64",
        "statfs",
        "statfs64",
        "statx",
        "symlink",
        "symlinkat",
        "sync",
        "sync_file_range",
        "syncfs",
        "sysinfo",
        "tee",
        "tgkill",
        "time",
        "timer_create",
        "timer_delete",
        "timerfd_create",
        "timerfd_gettime",
        "timerfd_settime",
        "timer_getoverrun",
        "timer_gettime",
        "timer_settime",
        "times",
        "tkill",
        "truncate",
        "truncate64",
        "ugetrlimit",
        "umask",
        "uname",
        "unlink",
        "unlinkat",
        "utime",
        "utimensat",
        "utimes",
        "vfork",
        "vmsplice",
        "wait4",
        "waitid",
        "waitpid",
        "write",
        "writev"
      ],
      "action": "SCMP_ACT_ALLOW",
      "args": [],
      "comment": "",
      "includes": {},
      "excludes": {}
    }
  ]
}
EOF

# Create AppArmor profile for containers
cat > ~/.config/containers/security-profiles/podman-secure << 'EOF'
#include <tunables/global>

profile podman-secure flags=(attach_disconnected,mediate_deleted) {
  #include <abstractions/base>

  # File system access restrictions
  deny /etc/shadow r,
  deny /etc/passwd w,
  deny /etc/sudoers r,
  deny /proc/sys/kernel/** w,
  deny /sys/kernel/security/** rw,

  # Network restrictions
  deny network raw,
  deny network packet,

  # Capability restrictions
  deny capability sys_admin,
  deny capability sys_module,
  deny capability sys_time,
  deny capability sys_boot,
  deny capability mac_admin,
  deny capability mac_override,

  # Allow container-specific operations
  capability chown,
  capability dac_override,
  capability fowner,
  capability fsetid,
  capability kill,
  capability setgid,
  capability setuid,
  capability setpcap,
  capability sys_chroot,
  capability net_bind_service,

  # File system access
  /usr/bin/** ix,
  /bin/** ix,
  /sbin/** ix,
  /lib/** mr,
  /lib64/** mr,
  /usr/lib/** mr,
  /tmp/** rw,
  /var/tmp/** rw,
  /dev/null rw,
  /dev/zero r,
  /dev/urandom r,
  /dev/random r,
  /proc/*/stat r,
  /proc/*/status r,
  /proc/meminfo r,
  /proc/cpuinfo r,
  /sys/fs/cgroup/** r,

  # Container runtime requirements
  mount fstype=tmpfs -> /tmp/,
  mount fstype=tmpfs -> /var/tmp/,
  mount fstype=proc -> /proc/,
  mount fstype=sysfs -> /sys/,
  mount fstype=devpts -> /dev/pts/,
  mount options=(bind,ro) -> /etc/resolv.conf,
  mount options=(bind,ro) -> /etc/hostname,
  mount options=(bind,ro) -> /etc/hosts,

  # Signal restrictions
  signal (send) set=(kill,term,int,quit,usr1,usr2),
  signal (receive) set=(kill,term,int,quit,usr1,usr2),

  # Ptrace restrictions
  deny ptrace (readby, tracedby),
  ptrace (trace) peer=@{profile_name},
}
EOF

# Create container security policy enforcement script
cat > ~/.config/containers/security-profiles/enforce-security.sh << 'EOF'
#!/bin/bash
# Container Security Policy Enforcement

# Configuration
SECURITY_PROFILES_DIR="$HOME/.config/containers/security-profiles"
SECCOMP_PROFILE="$SECURITY_PROFILES_DIR/strict-seccomp.json"
APPARMOR_PROFILE="podman-secure"

# Function to run container with strict security
run_secure_container() {
    local image="$1"
    local name="${2:-secure-container}"
    shift 2
    local cmd="$@"
    
    echo "🔐 Running container with enhanced security..."
    
    podman run \
        --name "$name" \
        --rm \
        --read-only \
        --tmpfs /tmp:rw,noexec,nosuid,size=100m \
        --tmpfs /var/tmp:rw,noexec,nosuid,size=50m \
        --security-opt seccomp="$SECCOMP_PROFILE" \
        --security-opt apparmor="$APPARMOR_PROFILE" \
        --security-opt no-new-privileges:true \
        --cap-drop ALL \
        --cap-add CHOWN \
        --cap-add DAC_OVERRIDE \
        --cap-add FOWNER \
        --cap-add SETGID \
        --cap-add SETUID \
        --user 1000:1000 \
        --userns keep-id \
        --network slirp4netns \
        --pids-limit 100 \
        --memory 512m \
        --cpus 1.0 \
        --ulimit nofile=1024:1024 \
        --ulimit nproc=64:64 \
        "$image" $cmd
}

# Function to create secure container with custom settings
create_secure_container() {
    local image="$1"
    local name="$2"
    local workdir="${3:-/app}"
    
    echo "🏗️  Creating secure container: $name"
    
    podman create \
        --name "$name" \
        --read-only \
        --tmpfs /tmp:rw,noexec,nosuid,size=100m \
        --security-opt seccomp="$SECCOMP_PROFILE" \
        --security-opt no-new-privileges:true \
        --cap-drop ALL \
        --cap-add CHOWN \
        --cap-add SETGID \
        --cap-add SETUID \
        --user 1000:1000 \
        --userns keep-id \
        --network none \
        --pids-limit 50 \
        --memory 256m \
        --cpus 0.5 \
        --workdir "$workdir" \
        "$image"
    
    echo "✅ Secure container '$name' created"
}

# Function to audit container security
audit_container_security() {
    local container_name="$1"
    
    if [ -z "$container_name" ]; then
        echo "Usage: audit_container_security <container_name>"
        return 1
    fi
    
    echo "🔍 Security audit for container: $container_name"
    echo "================================================"
    
    # Check if container exists
    if ! podman container exists "$container_name"; then
        echo "❌ Container '$container_name' does not exist"
        return 1
    fi
    
    # Get container configuration
    config=$(podman inspect "$container_name")
    
    echo "📋 Security Configuration:"
    echo "-------------------------"
    
    # Check read-only filesystem
    readonly_fs=$(echo "$config" | jq -r '.[0].HostConfig.ReadonlyRootfs')
    if [ "$readonly_fs" = "true" ]; then
        echo "✅ Read-only filesystem: Enabled"
    else
        echo "⚠️  Read-only filesystem: Disabled"
    fi
    
    # Check capabilities
    echo ""
    echo "🔐 Capabilities:"
    caps_add=$(echo "$config" | jq -r '.[0].HostConfig.CapAdd[]?' 2>/dev/null)
    caps_drop=$(echo "$config" | jq -r '.[0].HostConfig.CapDrop[]?' 2>/dev/null)
    
    if [ -n "$caps_drop" ]; then
        echo "✅ Dropped capabilities: $caps_drop"
    else
        echo "⚠️  No capabilities dropped"
    fi
    
    if [ -n "$caps_add" ]; then
        echo "⚠️  Added capabilities: $caps_add"
    fi
    
    # Check security options
    echo ""
    echo "🛡️  Security Options:"
    sec_opts=$(echo "$config" | jq -r '.[0].HostConfig.SecurityOpt[]?' 2>/dev/null)
    if [ -n "$sec_opts" ]; then
        echo "$sec_opts" | while read opt; do
            echo "✅ $opt"
        done
    else
        echo "⚠️  No security options configured"
    fi
    
    # Check resource limits
    echo ""
    echo "📊 Resource Limits:"
    memory=$(echo "$config" | jq -r '.[0].HostConfig.Memory')
    cpus=$(echo "$config" | jq -r '.[0].HostConfig.NanoCpus')
    pids_limit=$(echo "$config" | jq -r '.[0].HostConfig.PidsLimit')
    
    [ "$memory" != "0" ] && echo "✅ Memory limit: $(($memory / 1024 / 1024))MB"
    [ "$cpus" != "0" ] && echo "✅ CPU limit: $(echo "scale=2; $cpus / 1000000000" | bc)CPUs"
    [ "$pids_limit" != "0" ] && echo "✅ PIDs limit: $pids_limit"
    
    # Check user namespace
    echo ""
    echo "👤 User Configuration:"
    user=$(echo "$config" | jq -r '.[0].Config.User')
    [ -n "$user" ] && echo "✅ User: $user" || echo "⚠️  Running as root"
    
    echo ""
    echo "Security audit completed."
}

# Main function
case "$1" in
    run)
        shift
        run_secure_container "$@"
        ;;
    create)
        shift
        create_secure_container "$@"
        ;;
    audit)
        audit_container_security "$2"
        ;;
    *)
        echo "Container Security Enforcement Tool"
        echo "Usage: $0 {run|create|audit} [options]"
        echo ""
        echo "Commands:"
        echo "  run <image> [name] [cmd]     - Run container with strict security"
        echo "  create <image> <name> [dir]  - Create secure container"
        echo "  audit <container>            - Audit container security"
        echo ""
        echo "Examples:"
        echo "  $0 run alpine:latest test-container sh"
        echo "  $0 create alpine:latest secure-app /app"
        echo "  $0 audit my-container"
        ;;
esac
EOF

chmod +x ~/.config/containers/security-profiles/enforce-security.sh

echo "Advanced security policies configured! 🛡️"

What this creates: Comprehensive security policies with strict enforcement! 🌟

🔒 Step 3: Implement Network Security and Isolation

Configure Secure Container Networking

Let’s implement advanced network security for containers! 🌐

What we’re doing: Setting up network isolation, secure networking policies, and container-to-container communication controls.

# Create network security configuration
mkdir -p ~/.config/containers/networks

# Create secure network configuration
cat > ~/.config/containers/networks/secure-network.conf << 'EOF'
# Secure Container Network Configuration

# Network isolation levels
ISOLATION_LEVEL="strict"
INTER_CONTAINER_COMMUNICATION="false"
EXTERNAL_ACCESS="limited"

# Firewall rules for container networks
ALLOWED_PORTS="80,443,8080"
BLOCKED_RANGES="10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"

# DNS security
SECURE_DNS="true"
DNS_SERVERS="1.1.1.1,8.8.8.8"
EOF

# Create network security management script
cat > ~/.config/containers/networks/network-security.sh << 'EOF'
#!/bin/bash
# Container Network Security Management

# Configuration
NETWORKS_DIR="$HOME/.config/containers/networks"
CONFIG_FILE="$NETWORKS_DIR/secure-network.conf"

# Load configuration
[ -f "$CONFIG_FILE" ] && source "$CONFIG_FILE"

# Function to create secure network
create_secure_network() {
    local network_name="${1:-secure-net}"
    local subnet="${2:-10.89.0.0/24}"
    
    echo "🌐 Creating secure container network: $network_name"
    
    # Remove existing network if present
    podman network exists "$network_name" && podman network rm "$network_name"
    
    # Create isolated network
    podman network create \
        --driver bridge \
        --subnet "$subnet" \
        --disable-dns \
        --internal \
        "$network_name"
    
    echo "✅ Secure network '$network_name' created with subnet $subnet"
}

# Function to create DMZ network
create_dmz_network() {
    local network_name="${1:-dmz-net}"
    local subnet="${2:-10.89.1.0/24}"
    
    echo "🛡️  Creating DMZ network: $network_name"
    
    podman network create \
        --driver bridge \
        --subnet "$subnet" \
        --dns "1.1.1.1" \
        --dns "8.8.8.8" \
        "$network_name"
    
    # Apply firewall rules for DMZ
    create_dmz_firewall_rules "$network_name" "$subnet"
    
    echo "✅ DMZ network '$network_name' created with controlled access"
}

# Function to create firewall rules for DMZ
create_dmz_firewall_rules() {
    local network_name="$1"
    local subnet="$2"
    
    echo "🔥 Configuring firewall rules for DMZ network..."
    
    # Create iptables rules for container network security
    cat > "/tmp/dmz-firewall-${network_name}.sh" << FWEOF
#!/bin/bash
# DMZ Firewall Rules for $network_name

# Variables
SUBNET="$subnet"
INTERFACE="cni-podman1"

# Allow established connections
iptables -I FORWARD -o \$INTERFACE -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Allow specific outbound connections only
iptables -I FORWARD -i \$INTERFACE -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -i \$INTERFACE -p tcp --dport 443 -j ACCEPT
iptables -I FORWARD -i \$INTERFACE -p tcp --dport 53 -j ACCEPT
iptables -I FORWARD -i \$INTERFACE -p udp --dport 53 -j ACCEPT

# Block inter-container communication by default
iptables -I FORWARD -i \$INTERFACE -o \$INTERFACE -j DROP

# Block access to private networks
iptables -I FORWARD -i \$INTERFACE -d 10.0.0.0/8 -j DROP
iptables -I FORWARD -i \$INTERFACE -d 172.16.0.0/12 -j DROP
iptables -I FORWARD -i \$INTERFACE -d 192.168.0.0/16 -j DROP

# Log dropped packets
iptables -I FORWARD -i \$INTERFACE -j LOG --log-prefix "DMZ-DROPPED: "

echo "DMZ firewall rules applied for network $network_name"
FWEOF
    
    chmod +x "/tmp/dmz-firewall-${network_name}.sh"
    echo "Firewall rules script created: /tmp/dmz-firewall-${network_name}.sh"
}

# Function to run container in secure network
run_container_secure_network() {
    local image="$1"
    local network="${2:-secure-net}"
    local name="${3:-secure-app}"
    shift 3
    local cmd="$@"
    
    echo "🔒 Running container in secure network..."
    
    # Ensure network exists
    if ! podman network exists "$network"; then
        echo "Network '$network' not found. Creating..."
        create_secure_network "$network"
    fi
    
    # Run container with network security
    podman run \
        --name "$name" \
        --rm \
        --network "$network" \
        --dns "1.1.1.1" \
        --dns "8.8.8.8" \
        --read-only \
        --tmpfs /tmp:rw,noexec,nosuid,size=100m \
        --security-opt no-new-privileges:true \
        --cap-drop ALL \
        --cap-add CHOWN \
        --cap-add SETGID \
        --cap-add SETUID \
        --user 1000:1000 \
        --userns keep-id \
        --pids-limit 50 \
        --memory 256m \
        --cpus 0.5 \
        "$image" $cmd
}

# Function to create network isolation policy
create_network_policy() {
    local policy_name="$1"
    local policy_type="${2:-strict}"
    
    mkdir -p "$NETWORKS_DIR/policies"
    
    case "$policy_type" in
        strict)
            cat > "$NETWORKS_DIR/policies/${policy_name}.json" << 'STRICTEOF'
{
  "name": "strict-isolation",
  "description": "Strict network isolation policy",
  "rules": {
    "ingress": {
      "default": "deny",
      "allowed": []
    },
    "egress": {
      "default": "deny", 
      "allowed": [
        {
          "protocol": "tcp",
          "port": 443,
          "destination": "external"
        },
        {
          "protocol": "tcp", 
          "port": 80,
          "destination": "external"
        },
        {
          "protocol": "udp",
          "port": 53,
          "destination": "external"
        }
      ]
    },
    "inter_container": "deny"
  }
}
STRICTEOF
            ;;
        moderate)
            cat > "$NETWORKS_DIR/policies/${policy_name}.json" << 'MODEOF'
{
  "name": "moderate-isolation",
  "description": "Moderate network isolation policy",
  "rules": {
    "ingress": {
      "default": "deny",
      "allowed": [
        {
          "protocol": "tcp",
          "port": 8080,
          "source": "container_network"
        }
      ]
    },
    "egress": {
      "default": "allow",
      "blocked": [
        {
          "destination": "10.0.0.0/8"
        },
        {
          "destination": "172.16.0.0/12"
        },
        {
          "destination": "192.168.0.0/16"
        }
      ]
    },
    "inter_container": "limited"
  }
}
MODEOF
            ;;
    esac
    
    echo "Network policy '$policy_name' created with '$policy_type' isolation"
}

# Function to monitor network traffic
monitor_network_traffic() {
    local network_name="${1:-secure-net}"
    
    echo "📊 Monitoring network traffic for: $network_name"
    echo "Press Ctrl+C to stop monitoring"
    echo "================================"
    
    # Monitor iptables logs for network activity
    tail -f /var/log/messages | grep -E "(DMZ-DROPPED|FORWARD)" &
    TAIL_PID=$!
    
    # Monitor container network statistics
    while true; do
        echo ""
        echo "📈 Network Statistics - $(date)"
        echo "=============================="
        
        # Show active containers on network
        echo "Active containers:"
        podman network inspect "$network_name" 2>/dev/null | jq -r '.[] | .containers | keys[]?' | while read container_id; do
            if [ -n "$container_id" ]; then
                container_name=$(podman inspect "$container_id" 2>/dev/null | jq -r '.[0].Name' 2>/dev/null)
                echo "  - $container_name ($container_id)"
            fi
        done
        
        sleep 10
    done
    
    # Cleanup on exit
    trap "kill $TAIL_PID 2>/dev/null" EXIT
}

# Main function
case "$1" in
    create-secure)
        create_secure_network "$2" "$3"
        ;;
    create-dmz)
        create_dmz_network "$2" "$3"
        ;;
    run-secure)
        shift
        run_container_secure_network "$@"
        ;;
    policy)
        create_network_policy "$2" "$3"
        ;;
    monitor)
        monitor_network_traffic "$2"
        ;;
    list)
        echo "📋 Available networks:"
        podman network ls
        echo ""
        echo "📋 Network policies:"
        ls -1 "$NETWORKS_DIR/policies/"*.json 2>/dev/null | basename -s .json || echo "No policies found"
        ;;
    *)
        echo "Container Network Security Management"
        echo "Usage: $0 {create-secure|create-dmz|run-secure|policy|monitor|list} [options]"
        echo ""
        echo "Commands:"
        echo "  create-secure [name] [subnet]  - Create secure isolated network"
        echo "  create-dmz [name] [subnet]     - Create DMZ network with firewall"
        echo "  run-secure <image> [net] [name] [cmd] - Run container in secure network"
        echo "  policy <name> [strict|moderate] - Create network policy"
        echo "  monitor [network]              - Monitor network traffic"
        echo "  list                          - List networks and policies"
        ;;
esac
EOF

chmod +x ~/.config/containers/networks/network-security.sh

# Create default secure networks
~/.config/containers/networks/network-security.sh create-secure secure-net 10.89.0.0/24
~/.config/containers/networks/network-security.sh create-dmz dmz-net 10.89.1.0/24

echo "Container network security configured! 🌐"

What this creates: Advanced network security with isolation and monitoring! ✅

📊 Quick Podman Security Commands Table

CommandPurposeResult
🔧 podman run --read-onlyRead-only filesystem✅ Immutable container
🔍 podman run --cap-drop ALLRemove all capabilities✅ Minimal privileges
🚀 --security-opt no-new-privilegesPrevent privilege escalation✅ Security hardening
📋 --userns keep-idUse rootless user namespace✅ User isolation

🎮 Practice Time!

Let’s practice what you learned! Try these Podman security scenarios:

Example 1: Secure Web Application Deployment 🟢

What we’re doing: Deploying a complete web application with multi-layered security, including secure containers, network isolation, and monitoring.

# Create secure web application deployment
mkdir -p ~/.config/containers/web-app-security

# Create secure web application deployment script
cat > ~/.config/containers/web-app-security/deploy-secure-webapp.sh << 'EOF'
#!/bin/bash
# Secure Web Application Deployment with Podman

# Configuration
APP_NAME="secure-webapp"
DB_NAME="secure-database"
NETWORK_NAME="webapp-network"
WEB_IMAGE="nginx:alpine"
DB_IMAGE="postgres:alpine"

# Security profiles
SECCOMP_PROFILE="$HOME/.config/containers/security-profiles/strict-seccomp.json"

echo "🚀 Deploying secure web application stack..."

# Step 1: Create secure network
echo "1️⃣  Creating secure application network..."
podman network create \
    --driver bridge \
    --subnet 10.88.0.0/24 \
    --disable-dns \
    "$NETWORK_NAME"

# Step 2: Deploy secure database
echo "2️⃣  Deploying secure database container..."
podman run -d \
    --name "$DB_NAME" \
    --network "$NETWORK_NAME" \
    --ip 10.88.0.10 \
    --read-only \
    --tmpfs /tmp:rw,noexec,nosuid,size=100m \
    --tmpfs /var/run/postgresql:rw,noexec,nosuid,size=50m \
    --volume db-data:/var/lib/postgresql/data:Z \
    --security-opt seccomp="$SECCOMP_PROFILE" \
    --security-opt no-new-privileges:true \
    --cap-drop ALL \
    --cap-add CHOWN \
    --cap-add DAC_OVERRIDE \
    --cap-add FOWNER \
    --cap-add SETGID \
    --cap-add SETUID \
    --user postgres \
    --userns keep-id \
    --pids-limit 100 \
    --memory 512m \
    --cpus 1.0 \
    --ulimit nofile=1024:1024 \
    --env POSTGRES_DB=webapp \
    --env POSTGRES_USER=webapp \
    --env POSTGRES_PASSWORD=secure_password_123 \
    --restart unless-stopped \
    "$DB_IMAGE"

# Step 3: Deploy secure web server
echo "3️⃣  Deploying secure web server container..."

# Create nginx configuration
mkdir -p ~/.config/containers/web-app-security/nginx-config
cat > ~/.config/containers/web-app-security/nginx-config/nginx.conf << 'NGINXEOF'
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
    use epoll;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    # Security headers
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
    add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';";
    
    # Hide nginx version
    server_tokens off;
    
    # Logging
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /var/log/nginx/access.log main;
    
    # Performance
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    client_max_body_size 1M;
    
    # Gzip
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    
    server {
        listen 80;
        server_name localhost;
        root /usr/share/nginx/html;
        index index.html;
        
        # Security measures
        location ~ /\. {
            deny all;
            access_log off;
            log_not_found off;
        }
        
        location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
        
        location / {
            try_files $uri $uri/ =404;
        }
        
        # Health check endpoint
        location /health {
            access_log off;
            return 200 "healthy\n";
            add_header Content-Type text/plain;
        }
    }
}
NGINXEOF

# Create sample web content
cat > ~/.config/containers/web-app-security/nginx-config/index.html << 'HTMLEOF'
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Secure Web Application</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; background-color: #f5f5f5; }
        .container { max-width: 800px; margin: 0 auto; background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
        .header { color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; margin-bottom: 20px; }
        .security-badge { background: #27ae60; color: white; padding: 5px 10px; border-radius: 3px; font-size: 0.9em; }
        .feature { background: #ecf0f1; padding: 15px; margin: 10px 0; border-left: 4px solid #3498db; }
        .status { color: #27ae60; font-weight: bold; }
    </style>
</head>
<body>
    <div class="container">
        <h1 class="header">🔐 Secure Web Application <span class="security-badge">HARDENED</span></h1>
        
        <div class="feature">
            <h3>🛡️ Security Features</h3>
            <ul>
                <li><span class="status">✅</span> Rootless container execution</li>
                <li><span class="status">✅</span> Read-only filesystem</li>
                <li><span class="status">✅</span> Minimal capabilities</li>
                <li><span class="status">✅</span> Strict seccomp profile</li>
                <li><span class="status">✅</span> Network isolation</li>
                <li><span class="status">✅</span> Resource limits enforced</li>
            </ul>
        </div>
        
        <div class="feature">
            <h3>🌐 Network Security</h3>
            <ul>
                <li><span class="status">✅</span> Isolated container network</li>
                <li><span class="status">✅</span> Firewall rules applied</li>
                <li><span class="status">✅</span> Secure DNS configuration</li>
                <li><span class="status">✅</span> Inter-container communication controlled</li>
            </ul>
        </div>
        
        <div class="feature">
            <h3>📊 Monitoring</h3>
            <p>Container security is actively monitored with:</p>
            <ul>
                <li>Resource usage tracking</li>
                <li>Network traffic analysis</li>
                <li>Security policy compliance</li>
                <li>Vulnerability scanning</li>
            </ul>
        </div>
        
        <div class="feature">
            <h3>🚀 Deployment Info</h3>
            <p><strong>Platform:</strong> Alpine Linux with Podman</p>
            <p><strong>Security Level:</strong> Enterprise Grade</p>
            <p><strong>Deployment Date:</strong> <script>document.write(new Date().toLocaleDateString());</script></p>
        </div>
    </div>
</body>
</html>
HTMLEOF

# Deploy web server
podman run -d \
    --name "$APP_NAME" \
    --network "$NETWORK_NAME" \
    --ip 10.88.0.20 \
    --publish 8080:80 \
    --read-only \
    --tmpfs /tmp:rw,noexec,nosuid,size=100m \
    --tmpfs /var/cache/nginx:rw,noexec,nosuid,size=50m \
    --tmpfs /var/run:rw,noexec,nosuid,size=10m \
    --volume ~/.config/containers/web-app-security/nginx-config/nginx.conf:/etc/nginx/nginx.conf:ro,Z \
    --volume ~/.config/containers/web-app-security/nginx-config/index.html:/usr/share/nginx/html/index.html:ro,Z \
    --security-opt seccomp="$SECCOMP_PROFILE" \
    --security-opt no-new-privileges:true \
    --cap-drop ALL \
    --cap-add CHOWN \
    --cap-add DAC_OVERRIDE \
    --cap-add SETGID \
    --cap-add SETUID \
    --cap-add NET_BIND_SERVICE \
    --user nginx \
    --userns keep-id \
    --pids-limit 50 \
    --memory 256m \
    --cpus 0.5 \
    --ulimit nofile=1024:1024 \
    --restart unless-stopped \
    "$WEB_IMAGE"

# Step 4: Create monitoring script
cat > ~/.config/containers/web-app-security/monitor-webapp.sh << 'MONEOF'
#!/bin/bash
# Web Application Security Monitoring

echo "🔍 Secure Web Application Monitoring"
echo "===================================="

while true; do
    clear
    echo "📊 Security Status - $(date)"
    echo "============================"
    echo
    
    # Container status
    echo "📦 Container Status:"
    echo "  Web Server: $(podman inspect secure-webapp --format '{{.State.Status}}' 2>/dev/null || echo 'Not running')"
    echo "  Database: $(podman inspect secure-database --format '{{.State.Status}}' 2>/dev/null || echo 'Not running')"
    echo
    
    # Security compliance
    echo "🛡️  Security Compliance:"
    
    # Check read-only filesystem
    webapp_readonly=$(podman inspect secure-webapp --format '{{.HostConfig.ReadonlyRootfs}}' 2>/dev/null)
    [ "$webapp_readonly" = "true" ] && echo "  ✅ Web server: Read-only filesystem" || echo "  ❌ Web server: Writable filesystem"
    
    db_readonly=$(podman inspect secure-database --format '{{.HostConfig.ReadonlyRootfs}}' 2>/dev/null)
    [ "$db_readonly" = "true" ] && echo "  ✅ Database: Read-only filesystem" || echo "  ❌ Database: Writable filesystem"
    
    # Check capabilities
    webapp_caps=$(podman inspect secure-webapp --format '{{.HostConfig.CapDrop}}' 2>/dev/null)
    [[ "$webapp_caps" == *"ALL"* ]] && echo "  ✅ Web server: Capabilities dropped" || echo "  ⚠️  Web server: Full capabilities"
    
    # Resource usage
    echo
    echo "📈 Resource Usage:"
    if podman stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}" secure-webapp secure-database 2>/dev/null; then
        echo
    else
        echo "  No containers running"
    fi
    
    # Network connectivity test
    echo "🌐 Network Connectivity:"
    if curl -s -f http://localhost:8080/health >/dev/null; then
        echo "  ✅ Web application: Healthy"
    else
        echo "  ❌ Web application: Unhealthy"
    fi
    
    echo
    echo "Press Ctrl+C to stop monitoring"
    sleep 10
done
MONEOF

chmod +x ~/.config/containers/web-app-security/monitor-webapp.sh

echo "✅ Secure web application deployed!"
echo ""
echo "📋 Deployment Summary:"
echo "  🌐 Web application: http://localhost:8080"
echo "  🔗 Network: $NETWORK_NAME (10.88.0.0/24)"
echo "  📊 Monitoring: ./monitor-webapp.sh"
echo ""
echo "🔧 Management Commands:"
echo "  podman logs $APP_NAME        - View web server logs"
echo "  podman logs $DB_NAME         - View database logs"
echo "  podman stop $APP_NAME $DB_NAME - Stop application"
echo "  ./monitor-webapp.sh          - Start monitoring"
EOF

chmod +x ~/.config/containers/web-app-security/deploy-secure-webapp.sh

echo "Secure web application deployment ready! 🌐"
echo "Run: ./deploy-secure-webapp.sh to deploy"

What this does: Shows you how to deploy a complete secure web application with defense-in-depth! 🌐

Example 2: Container Security Audit and Compliance 🟡

What we’re doing: Creating a comprehensive container security audit system with compliance checking, vulnerability scanning, and automated reporting.

# Create container security audit system
mkdir -p ~/.config/containers/security-audit

# Create comprehensive security audit script
cat > ~/.config/containers/security-audit/security-audit.sh << 'EOF'
#!/bin/bash
# Comprehensive Container Security Audit for Podman

# Configuration
AUDIT_DIR="$HOME/.config/containers/security-audit"
REPORTS_DIR="$AUDIT_DIR/reports"
POLICIES_DIR="$HOME/.config/containers/security-profiles"

# Create reports directory
mkdir -p "$REPORTS_DIR"

# Function to audit container configuration
audit_container_config() {
    local container_name="$1"
    local report_file="$REPORTS_DIR/${container_name}-audit-$(date +%Y%m%d-%H%M%S).txt"
    
    echo "🔍 Auditing container: $container_name"
    
    {
        echo "CONTAINER SECURITY AUDIT REPORT"
        echo "==============================="
        echo "Container: $container_name"
        echo "Audit Date: $(date)"
        echo "Auditor: $(whoami)"
        echo ""
        
        # Check if container exists
        if ! podman container exists "$container_name"; then
            echo "❌ ERROR: Container '$container_name' does not exist"
            return 1
        fi
        
        # Get container configuration
        config=$(podman inspect "$container_name" 2>/dev/null)
        
        echo "CONFIGURATION AUDIT"
        echo "==================="
        echo ""
        
        # 1. Filesystem Security
        echo "1. FILESYSTEM SECURITY"
        echo "---------------------"
        readonly_fs=$(echo "$config" | jq -r '.[0].HostConfig.ReadonlyRootfs')
        if [ "$readonly_fs" = "true" ]; then
            echo "✅ PASS: Read-only filesystem enabled"
        else
            echo "❌ FAIL: Filesystem is writable (security risk)"
        fi
        
        # Check for tmpfs mounts
        tmpfs_mounts=$(echo "$config" | jq -r '.[0].HostConfig.Tmpfs | keys[]?' 2>/dev/null)
        if [ -n "$tmpfs_mounts" ]; then
            echo "✅ PASS: Temporary filesystems configured"
            echo "  Tmpfs mounts: $(echo "$tmpfs_mounts" | tr '\n' ' ')"
        else
            echo "⚠️  WARNING: No tmpfs mounts configured"
        fi
        echo ""
        
        # 2. Privilege Analysis
        echo "2. PRIVILEGE ANALYSIS"
        echo "--------------------"
        
        # Check user
        user=$(echo "$config" | jq -r '.[0].Config.User')
        if [ -n "$user" ] && [ "$user" != "0" ] && [ "$user" != "root" ]; then
            echo "✅ PASS: Running as non-root user ($user)"
        else
            echo "❌ FAIL: Running as root user (high risk)"
        fi
        
        # Check capabilities
        caps_dropped=$(echo "$config" | jq -r '.[0].HostConfig.CapDrop[]?' 2>/dev/null)
        caps_added=$(echo "$config" | jq -r '.[0].HostConfig.CapAdd[]?' 2>/dev/null)
        
        if [[ "$caps_dropped" == *"ALL"* ]]; then
            echo "✅ PASS: All capabilities dropped"
        else
            echo "❌ FAIL: Not all capabilities dropped"
        fi
        
        if [ -n "$caps_added" ]; then
            echo "⚠️  WARNING: Additional capabilities granted: $caps_added"
        fi
        
        # Check privileged mode
        privileged=$(echo "$config" | jq -r '.[0].HostConfig.Privileged')
        if [ "$privileged" = "false" ]; then
            echo "✅ PASS: Not running in privileged mode"
        else
            echo "❌ FAIL: Running in privileged mode (critical risk)"
        fi
        echo ""
        
        # 3. Security Options
        echo "3. SECURITY OPTIONS"
        echo "------------------"
        sec_opts=$(echo "$config" | jq -r '.[0].HostConfig.SecurityOpt[]?' 2>/dev/null)
        
        # Check no-new-privileges
        if echo "$sec_opts" | grep -q "no-new-privileges:true"; then
            echo "✅ PASS: no-new-privileges enabled"
        else
            echo "❌ FAIL: no-new-privileges not set"
        fi
        
        # Check seccomp
        if echo "$sec_opts" | grep -q "seccomp"; then
            echo "✅ PASS: Seccomp profile configured"
        else
            echo "⚠️  WARNING: No seccomp profile configured"
        fi
        
        # Check AppArmor/SELinux
        if echo "$sec_opts" | grep -qE "(apparmor|selinux)"; then
            echo "✅ PASS: MAC (Mandatory Access Control) enabled"
        else
            echo "⚠️  WARNING: No MAC system configured"
        fi
        echo ""
        
        # 4. Network Security
        echo "4. NETWORK SECURITY"
        echo "------------------"
        network_mode=$(echo "$config" | jq -r '.[0].HostConfig.NetworkMode')
        
        case "$network_mode" in
            "none")
                echo "✅ EXCELLENT: Network disabled (highest security)"
                ;;
            "host")
                echo "❌ FAIL: Host networking enabled (security risk)"
                ;;
            "bridge"|"container:"*)
                echo "✅ PASS: Isolated network configuration"
                ;;
            *)
                echo "⚠️  INFO: Custom network mode: $network_mode"
                ;;
        esac
        
        # Check published ports
        ports=$(echo "$config" | jq -r '.[0].HostConfig.PortBindings | keys[]?' 2>/dev/null)
        if [ -n "$ports" ]; then
            echo "⚠️  INFO: Published ports: $(echo "$ports" | tr '\n' ' ')"
        else
            echo "✅ PASS: No published ports"
        fi
        echo ""
        
        # 5. Resource Limits
        echo "5. RESOURCE LIMITS"
        echo "-----------------"
        memory=$(echo "$config" | jq -r '.[0].HostConfig.Memory')
        cpus=$(echo "$config" | jq -r '.[0].HostConfig.NanoCpus')
        pids_limit=$(echo "$config" | jq -r '.[0].HostConfig.PidsLimit')
        
        if [ "$memory" != "0" ]; then
            memory_mb=$(($memory / 1024 / 1024))
            echo "✅ PASS: Memory limit set: ${memory_mb}MB"
        else
            echo "⚠️  WARNING: No memory limit set"
        fi
        
        if [ "$cpus" != "0" ]; then
            cpu_limit=$(echo "scale=2; $cpus / 1000000000" | bc)
            echo "✅ PASS: CPU limit set: ${cpu_limit}CPUs"
        else
            echo "⚠️  WARNING: No CPU limit set"
        fi
        
        if [ "$pids_limit" != "0" ]; then
            echo "✅ PASS: PIDs limit set: $pids_limit"
        else
            echo "⚠️  WARNING: No PIDs limit set"
        fi
        echo ""
        
        # 6. Volume Mounts Security
        echo "6. VOLUME MOUNTS SECURITY"
        echo "------------------------"
        mounts=$(echo "$config" | jq -r '.[0].Mounts[]?')
        
        if [ -n "$mounts" ]; then
            echo "$config" | jq -r '.[0].Mounts[] | "Mount: \(.Source) -> \(.Destination) (\(.Mode))"' | while read mount_info; do
                if echo "$mount_info" | grep -q ":ro"; then
                    echo "✅ SECURE: $mount_info"
                else
                    echo "⚠️  REVIEW: $mount_info"
                fi
            done
        else
            echo "✅ PASS: No volume mounts"
        fi
        echo ""
        
        # 7. Environment Variables Security
        echo "7. ENVIRONMENT VARIABLES"
        echo "-----------------------"
        env_vars=$(echo "$config" | jq -r '.[0].Config.Env[]?' 2>/dev/null)
        
        if [ -n "$env_vars" ]; then
            echo "Environment variables found:"
            echo "$env_vars" | while read env_var; do
                # Check for sensitive patterns
                if echo "$env_var" | grep -qiE "(password|secret|token|key|api_key)"; then
                    echo "⚠️  SENSITIVE: $env_var"
                else
                    echo "ℹ️  INFO: $env_var"
                fi
            done
        else
            echo "✅ PASS: No environment variables"
        fi
        echo ""
        
        # Calculate security score
        echo "SECURITY SCORE CALCULATION"
        echo "========================="
        
        score=0
        total_checks=10
        
        [ "$readonly_fs" = "true" ] && score=$((score + 1))
        [ -n "$user" ] && [ "$user" != "0" ] && [ "$user" != "root" ] && score=$((score + 1))
        [[ "$caps_dropped" == *"ALL"* ]] && score=$((score + 1))
        [ "$privileged" = "false" ] && score=$((score + 1))
        echo "$sec_opts" | grep -q "no-new-privileges:true" && score=$((score + 1))
        echo "$sec_opts" | grep -q "seccomp" && score=$((score + 1))
        [ "$network_mode" != "host" ] && score=$((score + 1))
        [ "$memory" != "0" ] && score=$((score + 1))
        [ "$cpus" != "0" ] && score=$((score + 1))
        [ "$pids_limit" != "0" ] && score=$((score + 1))
        
        percentage=$((score * 100 / total_checks))
        
        echo "Score: $score/$total_checks ($percentage%)"
        
        if [ $percentage -ge 90 ]; then
            echo "✅ EXCELLENT: Container follows security best practices"
        elif [ $percentage -ge 70 ]; then
            echo "✅ GOOD: Container has good security configuration"
        elif [ $percentage -ge 50 ]; then
            echo "⚠️  MODERATE: Container needs security improvements"
        else
            echo "❌ POOR: Container has significant security risks"
        fi
        
        echo ""
        echo "RECOMMENDATIONS"
        echo "==============="
        [ "$readonly_fs" != "true" ] && echo "- Enable read-only filesystem"
        [ "$user" = "0" ] || [ "$user" = "root" ] && echo "- Run as non-root user"
        [[ "$caps_dropped" != *"ALL"* ]] && echo "- Drop all capabilities and add only required ones"
        echo "$sec_opts" | grep -q "no-new-privileges:true" || echo "- Enable no-new-privileges"
        echo "$sec_opts" | grep -q "seccomp" || echo "- Configure seccomp profile"
        [ "$memory" = "0" ] && echo "- Set memory limits"
        [ "$cpus" = "0" ] && echo "- Set CPU limits"
        [ "$pids_limit" = "0" ] && echo "- Set PIDs limit"
        
    } > "$report_file"
    
    echo "✅ Audit report generated: $report_file"
    echo "📊 Security score: $percentage%"
}

# Function to audit all containers
audit_all_containers() {
    echo "🔍 Auditing all containers..."
    
    containers=$(podman ps -a --format "{{.Names}}")
    
    if [ -z "$containers" ]; then
        echo "No containers found"
        return
    fi
    
    for container in $containers; do
        echo "Auditing: $container"
        audit_container_config "$container"
        echo ""
    done
    
    echo "✅ All container audits completed"
    echo "📁 Reports saved in: $REPORTS_DIR"
}

# Function to generate compliance report
generate_compliance_report() {
    local report_file="$REPORTS_DIR/compliance-report-$(date +%Y%m%d-%H%M%S).html"
    
    echo "📋 Generating compliance report..."
    
    cat > "$report_file" << 'HTMLEOF'
<!DOCTYPE html>
<html>
<head>
    <title>Container Security Compliance Report</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; background-color: #f5f5f5; }
        .container { max-width: 1200px; margin: 0 auto; background: white; padding: 30px; border-radius: 8px; }
        .header { color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; margin-bottom: 20px; }
        .pass { color: #27ae60; font-weight: bold; }
        .fail { color: #e74c3c; font-weight: bold; }
        .warning { color: #f39c12; font-weight: bold; }
        .section { margin: 20px 0; padding: 15px; background: #ecf0f1; border-radius: 5px; }
        table { width: 100%; border-collapse: collapse; margin: 10px 0; }
        th, td { padding: 10px; text-align: left; border-bottom: 1px solid #ddd; }
        th { background-color: #34495e; color: white; }
        .score-good { background-color: #d5edda; }
        .score-moderate { background-color: #fff3cd; }
        .score-poor { background-color: #f8d7da; }
    </style>
</head>
<body>
    <div class="container">
        <h1 class="header">🔐 Container Security Compliance Report</h1>
        <p><strong>Generated:</strong> $(date)</p>
        <p><strong>System:</strong> $(hostname) ($(uname -r))</p>
        
        <div class="section">
            <h2>📊 Executive Summary</h2>
            <p>This report provides a comprehensive security assessment of all Podman containers.</p>
        </div>
        
        <div class="section">
            <h2>📋 Container Inventory</h2>
            <table>
                <tr><th>Container Name</th><th>Status</th><th>Security Score</th><th>Risk Level</th></tr>
HTMLEOF
    
    # Add container data to HTML report
    containers=$(podman ps -a --format "{{.Names}}")
    for container in $containers; do
        status=$(podman inspect "$container" --format '{{.State.Status}}' 2>/dev/null)
        echo "                <tr><td>$container</td><td>$status</td><td>Audit Required</td><td>TBD</td></tr>" >> "$report_file"
    done
    
    cat >> "$report_file" << 'HTMLEOF'
            </table>
        </div>
        
        <div class="section">
            <h2>🛡️ Security Recommendations</h2>
            <ul>
                <li>Enable read-only filesystems for all containers</li>
                <li>Run containers as non-root users</li>
                <li>Drop all capabilities and add only required ones</li>
                <li>Configure strict seccomp profiles</li>
                <li>Implement resource limits</li>
                <li>Use isolated networks</li>
                <li>Regular security audits and updates</li>
            </ul>
        </div>
    </div>
</body>
</html>
HTMLEOF
    
    echo "✅ Compliance report generated: $report_file"
}

# Main function
case "$1" in
    container)
        audit_container_config "$2"
        ;;
    all)
        audit_all_containers
        ;;
    compliance)
        generate_compliance_report
        ;;
    reports)
        echo "📁 Available audit reports:"
        ls -la "$REPORTS_DIR"
        ;;
    *)
        echo "Container Security Audit System"
        echo "Usage: $0 {container|all|compliance|reports} [container_name]"
        echo ""
        echo "Commands:"
        echo "  container <name>  - Audit specific container"
        echo "  all              - Audit all containers"
        echo "  compliance       - Generate compliance report"
        echo "  reports          - List available reports"
        ;;
esac
EOF

chmod +x ~/.config/containers/security-audit/security-audit.sh

echo "Container security audit system created! 🔍"
echo "Commands:"
echo "  security-audit.sh all - Audit all containers"
echo "  security-audit.sh container <name> - Audit specific container"
echo "  security-audit.sh compliance - Generate compliance report"

What this does: Demonstrates comprehensive security auditing with compliance reporting! 🔍

🚨 Fix Common Problems

Problem 1: Rootless containers fail to start ❌

What happened: User namespace or permission issues preventing rootless execution. How to fix it: Check subUID/subGID configuration and permissions.

# Check subUID and subGID configuration
grep $USER /etc/subuid /etc/subgid

# Add missing entries if needed
echo "$USER:100000:65536" | sudo tee -a /etc/subuid
echo "$USER:100000:65536" | sudo tee -a /etc/subgid

# Reset user namespaces
podman system reset --force

# Test rootless functionality
podman run --rm alpine:latest id

Problem 2: Security profiles not applying ❌

What happened: Custom seccomp or AppArmor profiles not being enforced. How to fix it: Check profile paths and syntax.

# Validate seccomp profile syntax
cat ~/.config/containers/security-profiles/strict-seccomp.json | jq .

# Check AppArmor profile
sudo apparmor_parser -r ~/.config/containers/security-profiles/podman-secure

# Test security options
podman run --rm --security-opt seccomp=~/.config/containers/security-profiles/strict-seccomp.json alpine:latest echo "test"

Don’t worry! Container security requires careful configuration - testing and validation is essential! 💪

💡 Simple Tips

  1. Start with strict policies 📅 - Begin with maximum security and relax as needed
  2. Regular security audits 🌱 - Audit containers frequently for compliance
  3. Monitor resource usage 🤝 - Watch for unusual container behavior
  4. Keep images updated 💪 - Use latest security patches and minimal base images

✅ Check Everything Works

Let’s verify your Podman security setup is working perfectly:

# Complete Podman security system verification
cat > /usr/local/bin/podman-security-check.sh << 'EOF'
#!/bin/sh
echo "=== Podman Security System Check ==="

echo "1. Podman Installation:"
if command -v podman >/dev/null; then
    echo "✅ Podman installed"
    podman --version
    echo "Info: $(podman info --format='{{.Host.Arch}} {{.Host.Os}}')"
else
    echo "❌ Podman not found"
fi

echo -e "\n2. Rootless Configuration:"
if [ -f /etc/subuid ] && grep -q "$USER" /etc/subuid; then
    echo "✅ subUID configured"
    grep "$USER" /etc/subuid
else
    echo "❌ subUID not configured"
fi

if [ -f /etc/subgid ] && grep -q "$USER" /etc/subgid; then
    echo "✅ subGID configured"
    grep "$USER" /etc/subgid
else
    echo "❌ subGID not configured"
fi

echo -e "\n3. Security Profiles:"
if [ -f ~/.config/containers/security-profiles/strict-seccomp.json ]; then
    echo "✅ Seccomp profile available"
else
    echo "❌ Seccomp profile missing"
fi

if [ -f ~/.config/containers/security-profiles/enforce-security.sh ]; then
    echo "✅ Security enforcement script available"
else
    echo "❌ Security enforcement script missing"
fi

echo -e "\n4. Network Security:"
if [ -f ~/.config/containers/networks/network-security.sh ]; then
    echo "✅ Network security tools available"
else
    echo "❌ Network security tools missing"
fi

# Test secure networks
secure_nets=$(podman network ls --format "{{.Name}}" | grep -E "(secure|dmz)")
if [ -n "$secure_nets" ]; then
    echo "✅ Secure networks configured: $secure_nets"
else
    echo "⚠️  No secure networks found"
fi

echo -e "\n5. Container Security Test:"
echo "Testing rootless container execution..."
if podman run --rm --read-only --cap-drop ALL --user 1000:1000 alpine:latest echo "Security test passed" 2>/dev/null; then
    echo "✅ Rootless security test successful"
else
    echo "❌ Rootless security test failed"
fi

echo -e "\n6. Audit System:"
if [ -f ~/.config/containers/security-audit/security-audit.sh ]; then
    echo "✅ Security audit system available"
else
    echo "❌ Security audit system missing"
fi

echo -e "\n7. Configuration Files:"
config_files=(
    "~/.config/containers/containers.conf"
    "~/.config/containers/storage.conf"
    "~/.config/containers/policy.json"
)

for config_file in "${config_files[@]}"; do
    expanded_path=$(eval echo "$config_file")
    if [ -f "$expanded_path" ]; then
        echo "✅ $(basename "$config_file") configured"
    else
        echo "❌ $(basename "$config_file") missing"
    fi
done

echo -e "\n8. Security Best Practices Check:"
echo "🔐 Security recommendations:"
echo "  ✓ Use --read-only for immutable containers"
echo "  ✓ Drop all capabilities with --cap-drop ALL"
echo "  ✓ Run as non-root with --user 1000:1000"
echo "  ✓ Enable --security-opt no-new-privileges"
echo "  ✓ Use strict seccomp profiles"
echo "  ✓ Implement resource limits"
echo "  ✓ Use isolated networks"

echo -e "\nPodman security system check completed! ✅"
EOF

chmod +x /usr/local/bin/podman-security-check.sh
/usr/local/bin/podman-security-check.sh

Good output shows:

=== Podman Security System Check ===
1. Podman Installation:
✅ Podman installed
podman version 4.7.2

2. Rootless Configuration:
✅ subUID configured
✅ subGID configured

3. Security Profiles:
✅ Seccomp profile available
✅ Security enforcement script available

Podman security system check completed! ✅

🏆 What You Learned

Great job! Now you can:

  • ✅ Install and configure secure Podman environments with rootless execution
  • ✅ Implement advanced security policies including seccomp and AppArmor profiles
  • ✅ Configure strict security contexts and capability management
  • ✅ Set up network isolation and secure container networking
  • ✅ Deploy secure web applications with defense-in-depth
  • ✅ Create comprehensive security audit and compliance systems
  • ✅ Build enterprise-grade container security policies
  • ✅ Troubleshoot common Podman security configuration issues
  • ✅ Monitor and audit container security continuously

🎯 What’s Next?

Now you can try:

  • 📚 Implementing container image scanning and vulnerability management
  • 🛠️ Setting up automated security policy enforcement in CI/CD
  • 🤝 Integrating with enterprise security information systems
  • 🌟 Exploring advanced container runtime security with gVisor or Kata!

Remember: Container security is a journey, not a destination! You’re now building fortress-level protection for containerized applications on Alpine Linux! 🎉

Keep securing and you’ll master enterprise container security! 💫