One answer here might be to let other applications modify Tor's config without needing to learn how to modify the torrc file.
For example, we could imagine a 'tor-bridge' debian package that just adds a torrc.d/bridge-torrc file. Then you could become a bridge without needing a controller and without needing a text editor. We could also imagine a tor-relay deb.
Weasel, what do you think of this idea? Are debs like this a good idea, or is this approach bad precedent because it would bloat the number of total debs in the world too far?
It might also be useful for controllers like Vidalia on OSes where the Tor deb runs as a daemon and doesn't run as the user. In those cases we've talked about having Vidalia launch a script that prompts the user for her root password and then moves the new torrc file into place. Having it move its torrc into a Vidalia-specific name might keep things saner -- and might be doable without root if the torrc.d directory is owned by a group that the Vidalia deb puts the user into, as we might need to do to get ControlSocket going. On the other hand, ultimately it might instead just complicate the issue further once there are two controllers that each write their own config file.
If we do it, we'd want to sort out what to do if lines in different config files contradict each other.
{{{
| debs with just a single config file won't fly
| also, files/dirs in /etc/ being user writable is obviously bad too. it's a privileged escalation attack waiting to happen
| also, yes. conflicts are an issue
| I still think it's a good idea tho. for instance the debian-defaults patch could just be a config file snippet then
|> in what way will they not fly?
| ftp-master will never accept them
| packages cause an overhead. for a single file that's probably too much overhead.
weasel> it probably shouldn't read a hardcoded torrc.d but instead there should be an include directive that can include other files, including handling wildcards
The specific reason I requested this functionality is because I want to be able to easily maintain a centralized list of rogue ExitNodes which can easily pushed out to other servers running tor. (See ticket #3143 (moved).)
But there are obviously other reasons why one might want to dynamically add/change configuration/performance options, while maintaining a base configuration. Some of these changes might even be made frequently.
Right now, I am just using the "-f" option with a simple script which assembles the new configuration to achieve what I want, but being able to dump everything into a directory would be great (either with a hard-coded torrc.d directory, or an include option).
> on tor-relays there is a person talking about the /var/run/tor/control file.am i correct in thinking this is something some package script makes, not toritself?<weasel> arma: on 0.2.2.x debian packages, it's tor's control socket.> oh ho> does it go wherever $piddir is?<weasel> it goes to /var/run/tor. which is also where pid is.> perhaps this person who wants a tor config option for it is asking for areasonable thing<weasel> it's not a config option.<weasel> that's because ControlSocket is something that tor's config stuffappends to rather than replaces.<weasel> and because tor doesn't do tor.d/* style configuration, so I have topatch the settings the package should have into the binary
We outlined some benefits that would have a /etc/tor/torrc.d directory
full of configuration snippets:
The 'tor' package will not (or less) need patches to change the
default settings.
It would make it much easier to implement example setups
(relays, exit relays, bridges) either through a debconf question
or through a system script like 'tor-setup-relay'.
Tails developers will only need to drop a very small extra
configuration file instead of having to rewrite the whole, which
should ease development and reviewing.
Other packages which need a hidden service to work (e.g. 'onioncat')
would be able to create it automatically by installing the proper
configuration snippet. That would enable them to work right after being
installed.
The include directive was asked on #2863 (moved), btw - might be considered a duplicate.
Having a tor.d directory is an okay idea. You'll need a fairly rigorous definition of what order the files in it are read, and how they interact with torrc and the defaults_torrc (if any). (Make sure you understand how the defaults-torrc logic works here before designing anything; make sure it can be reused.)
I think this way would be good:
defaults_torrc gets overruled by /etc/tor/torrc gets overruled by /etc/tor.d/10_something gets overruled by /etc/tor.d/20_somethingelse.
The same in other words:
defaults_torrc: lowest priority
/etc/tor/torrc: normal priority
/etc/tor/tor.d: highest priority
Sourcing /etc/tor.d/ in lexical order, i.e. first source /etc/tor.d/10_something, then source /etc/tor.d/20_somethingelse. If /etc/tor.d/10_something contains "CookieAuthentication 0" and /etc/tor.d/20_somethingelse contains "CookieAuthentication 1", then "CookieAuthentication 1" will win.
This is the way it usually works on Linux for folders such as /etc/profile.d, and the run-parts(8) tool works the same way.
Please use the same indentation style as the rest of Tor.
strcpy? Please, no. We don't want heap overflows.
In fact, please don't use strcpy in any other program that's supposed to be secure.
Please no bubble sorts, insertion sorts, or other inefficient reimplementations of algorithms that are supposed to be O(n lg n). Just use smartlist_sort() or smartlist_sort_strings().
Rather than hardwiring "/etc/", try using CONFDIR ?
If we can't get FN_FILE from file_status(), why skip the file? Shouldn't we warn?
Nothing in this code frees dirlist or its contents.
Rather than making a fake command line and passing it to load_torrc_from_disk(), why not refactor the code into two functions: one to find the right configuration file, and the other to read and parse it. That way, this code could only send the second one.
Some more fundamental issues
I thought that the semantics of options_init_from_string were that it replaced the current configuration with cf_defaults+cf. But that appears to means that, in this code, the original torrc file is completely replaced with the first file in /etc/tor.d/, then by the second, then by the third, and so on. (Is this tested?)
It seems that for an ordinary Tor user, there's no way to override this stuff. If the system has an /etc/tor.d, I can't override those options even with "-f my_torrc", since the torrc is considered second, and the /etc/tor.d contents are considered last. There is no way to override that directory with another one, either. I don't think that can be the right way to do it, can it?
I thought that the semantics of options_init_from_string were that it replaced the current configuration with cf_defaults+cf. But that appears to means that, in this code, the original torrc file is completely replaced with the first file in /etc/tor.d/, then by the second, then by the third, and so on. (Is this tested?)
I did not mean, if /etc/tor.d/10_something contains "CookieAuthentication 1" and /etc/tor.d/20_somethingelse contains no line containing "CookieAuthentication", that /etc/tor.d/10_something is completely disregarded. The idea was that configuration fragments are joined together in a predictable order. (Bao, please see above.)
It seems that for an ordinary Tor user, there's no way to override this stuff. If the system has an /etc/tor.d, I can't override those options even with "-f my_torrc", since the torrc is considered second, and the /etc/tor.d contents are considered last. There is no way to override that directory with another one, either. I don't think that can be the right way to do it, can it?
This is a valid concern and no one considered that earlier. There is a solution.
At the moment in the Tor manual (man tor), there is...
-f FILE
Specify a new configuration file to contain further Tor configuration options. (Default: $HOME/.torrc, or /etc/tor/torrc if that file is not found)
and...
--defaults-torrc FILE
Specify a file in which to find default values for Tor options. The contents of this file are overridden by those in the regular configuration file, and by those on the command line. (Default: /etc/tor/torrc-defaults.)
I suggest adding..
--fragments FOLDER
Specify a folder to contain further Tor configuration file fragments. (Default: $HOME/.tor.d, or /etc/tor.d/ if that file is not found)
This should allow an ordinary Tor user to override it.
One crazy idea I had was to require that these files start with a two-digit number, since that's how everybody will do it anyway. Then we could define the priority of torrc to be (say) 50, and of the defaults-torrc to be 00, and of the command line to be 100.