whn0thacked/arti-docker

By whn0thacked

โ€ขUpdated 3 months ago

๐Ÿณ Docker image for Arti (Rust Tor client). Fully static binary, distroless runtime, non-root.

Buildkit cache
Image
Networking
Security
0

2.0K

whn0thacked/arti-docker repository overview

โ ๐Ÿณ arti-docker

Docker Image Size Docker Pulls Architecture Security: non-root Base Image Upstream

A minimal, secure, and production-oriented Docker image for Arti โ€” a complete rewrite of the Tor client in Rust, developed by The Tor Projectโ .

Built as a fully static binary with all features enabled and shipped in a distroless runtime image, running as non-root by default.


โ โœจ Features

  • ๐Ÿ” Secure by default: Distroless runtime + non-root user + static binary.
  • ๐Ÿ— Multi-arch: Supports amd64 and arm64.
  • ๐Ÿ“ฆ Fully static binary: Built for gcr.io/distroless/static:nonroot โ€” no libc, no dynamic linker.
  • ๐ŸŒ Full-featured: Built with --all-features โ€” SOCKS proxy, DNS resolver, onion services (client & server), pluggable transports, RPC, key management.
  • ๐Ÿงพ Config-driven: Mount a TOML config or configure entirely via CLI flags.
  • ๐Ÿ”„ Auto-updated: CI checks for new upstream commits every hour and rebuilds automatically.
  • ๐Ÿงฐ Build-time pinning: Upstream repo/ref are configurable via build args.

โ โš ๏ธ Important Notice

Arti is a Tor client. Using Tor may be restricted, monitored, or illegal depending on your jurisdiction. Operating Tor relays, bridges, or onion services carries additional legal and operational considerations.

You are responsible for compliance with local laws and for safe deployment (firewalling, access control, logging, monitoring).

Arti is under active development by The Tor Project. While functional, it may not yet have full feature parity with the C Tor implementation. Check the upstream statusโ  before production use.


โ ๐Ÿš€ Quick Start

Create docker-compose.yml:

services:
  arti:
    image: whn0thacked/arti-docker:latest
    container_name: arti
    restart: unless-stopped
    environment:
      RUST_LOG: "info"
    ports:
      - "127.0.0.1:9050:9050/tcp"
      # - "127.0.0.1:9053:9053/tcp"
      # - "127.0.0.1:9053:9053/udp"
    volumes:
      - arti-data:/var/lib/arti
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    read_only: true
    tmpfs:
      - /tmp:rw,nosuid,nodev,noexec,size=64m
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
        reservations:
          cpus: "0.1"
          memory: 128M
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "5"
        compress: "true"
    stop_grace_period: 30s

volumes:
  arti-data:
docker compose up -d

Verify:

curl --socks5-hostname 127.0.0.1:9050 https://check.torproject.org/api/ip
# {"IsTor":true,"IP":"xxx.xxx.xxx.xxx"}
โ Docker Run (one-liner)
docker run -d --name arti \
  -p 127.0.0.1:9050:9050 \
  -v arti-data:/var/lib/arti \
  --read-only --tmpfs /tmp:rw,nosuid,nodev,noexec,size=64m \
  --security-opt no-new-privileges:true --cap-drop ALL \
  --memory 512m --cpus 1.0 \
  --restart unless-stopped \
  whn0thacked/arti-docker:latest

โ โš™๏ธ Configuration Reference

โ Environment Variables
VariableRequiredDefaultDescription
RUST_LOGNoinfo (built-in)Log level filter. Supports per-module granularity.

RUST_LOG examples:

ValueEffect
infoDefault โ€” recommended for production
debugVerbose โ€” troubleshooting
warnQuiet โ€” only problems
arti=debug,tor_proto=infoPer-module granularity
traceExtreme verbosity (development only)
โ CLI Parameters (Global)
ParameterShortDescription
--config FILE-cLoad configuration from file. Can be specified multiple times.
--option KEY=VALUE-oOverride config values using TOML syntax. Can be specified multiple times.
--log-level LEVEL-lOverride log level (trace, debug, info, warn, error).
--disable-fs-permission-checksโ€”Disable filesystem permission checks (enabled by default in this image).
โ CLI Parameters (proxy subcommand)
ParameterShortDescription
--socks-port PORT-pOverride SOCKS listen port (default: 9050).
--dns-port PORTโ€”Override DNS listen port (default: 9053).
โ Subcommands
SubcommandDescription
proxyRun the SOCKS/DNS proxy (default).
keys listList all keys.
keys list-keystoresList key storage backends.
keys check-integrityVerify key integrity.
hsc key getGet onion service key.
hsc key listList onion service keys.
hssHidden service server operations.
โ Ports
PortProtocolPurpose
9050TCPSOCKS5 proxy โ€” main Tor entry point.
9053TCP/UDPDNS resolver โ€” anonymized DNS queries over Tor.
9150TCPAlternative SOCKS5 port (Tor Browser convention).
โ Volumes
Container PathPurposeBackup
/var/lib/artiPersistent state: consensus cache, descriptors, guard state. Safe to delete โ€” re-bootstraps in 30sโ€“2min.Optional
/var/lib/arti/keysCryptographic keys: onion service identity, client auth. Losing = losing .onion address.Critical
/etc/arti.tomlConfiguration file (optional โ€” mount from host as read-only).Optional

โ ๐Ÿง  Container Behavior

  • ENTRYPOINT: /usr/local/bin/arti
  • CMD (default):
proxy --disable-fs-permission-checks \
  -o "proxy.socks_listen=[\"0.0.0.0:9050\"]" \
  -o "proxy.dns_listen=[\"0.0.0.0:9053\"]"

The container runs a SOCKS5 proxy on 9050 and a DNS resolver on 9053, listening on all interfaces inside the container.

Override by passing your own arguments:

docker run ... whn0thacked/arti-docker:latest proxy -c /etc/arti.toml
docker run ... whn0thacked/arti-docker:latest proxy --socks-port 1080
docker run ... whn0thacked/arti-docker:latest keys list

โ ๐Ÿ“ Advanced Usage

โ Custom config file
docker run -d --name arti \
  -p 127.0.0.1:9050:9050 \
  -v ./arti.toml:/etc/arti.toml:ro \
  -v arti-data:/var/lib/arti \
  --read-only --tmpfs /tmp:rw,nosuid,nodev,noexec,size=64m \
  --security-opt no-new-privileges:true --cap-drop ALL \
  whn0thacked/arti-docker:latest \
  proxy --disable-fs-permission-checks -c /etc/arti.toml
โ CLI overrides (no config file needed)
docker run -d --name arti \
  -p 127.0.0.1:9050:9050 \
  -p 127.0.0.1:9053:9053 \
  whn0thacked/arti-docker:latest \
  proxy \
  --disable-fs-permission-checks \
  -o 'proxy.socks_listen=["0.0.0.0:9050"]' \
  -o 'proxy.dns_listen=["0.0.0.0:9053"]' \
  -l debug
โ DNS resolution over Tor
# Enable DNS port in compose or docker run:
# -p 127.0.0.1:9053:9053/tcp -p 127.0.0.1:9053:9053/udp

dig @127.0.0.1 -p 9053 torproject.org
nslookup torproject.org 127.0.0.1 -port=9053
โ Use with applications
# curl
curl --socks5-hostname 127.0.0.1:9050 https://example.onion

# Environment variable (works with many apps)
ALL_PROXY=socks5h://127.0.0.1:9050 curl https://check.torproject.org/api/ip

# proxychains
echo "socks5 127.0.0.1 9050" >> /etc/proxychains.conf
proxychains curl https://check.torproject.org/api/ip

# Firefox: Settings โ†’ Network โ†’ Manual Proxy โ†’ SOCKS Host: 127.0.0.1:9050
# โœ… Check "Proxy DNS when using SOCKS v5"

โ ๐Ÿง… Onion Services

โ Running an onion service

Create arti.toml with onion service config (see upstream docsโ ):

docker run -d --name arti-hs \
  -v ./arti.toml:/etc/arti.toml:ro \
  -v arti-keys:/var/lib/arti/keys \
  -v arti-data:/var/lib/arti \
  --read-only --tmpfs /tmp:rw,nosuid,nodev,noexec,size=64m \
  --security-opt no-new-privileges:true --cap-drop ALL \
  whn0thacked/arti-docker:latest \
  proxy --disable-fs-permission-checks -c /etc/arti.toml
โ Key management
docker run --rm whn0thacked/arti-docker:latest keys list
docker run --rm whn0thacked/arti-docker:latest keys list-keystores
docker run --rm whn0thacked/arti-docker:latest keys check-integrity

# With mounted keys volume:
docker run --rm -v arti-keys:/var/lib/arti/keys:ro \
  whn0thacked/arti-docker:latest hsc key list

โ ๐Ÿ›ก๏ธ Security Hardening

This image applies the following hardening measures:

MeasureDescription
Distroless baseNo shell, no package manager, no utilities โ€” minimal attack surface
Non-rootRuns as UID 65534 (nonroot)
Static binaryNo dynamic linker, no shared libraries
Read-only FSRoot filesystem is read-only; /tmp via tmpfs
No capabilitiesAll Linux capabilities dropped (cap_drop: ALL)
No privilege escalationno-new-privileges prevents setuid/setgid abuse
Resource limitsCPU and memory limits prevent DoS
Log rotationPrevents disk exhaustion
SIGINT shutdownGraceful shutdown via STOPSIGNAL SIGINT
Localhost bindingPorts bound to 127.0.0.1 by default in examples

โ ๐Ÿ›  Build

This Dockerfile supports pinning upstream Arti source:

  • ARTI_REPO (default: https://gitlab.torproject.org/tpo/core/arti.git)
  • ARTI_REF (default: main)
โ Multi-arch build
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t whn0thacked/arti-docker:latest \
  --push .
โ Build a specific commit
docker buildx build \
  --build-arg ARTI_REF=ba4163ed943a67cd8a55f7291797fb22a788f950 \
  -t whn0thacked/arti-docker:dev \
  --push .
โ Local test build
docker buildx build --load -t arti:test .
docker run --rm arti:test --version

Note: First build takes 15โ€“40 minutes due to LTO, build-std, and all features. Subsequent builds are faster thanks to BuildKit cache.



โ ๐Ÿ“„ License

This Dockerfile, CI pipeline, and associated documentation are licensed under the GNU General Public License v3.0โ .

Arti itself is licensed under MIT OR Apache-2.0 by The Tor Projectโ .

Tag summary

Content type

Buildkit_cache

Digest

sha256:9bad853c4โ€ฆ

Size

907.9 MB

Last updated

3 months ago

docker pull whn0thacked/arti-docker:cache