A unified, security-focused firewall management framework for Linux
supporting five backends with zero external runtime dependencies.
Quick Start · Commands · Usage Guide · Changelog · Security · Testing · Contributing
📖 Explore the Wiki Documentation »
- Overview
- Key Highlights
- Features
- Architecture
- Supported Platforms
- Supported Firewalls
- Prerequisites
- Quick Start
- CLI Command Reference
- Global Options
- Rule Lifecycle
- Compound Actions
- Connection Tracking
- Rate Limiting
- Backup and Recovery
- Logging
- Directory Structure
- Security Considerations
- Troubleshooting
- Testing
- Contributing
- Documentation
- Version History
- Acknowledgments
- License
- Support
Apotrópaios (from Greek ἀποτρόπαιος -- "turning away evil") is a zero-dependency Python 3.12+ framework for unified firewall management across multiple backends and Linux distributions. It wraps the complexity of five different firewall tools -- iptables, nftables, firewalld, ufw, and ipset -- into a single, consistent interface with UUID-tracked rule lifecycle management, full backup/recovery, and defense-in-depth security controls at every layer.
This is the Python variant of the bash Apotropaios framework, targeting 100% feature parity with v1.1.10. The Python implementation uses strict typing (mypy --strict with zero errors), a 5-layer architecture with enforced dependency ordering, and 322 automated tests across unit, integration, and security tiers.
Every firewall rule created through Apotropaios receives a unique UUID, is tracked in a persistent rule index, and supports full lifecycle operations: create, activate, deactivate, remove, and automatic TTL-based expiry. The framework handles the translation between its unified rule model and each backend's native syntax -- compound actions like log,drop become separate LOG + terminal rules in iptables, single expressions in nftables, rich rule log clauses in firewalld, and extracted terminal actions in ufw.
The framework emphasizes security at every layer: 27 whitelist input validators, shell injection prevention via list-form subprocess calls (never shell=True), secure file permissions (0o600/0o700), atomic file locking via fcntl.flock(), cryptographic integrity verification, and automatic masking of sensitive data in logs across four format families.
| Feature | Description | |
|---|---|---|
| 🔥 | Five Firewall Backends | iptables, nftables, firewalld, ufw, ipset -- auto-detected and selectable |
| 🆔 | UUID Rule Tracking | Every rule gets a UUID for lifecycle management: create, activate, deactivate, remove, expire |
| 🔀 | Compound Actions | log,drop and log,accept translated natively per backend -- no wrapper scripts |
| 📊 | Connection Tracking | new, established, related, invalid, untracked states on any rule |
| ⏱️ | Rate Limiting | 5/minute, 10/second, 100/hour with configurable burst -- per-rule granularity |
| 🖥️ | Interactive Menu | 8-category guided interface with validation, cancel support, and ExpiryMonitor daemon |
| 💾 | Backup & Recovery | Timestamped compressed archives, immutable chattr +i snapshots, SHA-256 verification |
| 📦 | Import / Export | Portable rule configurations with integrity verification and dry-run preview |
| 🛡️ | Security-First Design | 27 whitelist validators, CWE-mapped test suite, OWASP/NIST-aligned controls |
| 📝 | Structured Logging | Correlation IDs, 4-family sensitive data masking, secure rotation |
| ❓ | Progressive Help | Two-tier: global --help, per-command COMMAND --help (18 commands) |
| ⚡ | Zero Runtime Dependencies | Python 3.12+ stdlib only -- no pip packages required at runtime |
| 🔒 | Type-Safe | mypy --strict with zero errors across all 35 source files |
- Unified multi-backend management: Consistent CLI and menu across iptables, nftables, firewalld, ufw, and ipset
- Automatic backend detection: Scans installed firewalls, auto-selects the best available, or lets you choose with
--backend - UUID rule lifecycle: Create, activate, deactivate, remove, and automatic TTL-based expiry with full audit trail
- Compound actions:
log,drop,log,accept,log,reject-- translated to each backend's native representation - Connection state tracking:
--conn-state new,established,relatedon any rule, mapped to conntrack/ct state per backend - Rate limiting:
--limit 5/minute --limit-burst 10for traffic shaping, translated to-m limit(iptables),limit rate(nftables), or rich rule limit (firewalld) - Configuration portability: Import/export rule sets with SHA-256 integrity verification and dry-run preview
- Backup and recovery: Automatic restore points before destructive operations, timestamped compressed archives, and immutable
chattr +isnapshots - 21 CLI commands: Each with
--helpproviding synopsis, options, examples, and related commands - Interactive menu: 8-category guided interface with input validation and cancel support
- System-native rules: View raw backend rules via
system-rules(iptables -L, nft list, firewall-cmd --list-all, etc.)
- 27 whitelist validators for all user-supplied data types (ports, IPs, CIDRs, protocols, hostnames, paths, chains, tables, table families, zones, interfaces, rule IDs, actions, connection states, rate limits, log levels, log prefixes, descriptions)
- Whitelist-based input sanitization --
sanitize_input()keeps only known-safe characters via compiled regex - Shell metacharacter rejection via O(1) frozenset intersection (
_contains_shell_meta()) - Path traversal detection and null byte injection rejection on all file path parameters
- Maximum input length enforcement (4096 characters)
- nftables table family validation (inet, ip, ip6, arp, bridge, netdev)
- Parameter re-validation from rule index before removal operations
- No
evalorexecof user-supplied data; noshell=Truein any subprocess call - All subprocess calls use list-form arguments with captured stderr and 30-second timeout
See SECURITY.md for the full security design, implemented controls, and CWE coverage.
- Structured log format with ISO 8601 UTC timestamps and correlation IDs
- Seven log levels: TRACE, DEBUG, INFO, WARNING, ERROR, CRITICAL, NONE
- Dual output: color-coded console (stderr) and structured file
- Automatic log rotation at 100MB with configurable retention (default: 10 files)
- Sensitive data masking across four format families: key=value, key="quoted", JSON (
"key": "value"), and HTTP Authorization headers - Control character stripping prevents log injection
- Log files written with 0o600 permissions, log directories with 0o700
- Console handler removed before shutdown marker -- no post-shutdown noise
┌──────────────────────────────────────────────────────────────────┐
│ Layer 5: User Interface │
│ cli.py (18 commands) · menu/main.py · help_system.py │
├──────────────────────────────────────────────────────────────────┤
│ Layer 4: Rule Engine │
│ rules/engine.py · rules/index.py · rules/state.py │
│ rules/import_export.py · backup/ · install/installer.py │
├──────────────────────────────────────────────────────────────────┤
│ Layer 3: Firewall Backends │
│ firewall/common.py (registry + dispatch) │
│ iptables.py · nftables.py · firewalld.py · ufw.py · ipset.py │
├──────────────────────────────────────────────────────────────────┤
│ Layer 2: Detection │
│ detection/os_detect.py · detection/fw_detect.py │
├──────────────────────────────────────────────────────────────────┤
│ Layer 1: Core Infrastructure │
│ constants.py · validation.py · logging.py · errors.py │
│ security.py · utils.py │
└──────────────────────────────────────────────────────────────────┘
Key design decisions:
-
Whitelist-first validation: Every user input passes through whitelist pattern matching before reaching any system command. Validators use compiled regex patterns (precompiled at import, thread-safe).
-
List-form command construction: All firewall commands are built using Python lists (
["iptables", "-A", "INPUT", "-p", protocol]), never string interpolation orshell=True. This prevents shell injection regardless of input content. -
Backend-native translation: The rule engine validates the superset of options, then each backend adapter translates to its native syntax. Compound actions, connection tracking, and rate limiting are expressed differently across backends but validated identically.
-
Atomic file locking:
fcntl.flock()is used for race-condition-free file locking with stale PID detection and configurable timeout. -
Defense-in-depth logging: Sensitive data is masked before writing to any handler. Control characters are stripped. Log files have restricted permissions. Console handler removed before shutdown to prevent noise.
┌──────────┐
│ CREATE │
│ (UUID) │
└────┬─────┘
│
┌────▼─────┐
┌─────│ ACTIVE │─────┐
│ └────┬─────┘ │
│ │ │
┌────▼───┐ ┌──▼────┐ ┌──▼──────┐
│DEACTIVE│ │EXPIRED│ │ REMOVED │
│(index) │ │ (TTL) │ │(backend │
└────┬───┘ └───────┘ │ + index) │
│ └──────────┘
┌────▼─────┐
│REACTIVATE│
└────┬─────┘
│
┌────▼─────┐
│ ACTIVE │
└──────────┘
Every rule passes through: validation (27 validators) → engine (UUID assignment, index registration) → backend adapter (native command construction) → kernel (firewall rule applied). Deactivation removes from the kernel but preserves the index entry for reactivation. Removal deletes from both.
A compound action like log,drop is expressed differently by each backend:
| Backend | Native Translation |
|---|---|
| iptables | Two separate rules: -j LOG --log-prefix "..." --log-level info followed by -j DROP |
| nftables | Single expression: log prefix "..." level info drop |
| firewalld | Rich rule with log clause: rule ... log prefix "..." level info drop |
| ufw | Terminal action extracted for ufw verb; logging enabled via ufw logging |
Removal mirrors the add logic exactly -- for iptables, both the LOG rule and the terminal rule are deleted to prevent orphaned kernel rules.
| Distribution | Version | Family | Package Manager | CI Status |
|---|---|---|---|---|
| Ubuntu | 22.04 LTS, 24.04 LTS | Debian | apt | ✅ Verified |
| Kali Linux | Rolling | Debian | apt | ✅ Verified |
| Debian | 12 (Bookworm) | Debian | apt | ✅ Verified |
| Rocky Linux | 8, 9 | RHEL | dnf | ✅ Verified |
| AlmaLinux | 8, 9 | RHEL | dnf | ✅ Verified |
| Arch Linux | Rolling | Arch | pacman | ✅ Verified |
Also expected to work on any Linux distribution with Python 3.12+ and standard coreutils, including Fedora, openSUSE, Amazon Linux 2023, and Raspberry Pi OS.
| Backend | Binary | Description | Status |
|---|---|---|---|
| iptables | iptables |
Legacy netfilter packet filtering with compound action support | ✅ Full Support |
| nftables | nft |
Modern netfilter framework with native compound expressions | ✅ Full Support |
| firewalld | firewall-cmd |
Dynamic firewall with zones and rich rules | ✅ Full Support |
| ufw | ufw |
Uncomplicated Firewall with application profiles | ✅ Full Support |
| ipset | ipset |
IP set management with iptables integration | ✅ Full Support |
| Dependency | Purpose | Install |
|---|---|---|
| Python 3.12+ | Framework runtime (type annotations, stdlib modules) | Pre-installed on most modern distributions |
| At least one firewall | Backend for rule management | See install command |
| Dependency | Purpose | Install |
|---|---|---|
| pytest 8.0+ | Automated testing | pip3 install pytest |
| mypy 1.10+ | Static type checking | pip3 install mypy |
| Git | Version control | Pre-installed on most distributions |
- Root/sudo access for firewall operations (kernel-level packet filtering)
- Python 3.12+ for modern type annotation syntax (
X | None,dict[str, str]) - No external runtime dependencies -- stdlib only, no pip packages required
# 1. Clone or download
git clone https://github.com/Sandler73/Apotropaios-Firewall-Manager-Python-Variant.git
cd Apotropaios-Firewall-Manager-Python
# 2. Detect your system (no install needed)
sudo python3 apotropaios.py detect
# 3. Launch the interactive menu
sudo python3 apotropaios.py --interactive
# Or use the CLI directly:
sudo python3 apotropaios.py add-rule --dst-port 443 --action accept --protocol tcp
sudo python3 apotropaios.py list-rules
sudo python3 apotropaios.py backup pre-deployThree execution modes:
- Direct execution (
python3 apotropaios.py): No installation required. Works from the project root. - Module execution (
python3 -m apotropaios): Afterpip3 install .or within a venv. - Interactive mode (
--interactive): Launches the guided 8-category menu.
Alternative install methods: See SETUP_GUIDE.md for venv setup, system-wide pip install, and first-run instructions.
Quick copy-paste examples for common operations. See the Usage Guide for complete options and operational scenarios.
Add rules -- Create firewall rules with various options:
sudo python3 apotropaios.py add-rule --dst-port 443 --action accept --protocol tcp
sudo python3 apotropaios.py add-rule --src-ip 10.0.0.0/8 --action drop --direction inbound
sudo python3 apotropaios.py add-rule --dst-port 22 --action log,drop --conn-state new --limit 3/minute
sudo python3 apotropaios.py add-rule --dst-port 80 --action accept --duration temporary --ttl 3600Manage rules -- Lifecycle operations on existing rules:
sudo python3 apotropaios.py list-rules # Show all tracked rules
sudo python3 apotropaios.py remove-rule <UUID> # Remove a specific rule
sudo python3 apotropaios.py deactivate-rule <UUID> # Deactivate (keep in index)
sudo python3 apotropaios.py activate-rule <UUID> # Reactivate a deactivated ruleImport / Export -- Portable rule configurations:
sudo python3 apotropaios.py export /tmp/my-rules.conf # Export current rules
sudo python3 apotropaios.py import /tmp/my-rules.conf # Import rules from file
sudo python3 apotropaios.py import rules.conf --dry-run # Preview without applyingBackup / Restore -- Protect your configuration:
sudo python3 apotropaios.py backup pre-deploy # Create a named backup
sudo python3 apotropaios.py restore backup.tar.gz # Restore from specific backupQuick actions -- Emergency operations:
sudo python3 apotropaios.py block-all # Block all traffic
sudo python3 apotropaios.py allow-all # Allow all trafficSystem information -- Diagnostics:
sudo python3 apotropaios.py detect # Scan OS and firewalls
sudo python3 apotropaios.py status # Show service state
sudo python3 apotropaios.py system-rules # Show raw backend rules
sudo python3 apotropaios.py detect --log-level debug # Maximum diagnostic detailScan the system for installed operating system, firewall backends, and their current status.
sudo python3 apotropaios.py detectOutputs: detected OS (name, version, family, package manager), installed firewalls (with binary paths and service status), and auto-selected backend.
Create and apply a new firewall rule. The rule is validated, assigned a UUID, applied to the active backend, and registered in the rule index.
sudo python3 apotropaios.py add-rule [OPTIONS]| Option | Description |
|---|---|
--protocol <PROTO> |
Protocol: tcp, udp, icmp, icmpv6, sctp, all (default: tcp) |
--src-ip <IP/CIDR> |
Source IP address or CIDR |
--dst-ip <IP/CIDR> |
Destination IP address or CIDR |
--src-port <PORT> |
Source port or port range (e.g., 8080-8090) |
--dst-port <PORT> |
Destination port or port range |
--action <ACTION> |
Rule action: accept, drop, reject, log, masquerade, snat, dnat, return, or compound (log,drop) |
--direction <DIR> |
Traffic direction: inbound, outbound, forward |
--conn-state <STATES> |
Connection tracking: new, established, related, invalid, untracked (comma-separated) |
--limit <RATE> |
Rate limit: N/second, N/minute, N/hour, N/day |
--limit-burst <N> |
Burst allowance for rate limiting |
--log-prefix <PREFIX> |
Log prefix string (max 29 chars) |
--log-level <LEVEL> |
Syslog level: emerg, alert, crit, err, warning, notice, info, debug |
--zone <ZONE> |
Firewalld zone name |
--interface <IFACE> |
Network interface |
--chain <CHAIN> |
Custom chain name (iptables/nftables) |
--table <TABLE> |
Custom table name (iptables/nftables) |
--duration <TYPE> |
Duration: permanent or temporary |
--ttl <SECONDS> |
Time-to-live for temporary rules (60–2592000 seconds) |
--description <TEXT> |
Human-readable rule description |
Remove a rule by its UUID. Deletes from both the firewall backend and the rule index.
sudo python3 apotropaios.py remove-rule <UUID>Display all rules tracked in the rule index with their UUIDs, parameters, and current state.
sudo python3 apotropaios.py list-rulesToggle a rule's active state. Deactivation removes the rule from the firewall backend but preserves it in the index for later reactivation.
sudo python3 apotropaios.py deactivate-rule <UUID>
sudo python3 apotropaios.py activate-rule <UUID>Transfer rule configurations between systems or environments. Export produces a portable configuration file with SHA-256 integrity checksum. Import validates the checksum before applying.
sudo python3 apotropaios.py export /path/to/rules.conf
sudo python3 apotropaios.py import /path/to/rules.conf
sudo python3 apotropaios.py import /path/to/rules.conf --dry-runImport supports --dry-run to preview rules without applying them.
Create and restore timestamped backup archives of the complete framework state (rule index, state tracking, per-backend configs).
sudo python3 apotropaios.py backup [LABEL] # Create backup with optional label
sudo python3 apotropaios.py restore [BACKUP_FILE] # Restore from specific backupBackups are compressed tar.gz archives with SHA-256 checksums. Up to 20 backups are retained (configurable). Immutable snapshots can be created via the interactive menu.
Emergency actions that set default chain policies across the active backend.
sudo python3 apotropaios.py block-all # DROP all traffic
sudo python3 apotropaios.py allow-all # ACCEPT all trafficWarning: block-all will block all network traffic including SSH. Ensure you have out-of-band access before using this on remote systems.
Install or update firewall packages via the system package manager.
sudo python3 apotropaios.py install <FIREWALL> # Install a firewall backend
sudo python3 apotropaios.py update <FIREWALL> # Update a firewall backendSupported targets: firewalld, iptables, nftables, ufw, ipset. Auto-detects package manager (apt, dnf, pacman).
Display the active backend's service state or raw system rules.
sudo python3 apotropaios.py status # Service state (running/enabled/version)
sudo python3 apotropaios.py system-rules # Raw rules (iptables -L, nft list, etc.)Important distinction: status shows service state (running/stopped, enabled/disabled, version, binary). system-rules dumps native firewall rules. list-rules shows only Apotropaios-tracked rules.
Launch the interactive menu-driven interface.
sudo python3 apotropaios.py --interactive # Preferred
sudo python3 apotropaios.py --interactive --backend iptables # Pre-select backend
sudo python3 apotropaios.py menu # Backward compatibleThe --interactive flag is mutually exclusive with CLI commands and --non-interactive. The menu provides eight categories: Firewall Management, Rule Management, Quick Actions, Backup & Recovery, System Information, Install & Update, Help & Documentation, and Exit.
These options work before or after the command (position-independent):
| Option | Description |
|---|---|
--interactive |
Launch the interactive menu (mutually exclusive with commands and --non-interactive) |
--backend <NAME> |
Select firewall backend: iptables, nftables, firewalld, ufw, ipset |
--log-level <LEVEL> |
Set console verbosity: trace, debug, info, warning (default), error, critical |
--non-interactive |
Suppress interactive prompts; destructive commands such as reset proceed without confirmation (for scripting/automation) |
-v, --version |
Show version string and exit |
-h, --help |
Show context-sensitive help (global or per-command) |
Every rule created through Apotropaios follows a managed lifecycle:
- Validation: All 27 validators run against every parameter (ports, IPs, CIDRs, protocols, actions, states, limits, etc.)
- UUID Assignment: A cryptographically random UUID v4 is generated via
uuid.uuid4() - Index Registration: The rule is recorded in the persistent pipe-delimited rule index with all 27 fields, timestamps, and backend association
- Backend Application: The rule engine dispatches to the active backend adapter, which translates to native syntax and executes via list-form subprocess
- State Tracking: The rule's state (active/inactive), duration type (permanent/temporary), and TTL are tracked independently with atomic persistence
Temporary rules are checked for expiry by the ExpiryMonitor daemon thread (30-second interval, interactive mode only). Expired rules are deactivated from the backend and marked as expired in the index.
Compound actions combine a non-terminal action (like log) with a terminal action (like drop) in a single logical rule:
sudo python3 apotropaios.py add-rule --dst-port 22 --action log,drop
sudo python3 apotropaios.py add-rule --dst-port 80 --action log,accept --log-prefix "HTTP: "
sudo python3 apotropaios.py add-rule --src-ip 10.0.0.0/8 --action log,reject --log-level warningThe framework validates that compound actions contain exactly one terminal action and one or more non-terminal actions. Double-terminal combinations (e.g., accept,drop) are rejected. Removal operations mirror the add logic exactly to prevent orphaned rules in the kernel.
Connection state tracking filters packets based on their relationship to established connections:
sudo python3 apotropaios.py add-rule --dst-port 443 --action accept --conn-state new,established
sudo python3 apotropaios.py add-rule --action drop --conn-state invalid| State | Description |
|---|---|
new |
First packet of a new connection |
established |
Packet belonging to an already established connection |
related |
Packet related to an established connection (e.g., FTP data) |
invalid |
Packet that does not match any known connection |
untracked |
Packet not tracked by conntrack |
Multiple states can be comma-separated. The framework translates to: -m conntrack --ctstate (iptables), ct state (nftables), or rich rule state clause (firewalld).
Per-rule rate limiting controls the frequency of matched packets:
sudo python3 apotropaios.py add-rule --dst-port 22 --action log,drop --limit 3/minute --limit-burst 5
sudo python3 apotropaios.py add-rule --action accept --limit 10/second| Parameter | Format | Examples |
|---|---|---|
--limit |
N/unit | 5/second, 30/minute, 100/hour, 1000/day |
--limit-burst |
N | 5, 10, 20 (packets allowed before rate limiting kicks in) |
Translated to: -m limit --limit N/unit --limit-burst N (iptables), limit rate N/unit burst N packets (nftables), or rich rule limit value="N/unit" (firewalld).
Three levels of configuration protection:
- Automatic restore points: Created before destructive operations (restore creates a pre-restore backup)
- Manual backups: Timestamped compressed archives with optional labels and SHA-256 checksums
- Immutable snapshots:
chattr +iprotected files that cannot be modified or deleted without explicit unlock
sudo python3 apotropaios.py backup pre-deploy # Create labeled backup
sudo python3 apotropaios.py backup # Create timestamped backup
sudo python3 apotropaios.py restore backup.tar.gz # Restore from specific backupBackups include: per-backend configuration exports, rule index, rule state tracking, and backup manifest with SHA-256 checksums. Up to 20 backups are retained with automatic rotation of older archives.
| Log | Path | Description |
|---|---|---|
| Execution log | data/logs/apotropaios-<timestamp>.log |
All operations for the current session |
| Console output | stderr | Color-coded severity levels (TRACE through CRITICAL) |
[2026-03-30T00:30:02.743Z] [INFO] [rule_engine] [cid:c4015d9f] Rule created: 550e8400-... | backend=iptables direction=inbound action=log,drop
All log messages are automatically sanitized before writing. The following patterns are masked:
| Format | Example | Masked Output |
|---|---|---|
| Key=value | password=secret123 |
password=***MASKED*** |
| Quoted value | token="my secret" |
token="***MASKED***" |
| JSON | "apikey": "abc123" |
"apikey": "***MASKED***" |
| HTTP header | Authorization: Bearer eyJ... |
Authorization: Bearer ***MASKED*** |
apotropaios-python/ # Repository root
├── apotropaios.py # Standalone execution script (no install needed)
├── Makefile # 56 targets: build, test, package, install, security-scan
├── pyproject.toml # Build configuration, SPDX license, package discovery
├── .gitignore # 221-line exclusion rules
├── apotropaios/ # Python package root
│ ├── __main__.py # Package entry point (python3 -m apotropaios)
│ ├── cli.py # 21 CLI commands, progressive help, dispatch
│ ├── core/ # Layer 1: Infrastructure (6 modules)
│ │ ├── constants.py (746 lines)
│ │ ├── validation.py # 27 whitelist validators (1,256 lines)
│ │ ├── logging.py # 4-family masking, dual output (729 lines)
│ │ ├── errors.py # 25 exceptions, cleanup stack (897 lines)))
│ │ ├── security.py # FileLock, SHA-256, UUID (678 lines)
│ │ └── utils.py # Timestamps, formatting (503 lines)
│ ├── detection/ # Layer 2: Detection
│ │ ├── os_detect.py # 4-fallback OS detection
│ │ └── fw_detect.py # 5-backend firewall probing
│ ├── firewall/ # Layer 3: Backends (5 implementations)
│ │ ├── base.py # ABC with 12 abstract methods
│ │ ├── common.py # Registry + dispatch
│ │ ├── iptables.py # Compound actions, match builder
│ │ ├── nftables.py # Single-expression compounds
│ │ ├── firewalld.py # Zone-aware rich rules
│ │ ├── ufw.py # Simplified syntax
│ │ └── ipset.py # Set management + iptables refs
│ ├── rules/ # Layer 4: Rule Engine
│ │ ├── engine.py # Lifecycle orchestrator
│ │ ├── index.py # Persistent pipe-delimited index
│ │ ├── state.py # TTL tracking
│ │ └── import_export.py # Bulk import/export
│ ├── backup/ # Layer 4: Backup
│ │ ├── backup.py # Archive creation + retention
│ │ ├── restore.py # Recovery with safety backup
│ │ └── immutable.py # chattr +i snapshots
│ ├── install/ # Layer 4: Installation
│ │ └── installer.py # apt/dnf/pacman dispatch
│ └── menu/ # Layer 5: Interactive Menu
│ ├── main.py # 8-category menu, ExpiryMonitor
│ └── help_system.py # Per-command help functions
├── tests/ # 322 automated tests
│ ├── unit/ # 12 files, 267 tests
│ ├── integration/ # 2 files, 13 tests
│ ├── security/ # 1 file, 15 tests
│ └── ci/ # 1 file, 27 tests (workflow/template meta-tests)
├── docs/ # 12 documentation files + wiki
│ ├── wiki/ # 15 standalone wiki pages
│ └── LICENSE # MIT + 12 supplementary sections
├── tasks/ # Project tracking
└── data/ # Runtime data (gitignored)
├── logs/ # Per-execution log files (0o600)
├── rules/ # Rule index and state (0o600)
└── backups/ # Compressed archives (0o600)
- All input validated at the framework boundary before any system interaction. 27 whitelist validators reject everything not explicitly permitted.
- No
shell=Truein any subprocess call. All commands use list-form arguments. Static security scan (make security-scan) verifies this on every build. - No
evalorexecof user-supplied data. Security scan checks for these patterns. - 0o600/0o700 permissions on all created files and directories. Umask set to 0o077 during initialization.
- Atomic file writes via temp-then-replace for all persistent data. Prevents partial writes on crash.
- SHA-256 integrity verification on backup archives and import files.
- Sensitive data masking in all log output across four format families.
- Path traversal prevention on all file path parameters (
..and null byte rejection). - Stale lock detection with PID validation prevents indefinite lock blocking.
See SECURITY.md for the complete security design documentation.
| Issue | Solution |
|---|---|
Permission denied |
Use sudo python3 apotropaios.py COMMAND |
No backend selected |
Install a firewall or use --backend NAME |
Protocol not supported |
Load kernel modules: sudo modprobe ip_tables |
| No visible output | Default console is WARNING. Use --log-level info |
| pip3 install fails | Run pip3 install --upgrade pip setuptools wheel first |
| Log file unreadable | Read with sudo cat data/logs/*.log (0o600 perms) |
Diagnostic commands:
sudo python3 apotropaios.py detect --log-level trace # Maximum diagnostic detail
sudo python3 apotropaios.py --version # Check version
python3 --version # Check Python version
make check-deps # Check all dependenciesSee TROUBLESHOOTING.md for troubleshooting details.
322 automated tests across four tiers:
| Tier | Tests | Description |
|---|---|---|
| Unit | 267 | Module-level testing of all 27 validators, error handling, logging, security, detection, backends, rule engine, backend re-validation, and audit regressions |
| Integration | 13 | End-to-end CLI via subprocess, base-directory isolation, full rule lifecycle with MockBackend |
| Security | 15 | CWE-mapped injection prevention: shell, path traversal, XSS, hostname |
| CI meta | 27 | Workflow and issue-template validation (YAML, action pins, headers) |
make test # Full suite: lint + unit + integration + security
make test-quick # Unit tests only (fast feedback)
make test-report # Detailed per-file report
make security-scan # Static pattern analysis (6 checks)
make metrics # Project statisticsSee make help for all 56 Makefile targets including individual per-module test targets.
Contributions are welcome. Before submitting:
- Run
make check(must pass: mypy --strict + 322 tests) - Follow coding standards in DEVELOPMENT_GUIDE.md
- All user-supplied inputs must pass through existing validation functions
- New CLI commands must be added to the parser, help function, and at least one test
- Update
CHANGELOG.mdwith your changes - Read and follow the Code of Conduct
- Report security vulnerabilities privately per SECURITY.md -- do not open public issues for security bugs
For the complete development guide including environment setup, test architecture, coding standards, and PR process, see CONTRIBUTING.md and DEVELOPMENT_GUIDE.md.
| Document | Description |
|---|---|
| README.md | Project overview, features, architecture, and quick reference (this file) |
| SETUP_GUIDE.md | Installation, venv setup, configuration, and first-run |
| USAGE_GUIDE.md | Complete CLI and interactive menu reference with operational scenarios |
| DEVELOPER_GUIDE.md | Code component catalog: all 35 modules, function tables, design rationale |
| DEVELOPMENT_GUIDE.md | Contributing guide: coding standards, testing patterns, workflow |
| CHANGELOG.md | Complete version history with detailed change descriptions |
| Wiki | 15-page wiki with architecture diagrams and operational scenarios |
| SECURITY.md | Security policy, vulnerability reporting, design documentation |
| CONTRIBUTING.md | Contribution guidelines and development environment setup |
| CODE_OF_CONDUCT.md | Contributor Covenant v2.1 |
| LICENSE | MIT License with 12 supplementary sections (warranty, liability, firewall disclaimer) |
| TROUBLESHOOTING.md | Common issues, root cause analysis, diagnostic commands |
| FAQ | 25+ frequently asked questions with answers |
Release-by-release details are maintained exclusively in CHANGELOG.md.
- netfilter.org -- iptables, nftables, and ipset -- the kernel-level packet filtering framework this tool manages
- firewalld -- dynamic firewall management daemon with D-Bus interface
- ufw -- Ubuntu's Uncomplicated Firewall providing simplified iptables management
- pytest -- Python testing framework used for the test suite
- mypy -- Static type checker for Python
- Contributor Covenant -- code of conduct framework
- Keep a Changelog -- changelog format standard
- Shields.io -- badge generation service
- OWASP and NIST -- security standards referenced throughout
Distributed under the MIT License. See LICENSE for full terms including 12 supplementary sections covering warranty disclaimer, liability limitation, firewall-specific disclaimer, assumption of risk, export compliance, and contribution licensing.
MIT License · Copyright (c) 2026 Apotropaios Project Contributors
This software is intended for authorized systems administration, network security management, and firewall configuration. Users are solely responsible for ensuring their use complies with all applicable laws and regulations. See the Firewall and Network Security Disclaimer in the LICENSE file.
Getting Help:
- Documentation: Start with the Wiki and USAGE_GUIDE.md
- Built-in Help: Run
python3 apotropaios.py COMMAND --helpfor any of the 18 commands - Security Issues: See SECURITY.md -- use private reporting for critical vulnerabilities
Diagnostic Commands:
sudo python3 apotropaios.py detect # System scan
sudo python3 apotropaios.py detect --log-level trace # Maximum diagnostic detail
sudo python3 apotropaios.py --version # Check version
python3 --version # Check Python version
make check-deps # Check all dependencies
Apotropaios -- Turning away evil
Made with focus on security, reliability, and simplicity.
