Improve Onion Service Usability by Script / GUI

Question about a variable utility for Whonix:

tor_hiddenserviceport_target_addr

For debian, HiddenServicePort defaults to 127.0.0.1.
For anon-gateway, onionjuggler-cli blocks setting 127.0.0.1 as HiddenServicePort unless --gateway is specified, this is to avoid making an onion service targeting the gateway when it is better to target the workstation, if that is understandable, then using the gateway option the service can be created for the gateway.

But how to easily set a HiddenServicePort TARGET_ADDR targeting the workstation?
On Qubes-Whonix, it asks for the variable tor_hiddenserviceport_target_addr to be set.
On other virtualizers, it defaults to 10.152.152.11.

If tor_hiddenserviceport_target_addr is set, you only need to specify the virtual port and the target port, the target_addr will be set by that variable.

But if it is more secure to host different application servers on different workstation, is it really useful to have tor_hiddenserviceport_target_addr?

First thing is that option needs to be set once on the configuration else it needs to be specified everytime on the command line.

For services targeting the workstation:
If variable is not set:

  • --port 80:10.137.0.10:5000 22:10.137.0.10:22

If variable is set:

  • --port 80:5000 22:22

If variable is set to 10.137.0.10 and you want to target another ws 10.137.0.11, target set by command line overrides the configuration option as expected:

  • --port 80:10.137.0.11:5000 22:10.137.0.11:22

Is that really a helper or you feel it will be an underused variable is for every server it is set to target a different workstation?

1 Like

Does it use Tor configuration drop-in folder /etc/tor/torrc.d? In Qubes-Whonix, /usr/local/etc/tor/torrc.d would be required so for consistency for all Whonix platforms /usr/local/etc/tor/torrc.d.

torrc.d support is now very stable. Only config files matching *.conf are parsed. (*.conf.dpkg-old, ~, etc. are not parsed).

No need compete with the user editing /etc/tor/torrc file.

Y

Yes onionjuggler/etc/onionjuggler/anon.conf at efb585ddc89549b7f0ddab6994b7d206ce6c170b · nyxnor/onionjuggler · GitHub
but that is unrelated to the above question.

When creating an onion service:

In short, do you think setting a defaut WS as target for the onion services would be useful or it is better to explictly set on the command line every time?

On every other system, the default is 127.0.0.1.
But on whonix, is purposefully block 127.0.0.1 (service targeting the GW) unless --gateway option is given.
But if service should target the WS, is it useful to set a default target address or explictly set it on the cli?

1 Like

If you don’t understand, that is okay, maybe it is difficult to grasp in the beginning.

1 Like

I haven’t looked deep enough yet. Hence, skipped this question for now. I didn’t find --gateway in the man page. Therefore not sure I understand the question good enough.

More secure probably but that really depends on user preferences, effort vs security.

For a cli tool, I don’t know any easy option. In the default setup without multiple workstation, that’s easier, since IP could be hardcoded. So a low level CLI tool probably shouldn’t have a hardcoded default. But any higher level usability tools on top could guide through that by asking that as a question (“Do you use multiple Whonix-Workstation behind the same Whonix-Gateway?” or “Did you change Whonix-Workstation internal IP address? In doubt, say no”)

Seems rather complex. I guess best is to keep the code simple and a low level CLI tool should always require everything mandatory. A higher level usability tool could help the user in the easy cases. For very advanced users, these could use the command line parameters and/or environment variables.

That syntax seems a bit weird. --port might be too generic a name here? Hidden service virtual port or local port? But then the parameter is not a simple port. It’s port:ip:port ip:port.

1 Like

On that note, I noticed something yesterday.

onionjuggler --list to print service information only list services that are managed by onionjuggler.conf, which is kinda expected, but on the other hand, it will mist services created by other files and other programs. Maybe I should list all services on the system and indicate which ones are managed by each files…

It doesn’t have that, for now, if Qubes-Whonix user doesn’t modify the target on the onionjuggler configuration or on the cli, it will error out.

$ sudo ./onionjuggler-cli --on --service abc --port 6000
Saving a copy of /usr/local/etc/torrc.d/40_onionjuggler.conf to /usr/local/etc/torrc.d/40_onionjuggler.conf.afaqv.conf
Moving original file /usr/local/etc/torrc.d/40_onionjuggler.conf to /usr/local/etc/torrc.d/.40_onionjuggler.conf-orig
Including Hidden Service configuration to /usr/local/etc/torrc.d/40_onionjuggler.conf.afaqv.conf

HiddenServiceDir /var/lib/tor/services/abc
HiddenServiceVersion 3
error: Option '--gateway' was not specified but target was set to 127.0.0.1. Either set the Workstation Qube IP address using the option 'tor_hiddenserviceport_target_addr' on /etc/onionjuggler/conf.d/*.conf to target a WS or use the gateway option to enforce a service to be run on the GW

Restoring /usr/local/etc/torrc.d/.40_onionjuggler.conf-orig to /usr/local/etc/torrc.d/40_onionjuggler.conf
removed '/usr/local/etc/torrc.d/40_onionjuggler.conf.afaqv.conf'

but giving the target on cli or conf works

sudo ./onionjuggler-cli --on --service abc --port 80:10.137.0.10:6000
Saving a copy of /usr/local/etc/torrc.d/40_onionjuggler.conf to /usr/local/etc/torrc.d/40_onionjuggler.conf.gMjNp.conf
Moving original file /usr/local/etc/torrc.d/40_onionjuggler.conf to /usr/local/etc/torrc.d/.40_onionjuggler.conf-orig
Including Hidden Service configuration to /usr/local/etc/torrc.d/40_onionjuggler.conf.gMjNp.conf

HiddenServiceDir /var/lib/tor/services/abc
HiddenServiceVersion 3
HiddenServicePort 80 10.137.0.10:6000

Verifying tor configuration
Aug 19 09:04:19.649 [warn] Option 'DisableNetwork' used more than once; all but the last value will be ignored.
Configuration OK
File /usr/local/etc/torrc.d/40_onionjuggler.conf.gMjNp.conf differs from /usr/local/etc/torrc.d/.40_onionjuggler.conf-orig
Moving temporary /usr/local/etc/torrc.d/40_onionjuggler.conf.gMjNp.conf back to its original location /usr/local/etc/torrc.d/40_onionjuggler.conf
Removing original file that was made hidden /usr/local/etc/torrc.d/.40_onionjuggler.conf-orig

The problem here is usability, mentioning the target every time if not configured otherwise.

So I will remove the default target address for hiddenservices, which does not have a default for qubes-whonix.
The target will be mandary on the cli.

Actually, I experimented with a lot of syntax options before, and this seemed the better so far, but contributions can be received.
The syntax is --port VIRTPORT[:TARGET_ADDR[:TARGET_PORT]] VIRTPORTn[:TARGET_ADDRn[:TARGET_PORTn]]

Virtport is the onion service virtual port.
Target address and port is the local address and port.

Any number of HiddenServicePort lines can be used, it loops.
So you can set --port="80 22" --gateway or --port="80:127.0.0.1 22:127.0.0.1" --gateway or --port="80:127.0.0.1:80 22:127.0.0.1:22" --gateway and both will produce:

HiddenServicePort 80
HiddenServicePort 22

or

HiddenServicePort 80 127.0.0.1
HiddenServicePort 22 127.0.0.1

But for uniformity I make the script only create full explict options

HiddenServicePort 80 127.0.0.1:80
HiddenServicePort 22 127.0.0.1:22

as these options are equal.

Actualy, my syntax is following tor defaults.
If only VIRTPORT is set but TARGET is not, bind the VIRTPORT port to 127.0.0.1:VIRTPORT
If VIRTPORT is set but TARGET_PORT is not set, bind the same port to TARGET_ADDR:VIRTPORT.

This can be read on man torrc and man onionjuggler-cli

1 Like

The port syntax is the same as SSH tunnel handler and qvm-connect-tcp

Examples of the same syntax:

1 Like

Merged, thanks!

1 Like

With the auto complete feature, it can list enabled servers with TABTAB

Just to give an overview of the project:

  • I didn’t have a basis for the project as I don’t see any prominent tor related project trying to handle the torrc, they normally interact with the controller that has expected responses, and onion services created on the controller don’t have to deal with the file system, but they disappear on every tor start, which then the user would have to load the private key of the service every time tor is restarted. You can test this as instructed in tor-ctrl-onion: explore onion services `ADD_ONION` `DEL_ONION` · Issue #17 · nyxnor/tor-ctrl · GitHub
  • So there may be a simpler an easier way to do what onionjuggler is doing and not break the torrc with an invalid configuration, but I don’t know how.
  • onionjuggler tries its best to filter user input to avoid special characters, avoid wrong paths, avoid wrong ports, wrong client keys, because even though there is a fail mechanism that if tor fails to --verify-config, it will restore the original file, it is a last resort and sometimes not informative of the problem, so I prefer the method fail fast, so the user is informed about the problem.

Design

  • check if tor configuration is valid before running anything
    • if not, warn about it and exit
    • if not but you believe you know the problem and want to restore with onionjuggler, then there is an env variable for it documented on the manual.
  • check user input
    • if service configuration already exist when creating one with the same name, warn and error out
    • if ports are not valid, warn and error out
    • if client keys, config or onion is not valid, warn and error out
  • safe_edit():
    • copy the orignal torrc (/usr/loca/etc/torrc.d/40_onionjuggler.conf) to the same path under the name .40_onionjuggler.conf-orig (it needs to have a dot to be hidden and tor not parse it twice.
    • move the original file to the same path under the name 40_onionjuggler.conf.XXXXXX.tmp.conf. The suffix .conf is dynamic, it works for client files with .auth and .auth_private. This temporary file will be parsed.
  • echo user input to temporary file.
  • verify_config_tor():
    • verify configuration including all configuraitons so it can be valid, with debian and derived including whonix, it runs tor -f /etc/tor/torrc --defaults-torrc /usr/share/tor/tor-service-defaults-torrc --verify-config hush, so the .tmp.conf is included and is parsed because it ends with .conf.
    • if verification fails, move -orig to orignal location, remove .tmp.conf.
    • if verification succeeds, move .tmp.conf to original location, remove -orig.
  • safe_edit save:
    • now that it didn’t exit on the verify config, save modified temp file to original location and remove .file-orig.
  • signal_tor:
    • signal tor to reload (default), restart, none. The reload is all you normally need. The restart is only if the config was previously broken and you need to restart it. The none is for when running a lot of time and you don’t want to reload tor because it will signal newnym tons of times and will overload the guards and you will loose connection.
  • ending with info:
    • at the end, important info will be printed, to which file the data was inserted, the full data that was inserted, how to connect etc.
1 Like

Tor parses *.conf. I didn’t test if that would also match *.conf-orig but if it does, perhaps best to avoid .conf inside temporary or backup files altogether?

This file extension .conf should with certainty be avoided for temporary files.

It does not match *.conf-orig. It would match if the include line was %include *.conf*, with an extra * as the end, but that would be wrong anyway and the correct is *.conf.

Tor doesn’t parse hidden files unless explictly set to:
man torrc

       The supported wildcards are * meaning any number of characters including none and ? meaning exactly one character.
       These characters can be escaped by preceding them with a backslash, except on Windows. Files starting with a dot are
       not matched when expanding wildcards unless the starting dot is explicitly in the pattern, except on Windows.

So unless the include pattern is %include .*.conf (notice the dot in the beginning, it won’t parse hidden files because whonix include is %include *.conf.

Then tor wouldn’t parse that file and it would be verified, and that is the problem, what is why it needs .conf.
Previously I was not using that for the temporary file and the verify config was not working because of that, the temporary file was not being included.
Anyway, to reasons not to worry about that:

  • there is a fail safe trap for all possible signals EXIT INT QUIT TERM
  • It is not possible to trap KILL signal, so unless you get the onionjuggler pid of a script that takes less than 2 seconds to run and kill it, certainly improbable.

  • if for whatever reason, the trap fails (if you can make it fail, let me know, I already tried), the temporary file has a distinctive name ORIGINALFILENAME.XXXXXX.tmp.conf, where XXXXXX is generated by mktemp a random string. And the original file name will be hidden with name .ORIGINALFILENAME-orig but can be found with ls -a.

But again, this is never necessary because the trap works.

The same way tor wouldn’t include files without *.conf, it wouldn’t verify the temporary file without the *.conf, so it is necessary.

Modify this line to remove the file suffix and see what happens with set -x

Also read improve verify_config_tor() parser and safe_edit() file mangement · Issue #66 · nyxnor/onionjuggler · GitHub

1 Like

updated the design above to explain about saving files and signaling tor.

1 Like

fixed issue with qube whonix file persistence to support /usr/local/etc.

Patrick,
Is there a plan to include onionjuggler to Whonix packages or is something you feel the advantages vs disadvantages of packaging and guiding?

I only tested on qube-whonix and plain debian, but it might be function on non-qubes-whonix.

1 Like

That’s quite a big contribution and will take some time to review.

Non-Qubes-Whonix would need at least some basic support. In worst case it would say it doesn’t work on Non-Qubes-Whonix but I guess Non-Qubes-Whonix will already have similar functionality to Qubes-Whonix wrt to onionjuggler.

Quote GitHub - nyxnor/onionjuggler: Manage your Onion Services via CLI or TUI on Unix-like operating system with a POSIX compliant shell.

WARNING: do not trust this repo yet, backup your hs keys in another location. This project has not been released and should be considered for development only.

Does this still apply?

https://github.com/nyxnor/onionjuggler/raw/main/images/tui-whiptail.png looks nice.

https://github.com/nyxnor/onionjuggler/raw/main/images/cli.png looks also nice.

Does the command backup work in Whonix?

What would the vanguards command do inside Whonix?

What about other commands?

Always with the question in mind for each command, what if the user runs that command in the wrong VM? WIll onionjuggler bail out with an error message?

Also helpful would be a wiki page in Whonix wiki. Should I create one and could you document some examples please?

I have to update the readme…

No, the problem was that the TUI was buggy when the dialog was missing options, making the service name appear wrong, and could lead to wrong purging of keys.

This passed but I didn’t remove the warning because, well, it is better if someone else then me test, because developers are normally blind on the code they see everyday.

Using onionjuggler on Whonix made I improve onionjuggler usability overall by separating scripts and manuals to different files instead of one big file as it was in the beginning. So I’d say it is running smoothly for me, but if you find any problems, comment.

Photos need to be updated also, it still looks like that, but without the vanguards and backup. I removed them

  • vanguards had no recently signed git tag
  • backup was too difficult to manage, to reintegrate mostly without overwriting files.

Yes, anon-apps-config/etc/onionjuggler/conf.d/30_whonix.conf at master · Whonix/anon-apps-config · GitHub
anon-apps-config/etc/onionjuggler/conf.d/30_whonix.conf at master · Whonix/anon-apps-config · GitHub

Only the enabled plugins will be able to run, if not, exit with error message that plugin is deactivated.

onion authentication via files can’t be run from the workstation, just the gateway.

web (nginx) script is enforced via that config to only run on the workstation, because as it is a simple script to create a webserver, if user really wants to create it on the gateway, then that is their task to do it manually.

Everything that can be run from the cli, can be run from the tui.
This is a design goal and is actually difficult to make because the TUI has to adapt depending on what scripts are available, which services, files, authorizations exist.

I’d say the the CLI is pumping but the TUI needs some work on the code, although it is working, it needs to use more functions to return instead of large if else statements.

Yes, I can document all examples.
The commands are almost the same as on plain debian, except the target host that is most of the times the workstation or enforce to run service on the gateway with the --gateway option.

1 Like

Now on a second thought, once review is done and onionjugger is installed by default, would it be better to edit Onion Services - Whonix instead? Then the current manual instructions could be moved to wiki/Deprecated/Onion_Services.

That is only if onionjugger could completely (and reliably) replace the manual onion setup instructions currently on wiki/Onion_Services. (Not a problem is not.)

Hm.

I think it should be on the Onion Services whonix page, but not get rid of it.

It can reliably and completely do all of the steps shown on that page.

But that guide is useful if someone wants to learn how to do it, instead of just running a script that does every step.

So I think it is best to add a section of automated onion service management instead of replacing the manual steps.

1 Like

Spec here:
https://tpo.pages.torproject.net/onion-services/oniongroove/specs/

1 Like