GuixSD on servers: How to run a tor-relay (draft)

Obligatory Disclaimer: Read the upstream documentation and notices, especially the legal ones, about running tor relays.

Today in GuixSD on servers, we are going to run a tor-relay.

I assume you already went through the joy of installing a basic GuixSD somehow, somewhere and all you need is a system config which gives some insight into how to run this one-service specific server.
With the recent introduction of containers for system services in GuixSD, this adds some safety to running tor relays (not legal one though).

Please keep in mind that this is a theoretic construction, it will be put to practice once I can run a relay again for a short moment.

It also features no notice of adding your OpenSSH keys to the machine + setting a password.
Someone is working on making SSH keys an option in the system config, this post will be updated once it’s possible.

(use-modules (gnu)
	     (gnu system nss)
	     (srfi srfi-1)
	     (srfi srfi-26) ; cut
	     (guix store) ; %default-substitute-urls
	     (gnu services base)) ; %default-authorized-guix-keys
(use-service-modules desktop networking base ssh
		     version-control xorg avahi
		     dbus admin mcron)
(use-package-modules certs gnome vim
		     tor version-control admin
		     ntp suckless xdisorg
		     linux wget web
		     package-management tls ssh)

(define %tordate
  #~(job '(next-hour '(4))
	 (string-append #$tlsdate "/bin/tlsdate -l -t -v -V")))

(operating-system
  (host-name "noisemachine")
  (timezone "UTC")
  (locale "en_US.UTF-8")

  ;; Assuming /dev/sda is the target hard disk, and "my-root"
  ;; is the label of the target root file system.
  (bootloader (grub-configuration (device "/dev/sda")))

  (file-systems (cons (file-system
                        (device "/dev/sda2")
                        (title 'device)
                        (mount-point "/")
                        (type "ext4"))
                      %base-file-systems))

  ;; Assuming you have created a swap file named "swap.file" in the root of "/".
  (swap-devices '("/swap.file"))

  (users (cons (user-account
                (name "user")
                (comment "")
                (group "users")
                (supplementary-groups '("wheel"))
                (home-directory "/home/user"))
               %base-user-accounts))

  (packages (cons* nss-certs         ;for HTTPS access
                   emacs-no-x
                   nyx tor torsocks
                   %base-packages))

  (services (cons* (service rottlog-service-type (rottlog-configuration))
		   (service mcron-service-type
			    (mcron-configuration
			      (jobs (list %tordate))))
                   (tor-service
                    (plain-file "torrc"
                                "#### This section is just for relays ####\n
## See https://www.torproject.org/docs/tor-doc-relay for details.\n
## Required: what port to advertise for incoming Tor connections.\n
ORPort 9001\n
## If you want to listen on a port other than the one advertised in\n
## ORPort (e.g. to advertise 443 but bind to 9090), you can do it as\n
## follows.  You'll need to do ipchains or other port forwarding\n
## yourself to make this work.\n
#ORPort 443 NoListen\n
#ORPort 127.0.0.1:9090 NoAdvertise\n
## The IP address or full DNS name for incoming connections to your\n
## relay. Leave commented out and Tor will guess.\n
#Address noname.example.com\n
## If you have multiple network interfaces, you can specify one for\n
## outgoing traffic to use.\n
## OutboundBindAddressExit will be used for all exit traffic, while\n
## OutboundBindAddressOR will be used for all other connections.\n
## If you do not wish to differentiate, use OutboundBindAddress to\n
## specify the same address for both in a single line.\n
#OutboundBindAddressExit 10.0.0.4\n
#OutboundBindAddressOR 10.0.0.5\n
## A handle for your relay, so people don't have to refer to it by key.\n
## Nicknames must be between 1 and 19 characters inclusive, and must\n
## contain only the characters [a-zA-Z0-9].\n
Nickname heckthecistem\n
## Define these to limit how much relayed traffic you will allow. Your\n
## own traffic is still unthrottled. Note that RelayBandwidthRate must\n
## be at least 75 kilobytes per second.\n
## Note that units for these config options are bytes (per second), not\n
## bits (per second), and that prefixes are binary prefixes, i.e. 2^10,\n
## 2^20, etc.\n
#RelayBandwidthRate 100 KBytes  # Throttle traffic to 100KB/s (800Kbps)\n
#RelayBandwidthBurst 200 KBytes # But allow bursts up to 200KB (1600Kb)\n
## Use these to restrict the maximum traffic per day, week, or month.\n
## Note that this threshold applies separately to sent and received bytes,\n
## not to their sum: setting "40 GB" may allow up to 80 GB total before\n
## hibernating.\n
## Set a maximum of 40 gigabytes each way per period.\n
#AccountingMax 40 GBytes\n
## Each period starts daily at midnight (AccountingMax is per day)\n
#AccountingStart day 00:00\n
## Each period starts on the 3rd of the month at 15:00 (AccountingMax\n
## is per month)\n
#AccountingStart month 3 15:00\n
## Administrative contact information for this relay or bridge. This line\n
## can be used to contact you if your relay or bridge is misconfigured or\n
## something else goes wrong. Note that we archive and publish all\n
## descriptors containing these lines and that Google indexes them, so\n
## spammers might also collect them. You may want to obscure the fact that\n
## it's an email address and/or generate a new address for this purpose.\n
ContactInfo Random Person \n
## You might also include your PGP or GPG fingerprint if you have one:\n
#ContactInfo 0xFFFFFFFF Random Person \n
## Uncomment this to mirror directory information for others. Please do\n
## if you have enough bandwidth.\n
DirPort 9030 # what port to advertise for directory connections\n
## If you want to listen on a port other than the one advertised in\n
## DirPort (e.g. to advertise 80 but bind to 9091), you can do it as\n
## follows.  below too. You'll need to do ipchains or other port\n
## forwarding yourself to make this work.\n
#DirPort 80 NoListen\n
#DirPort 127.0.0.1:9091 NoAdvertise\n
## Uncomment to return an arbitrary blob of html on your DirPort. Now you\n
## can explain what Tor is if anybody wonders why your IP address is\n
## contacting them. See contrib/tor-exit-notice.html in Tor's source\n
## distribution for a sample.\n
DirPortFrontPage /var/www/tor-exit-notice.html\n
## Uncomment this if you run more than one Tor relay, and add the identity\n
## key fingerprint of each Tor relay you control, even if they're on\n
## different networks. You declare it here so Tor clients can avoid\n
## using more than one of your relays in a single circuit. See\n
## https://www.torproject.org/docs/faq#MultipleRelays\n
## However, you should never include a bridge's fingerprint here, as it would\n
## break its concealability and potentially reveal its IP/TCP address.\n
#MyFamily $keyid,$keyid,...\n
## A comma-separated list of exit policies. They're considered first\n
## to last, and the first match wins.\n
## If you want to allow the same ports on IPv4 and IPv6, write your rules\n
## using accept/reject *. If you want to allow different ports on IPv4 and\n
## IPv6, write your IPv6 rules using accept6/reject6 *6, and your IPv4 rules\n
## using accept/reject *4.\n
## If you want to _replace_ the default exit policy, end this with either a\n
## reject *:* or an accept *:*. Otherwise, you're _augmenting_ (prepending to)\n
## the default exit policy. Leave commented to just use the default, which is\n
## described in the man page or at\n
## https://www.torproject.org/documentation.html\n
## Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses\n
## for issues you might encounter if you use the default exit policy.\n
## If certain IPs and ports are blocked externally, e.g. by your firewall,\n
## you should update your exit policy to reflect this -- otherwise Tor\n
## users will be told that those destinations are down.\n
## For security, by default Tor rejects connections to private (local)\n
## networks, including to the configured primary public IPv4 and IPv6 addresses,\n
## and any public IPv4 and IPv6 addresses on any interface on the relay.\n
## See the man page entry for ExitPolicyRejectPrivate if you want to allow\n
## "exit enclaving".\n
#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports on IPv4 and IPv6 but no more\n
#ExitPolicy accept *:119 # accept nntp ports on IPv4 and IPv6 as well as default exit policy\n
#ExitPolicy accept *4:119 # accept nntp ports on IPv4 only as well as default exit policy\n
#ExitPolicy accept6 *6:119 # accept nntp ports on IPv6 only as well as default exit policy\n
ExitPolicy reject *:* # no exits allowed\n"))
		   (avahi-service)
		   (wicd-service)
		   (upower-service)
		   (colord-service)
		   (geoclue-service)
		   (polkit-service)
		   (elogind-service)
		   (dbus-service)
		   %base-services))

Flattr this!