Guidelines for developing services to be run on Tor machines
The Tor Project develops a couple of services designed to be run on Tor machines. This page is a collection of guidelines for developing such services. The rule of thumb is that every service that runs a custom process on a Tor machine should adhere to these guidelines.
Services that only provide static web content are in general not affected by these guidelines, even if they depend on certain tools to be built. That also means that if a service can be built so that it doesn't require dynamic processes by only serving static content, that makes deployment on Tor machines a lot easier.
Dependencies
The following guidelines apply to dependencies on other software packages, either developed by The Tor Project or by third parties:
- A service must not require any Debian packages not available in stable (exceptions can be made for packages that are in backports).
- It's discouraged to build or otherwise provide own libraries. If one has to do that, it must happen in
/srv/foo.torproject.org/
, and it's the service operator's responsibility to watch the entire dependency tree for (security-related) updates. - It's highly discouraged to rely on third-party package managers. Third-party package managers typically do lots of things beyond the user's control, and it's often difficult or impossible to know whether packages have been authenticated or which versions have been installed. This includes pip and virtualenv in the Python world, Maven in the Java world,
go get
in the Go world, CRAN in R world, and so on. If any of these third-party package managers are to be used, they must be run without root privileges (e.g., by installing into the home directory of the role account running the service), because it's the service operator's responsibility to install (security-related) updates.
The following table contains most if not all services running on Tor machines that have at least one dependency (again, excluding services providing static web content, which only depend on Apache):
= Service = | = Repository = | = Maintainers = | = Debian stable packages (good) = | = Debian backports packages (okay) = | = Self-provided libraries (bad) = | = Packages installed via third-party package managers (really bad) = |
---|---|---|---|---|---|---|
_ Python-based services _ | ||||||
bridges.torproject.org | bridgedb | isis, sysrqb | python2.7 python-dev build-essential libgpgme11 libgpgme11-dev openssl libgeoip-dev sqlite3 geoip-database python-setuptools python-twisted-core python-twisted-web python-twisted-mail python-twisted-names python-gpgme python-recaptcha python-mako python-beautifulsoup python-babel python-ipaddr python-openssl python-crypto | pygeoip, BridgeDB installed via git | None. Make certain to to erase everything from /home/bridgedb/bridgedb/requirements.txt before running /srv/bridges.torproject.org/bin/deploy to ensure that Pip is not used. |
|
compass.torproject.org | compass | gsathya | python-flask, python-jinja2, python-werkzeug | |||
consensus-health list | doctor | atagar | stem via git | |||
gettor.torproject.org | ? | sukhe | ? | ? | ? | ? |
support.torproject.org | pups | phoul, lunar, helix | apache2 prosody libapache2-mod-passenger python2 python-django python-django-south | mod_auto_accept_subscriptions via hg | ||
| torperf.torproject.org | torperf | karsten | |||
weather.torproject.org | ? | karsten | ? | ? | ? | ? |
----------------------------------------------------------- | --- | --------- | --- | --- | --- | --- |
_ Java-based services _ | ||||||
= Service = | = Repository = | = Maintainers = | = Debian stable packages (good) = | = Debian backports packages (okay) = | = Self-provided libraries (bad) = | = Packages installed via third-party package managers (really bad) = |
collector.torproject.org | metrics-db | karsten | ant-optional ant apache2 git junit4 libcommons-codec-java libcommons-compress-java libcommons-lang-java openjdk-6-jdk | metrics-lib via git submodule | ||
consensus-health.torproject.org | java branch of doctor | karsten | ant apache2 git openjdk-6-jdk | Apache Commons Codec and Compress via wget, metrics-lib via git submodule | ||
exonerator.torproject.org | exonerator | karsten | ant apache2 git libcommons-codec-java libpostgresql-jdbc-java openjdk-6-jdk postgresql tomcat6 | |||
metrics.torproject.org | metrics-web | karsten | ant-optional ant apache2 git junit4 libcommons-codec-java libcommons-compress-java libcommons-lang-java libpostgresql-jdbc-java libpq-dev libservlet3.0-java openjdk-6-jdk postgresql r-base-dev tomcat6 | metrics-lib via git submodule | Rserve, ggplot2, and RPostgreSQL via CRAN | |
onionoo.torproject.org | onionoo | karsten | ant-optional ant apache2 git junit4 libcommons-codec-java libcommons-compress-java libcommons-lang-java libgoogle-gson-java libservlet3.0-java openjdk-6-jdk tomcat6 | metrics-lib via git submodule | ||
_ Go-based services _ | ||||||
= Service = | = Repository = | = Maintainers = | = Debian stable packages (good) = | = Debian backports packages (okay) = | = Self-provided libraries (bad) = | = Packages installed via third-party package managers (really bad) = |
check.torproject.org | check | arlolra | git golang gettext python-dateutil python-stem |
go-gettext via go get
|
||
_ Haskell-based services _ | ||||||
= Service = | = Repository = | = Maintainers = | = Debian stable packages (good) = | = Debian backports packages (okay) = | = Self-provided libraries (bad) = | = Packages installed via third-party package managers (really bad) = |
TorDNSEL | TorDNSEL | arlolra | git ghc libghc-hunit-dev libghc-binary-dev libghc-conduit-dev libghc-conduit-extra-dev libghc-mtl-dev libghc-network-dev libghc-stm-dev |
Permissions
A service must not require torproject-admin and/or root access in its normal operation or to update, stop, start, and maintain the service. But of course, setting up a service requires root. That's why the following guidelines are subdivided into a setup and an operation phase.
Setup phase
During setup, the following steps can be executed using root privileges, which will be done by the sysadmins, of course:
- Create a service role account. Every service operator will be able to
sudo
into that role account later; see operation phase below. - Create service directory in
/srv/foo.torproject.org/
owned by the role account. All files that are relevant to the service should be contained in this directory. It also contains the home directory of the service role account. - Configure system-provided services like Apache and/or Tomcat, create databases, setup mail, and so on, based on the service's needs. Every deviation from the defaults should be explained to the sysadmins. Changing the defaults may make it harder to update packages.
- If necessary, allow the role account to restart system services like Apache or Tomcat, or read their logs, which is usually restricted to root.
Operation phase
As stated above, a service must not require torproject-admin and/or root access in its normal operation or to update, stop, start, and maintain the service. The following operations are permitted for the service role account:
- Edit crontab, either using
@reboot
entries to start the service after a reboot, or by adding more entries to run periodic tasks. - If configured, run certain commands with root privileges; see
sudo -l
for a list of allowed commands.