{"id":6164,"date":"2026-09-05T00:42:32","date_gmt":"2026-09-04T15:42:32","guid":{"rendered":"https:\/\/eternalsphere.net\/echoes\/?p=6164"},"modified":"2026-09-12T17:17:47","modified_gmt":"2026-09-12T08:17:47","slug":"tja539f5ibysinx","status":"publish","type":"post","link":"https:\/\/blog.eternalsphere.net\/index.php\/2026\/09\/05\/tja539f5ibysinx\/","title":{"rendered":"Security Architecture of a Tor Relay: Least Privilege, Firewalls, and Service Isolation"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">A secure Tor relay does not depend on exotic hardening.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The strongest baseline is a conventional Linux security model applied carefully:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>least privilege\n+\nminimal exposed ports\n+\nrestricted identity keys\n+\nlocal administrative interfaces\n+\nregular updates<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A non-exit relay is especially suitable for this approach because it does not need to originate arbitrary Internet traffic on behalf of users.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dedicated service accounts are essential<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A Tor daemon should not run permanently as root.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Modern Debian-derived packages normally execute Tor under a dedicated system service account created specifically for the package.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This account differs from a human login account.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It typically has:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>no interactive shell;<\/li>\n\n\n\n<li>no usable password;<\/li>\n\n\n\n<li>no home directory under <code>\/home<\/code>;<\/li>\n\n\n\n<li>ownership of the Tor state directory;<\/li>\n\n\n\n<li>access only to files required by Tor.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This creates an important security boundary.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the Tor process were ever compromised, the attacker would initially inherit the privileges of the restricted service identity rather than full administrative privileges.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Protect relay identity keys<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Tor state directory contains long-term relay identity material.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Typical structure:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/var\/lib\/tor\/\n\u2514\u2500\u2500 keys\/<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Permissions should be restrictive.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Conceptually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>owner: dedicated Tor service user\ngroup: dedicated Tor service group\nworld access: none<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Configuration files may be readable by other local users, but private identity keys should not be.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Relay fingerprints and public descriptors are intentionally public. Private identity keys are not.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Only expose the ORPort<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A well-designed relay has a very small Tor-specific network surface.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A port scan should show something conceptually similar to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LISTEN 0.0.0.0:&lt;RELAY_PORT&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">while ports associated with local SOCKS or control access remain absent.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The intended design is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Internet\n   \u2193\nORPort only<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">not:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Internet\n   \u251c\u2500 ORPort\n   \u251c\u2500 SOCKS proxy\n   \u251c\u2500 ControlPort\n   \u2514\u2500 miscellaneous administrative ports<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Keeping management interfaces off the public network reduces risk significantly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Unix control sockets are preferable for local monitoring<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Tools such as Nyx or custom monitoring scripts can communicate with Tor over a local Unix socket.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/run\/tor\/control<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This avoids opening an additional TCP control service.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Permissions can then be handled using normal filesystem ownership:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>srw-rw----<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Only the Tor service identity and authorized local processes should be able to access the socket.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Host firewall and router firewall serve different roles<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A typical home or small-office relay may sit behind NAT.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The router performs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public TCP connection\n        \u2193\nDNAT \/ port forward\n        \u2193\ninternal relay server<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The host firewall then decides whether the relay server itself accepts the packet.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Using both layers provides defense in depth.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The external router should forward only the ORPort, while the host firewall should permit exactly the service that Tor is listening on.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">IPv4-only configurations should remain explicit<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If a relay is configured with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ORPort &lt;RELAY_PORT&gt; IPv4Only<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">then opening an equivalent IPv6 firewall rule does not automatically expose Tor over IPv6 if Tor itself is not listening there.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nevertheless, matching firewall policy to actual application behavior keeps configuration easier to audit.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Unused rules can eventually be removed for clarity.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Understanding systemd security scores<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Commands such as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemd-analyze security &lt;service&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">are useful but frequently misunderstood.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The resulting score is a <strong>sandboxing exposure score<\/strong>, not a vulnerability scanner.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A service might receive a \u201cmedium\u201d rating because the unit lacks directives such as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ProtectKernelModules=\nProtectControlGroups=\nRestrictNamespaces=<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">without having any known security flaw.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Some packages also perform privilege dropping internally rather than through <code>User=<\/code> directly in the systemd unit.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemd exposure score\n\u2260\nCVE severity\n\u2260\nevidence of compromise<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Blindly adding every possible sandbox directive merely to improve the score can break package assumptions or interfere with upgrades.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hardening should be based on actual threat models.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Useful protection mechanisms<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Commonly valuable systemd protections include:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>NoNewPrivileges=true\nPrivateTmp=true\nProtectHome=true\nPrivateDevices=true<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Capability restrictions are also useful.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A Tor relay generally does not need privileges such as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CAP_SYS_ADMIN\nCAP_SYS_MODULE\nCAP_NET_ADMIN\nCAP_SYS_PTRACE<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Removing unnecessary capabilities limits what a compromised service could do.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Keep package sources trustworthy<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Tor should be installed from a well-maintained distribution repository or the official Tor Project package repository.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The package source should be periodically checked:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apt-cache policy tor<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This makes it possible to confirm:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>installed version;<\/li>\n\n\n\n<li>candidate version;<\/li>\n\n\n\n<li>repository origin.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Security updates to the operating system are equally important.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A perfectly configured Tor daemon still depends on OpenSSL, libc, the Linux kernel, SSH, and other system components.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Avoid unnecessary complexity<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Security architecture often improves when components are removed rather than added.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A sensible non-exit relay security model can remain extremely simple:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dedicated service user\n+\nrestricted key directory\n+\nsingle public relay port\n+\nUnix control socket\n+\nhost firewall\n+\nNAT firewall\n+\nautomatic security updates<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is usually more robust than a heavily customized configuration whose behavior becomes difficult to understand after several years of upgrades.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A secure Tor relay does not depend on exotic hardening. The strongest baseline is a conventional Linux security model applied carefully: A non-exit relay is especially suitable for this approach because it does not need to originate arbitrary Internet traffic on behalf of users. Dedicated service accounts are essential A &hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[120],"tags":[265,245],"class_list":["post-6164","post","type-post","status-publish","format-standard","hentry","category-1s3b6h7r2zay02x","tag-security","tag-tor"],"_links":{"self":[{"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/posts\/6164","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/comments?post=6164"}],"version-history":[{"count":1,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/posts\/6164\/revisions"}],"predecessor-version":[{"id":6165,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/posts\/6164\/revisions\/6165"}],"wp:attachment":[{"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/media?parent=6164"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/categories?post=6164"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.eternalsphere.net\/index.php\/wp-json\/wp\/v2\/tags?post=6164"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}