[metrics-bugs] #33733 [Internal Services/Tor Sysadmin Team]: How do home directories work?

Tor Bug Tracker & Wiki blackhole at torproject.org
Thu Mar 26 14:01:20 UTC 2020

#33733: How do home directories work?
 Reporter:  irl                                  |          Owner:  tpa
     Type:  task                                 |         Status:
                                                 |  needs_review
 Priority:  Medium                               |      Milestone:
Component:  Internal Services/Tor Sysadmin Team  |        Version:
 Severity:  Normal                               |     Resolution:
 Keywords:                                       |  Actual Points:
Parent ID:  #33715                               |         Points:
 Reviewer:                                       |        Sponsor:
Changes (by anarcat):

 * status:  new => needs_review


 Replying to [ticket:33733 irl]:
 > There seems to be little consistency here, which isn't what I expect
 from an orchestrated process, so I'm maybe missing something.

 You're right! It's not fully orchestrated yet. Some of those things were
 created by hands before Puppet, most are managed in LDAP (by hand as well)
 and some are managed by Puppet *and* LDAP. It's a bit all over the place.

 You're dealing with old code here. Sorry for the inconvenience! :)

 > Each service has a directory in /srv/{service}.torproject.org/ and then
 sometimes there is a home directory, which is sometimes linked in some way
 to /home/{service}. When there are multiple users for a service, they can
 share the same /srv directory but then have inconsistent naming of home

 What do you mean "multiple users"? Could you give an example here

 > Is there some documentation I can read to make sense of this?

 Unfortunately: not much. I created "operational" docs that deal with "how
 to create a normal or role user", for example, in:


 Then some user-facing documentation and policy is available in:


 But I understand you might not have found those or that, if you did, they
 were not satisfactory.

 This is not really standardized in Puppet either, as I have just begun
 refactoring that code. The fact that it's also bound to LDAP complicates
 things as well because Puppet cannot (currently?) *write* to LDAP so
 manual operations need to be done on both systems for things to happen.

 My hope is that we can eventually replace LDAP for some of the role stuff,
 and move that into puppet, to have a more uniform experience. But it's a
 far-ranging project, as it involves touching `ud-ldap`, which is a huge

 The closest I've got to "standardizing" this is when we setup the new
 `check` service. I ended up writing this Puppet profile:

 # rewrite of the exit scanner
 # not to be confused with the old roles::check that is now deprecated.
 class profile::check inherits apache2 {
   # disable the default site so the FQDN site alias works
   Apache2::Site['00-default'] {
     ensure => absent,

   include apache2::ssl
   include apache2::proxy_http

   $users = ['tordnsel', 'check']
   $users.each |String $user| {
     file { [
       ensure => 'directory',
       mode   => '0775',
       owner  => $user,
       group  => $user,
     # LDAP expects the home there
     file { "/home/${user}":
       ensure => link,
       target => "/srv/${user}.torproject.org",
     loginctl_user { $user:
       linger => enabled,
     file { "/etc/sudoers.d/${user}":
       mode    => '0440',
       content => @("EOF"),
       # allow ${user} user sudo access to ${user} group
       %${user}                  ALL=(${user})                   ALL
       | EOF

   $vhost_name = 'check.torproject.org'
   apache2::site { $vhost_name:
     content => template('profile/check/vhost.erb'),

   ssl::service { 'check.torproject.org': notify  => Exec['service apache2
 reload'], key => true, }

   ensure_packages('tor', {ensure => installed})
   # NOTE: tor service is ran by the service admin (through systemd
   # --user), so we mask it here (in systemd --system)
   dsa_systemd::mask { [
     'tor at default.service'
     notify => Package['tor'],

   # new exit scanner dependencies, see #33362
   # ...

 That `  $users.each |String $user| {` should really be a new resource that
 would standardize the way users are created from Puppet's perspective. You
 can also see the symlink hack to take into account the LDAP home directory

 > Context: I'm putting together our Ansible roles (#33715) that should
 replicate what TPA will give us when we move things to a TPA host after
 we're convinced it's ready for deployment and we know what the specs will
 be, but I'm having trouble generalising even from just the Onionoo and
 Exit Scanner setups.

 Which problem are you having specifically? Hopefully the above code sample
 should provide you with some guidance, but I understand it's not
 documentation and I apologize for the lack of standardization in that

 > I'd like to be able to set some variables, like what usernames exist,
 what groups exist, and what paths will exist and should be used for stuff,
 and then let this role set that up. The service specific (e.g. Onionoo or
 Exit Scanner) roles will then run equally on our AWS dev instances and the
 production TPA instance.

 That shouldn't be a problem: we basically do the same in Puppet, even
 though the users and groups are actually created in LDAP.

 I hope that helps, let me know if you have any further questions!

 (PS: one thing that would be useful for me is to know where you look for
 this documentation, instinctively. Then I could go *there* and add a
 pointer to the existing documentation. When you're happy with the answers
 here, I would also go there and add the missing bits. :)

Ticket URL: <https://trac.torproject.org/projects/tor/ticket/33733#comment:2>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online

More information about the metrics-bugs mailing list