# A private Tor network: a directory authority, three relays, an exit, a web # server and a client. The network is internal: no container can reach the # Internet, so nothing here touches the real Tor network or a real site. # # docker compose up -d --build start it # docker compose down stop and remove this lab's containers x-tor: &tor build: . volumes: ["./torrc:/lab/torrc:ro"] read_only: true tmpfs: - /data:mode=0700 - /tmp cap_drop: [ALL] # tcpdump uses raw sockets; -p avoids needing promiscuous-mode privileges. cap_add: [NET_RAW] security_opt: [no-new-privileges:true] pids_limit: 64 mem_limit: 256m cpus: 1.0 logging: driver: json-file options: {max-size: 5m, max-file: "2"} services: da: <<: *tor # The authority's keys are fixed, so every node can be told in advance # which authority to trust (the DirAuthority line in common.torrc). command: sh -c "mkdir -p /data/keys && cp /lab/da-keys/* /data/keys/ && chmod 700 /data && tor -f /lab/torrc/da.torrc" networks: {tornet: {ipv4_address: 10.77.0.10}} relay1: <<: *tor command: tor -f /lab/torrc/relay.torrc --Nickname relay1 --Address 10.77.0.11 networks: {tornet: {ipv4_address: 10.77.0.11}} relay2: <<: *tor command: tor -f /lab/torrc/relay.torrc --Nickname relay2 --Address 10.77.0.12 networks: {tornet: {ipv4_address: 10.77.0.12}} relay3: <<: *tor command: tor -f /lab/torrc/relay.torrc --Nickname relay3 --Address 10.77.0.14 networks: {tornet: {ipv4_address: 10.77.0.14}} exit: <<: *tor command: tor -f /lab/torrc/exit.torrc networks: {tornet: {ipv4_address: 10.77.0.13}} web: <<: *tor # Python's built-in web server. Its log shows the address of every request. volumes: ["./web:/srv:ro"] command: python3 -u -m http.server 80 --directory /srv networks: {tornet: {ipv4_address: 10.77.0.80}} client: <<: *tor command: tor -f /lab/torrc/client.torrc networks: {tornet: {ipv4_address: 10.77.0.100}} networks: tornet: internal: true ipam: config: [{subnet: 10.77.0.0/24}]