Skip to content

terok-ai/terok-shield

Repository files navigation

terok-shield

License: Apache-2.0 REUSE status codecov Quality Gate Status

nftables-based egress firewalling for rootless Podman containers.

Overview

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.

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, probably 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 with one domain or IP per line:

mkdir -p ~/.config/terok/shield/profiles
cat > ~/.config/terok/shield/profiles/my-project.txt << 'EOF'
api.example.com
cdn.example.com
203.0.113.10
EOF

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

Documentation

  • User Guide — getting started, allowlist profiles, firewall modes, CLI reference
  • Developer Guide — contributing, security model, architecture

License

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

About

nftables-based egress firewalling for podman containers with domain-based allowlists

Resources

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages