Implement Podman pod security with network policies and microsegmentation

Advanced 45 min Apr 23, 2026 591 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Secure Podman pods with custom network policies, traffic filtering, and microsegmentation using CNI plugins and netavark. Implement zero-trust networking with firewall rules and container isolation.

Prerequisites

  • Root or sudo access
  • Basic understanding of containers and networking
  • Familiarity with iptables and systemd

What this solves

Podman's default networking allows containers to communicate freely, creating potential security risks in multi-tenant environments. This tutorial implements network policies and microsegmentation to control traffic between pods, isolate workloads, and create secure network boundaries using CNI plugins and custom firewall rules.

Step-by-step configuration

Update system and install Podman with network tools

Install Podman and required networking components for advanced security configuration.

sudo apt update && sudo apt upgrade -y
sudo apt install -y podman cni-plugins iptables netavark aardvark-dns slirp4netns
sudo dnf update -y
sudo dnf install -y podman cni-plugins iptables netavark aardvark-dns slirp4netns

Configure Podman for rootless operation with network security

Enable user namespaces and configure subuid/subgid mappings for secure container isolation.

sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $(whoami)
echo "net.ipv4.ip_unprivileged_port_start=80" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
podman system migrate

Create custom secure network configurations

Define network policies with traffic filtering and microsegmentation capabilities.

{
  "name": "secure-frontend",
  "cniVersion": "1.0.0",
  "plugins": [
    {
      "type": "bridge",
      "bridge": "secure-frontend0",
      "isDefaultGateway": true,
      "ipMasq": true,
      "hairpinMode": true,
      "ipam": {
        "type": "host-local",
        "subnet": "10.89.0.0/24",
        "routes": [
          {
            "dst": "0.0.0.0/0"
          }
        ]
      }
    },
    {
      "type": "firewall",
      "backend": "iptables"
    },
    {
      "type": "tuning"
    }
  ]
}

Create backend network with restricted access

Configure an isolated backend network that blocks external internet access.

{
  "name": "secure-backend",
  "cniVersion": "1.0.0",
  "plugins": [
    {
      "type": "bridge",
      "bridge": "secure-backend0",
      "isDefaultGateway": false,
      "ipMasq": false,
      "hairpinMode": false,
      "ipam": {
        "type": "host-local",
        "subnet": "10.90.0.0/24"
      }
    },
    {
      "type": "firewall",
      "backend": "iptables",
      "iptablesAdminChainName": "BACKEND_ADMIN"
    }
  ]
}

Configure network policies with iptables rules

Implement granular traffic filtering between network segments using custom iptables chains.

#!/bin/bash

# Create custom iptables chains for network policies
iptables -t filter -N PODMAN_FRONTEND_POLICY 2>/dev/null
iptables -t filter -N PODMAN_BACKEND_POLICY 2>/dev/null
iptables -t filter -N PODMAN_MICROSEGMENT 2>/dev/null

# Flush existing rules
iptables -t filter -F PODMAN_FRONTEND_POLICY
iptables -t filter -F PODMAN_BACKEND_POLICY
iptables -t filter -F PODMAN_MICROSEGMENT

# Frontend network policies (10.89.0.0/24)
# Allow HTTP/HTTPS outbound
iptables -t filter -A PODMAN_FRONTEND_POLICY -s 10.89.0.0/24 -p tcp --dport 80 -j ACCEPT
iptables -t filter -A PODMAN_FRONTEND_POLICY -s 10.89.0.0/24 -p tcp --dport 443 -j ACCEPT

# Allow DNS
iptables -t filter -A PODMAN_FRONTEND_POLICY -s 10.89.0.0/24 -p udp --dport 53 -j ACCEPT
iptables -t filter -A PODMAN_FRONTEND_POLICY -s 10.89.0.0/24 -p tcp --dport 53 -j ACCEPT

# Allow communication to backend network
iptables -t filter -A PODMAN_FRONTEND_POLICY -s 10.89.0.0/24 -d 10.90.0.0/24 -p tcp --dport 5432 -j ACCEPT
iptables -t filter -A PODMAN_FRONTEND_POLICY -s 10.89.0.0/24 -d 10.90.0.0/24 -p tcp --dport 6379 -j ACCEPT

# Backend network policies (10.90.0.0/24)
# Block all outbound internet access
iptables -t filter -A PODMAN_BACKEND_POLICY -s 10.90.0.0/24 ! -d 10.0.0.0/8 -j DROP

# Allow established connections back from frontend
iptables -t filter -A PODMAN_BACKEND_POLICY -s 10.90.0.0/24 -d 10.89.0.0/24 -m state --state ESTABLISHED,RELATED -j ACCEPT

# Microsegmentation rules
# Block inter-container communication within same network unless explicitly allowed
iptables -t filter -A PODMAN_MICROSEGMENT -s 10.89.0.0/24 -d 10.89.0.0/24 -j DROP
iptables -t filter -A PODMAN_MICROSEGMENT -s 10.90.0.0/24 -d 10.90.0.0/24 -j DROP

# Apply policies to FORWARD chain
iptables -t filter -I FORWARD -j PODMAN_FRONTEND_POLICY
iptables -t filter -I FORWARD -j PODMAN_BACKEND_POLICY
iptables -t filter -I FORWARD -j PODMAN_MICROSEGMENT

echo "Network policies applied successfully"

Make network policy script executable and persistent

Set proper permissions and create systemd service for automatic policy enforcement.

sudo chmod 755 /usr/local/bin/podman-network-policies.sh
sudo /usr/local/bin/podman-network-policies.sh
[Unit]
Description=Podman Network Security Policies
After=network.target
Before=podman.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/podman-network-policies.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Enable persistent network policies

Enable the systemd service to apply network policies automatically on boot.

sudo systemctl daemon-reload
sudo systemctl enable --now podman-network-policies.service
sudo systemctl status podman-network-policies.service

Create pod with network security policies

Deploy a secured pod using the custom network configuration with traffic filtering.

podman pod create --name secure-web-pod \
  --network secure-frontend \
  --security-opt label=level:s0:c100,c200 \
  --security-opt no-new-privileges \
  --publish 8080:80

Deploy containers with microsegmentation

Run application containers with strict network isolation and minimal privileges.

# Deploy web frontend with network restrictions
podman run -d --name web-frontend \
  --pod secure-web-pod \
  --security-opt label=level:s0:c100,c200 \
  --read-only \
  --tmpfs /tmp:noexec,nosuid,size=100m \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  nginx:alpine

# Create backend pod with isolated network
podman pod create --name secure-db-pod \
  --network secure-backend \
  --security-opt label=level:s0:c300,c400 \
  --security-opt no-new-privileges

# Deploy database with strict isolation
podman run -d --name postgres-db \
  --pod secure-db-pod \
  --security-opt label=level:s0:c300,c400 \
  --read-only \
  --tmpfs /tmp:noexec,nosuid,size=50m \
  --tmpfs /var/run/postgresql:noexec,nosuid,size=10m \
  --cap-drop ALL \
  -e POSTGRES_DB=appdb \
  -e POSTGRES_USER=appuser \
  -e POSTGRES_PASSWORD=secure_password123 \
  postgres:15-alpine

Configure network monitoring and logging

Set up traffic monitoring to detect policy violations and security incidents.

#!/bin/bash

# Enable iptables logging for policy violations
iptables -t filter -A PODMAN_MICROSEGMENT -j LOG --log-prefix "PODMAN_POLICY_VIOLATION: " --log-level 4
iptables -t filter -A PODMAN_BACKEND_POLICY -s 10.90.0.0/24 ! -d 10.0.0.0/8 -j LOG --log-prefix "BACKEND_INTERNET_BLOCK: " --log-level 4

# Monitor network connections
echo "Monitoring Podman network traffic. Check /var/log/syslog for policy violations."

# Display current connections
echo "Current network connections:"
ss -tuln | grep -E ":(80|443|5432|6379|8080)"

# Show iptables packet counters
echo "\nNetwork policy statistics:"
iptables -t filter -L PODMAN_FRONTEND_POLICY -v -n
iptables -t filter -L PODMAN_BACKEND_POLICY -v -n
sudo chmod 755 /usr/local/bin/monitor-podman-traffic.sh

Test network policies and microsegmentation

Verify that traffic filtering and isolation rules are working correctly.

# Test frontend to backend connectivity (should work on allowed ports)
podman exec web-frontend nc -zv 10.90.0.1 5432

# Test blocked inter-container communication within same network
podman run --rm --network secure-frontend alpine nc -zv 10.89.0.2 80

# Test backend internet access (should be blocked)
podman exec postgres-db nc -zv 8.8.8.8 53

# View policy violations in logs
sudo tail -f /var/log/syslog | grep "PODMAN_POLICY"

Verify your setup

Confirm that network policies and microsegmentation are properly configured and enforcing security boundaries.

# Check pod status and network assignments
podman pod ls
podman network ls

# Verify iptables rules are active
sudo iptables -t filter -L PODMAN_FRONTEND_POLICY -v -n
sudo iptables -t filter -L PODMAN_BACKEND_POLICY -v -n
sudo iptables -t filter -L PODMAN_MICROSEGMENT -v -n

# Test network connectivity
podman exec web-frontend wget -q --spider --timeout=5 http://example.com && echo "Frontend internet: OK" || echo "Frontend internet: BLOCKED"
podman exec postgres-db wget -q --spider --timeout=5 http://example.com && echo "Backend internet: ERROR - Should be blocked" || echo "Backend internet: BLOCKED - OK"

# Check container security labels
podman inspect web-frontend --format '{{.ProcessLabel}}'
podman inspect postgres-db --format '{{.ProcessLabel}}'

# Monitor traffic
sudo /usr/local/bin/monitor-podman-traffic.sh

Common issues

SymptomCauseFix
Containers can't reach internet iptables rules blocking all traffic Check sudo iptables -L -v -n and verify ACCEPT rules are before DROP rules
Network policies not applying CNI plugins not properly configured Restart podman service: systemctl --user restart podman
SELinux denials blocking containers Incorrect security labels Check sudo ausearch -m avc and use --security-opt label=disable for testing
DNS resolution failing Firewall blocking DNS traffic Ensure UDP/TCP port 53 is allowed in frontend policy
Inter-pod communication failing Overly restrictive microsegmentation Add specific allow rules before the blanket DROP rule in PODMAN_MICROSEGMENT

Next steps

Running this in production?

Want this handled for you? Running this at scale adds a second layer of work: capacity planning, failover drills, cost control, and on-call. Our managed platform covers monitoring, backups and 24/7 response by default.

Automated install script

Run this to automate the entire setup

Nie chcesz zarządzać tym samodzielnie?

Zarządzamy infrastrukturą firm, które zależą od dostępności. W pełni zarządzana, z jednym stałym kontaktem, który zna Twoje środowisko.

Macie jednego stałego opiekuna, który zna Waszą konfigurację

Rotterdam 12:58 · dostępny w wiadomości, bez formularza zgłoszeń