Re: [Tails-dev] Persistent torrc [Was: Tails Server: updated…

Delete this message

Reply to this message
Author: segfault
Date:  
To: The Tails public development discussion list
Subject: Re: [Tails-dev] Persistent torrc [Was: Tails Server: updated plan and GSoC!]
anonym:
> segfault:
>> anonym:
>>> segfault:
>>>> anonym:
>>>>> segfault:
>>> [...]
>>>>>> I wrote some code to make single files persistent by creating a new
>>>>>> directory in TailsData_unlocked, moving the file into it and adding the
>>>>>> directory to the persistence.conf with type "link". I think this a
>>>>>> pretty ugly solution.
>>>>>
>>>>> It sounds ugly, indeed.
>>>>
>>>> Right. Do you have any other idea to solve this problem of making single
>>>> files persistent?
>>>
>>> Yes, to implement the support for this properly in the persistence
>>> back-end, in live-boot (which I believe mostly amounts to removing some
>>> `[ -d ... ]` checks). I believe I've offered before to do that if
>>> needed, otherwise, here's my explicit offer. :)
>>
>> Wow, that would be great. We talked about this feature before and we
>> agreed that it would be great if we had this, but I don't think you
>> offered to do this yourself :)
>
> I now remember that I offered it to intrigeri, for another purpose.
>
>> Actually, I took a look at the
>> persistence backend to figure out what would be needed to get this done,
>> but I was deterred by the vast amount of perl code :D
>
> Yes, I remember that, but you were not looking at the right place if you
> found perl code. You probably looked at the frontend, e.g.
> tails-persistence-setup, which is a GUI for creating the persistence
> partition, and editing persistence.conf.


Right, I think it was tails-persistence-setup.

> If you are curious, the backend is written in even worse shell script,
> and lives in `/lib/live/boot/9990-misc-helpers.sh` (installed by the
> live-boot package).
>
>>> However, if possible, let's try an approach that doesn't rely on this,
>>> ok? But I still guess you'd like to have this for the persistent
>>> configuration/date for services (i.e. the non-Tails Server bits, e.g.
>>> mumble-server's database and similar) as we've discussed before?
>>
>> ACK. I agree that the other options are better than making the torrc
>> persistent. But I still need to make single configuration files
>> persistent (e.g. /etc/mumble-server.ini).
>
> Ok, I created #11533 [0] to track this and pushed a branch with a first
> attempt at patching live-boot. I haven't tested it, so please do! If it
> doesn't work, perhaps the patch gives you enough context to fix it
> yourself (it should be confined to `activate_custom_mounts()`)? :) But
> please don't waste time on it -- this code is my own baby Frankenstein.
>
> [0] https://labs.riseup.net/code/issues/11533


I tested it and it works! Thanks so much for implementing this :)

>>> [...]
>>>>> # torrc.d hack
>>>>>
>>>>> We have a wrapper that we *always* use to (re)start to, namely
>>>>> restart-tor [0]. We could simply add logic to it so that before starting
>>>>> tor, for each $line of all files in /etc/tor/torrc.d/*.conf, check if
>>>>> $line is already present in /etc/tor/torcc, and if not, append $line.
>>>>> It's not as refined as the upstream feature will be, but it'll serve our
>>>>> purposes for now, so I think it is good enough.
>>>>>
>>>>> [0] config/chroot_local-includes/usr/local/sbin/restart-tor
>>>>
>>>> This way we would have to call restart-tor to add / remove a hidden
>>>> service, right? So this would actually restart Tor, but right now I use
>>>> "systemctl reload tor@default", which does not restart tor but still
>>>> adds / removes hidden services. I think reloading provides better UX,
>>>> because restarting Tor closes all circuits.
>>>
>>> You're right! The easy solution would be to extract that part into a
>>> reload-tor, which we'd call instead. Of course, restart-tor would also
>>> call it, to get what I described above.
>>
>> That would work, but I prefer the other options :)
>
> Great, then we agree! :)
>
>>>>> # Maintain HiddenService{Dir,Port} lines in /etc/tor/torrc
>>>>>
>>>>> This is very similar to the torrc.d hack above, but this logic is in
>>>>> Tails Server instead. This is what the mumble-server script did,
>>>>> essentially, and the availability of this option is what made me say "We
>>>>> won't have that problem, I think" in the text you quoted from an earlier
>>>>> email of mine above. No torrc persistence is needed for this -- Tails
>>>>> Server's persistent configuration will contain all the parameters needed
>>>>> for knowing exactly which HiddenService{Dir,Port} lines that should be
>>>>> in /etc/tor/torrc. Therefore I think it's preferable to the previous option.
>>>>
>>>> So you mean we shouldn't use the Tails persistence feature for this at
>>>> all and simply ensure the lines are present when starting a Tails
>>>> service, right? I didn't think about this before, but I think this would
>>>> work.
>>>
>>> Unless I have the wrong assumptions here. :) How I imagine this is that
>>> Tails Server itself has a persistent configuration storing the settings
>>> exposed by Tails Server for each service (is service X persistent?
>>> autostart? and user options etc.).
>>
>> Just to clarify things: Currently Tails Server does have a configuration
>> file for each service (which is made persistent if the service is
>> persistent). Those are currently in /usr/share/tails-server/options/,
>> e.g. /usr/share/tails-server/options/mumble. But I only store options in
>> there which are not part of some other configuration file, in order to
>> prevent redundancy and inconsistent states. So everytime Tails Server
>> needs the value of an user option, the corresponding configuration file
>> (e.g. /etc/mumble-server.ini for the server password) is parsed.
>> (But the persistent option is not stored anywhere else, so it is stored
>> in this internal options file.)
>>
>> Please tell me if you see any problems with this approach.
>
> Yes, this is exactly what we had very good reason to agree to do before,
> so it's awesome! So, read my paragraph above again and just remove the
> "and user options etc" part that I wrote without thinking. Then I think
> we agree, right?


Right :)

> However, `/usr/share` is not a suitable place for storing data expected
> to change, like configurations. Might I suggest `/var/lib/tails-server`
> instead? The service templates should live in `/usr/share/tails-server`,
> however.


ACK. I will move the options files to /var/lib/tails-server.

>>> Probably we'd also store all "persistent" hs keys here too.
>>
>> You mean the private key from the hidden service directory? I simply
>> make the hidden service directory (e.g. /var/lib/tor/mumble) persistent,
>> so I don't store this key anywhere else. I could move the hidden service
>> directory
>
> Yeah, that's right! Otherwise we'll have to fight the Apparmor profile.
>
>>> Beyond this, each service marked
>>> "persistent" would have some directory for its persistent configuration
>>> too. That's all.
>>
>> ACK.
>>
>>>
>>> Next, no matter how a service is started, Tails Server's CLI (or
>>> similar) is involved somehow: if the user starts a service manually
>>> through the GUI/CLI, then this is trivially true; if a service is marked
>>> "autostart", when starting Tails we'll need a hook somewhere that calls
>>> Tails Server's CLI in some way so that all such services are started.
>>> So, Tails Server is involved in all cases, and can thus be responsible
>>> for setting up these things.
>>
>> Right, that's exactly how I started impementing it right now :)
>
> I'm glad we're on the same page, then! :)
>
> [...]
>>>>> # add_onion
>>>>>
>>>>> By using stem to communicate with Tor over the control port/socket to
>>>>> add the hidden services, just like onionshare does (which would be a
>>>>> good source for inspiration, code-wise), you don't need any torrc
>>>>> persistence just like in the previous approach. This is probably the
>>>>> most "proper" solution of these three (and requires implementing less
>>>>> logic on our side), and it might even be the easiest after you've
>>>>> familiarized yourself with the API. This seems like the best option to me.
>>>>
>>>> Right. I didn't see this option either, but I think this would work too.
>>>> I will try this :)
>>>
>>> It's ~new, which might explain it. Any way, I really hope this approach
>>> works out since it looks the cleanest of those presented so far!
>>
>> I'm positive that this will work. But I think I will use the old
>> create_hidden_service() [1] instead of the new
>> create_ephemeral_hidden_service() [2], because the latter does not
>> create a hidden service directory, which I need to make the service
>> persistent. Also, only create_hidden_service() supports client
>> authentication, which I want to support.
>
> Sounds great!


Unfortunately, it seems like the create_hidden_service() won't work with
the sandboxed Tor we use, because the sandbox prevents Tor to access the
hidden service directory, which create_hidden_service() needs to access.
Micah Lee ran into the same problem with OnionShare [1] (He fixed it by
using create_ephemeral_hidden_service(), but I need the hidden service
directory for persistence, so I think this is no option for me).

[1] https://github.com/micahflee/onionshare/issues/179

For now I'm back to the "# Maintain HiddenService{Dir,Port} lines in
/etc/tor/torrc" option, which is working fine.