How the Tor Protocol Works (Part 1) | homelabird-blog
UpdatedFeb 13, 2026•9 min read
9 views
How the Tor Protocol Works (Part 1)
Part 1 explains how Tor circuits, relay roles, onion routing work, plus the threat model and tradeoffs. It sets up the series path toward crawling through Tor.
Tor is a network that routes traffic through multiple relays so that no single relay can see both who you are and where you are going. It does this by building a circuit of relays and layering encryption for each hop.
Tor does not just encrypt once. It negotiates a unique session key with each hop, then wraps data in layers. Each relay removes one layer and forwards the rest. This is why it is called onion routing.
Layered encryption sequence
sequenceDiagram
autonumber
participant C as Client (Alice)
participant Entry as Entry Node (Guard)
participant Middle as Middle Node
participant Exit as Exit Node
participant Server as Destination (Bob)
Note over C: 1. Circuit Building & 3-Layer Encryption (Onion)
C->>Entry: Send Packet [Encrypted with keys for Entry+Middle+Exit]
Note right of C: 3 Layers
Note over Entry: 2. Removes 1st Layer
Note right of Entry: Knows: Client IP<br/>Unknown: Destination / Content
Entry->>Middle: Forward Packet [Encrypted with keys for Middle+Exit]
Note right of Entry: 2 Layers
Note over Middle: 3. Removes 2nd Layer
Note right of Middle: Knows: Entry & Exit<br/>Unknown: Client / Content
Middle->>Exit: Forward Packet [Encrypted with key for Exit]
Note right of Middle: 1 Layers
Note over Exit: 4. Removes Final Layer
Note right of Exit: Knows: Destination & Content<br/>Unknown: Client IP
Exit-->Server: Send Actual Request
Note right of Exit: Decrypted Data
Server-->>Exit: Send Response
Note over Exit, C: Response is encrypted in reverse order (wrapped) back to Client
Tor clients need a trusted view of the network. A small set of directory authorities publish a signed consensus document that lists relays, keys, and flags. Clients download this consensus and pick relays from it to build circuits.
Tor clients stick to a small set of guards for long periods. This reduces the chance that you randomly pick a malicious first hop over time. The tradeoff is that a compromised guard is more damaging, so guard selection is conservative.
Path selection details (guards, middles, exits)
Guards: chosen from relays with the Guard flag and weighted by bandwidth. Clients keep a small, persistent guard set for long periods to reduce exposure. Family/subnet restrictions prevent picking a related relay.
Middles: picked to avoid the same family or subnet as the guard or exit. Bandwidth weights favor higher-capacity relays to improve performance.
Exits: filtered by exit policies to match the destination port (and sometimes address). Only exits that allow the target port are eligible; otherwise the client retries with a different exit.
Onion services (also called hidden services) do not use exit relays. The client and the service meet at a rendezvous point, so neither side learns the other's IP. This is the foundation for hosting a site on Tor.
Onion services v3 (intro points, HSDir, rendezvous)
Onion services v3 use descriptors and introduction points instead of exits.
Service identity: the service has a long-term ed25519 identity key; its v3 .onion address is derived from this public key.
Intro points: the service builds circuits to several introduction points and keeps them alive.
Publish descriptor: the service publishes a signed descriptor (with intro points and keys) to HSDir relays using a blinded key that rotates periodically.
Client lookup: the client computes which HSDirs hold the descriptor and fetches it over Tor, learning the intro points.
Rendezvous: the client creates a rendezvous point and sends an INTRODUCE message via an intro point with a one-time cookie.
Meet: the service connects to the rendezvous point, and the client and service establish an end-to-end encrypted circuit.
HSDir relays are ordinary Tor relays with the HSDir flag. They store descriptors but never see the service IP.
Tor adds latency by design. Circuit setup, multi-hop routing, and relay capacity all reduce speed. This is expected. If you want privacy, you accept slower performance.
Tor helps when you need to crawl public content without exposing your origin IP and you want circuit isolation per target. In Part 5, we build a crawler that routes traffic through Tor and avoids DNS leaks.
Tor clients download a consensus, pick relays, then build a circuit hop-by-hop with layered keys.
sequenceDiagram
participant C as Client
participant D as Directory
participant G as Guard
participant M as Middle
participant E as Exit
C->>D: Fetch consensus
C->>G: CREATE cell + key handshake
C->>M: EXTEND cell via Guard
C->>E: EXTEND cell via Middle
NTor handshake (step-by-step)
NTor is the default handshake for creating a hop in modern Tor circuits. It yields independent forward and backward keys without exposing the client.
Client prepares: pick relay identity (ID) and ntor onion key (B) from the consensus, generate ephemeral secret x and public X = g^x.
CREATE2: send CREATE2 containing ID, B, and X.
Relay responds: relay generates y and Y = g^y, derives the shared secret, and replies with CREATED2 carrying Y and an AUTH value.
Key expansion: client derives the same shared secret, verifies AUTH, and expands it into forward/backward keys for that hop.
sequenceDiagram
participant C as Client
participant R as Relay (ntor)
C->>R: CREATE2 {ID, B, X = g^x}
R->>R: Derive Y = g^y and shared secret
R-->>C: CREATED2 {Y, AUTH}
C->>C: derive secret, verify AUTH, expand keys
Links vs circuits: relays connect with long-lived TLS links; circuits are virtual paths multiplexed over those links.
Cells and commands: Tor moves data in fixed-size cells. Relay cells carry a circuit ID, a command (BEGIN/DATA/END), a stream ID, and a per-hop digest.
Handshakes: the client builds the first hop with CREATE/CREATE2 and a key exchange, then extends with RELAY_EXTEND/EXTENDED (each hop gets its own forward/backward keys).
Streams: a TCP stream starts with RELAY_BEGIN and RELAY_CONNECTED; application data flows in RELAY_DATA; shutdown uses RELAY_END.
Layered integrity: each hop verifies its digest and peels one layer; this prevents tampering and keeps hop-to-hop separation intact.
Circuit lifecycle: circuits rotate over time; isolation settings keep different destinations on separate circuits to reduce correlation.
Cell format and relay payload (structured view)
Exact sizes depend on OR protocol version; the tables below show the legacy fixed-size layout for intuition.
Channel vs circuit vs stream: channels are TLS connections between relays; circuits are onion-encrypted paths over channels; streams are TCP connections multiplexed inside circuits.
Key separation: each hop has distinct forward and backward keys derived during the handshake to isolate direction and hop.
Relay integrity: per-hop digests let relays verify integrity without learning other hops' keys or endpoints.
Flow control: SENDME-style control cells provide per-circuit and per-stream windows so fast senders cannot overwhelm relays.
Exit policies: exits advertise allowed ports and protocols, so the client selects an exit compatible with the destination.
Directory selection: clients use the consensus (often with microdescriptors) plus bandwidth weights and flags (Guard/Exit/Stable) for path selection.
Sharing hands-on cloud infrastructure and DevOps experience. Writing about Kubernetes, Terraform, and observability, and documenting lessons learned as a solo operator.