I am attempting to set up a Tor hidden service on CentOS 7 (with systemd), using the tor package from the EPEL repository.

Previously this was working fine until a few days ago when it stopped working. Nothing on the system was restarted at this time, though automatic updates are enabled via yum-cron so perhaps something updated.

However, for what it's worth, I have also seen this issue on a mostly-stock installation of Fedora Server and on Fedora Workstation.

Now when I attempt to start the tor service with the hidden service lines in the /etc/tor/torrc file, it fails to start.

I have been checking error messages using journalctl -xn, and they are not consistent - however the primary errors seem to be:

Nov 09 22:05:18 hostname tor[7561]: Nov 09 22:05:18.245 [warn] Directory /var/lib/tor/sshservice/ cannot be read: Permission denied

and sometimes:

Nov 09 22:12:33.119 [warn] /var/lib/tor/sshservice/ is not owned by this user (root, 0) but by toranon (997). Perhaps you are running Tor as the wrong user

I have ensured the following about the entire /var/lib/tor path, but with no success:

  • Directory is owned by user/group toranon (default tor user for the EPEL package)
  • Permissions are set appropriately (I have tried 700, 770, 600, 660) on the directory.
  • SELinux contexts are set appropriately for the directory and I have verified this using restorecon.

Other info:

  • If I change ownership of the directory to root, I recieve the same "wrong user" message as before, but with the usernames reversed.
  • I have attempted to disable SELinux completely and verified that the tor service still does not start.
  • The hidden service directory is already populated with the private key and hostname files, and they were created by the tor daemon on this system. This configuration previously fully worked.
  • If I completely remove the HiddenServiceDir and HiddenServicePort lines from the config, tor starts up as expected.

Some potentially helpful output from /etc/tor/torrc:

# Do not run as client
SocksPort 0 #Run Tor only as a relay and do not create a local SOCKS proxy
SocksPolicy reject *

# Define hidden service for SSH
HiddenServiceDir /var/lib/tor/sshservice/
HiddenServicePort 44674 #Redirect local SSH port to a nonstandard public port

ls -Z of /var/lib/tor:

[root@sagan tor]# ls -Z
-rw-------. toranon toranon system_u:object_r:tor_var_lib_t:s0 cached-certs
-rw-------. toranon toranon system_u:object_r:tor_var_lib_t:s0 cached-microdesc-consensus
-rw-------. toranon toranon unconfined_u:object_r:tor_var_lib_t:s0 cached-microdescs
-rw-------. toranon toranon unconfined_u:object_r:tor_var_lib_t:s0 cached-microdescs.new
-rw-------. toranon toranon unconfined_u:object_r:tor_var_lib_t:s0 lock
drwx------. toranon toranon system_u:object_r:tor_var_lib_t:s0 sshservice
-rw-------. toranon toranon unconfined_u:object_r:tor_var_lib_t:s0 state

Not sure what might be causing this issue, but I suspect it's something to do with the precise configuration of systemd. I have experimented with commenting and removing some of the lines in the default systemd tor.service file, but with no success.

Currently I am attempting to start tor using systemctl start tor using the default systemd tor.service file shipped with CentOS.

Any ideas? Help would be greatly appreciated.

  • You have to start TOR with service tor start. Then it runs as toranon and permissions are aligned. – Chloe Mar 17 '17 at 7:16

I just puzzled through this problem myself, no thanks to systemd's horrible lack of debugging ability.

It turns out that systemd was interfering in my case. It was allowing the toranon user to read /var/lib/tor/ but not its subdirectory /var/lib/tor/hidden_service on startup. Thus, if I started up tor as root using the same command it would work, but starting under systemd caused it to fail cryptically. The permissions on the directory were correct, which was all the more baffling.

The way I fixed the problem was to change my torrc file write the hidden service files to a directory that systemd allowed the process to write. That is, you may be able to change your line from:

HiddenServiceDir /var/lib/tor/sshservice/


HiddenServiceDir /var/lib/tor/

and everything may finally work.

The other option would probably be to tell systemd to allow the process to read the subdirectory by changing the systemd configuration file for tor.service, likely in:


And changing the ReadWriteDirectories option to include the subdirectory you're creating, possibly by adding a line:


Or adding that path as a space-separated list to one of the existing entries in that file. (It already has two different ReadWriteDirectories lines but I'm not sure if the second one works as no logs are getting written.) According to the documentation for systemd, the entry should be a space-separated list of absolute paths like:

ReadWriteDirectories=/var/lib/tor /var/lib/tor/sshservice /var/log/tor

Although I haven't tried making this more obscure change, silently hoping that systemd will die in a fire so we don't have to maintain a third set of files and permissions.

  • Thanks! Can confirm that the same solution you opted for also works for me. I had hoped to use the method that involved editing the systemd service file (as this current solution will only work for a single hidden service), however that didn't seem to work for me. I can verify that having multiple instances of ReadWriteDirectories vs concatenating them on a single line does not make any difference though - systemd seems to concatenate them itself (as seen when you run systemctl show tor after running a systemctl daemon-reload). I'll keep playing around and let you know if I succeed. – Alex Haydock Nov 14 '15 at 2:13

A few of the fixes that have been posted in answer to this question do work, but with variable rates of success.

One fix I have come across which works consistently is to load a few exceptions into SELinux.

Step 1

Create a tor-selinux-workaround.cil file with the following content:

(typeattributeset cil_gen_require tor_t) (allow tor_t self (capability (dac_override dac_read_search)))

Step 2

Import that file into SELinux with the following command:

sudo semodule -i tor-selinux-workaround.cil

This should work flawlessly for up-to-date Fedora and CentOS systems.

More Info

For a more complete explanation, see my post here: https://alexhaydock.co.uk/tech/fix-tor-onion-services-on-centos-fedora


In my case, I had to add CAP_DAC_READ_SEARCH to the CapabilityBoundingSet of the systemd service:


@@ -30,7 +30,7 @@


(changing ReadWriteDirectories was not required)

  • /etc/centos-release: CentOS Linux release 7.2.1511 (Core)
  • systemctl --version: systemd 219
  • tor --version: Tor version
  • selinux: disabled

If selinux is enabled, tor still does not work! /var/log/audit/audit.log:

type=AVC msg=audit(1475960766.994:123): avc:  denied  { dac_override } for  pid=2317 comm="tor" capability=1  scontext=system_u:system_r:tor_t:s0 tcontext=system_u:system_r:tor_t:s0 tclass=capability
type=AVC msg=audit(1475960766.994:123): avc:  denied  { dac_read_search } for  pid=2317 comm="tor" capability=2  scontext=system_u:system_r:tor_t:s0 tcontext=system_u:system_r:tor_t:s0 tclass=capability

Follow https://bugzilla.redhat.com/show_bug.cgi?id=1292626 to fix that.

The above seems to be required only, if hidden services are used.

  • If you read carefully, you're advised to not use CAP_DAC_READ_SEARCH. It's far better to relax perms for the folder, and adding root to the allowed groups to access dirs. – m3nda Apr 24 '17 at 10:45

on Debian Jessie, this worked for me (I store tor hidden service information in /opt/tor)

edit /etc/tor/torrc by adding appropriate HiddenServiceDir and HiddenServicePort directives:

HiddenServiceDir /opt/tor/

HiddenServicePort 80

edit /lib/systemd/system/tor@default.service , add this line at the end of file:


create directory and set ownership and permissions:

mkdir /opt/tor

chown debian-tor. /opt/tor

chmod go-rwx /opt/tor

reload service configuration:

systemctl daemon-reload

and start service:

systemctl start tor

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.