# Running an onion service As of February 2024, you can run an onion service... for testing purposes. In this document, we'll explain how to do it, and why you might not want to do so yet. This is a temporary document; we'll remove most of the limitations here as we do more development, and integrate these instructions elsewhere. **Do not follow these instructions** without looking at the Limitations section! There are many serious problems right now! ## Building arti with onion service support When you build arti, make sure that you enable the `onion-service-service` feature, as in: ``` cargo build -p arti --locked --release \ --features=onion-service-service ``` ## Configuring your onion service(s) Add a block like this to your arti configuration. (You will probably want to customize it, unless you want this exact behavior.) ``` # The second part of this section's name ("allum-cepa") is a local nickname # for this onion service. # # This is saved on disk, and used to tell onion services apart; it is not # visible outside your own Arti instance. [onion_services."allium-cepa"] # A description of what to do with incoming connections to different ports. # This is given as a list of rules; the first matching rule applies. proxy_ports = [ # Forward port 80 on the service to localhost:10080. ["80", "127.0.0.1:10080"], # Tear down the circuit on attempts to connect to port 22. ["22", "destroy"], # Ignore attempts to connect to port 265. # ("ignore" is not generally a good idea for an anonymous service; # "destroy" is safer.) ["265", "ignore"], # Any other connection attempts will make us destroy the circuit. # (This is the default; you do not need to include this line.) ["*", "destroy"] ] ``` ## Starting your onion service Just start arti as usual, as in ./target/release arti proxy -c config_file.toml ## Finding your .onion address When you start arti, look for a log message like this: ``` 2025-08-25T01:07:59Z INFO tor_hsservice: Generated a new identity for service allium-cepa: […]2qd.onion ``` (If it includes the full .onion address instead of `[…]`, you have disabled safe logging.) Once this has appeared, you can find your onion .address using the `arti hss` command (replace `` with the nickname of your service): ``` ./target/release/arti hss --nickname onion-address ``` ## Limitations Arti's Onion Service (hidden service) support is **suitable for testing and experimentation only** and should not be used for anything you care about. It **may even compromise the privacy of your other uses of the same Arti instance!** The limitations discussed here are only the most important ones. There are many missing features. ### Stability We expect that there will be some stability and reachability issues for now. You may experience bugs including internal errors and Rust stack backtraces. ### Persistent state (privacy, usability, and disk space hazards) Arti needs to generate and record various information on-disk as it operates your hidden service. There is not currently a built-in way to decomission a hidden service: you'll probably want to delete its state but there is no tooling for that. So, right now you'll have to manually remove things. But there is not even any documentation about what to safely remove. ### No client authorization There is no configuration logic (yet) to let you enable client authorization. > (This is #1028.) > Note: "client authorization" is now known as "restricted discovery". ### Missing security features; deanonymisation risks There are a *ton* of missing security features. You should not expect privacy (yet) when you are running onion services with Arti. * Missing "Vanguard" support means that operating a hidden service with Arti might enable (or help) attackers to discover your Guard relays and deanonymise you. * No meaningful protection against denial of service attacks. Rate limits, per-circuit connection limits, proof-of-work, and memory limits are not implemented. * We do not yet support circuit padding machines to hide the patterns onion service circuit setup. # Rust APIs If you want to write a program in Rust that provides an onion service, see the [`TorClient::launch_onion_service`] API. Also have a look at the `tor-hsrproxy` crate if you want to relay the connections from an onion service to a local port. [`TorClient::launch_onion_service`]: https://tpo.pages.torproject.net/core/doc/rust/arti_client/struct.TorClient.html#method.launch_onion_service