Transparent Tor Proxy v0.4.0
TTP is a Linux CLI tool designed to route all system traffic transparently through the Tor network. Using nftables and a systemd watchdog service, it provides a crash-safe, leak-proof environment for secure online privacy. It intercepts all outgoing network traffic without requiring per-application configuration, loading firewall rules atomically and always restoring your network after any crash or outage.
TTP Installation & Setup Guide
Requirements
| Requirement | Notes |
|---|---|
| Linux with systemd | Tested on Debian 12+, Ubuntu 22.04+, Fedora 40+, Arch Linux |
| Python 3.10+ | Required for union type hints and modern stdlib features |
| nftables | Pre-installed on Debian 12+, Fedora 33+, Arch. Replaces iptables as firewall backend. |
| Root privileges |
Required for firewall and DNS modifications, and all
commands must be run with sudo
|
1. Native Packages (Recommended)
Installing via native packages ensures that all system
dependencies (tor,
nftables) and kernel-level
optimizations (SELinux) are managed by your OS package manager.
$ sudo apt install ./packaging/*.deb
$ sudo dnf install ./packaging/*.rpm
$ cd packaging && makepkg -si
2. Universal Source Script (Developer)
If you want to install from the repository, use the "intelligent" installer. It handles SELinux optimization on Fedora by compiling a custom policy module on the fly.
3. Fallback: pipx / venv (PEP 668)
Modern Linux distributions prevent global
pip install. Using these methods will
bypass kernel-level optimizations (SELinux) and won't handle
system dependencies automatically.
$ pipx install transparent-tor-proxy
$ pip install .
ttp command is
registered system-wide via the
pyproject.toml entry point
ttp = "ttp.cli:app". Tor itself does
not need to be pre-installed, as TTP detects its absence and
installs it automatically using the system's package manager.
Python dependencies
| Package | Source | Purpose |
|---|---|---|
| stem | PyPI |
Official Python library from the Tor Project. Used to
connect to Tor's Control Port/Socket, monitor bootstrap
progress, and send
NEWNYM signals.
|
| typer | PyPI |
Modern CLI framework. Provides argument parsing,
--help generation, and clean
command routing.
|
| rich | PyPI | Terminal output formatting: panels, progress bars, colored text. |
TTP System Architecture & Tor Routing Design
TTP is structured as a set of independent Python modules, each
with a single responsibility. No module imports from
cli.py. UI logic (rich, typer) is confined exclusively to
cli.py while all other modules return
plain data.
Read-only module. Checks if Tor is installed (shutil.which), running (systemctl is-active +
pgrep), and correctly configured
(TransPort 9041,
DNSPort 9054,
ControlSocket /run/tor/ttp/control.sock in torrc).
Dynamically detects the Tor system user, SELinux enforcement
state, and Firewalld presence. Returns a structured
dictionary, but never modifies anything.
Orchestrates Tor detection and auto-installation. Generates a dynamic
volatile torrc in
/run/tor/ttp/torrc, compiles a custom
SELinux policy from source on Fedora/RHEL, writes a dedicated volatile
service unit file to /run/systemd/system/ttp-tor.service,
and restarts it using native service control.
Implements a multi-chain, "Safe-Release" architecture.
Generates a stateless ruleset with three chains:
prerouting,
output (NAT), and
filter_out (Filter). The latter
acts as a dedicated Kill-Switch. Supports **Selective Root Routing** (sudo/root routed
by default), automatic **LAN Bypass** (local RFC 1918 subnets), and **DoT Prevention** (port 853
reject). Applied atomically via nft -f.
Stateless Kernel-level DNS redirection. Writes the Tor resolver to
/run/ttp/resolv.conf and overlays it on
/etc/resolv.conf using mount --bind.
Implements **DoH/DoT Leak Mitigation** (intercepting browser-level DoH by mapping Mozilla's canary
domain use-application-dns.net to 0.0.0.0 in the
Tor configuration), resolves symlinks, and uses a lazy umount -l fallback.
Volatile session locking. Reads and writes a JSON lock file at
/run/ttp/ttp.lock (tmpfs) containing session PID, ports, timestamp, and
watchdog status keys (watchdog_active, watchdog_pid). Verifies PID validity to auto-recover orphaned sessions, and runs
the pre-flight safety check to ensure sufficient tmpfs RAM.
Handles Tor control Socket interactions. Connects to Tor's dedicated
private socket at /run/tor/ttp/control.sock,
monitors bootstrap progress via status/bootstrap-phase,
rotates circuits with NEWNYM, verifies
Tor routing, and performs a graceful cryptographical
SHUTDOWN teardown.
Integrity and auto-healing monitor. Spawns and manages the TTP session background watchdog daemon
service (ttp-watchdog.service). Periodically monitors firewall table rules,
the DNS overlay mount, and Tor daemon connectivity. Handles Auto-Healing (First Strike)
and triggers the Emergency Killswitch (Second Strike) if recovery fails, completely
locking network interfaces and broadcasting system alerts.
Pure data-gathering module used by
ttp diagnose. Collects OS info,
Tor service status, active torrc settings, nftables ruleset,
DNS state, and Tor control interface status. Returns a flat
dict[str, str]. Every subprocess
call is wrapped in a try/except so a single failure never
aborts the full diagnostic.
Defines a custom exception hierarchy for the project. Includes
TTPError (base) and specialized
classes: FirewallError,
DNSError,
StateError, and
TorError. Used to distinguish
between fatal issues and recoverable states.
/run/ttp/ttp.log. Starting with
v0.3.0, it employs a
RotatingFileHandler
with a 1MB limit to prevent memory exhaustion in the RAM disk.
TTP Session Execution & Core Process Flow
ttp start
1. Pre-flight check, Signal registration & SELinux
Verifies root privileges (os.geteuid() == 0), registers signal handlers,
and executes a **Pre-flight safety check** verifying that /run/ttp (tmpfs)
has at least 5MB of free space to prevent out-of-memory crashes. On Fedora/RHEL, ensures the custom
SELinux policy is compiled.
2. Orphan detection
Inspects the volatile lock file at /run/ttp/ttp.lock. If
the lock exists but its PID is no longer running, it automatically triggers
state.attempt_recovery() to safely restore firewall rules and DNS
from the orphan session before initiating the new startup.
3. Volatile Tor service setup
tor_install.ensure_tor_ready() generates a volatile, sandboxed
torrc in /run/tor/ttp/torrc and writes
a dedicated service unit file directly to the systemd path at
/run/systemd/system/ttp-tor.service. It then reloads systemd and
starts this isolated Tor instance.
4. Stateless multi-chain firewall application
Applies a stateless ruleset atomically via nft -f.
This redirects system TCP and DNS traffic to Tor's dedicated ports while
enabling a strict filter-based Kill-Switch to reject all non-Tor cleartext traffic
and IPv6 leaks immediately.
5. Stateless DNS overlay
DNS is redirected at the Kernel level. The module writes nameserver 127.0.0.1
to /run/ttp/resolv.conf and binds it directly over
/etc/resolv.conf using mount --bind.
This achieves clean redirection without altering physical disk configuration.
6. Volatile lock file write
Writes a JSON session lock file to /run/ttp/ttp.lock containing the active
process PID, timestamps, and DNS backup parameters (mount_target). This file
resides entirely in `tmpfs` and evaporates automatically if the host loses power.
7. Bootstrap wait & verification
Monitors bootstrap progress up to 100% via the private Unix ControlSocket
/run/tor/ttp/control.sock. After a brief settling delay, verifies Tor
routing
via multiple public lookup APIs to confirm that all network traffic is properly tunneled.
8. Watchdog service daemon activation
If the watchdog monitor is enabled (via --watchdog or -w), the CLI automatically writes the volatile systemd service unit file /run/systemd/system/ttp-watchdog.service and starts it to monitor the session's
health proactively.
ttp stop
Preventive Watchdog Stop & Graceful Teardown
Stops the background watchdog service daemon immediately to prevent triggering the emergency killswitch
during teardown. Then sends a cryptographic SHUTDOWN signal to Tor to close
active circuits cleanly before touching firewall rules, eliminating cleartext RST leaks.
Stop Tor service
Stops the dedicated TTP Tor service, unlinks the volatile unit file at
/run/systemd/system/ttp-tor.service, and triggers a systemd daemon-reload.
Restore firewall
Atomically flushes and removes the entire TTP ruleset table by executing:
nft destroy table inet ttp.
Restore DNS
Dismantles the resolver bind-mount using umount -l (lazy unmount)
to ensure the overlay is detached instantly even if system resources are temporarily busy, then cleans
up
the volatile resolv.conf from the RAM disk.
Delete lock
Removes /run/ttp/ttp.lock. Cleartext networking is restored.
Firewall Rules & Nftables Routing Redirection
TTP generates a single nftables table. The ruleset is written to a
temporary file and loaded with a single
nft -f call, meaning all rules apply
atomically, or none do.
-
DNS before LAN Bypass: The DNS redirect rules must run before the LAN bypass
rules. Since browsers might query the LAN gateway (e.g.
192.168.1.1:53) for DNS resolution, executing LAN bypass first would allow these queries to bypass Tor entirely, resulting in a severe DNS leak. -
DNS before Loopback: The DNS redirect rules must run before the loopback
accept rule. If loopback accept matches first, local resolver queries sent to
127.0.0.1are allowed without being redirected to Tor's DNSPort.
filter_out chain that acts as a global
Kill-Switch. It explicitly allows Tor, root, and
local traffic while rejecting everything else. This ensures that
no cleartext traffic can bypass the NAT redirection, covering edge
cases like pre-existing connections or processes failing to be
intercepted.
Allows local network communication by exempting RFC 1918 subnets (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), Link-Local (169.254.0.0/16), and
IPv6 local ranges (fc00::/7, fe80::/10) from Tor
redirection. Local services like SSH, NFS, and printing remain fully operational. Disabling is possible
via --no-lan-bypass.
Intercepts root process traffic (UID 0) by default to prevent leak vectors during package manager runs
(dnf, apt) or background system tasks. For
scenarios requiring administrative cleartext communication, the --allow-root
flag exempts UID 0 from redirection.
Explicitly rejects outbound TCP/UDP port 853 inside the filter_out chain.
Blocking DNS-over-TLS (DoT) forces local stub resolvers and modern browsers to fall back to plain
UDP/TCP port 53 DNS queries, which are then securely intercepted and routed through Tor's anonymous
resolver.
Rejects direct traffic to well-known public DoH resolver IPs on port 443 (Cloudflare, Google, Quad9, OpenDNS) - both IPv4 and IPv6. This provides defense-in-depth protection against non-compliant browsers that bypass the local resolver and ignore canary domain signals.
DNS Handling & Leak Prevention
DNS leak prevention is critical for anonymity. TTP employs a robust,
stateless kernel-level overlay to safely redirect all system DNS traffic
to Tor's DNSPort at 127.0.0.1:9054.
This strategy eliminates the legacy dependency on systemd-resolved / resolvectl,
ensuring universal compatibility and absolute reliability without modifying permanent system configuration
files.
TTP generates a volatile resolv configuration at /run/ttp/resolv.conf
containing only nameserver 127.0.0.1, and bind-mounts it directly over the
system's resolver configuration. This stateless overlay is instantly visible to all processes and
disappears completely on unmount.
If /etc/resolv.conf is a symlink (e.g., pointing to systemd-resolved's stub
file), TTP resolves its absolute physical path via realpath and applies the
bind-mount onto the target file. This preserves symlink integrity and ensures sandboxed apps see the
redirected DNS.
In case of unclean shutdowns, multiple mount layers could stack on the resolver file. During pre-flight
checks, TTP inspects /proc/mounts and iteratively clears stale overlays by
running a loop of lazy unmounts (umount -l, up to 10 times) before applying
the fresh layer.
DNSPort (127.0.0.1:9054), while the DNS Overlay makes sure local glibc
resolver queries are explicitly addressed to 127.0.0.1.
MapAddress entries into the generated
torrc to neutralize DoH canary domains for Cloudflare (use-application-dns.net), Google, Quad9, OpenDNS, and AdGuard. Compliant browsers
querying these domains receive null responses, signaling them to disable DoH and fall back to the system
resolver, which TTP then safely routes through Tor. Additionally, TTP blocks outbound connections to
well-known DoH resolver IPs on port 443 as defense-in-depth.
TTP CLI Command Reference
All commands require sudo. Global
flags --verbose / -v,
--quiet / -q, and
--log-format text|json are available on all commands.
Starts the transparent proxy session. Orchestrates the full startup sequence, establishing the volatile Tor daemon, loading network-level nftables intercepts, and mounting the DNS resolver overlay.
Stops the session and restores the network to its original state.
Requests a new Tor circuit without stopping the session. Traffic continues to flow through Tor uninterrupted while the circuit rotates.
Shows the current session status. Resolves and displays the active external exit IP if the session is active.
Quickly restarts the session. Shortcut for
stop followed by
start, accepting the same startup arguments.
Manages the background health monitoring daemon (ttp-watchdog.service). If
spawned, the watchdog performs diagnostic checks every 15 seconds to ensure system integrity.
Network diagnostics command. Verifies Tor connectivity, latency to torproject.org, and local controller stability.
Performs a battery of DNS and IP leak tests. Use
--verbose
to see full test results.
Displays logs from the volatile TTP log file at
/run/ttp/ttp.log. Automatically
shows startup events, connection states, and Tor daemon feedback.
Runs a comprehensive system diagnostic and prints a detailed report. Checks Tor service status, torrc configuration, active nftables rules, and DNS settings.
Performs a deep cleanup of the TTP state. Stops any active session, removes the SELinux policy module, and deletes log files.
Crash Recovery & Systemd Watchdog Protection
TTP is designed around the assumption that any process can die at
any time. The lock file at
/run/ttp/ttp.lock maintains active session states,
enabling immediate recovery and clean slate verification.
Reads lock → destroys isolated nftables table → unmounts DNS overlay → unloads volatile Tor service → deletes lock. Clean exit.
Signal handlers registered at startup intercept the signal
and call the same cleanup routine as
ttp stop before exiting.
The lock file survives in tmpfs. On the next
ttp start, if the process is
dead, the lock is orphaned, and TTP runs pre-flight recovery:
cleaning stacked mounts, destroying the stale nftables table, and
clearing the orphan lock.
Proactive Health Watchdog Daemon
TTP establishes a background monitoring unit (ttp-watchdog.service). Operating
continuously during an active session, it runs integrity diagnostics every 15 seconds to ensure that no
leakage vectors develop due to system service restarts, third-party interventions, or hardware anomalies.
In v0.4.0, the watchdog was upgraded to be network-resilient: it dynamically detects
physical network carrier drops and route removals, safely suspending integrity checks when offline to
prevent false-positive lockouts, and automatically resuming when connectivity stabilizes. The watchdog
operates under a strict two-strike escalation protocol:
STRIKE 1: AUTO-HEALING
Non-Destructive CorrectionIf the watchdog detects a minor anomaly (such as the DNS overlay being unmounted by a system update or a brief failure in resolving Tor status), it triggers an immediate, silent auto-healing attempt. It will clear stacked resolver mounts and re-apply structural configurations to restore the secure pipeline without interrupting your active internet connection or rotating your Tor circuit.
STRIKE 2: EMERGENCY LOCKDOWN
Emergency Killswitch
If the anomaly persists on the second consecutive probe, or if a critical component is compromised, or
if the auto-healing command itself fails (such as being unable to re-apply rules), the watchdog
instantly engages a system-wide lockdown. It drops all physical network traffic, broadcasts a terminal
console warning (wall alert), and triggers a desktop popup via notify-send.
Or use the nuclear option:
sudo ./scripts/restore-network.sh
Linux Distribution Compatibility & Support
TTP handles the main differences between distributions automatically.
| Distribution | Service Unit | Tor User | Package Manager | Status |
|---|---|---|---|---|
| Debian 12+ | tor@default |
debian-tor |
apt-get |
Validated |
| Ubuntu 22.04+ | tor@default |
debian-tor |
apt-get |
Validated |
| Fedora 40+ | tor |
toranon |
dnf |
Validated |
| Arch Linux | tor |
tor |
pacman |
Tested (Docker) |
tor.service is a
multi-instance master that reports active (exited) even
when no daemon is actually running. The real daemon lives in
tor@default.service. TTP detects this
safely.
TTP Codebase Development & Custom Compilations
Running unit tests
Unit tests are fully mocked, no root, no network, no system modifications.
VM integration tests
Integration tests require root and a real Tor daemon. They run inside a QEMU VM (Debian 13) or Docker containers.
Project structure
Known Limitations & Security Considerations
TransPort only supports TCP.
ttp status reflects the circuit used
to reach check.torproject.org, which
may differ from the circuit used by other applications.
/etc/tor/torrc to add required
directives. The original file is backed up to
torrc.bak
before any changes. Custom configurations are preserved where
possible.
Complete System Uninstallation
TTP provides two levels of removal depending on how you installed it.
Use this to clean up the system state while keeping the TTP binary. It stops any active session, removes the SELinux policy module, and clears log files.
A complete system removal. If you used
scripts/install.sh, this script
will remove /opt/ttp, the symlink
in /usr/local/bin, and perform all
the cleanups of the CLI command.