Bug 1602171 - Hidden services are blocked by SELinux
Summary: Hidden services are blocked by SELinux
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: tor
Version: 28
Hardware: All
OS: Linux
unspecified
medium
Target Milestone: ---
Assignee: Nobody's working on this, feel free to take it
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2018-07-17 23:47 UTC by Suvayu
Modified: 2020-11-05 09:31 UTC (History)
8 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2019-01-06 11:38:18 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
Error messages from Tor in the journal (1.18 KB, text/plain)
2018-07-17 23:48 UTC, Suvayu
no flags Details
First AVC denial message (2.44 KB, text/plain)
2018-07-17 23:49 UTC, Suvayu
no flags Details
Second AVC denial message (2.18 KB, text/plain)
2018-07-17 23:49 UTC, Suvayu
no flags Details
AVC messages (21.87 KB, text/plain)
2018-07-23 17:36 UTC, Suvayu
no flags Details

Description Suvayu 2018-07-17 23:47:32 UTC
Description of problem:
Running a Tor hidden service is being blocked by SELinux. After updating the configuration file, when I restart Tor the hidden service is available.  However, on subsequent restarts, SELinux blocks it.

I believe this is because on first run, HiddenServiceDir doesn't exist, but on subsequent runs when Tor starts, access to the directory is blocked by SELinux. 

Version-Release number of selected component (if applicable):
tor-0.3.2.10-1.fc28.x86_64

How reproducible:
Always

Steps to Reproduce:
1. Edit /etc/tor/torrc and configure a *new* hidden service.

   HiddenServiceDir /var/lib/tor/ssh_hsv3/
   HiddenServiceVersion 3
   HiddenServicePort 22 127.0.0.1:22

2. Restart Tor, and check the hidden service is up and running.
   The hostname can be found in <HiddenServiceDir>/hostname.

3. Restart again, Tor fails to start due to two AVC denial messages:
   dac_read_search and dac_override. Detailed messages are attached.

Actual results:
AVC denial messages blocks Tor from starting.

Expected results:
Tor starts normally, and the hidden services are available.

Additional info:
I found a question on serverfault which matched my issues almost exactly (it had a few other SELinux messages that I couldn't replicate).  The response seemed to have a well reasoned analysis of the problem, maybe it will be helpful: https://serverfault.com/a/891043/93753

Comment 1 Suvayu 2018-07-17 23:48:11 UTC
Created attachment 1459574 [details]
Error messages from Tor in the journal

Comment 2 Suvayu 2018-07-17 23:49:03 UTC
Created attachment 1459575 [details]
First AVC denial message

Comment 3 Suvayu 2018-07-17 23:49:35 UTC
Created attachment 1459576 [details]
Second AVC denial message

Comment 4 Marcel Haerry 2018-07-20 21:40:44 UTC
As this already used to be an issue in the past (#1375369) until selinux-policy got a fix and because recently there were more changes to SELinux & DAC: https://lukas-vrabec.com/index.php/2018/07/03/why-do-you-see-dac_override-selinux-denials/ we should really move to the solution outlined in the serverfault article.

It looks like the switch could be pretty trivial as User toranon is in a non-config file, so it will be replaced during an update.

Need to investigate, whether we can really that easily update it.

Comment 5 Marcel Haerry 2018-07-20 22:39:45 UTC
There is a scratch build with these things fixed:

https://koji.fedoraproject.org/koji/taskinfo?taskID=28479881

But I need a lot more testing before pushing these changes. Would you mind testing it? Thanks!

Comment 6 Suvayu 2018-07-20 23:32:49 UTC
(In reply to Marcel Haerry from comment #4)
> As this already used to be an issue in the past (#1375369) until
> selinux-policy got a fix and because recently there were more changes to
> SELinux & DAC:
> https://lukas-vrabec.com/index.php/2018/07/03/why-do-you-see-dac_override-
> selinux-denials/ we should really move to the solution outlined in the
> serverfault article.

Thanks for the link, I'll read it.  I have been on Fedora for years, and still I don't quite understand SELinux :-|.

> It looks like the switch could be pretty trivial as User toranon is in a
> non-config file, so it will be replaced during an update.
> 
> Need to investigate, whether we can really that easily update it.

I tried the scratch build, it works well :).

What I did to test:

1. I restarted Tor after uncommenting the hidden service section mentioned above
2. I started Orbot on my phone, and connected through the onion address mentioned
   in <HiddenServiceDir>/hostname using an SSH client.

Everything went without a hitch.  Thanks a lot for the quick fix :).

Comment 7 nusenu 2018-07-21 22:05:38 UTC
please do not change the default user, this will break lots of existing setups.

You can easily get this to work by 

- adding root to the toranon group
- add "HiddenServiceDirGroupReadable 1" to your torrc

Comment 8 Marcel Haerry 2018-07-23 08:19:08 UTC
I am not changing the default user, what I am changing is that not anymore Tor is dropping privileges, but rather systemd invokes Tor only as unprivileged user (but still as the same one as before).

https://src.fedoraproject.org/rpms/tor/c/b5f1d70840260a5049a64ad202a86676c1a956b4?branch=master-test

The problem with SELinux blocking DAC comes (based on my understanding) from the point that systemd is executing Tor as root and Tor does then a few things as root before dropping priviliges. Tor is being executed twice by systemd: Once for checking the config and then for starting the service, where later in that process the daemon then drops privileges to the user configured in the config file.
So from my understanding what you are suggesting is what we are already doing now and it still needs DAC.

I can see that it might break setups where folks have chosen a different user than the default one to run tor, which would require them to add an additional systemd-unit file that configures the user there.

The problem is that a) I don't see a way how we can avoid the need for DAC (even with root in the toranon group) when running the process as root (it's not only reading the directory, but also various files (like /var/lib/tor/lock which has chmod 0600) and b) I really think it was not a good idea in the first place that the Tor process gets executed as root, when there is really no need for it.

So in summary: I don't see a way to not require DAC by not changing how we invoke Tor.

I still thinks this needs further discussion and investigation and I'm glad for any kind of input.

Comment 9 Marcel Haerry 2018-07-23 08:32:48 UTC
For documentation: e.g. the ansible role tor-relayor (https://github.com/nusenu/ansible-relayor) sets up the relays with their own dedicated user, which would be broken after introducing the proposed change.

Comment 10 nusenu 2018-07-23 08:41:45 UTC
(In reply to Marcel Haerry from comment #8)
> So from my understanding what you are suggesting is what we are already
> doing now and it still needs DAC.

That is not correct, I'm not chanigng the systemd service user from root to toranon - which avoids breaking existing configurations.
The solution I propose does NOT require dac_override and the hidden service config example works with the current package version (tor-0.3.2.10-1.fc28.x86_64) using the approach I mentioned. (yes I also tested it)

Did you test my proposed solution and observed an issue that lead you to the conclusion that it still requires DAC_OVERRIDE?



> The problem is that a) I don't see a way how we can avoid the need for DAC
> (even with root in the toranon group) when running the process as root (it's
> not only reading the directory, but also various files (like
> /var/lib/tor/lock which has chmod 0600) and b) I really think it was not a
> good idea in the first place that the Tor process gets executed as root,
> when there is really no need for it.

to be able to use the "User" parameter in torrc files there actually is a need for it and for things like ORPorts/DirPorts on <1024


> So in summary: I don't see a way to not require DAC by not changing how we
> invoke Tor.

see my questions above

Comment 11 Marcel Haerry 2018-07-23 09:31:14 UTC
I am not able to get your proposed solution to work. I am using the following Vagrantfile for testing:

script = <<-SCRIPT
echo Installing tor
dnf install tor -y
echo configuring hidden service
cat >/etc/tor/torrc<<EOF
HiddenServiceDir /var/lib/tor/ssh_hsv3/
HiddenServiceVersion 3
HiddenServicePort 22 127.0.0.1:22
EOF
echo Adding root to group toranon
groupmems -g toranon -a root
echo
echo Add HiddenServiceDirGroupReadable 1 to torrc
echo HiddenServiceDirGroupReadable 1 >> /usr/share/tor/defaults-torrc
echo
echo starting tor
systemctl start tor
echo
echo tor status 1st time
systemctl status tor
echo
grep AVC /var/log/audit/audit.log
echo
echo Waiting 10s
sleep 10
echo
echo restarting tor
systemctl restart tor
echo
echo status tor 2nd time
systemctl status tor
echo
grep AVC /var/log/audit/audit.log
SCRIPT

Vagrant.configure("2") do |config|
  config.vm.box = "fedora/28-cloud-base"
  config.vm.box_version = "20180425"
  config.vm.provision "shell", inline: script
end

The second restart is still failing and SELinux still blocks the requested DAC.

Comment 12 Marcel Haerry 2018-07-23 09:39:29 UTC
And yes, I see that we must run tor as root if we want to allow privileged ports.

Comment 13 Marcel Haerry 2018-07-23 10:26:24 UTC
Ok I am getting it to work with the following steps:

* HiddenServiceDirGroupReadable 1 cannot be in the defaults-rc it must be part of the HiddenService definition.
* While tor creates the directory readable for the toranon group, when initially starting up, it still requires DAC on the second start, although root is part of the toranon group
* changing the group of the directory back to be root, makes starting up work.

The situation is still ugly and not really feasible, because a) none of the examples online include HiddenServiceDirGroupReadable 1 for setting up onionservices. So everybody would need to learn about that requirement (if we can't be clever and add it somehow to our startup script). And b) it requires a second step to change group ownership back to root, which technically we could do as part of Pre start script, but I would rather see as hacky. 

What is the difference to how you got it working?

script = <<-SCRIPT
echo Installing tor
dnf install tor -y
echo configuring hidden service
cat >/etc/tor/torrc<<EOF
HiddenServiceDir /var/lib/tor/ssh_hsv3/
HiddenServiceVersion 3
HiddenServicePort 22 127.0.0.1:22
HiddenServiceDirGroupReadable 1
EOF
echo Adding root to group toranon
groupmems -g toranon -a root
echo
echo starting tor
systemctl start tor
echo
echo tor status 1st time
systemctl status tor
echo
grep AVC /var/log/audit/audit.log
echo
echo Waiting 10s
sleep 10
echo
echo restarting tor
systemctl restart tor
echo
echo status tor 2nd time
systemctl status tor
echo
grep AVC /var/log/audit/audit.log
echo
echo "chgrp to root"
chgrp root /var/lib/tor/ssh_hsv3
echo
echo restarting tor
systemctl restart tor
echo
echo status tor 3rd time
systemctl status tor
echo
grep AVC /var/log/audit/audit.log
SCRIPT

Vagrant.configure("2") do |config|
  config.vm.box = "fedora/28-cloud-base"
  config.vm.box_version = "20180425"
  config.vm.provision "shell", inline: script
end

Comment 14 Marcel Haerry 2018-07-23 11:00:44 UTC
Hrmpf, maybe I should re-read the bug reports I am linking to (or first fully recover from being sick before debugging).

So the situation is that OnionServices require DAC and there is a SEBoolean to allow that for tor:

 setsebool -P tor_can_onion_services on

For details read: https://bugzilla.redhat.com/show_bug.cgi?id=1375369#c31

And as shown above, there is barely a way how we can get it to work without allowing DAC.

So the only question left: How can we make it more obvious that one needs to do that?

@Suvayu: Does it work when enabling the boolean for you?


script = <<-SCRIPT
echo Installing tor
dnf install tor -y
echo configuring hidden service
cat >/etc/tor/torrc<<EOF
HiddenServiceDir /var/lib/tor/ssh_hsv3/
HiddenServiceVersion 3
HiddenServicePort 22 127.0.0.1:22
EOF
echo Enabling SELinux tor onion services
setsebool -P tor_can_onion_services on
echo
echo starting tor
systemctl start tor
echo
echo tor status 1st time
systemctl status tor
echo
grep AVC /var/log/audit/audit.log
echo
echo Waiting 10s
sleep 10
echo
echo restarting tor
systemctl restart tor
echo
echo status tor 2nd time
systemctl status tor
echo
grep AVC /var/log/audit/audit.log
SCRIPT

Vagrant.configure("2") do |config|
  config.vm.box = "fedora/28-cloud-base"
  config.vm.box_version = "20180425"
  config.vm.provision "shell", inline: script
end

Comment 15 nusenu 2018-07-23 11:19:14 UTC
Due to the discovery of the boolean 'tor_can_onion_services' I assume that questions in my direction are obsolete by now (let me know if that is not the case). I still will rise the question with tor developers if tor could drop privileges earlier to solve this properly.

Comment 16 Marcel Haerry 2018-07-23 12:19:13 UTC
Yes, unless you got it working in a way that I didn't yet realize. If possible, please include me in discussion with tor developers.

Comment 17 Suvayu 2018-07-23 13:11:56 UTC
Hi Marcel,

This is what I did:

1. Downgrade to tor-0.3.2.10-1.fc28.x86_64 (as I had the koji version running).
   This triggered the old AVC denials.
2. I moved the old hidden service directory
3. Set tor_can_onion_services to on
4. Started tor, there were no AVC denials, systemctl status showed success.
5. When I grepped audit.log for AVC, I found these messages:

   type=USER_AVC msg=audit(1532349074.675:436): 
     pid=782 uid=81 auid=4294967295 ses=4294967295 
     subj=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023 msg='avc:  received 
     policyload notice (seqno=2)  exe="/usr/bin/dbus-daemon" sauid=81 hostname=? 
     addr=? terminal=?'
   type=USER_AVC msg=audit(1532349076.525:437):
     pid=782 uid=81 auid=4294967295 ses=4294967295 
     subj=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023 msg='avc:  received 
     policyload notice (seqno=3)  exe="/usr/bin/dbus-daemon" sauid=81 hostname=? 
     addr=? terminal=?'
   type=USER_AVC msg=audit(1532349134.153:439):
     pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 
     msg='avc:  received policyload notice (seqno=2)  exe="/usr/lib/systemd/systemd"
     sauid=0 hostname=? addr=? terminal=?'
   type=USER_AVC msg=audit(1532349134.153:440):
     pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 
     msg='avc:  received policyload notice (seqno=3)  exe="/usr/lib/systemd/systemd"
     sauid=0 hostname=? addr=? terminal=?'

   While the timestamp of audit.log is new, I believe the contents are old,
   because on subsequent restarts (step 7 and onwards) no new lines were added.
6. I tested logging in with SSH from my phone, it worked
7. I restarted tor, no AVC denials, systemctl status showed success.
8. grepping for AVC in audit.log showed the exact same lines.
   The timestamp was updated.
9. I could login with SSH from my phone.

I guess this confirms the setsebool trick works?

Btw, I see very similar AVC messages in the journal everytime tor is (re)started.

audit[1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=sysstat-collect comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
audit[1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=sysstat-collect comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'

Comment 18 Marcel Haerry 2018-07-23 13:58:30 UTC
These are not AVC messages, just standard audit logs. AVC messages being like that type=AVC

As I can't close the ticket, can you do it? Thanks.

Comment 19 Suvayu 2018-07-23 17:36:10 UTC
Created attachment 1470008 [details]
AVC messages

Sorry about the incomplete info in my last comment, I'm quite clueless about SELinux. It's hard for me to understand what is relevant and what is not. Doing `grep --color=never AVC /var/log/audit/audit.log` gives me a somewhat long output, so I had only provided the last four lines.  Since that's not what you were looking for, I am attaching the whole output as a text file.

If I understood it correctly, the floating point number in the msg=audit(<float>:<num>) part is the unix time stamp.  All but the last 12 of the type=AVC are the errors that prompted me to file the bug report, and the last 12 correspond to the timestamp of when I downgraded tor (koji build -> repo) so that I can provide feedback (2018-07-23 17:49:45 localtime). There are no type=AVC messages since I set tor_can_onion_services (2018-07-23 18:01:13 localtime).

I hope I have provided all the information clearly.


Note You need to log in before you can comment on or make changes to this bug.