Skip to main content

nftables-based egress firewalling for Podman containers

Project description

terok-shield

terok-shield

PyPI License: Apache-2.0 REUSE status codecov Quality Gate Status

Default-deny egress firewall for rootless Podman containers.

terok-shield enforces default-deny outbound network filtering on Podman containers using nftables. Containers can only reach explicitly allowed destinations — everything else is rejected with an ICMP error and a per-packet audit entry.

terok ecosystem — terok-shield is the security boundary at the bottom of the stack

Where it sits in the stack

terok-shield is the firewall layer of the terok ecosystem. The hardened-Podman runtime (terok-sandbox) installs the OCI hooks at setup time; the operator-in-the-loop verdict service (terok-clearance) mutates the live ruleset on Allow / Deny decisions. The shield itself is independent of all of these — it works on any rootless Podman container, with or without the rest of terok.

Features

  • Default-deny egress with curated allowlists (domains and IPs)
  • Dynamic DNS allowlisting — per-container dnsmasq with --nftset auto-populates allow sets on every DNS resolution, handling IP rotation at runtime; falls back to static pre-start resolution via dig or getent when dnsmasq is unavailable
  • Live allow/deny at runtime for individual containers
  • Per-container isolation — each container gets its own state bundle, hooks, and audit log
  • Connection audit logging (JSON-lines lifecycle logs + kernel-level per-packet nftables logs)
  • Fail-closed — hook failure prevents the container from starting

Requirements

  • Linux with nftables (nft binary) — tested on Fedora 43, Debian 12 and 13, and Ubuntu 24.04, also works on other modern Linux distros
  • Podman (rootless, recommended ≥ 5.6.0, untested < 4.3.1)
  • Python 3.12+
  • dnsmasq (recommended) for dynamic DNS-based egress control; dig (dnsutils / bind-utils) as fallback

Installation

pip install terok-shield

Quick start

1. Choose your allowlists

terok-shield ships with several bundled profiles (see Allowlist Profiles):

Profile Domains
base DNS roots, NTP, OCSP, OS package repos
dev-standard GitHub, Docker Hub, PyPI, npm, crates.io, Go
dev-python Conda, Read the Docs, Python docs
dev-node Yarn, jsDelivr, unpkg
nvidia-hpc CUDA, NGC, NVIDIA drivers

The default profile is dev-standard. To add a custom allowlist, create a .txt file in ~/.config/terok/shield/profiles with one domain or IP per line:

e.g. ~/.config/terok/shield/profiles/my-project.txt

api.example.com
cdn.example.com
203.0.113.10

2. Start a container with the shield

terok-shield run my-container -- alpine:latest sh

This resolves DNS, installs OCI hooks, and launches the container with a default-deny firewall — only destinations in the dev-standard profile are reachable. To use custom profiles:

terok-shield run my-container --profiles dev-standard,my-project -- alpine:latest sh

3. Allow a domain at runtime

terok-shield allow my-container example.com
# Allowed example.com -> <resolved-ip> for my-container

terok-shield deny my-container example.com   # revoke later

License

Apache-2.0 — see LICENSES/Apache-2.0.txt.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

terok_shield-0.7.2.tar.gz (114.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

terok_shield-0.7.2-py3-none-any.whl (146.0 kB view details)

Uploaded Python 3

File details

Details for the file terok_shield-0.7.2.tar.gz.

File metadata

  • Download URL: terok_shield-0.7.2.tar.gz
  • Upload date:
  • Size: 114.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for terok_shield-0.7.2.tar.gz
Algorithm Hash digest
SHA256 6aa5e66b27c9901b0f06c86fb62930522aae73282e08a7b4110b1b4ed9e3b80a
MD5 b8bc27d2c930dd60bdd7c6526589bf4b
BLAKE2b-256 fbd4a71777a077338fda14b60518b15d97eead558430907e80c4bcfcb8e8281f

See more details on using hashes here.

Provenance

The following attestation bundles were made for terok_shield-0.7.2.tar.gz:

Publisher: release.yml on terok-ai/terok-shield

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file terok_shield-0.7.2-py3-none-any.whl.

File metadata

  • Download URL: terok_shield-0.7.2-py3-none-any.whl
  • Upload date:
  • Size: 146.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for terok_shield-0.7.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e88f3fb2a897aa8b033540e646d14c58fa2fd497774acd7500f56240d0042b09
MD5 66a8768d7047c406d19c0fb254dd8030
BLAKE2b-256 10c10d4f2d86c8b5fbd60de3e937dbc4a57a25c4bc0838d5705317380fb4ac8c

See more details on using hashes here.

Provenance

The following attestation bundles were made for terok_shield-0.7.2-py3-none-any.whl:

Publisher: release.yml on terok-ai/terok-shield

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page