tor-ctrl - Tor control port command line tool

I was thinking of using tor-ctrl SETEVENTS GUARD but figuring out exactly what to do on what events would require a lot of testing.
GETINFO entry-guards shows 3 ‘up’ out of 20. When I reboot in immutable mode it’s the same 3 but it seems to favor a different guard for most circuits according to GETINFO circuit-status.

Anyway, tor-ctrl (or something) should have a socat dependency since it’s somehow not installed on Whonix-Gateway-CLI.
I added a monitor mode to tor-ctrl where it does not exit but simply continues to output events. Something like

100a101,104
>        [-w]           = wait instead of exiting after command
>                         default: not set
>                         notice: implies verbose. Useful with SETEVENTS.
> 
146c150,154
<         sendcmd "QUIT"
---
>         if [ -z "$WAIT" ]; then
>                 sendcmd "QUIT"
>         else
>                 while sleep 3600; do :; done
>         fi
159,163c167,174
<         STR="$(cat)"
<         vecho "$STR"
< 
<         echo "$STR" | if [ "$(grep -c ^"250 ")" = 3 ]; then
<                 exit 0
---
>         if [ -z "$WAIT" ]; then
>                 STR="$(cat)"
>                 vecho "$STR"
>                 echo "$STR" | if [ "$(grep -c ^"250 ")" = 3 ]; then
>                         exit 0
>                 else
>                         exit 1
>                 fi
165c176
<                 exit 1
---
>                 cat
179c190
< while getopts ":a:c:s:p:P:f:vh" Option
---
> while getopts ":a:c:s:p:P:f:vwh" Option
188a200
>                 w) WAIT=1;;
194c206
< if [ -e "$FILE" ]; then
---
> if [ -e "$FILE" -o "$FILE" = "-" ]; then

I don’t know what the option should be called, wait? filepipe could also wait but the user can keep the pipe open to work around that. I don’t know an elegant way of not exiting in cmdpipe. And piping to cat is inefficient but?

Posting here since I see Patrick is the maintainer and the website listed in the script doesn’t exist.

https://github.com/Whonix/tor-ctrl/commit/9ff66c2b76d1c46dee4edda540da9e997bccad88

No more upstream indeed.

Yes, tor-ctrl could use some love. Didn’t work on it much since no one ever cared about it. So even considered deprecation.

Documentation Control and Monitor Tor currently is needlessly complicated due to deficencies of the script

tor-ctrl -a /var/run/tor/control.authcookie -c "signal newnym"
  • -a /var/run/tor/control.authcookie could be avoided by using Tor auth cookie authentication by default.
  • -c could be the default (and then -c switch could be avoided).
  • -f file does not seem important. Could be removed. And if needed, better to invent a wrapper around it.
  • SLEEP_AFTER_CMD=1 - if we use sleep it means we didn’t figure out a proper event based flow.
  • Tor ControlPort support should be deprecated for code simplification. Debian tor package nowadays sets up Tor ControlSocket by default. No more need to use ControlPort. Then we could remove all references to telnet and the dependency on telnet.
  • I never tested SETEVENTS / long running sessions. If you can make that work, cool.

Help welcome.

Is ok.

I don’t think efficiency (as in speed) is important here?

Deprecated tor-ctrl just now.

(Removed from https://github.com/Whonix/Whonix/tree/master/packages .)

I found the tor-ctrl an awesome tool and implemented most of the changes you wanted from above.

Also implemented a way to use setevents, see examples directory for listing circuit path or even streams organized and showing the final target.

my fork is on github and has the same name, I can’t include links.

-a is removed and the cookie file is discovered by sending PROTOCOLINFO to the controller.
-c command be avoided not implemented
-f removed
sleep 1 if the program used is telnet, else for socat and nc/netcat sleep 0 by default. Sleep time can till be set with the -t [time] option.
tor's socket can be used for tcp or for unix domain, format is [addr:]port or [unix:]path. If none is presented, fallback to 9051, which although debian default is /run/tor/control, I made the script to be portable and not depend on debian an bash, but this can be easily fixed on one line
setevents must be used with -w to await for user confirmation with an enter

Also, I don’t understand why it is not supported upstream just because it has a default path to ControlSocket? I see that as a gain to not specify one more thing on debian systems.

For now, I removed the deficencies on the script, so no need to specify anymore the cookie file path, the time and it is verbose by default, quiet -q only if you want.

The main thing is missing for me is SAFECOOKIE option to authenticate, which avoids leakage that happens with COOKIE and HASHEDPASSWORD.

1 Like

Nice!

Does it work in Whonix?


man page: https://github.com/nyxnor/tor-ctrl/blob/master/man/tor-ctrl.8#L1 - if created from markdown to pandoc, could you please share the original markdown too?

Whonix example:

Still found here in usage function: https://github.com/nyxnor/tor-ctrl/blob/master/bin/tor-ctrl#L60

Also -c is documented under usage: GitHub - nyxnor/tor-ctrl: Raw use of tor's controller

How would it be used without -c?

Upstream by the usual definition as I understand it used in the Open Source ecosystem means the (original) developer / maintainer. There is no upstream for tor-ctrl. The original developer hasn’t been seen in years. Deprecated upstream means that the original developer vanished. There is no contact person upstream to accept bug reports, implement fixes or feature requests. It’s dead source code until a new maintainer steps up and becomes the new upstream.

Whonix by definition is a Linux distribution downstream from its upstream projects such as Debian. The Tor Project. tor-ctrl.

Now possible.
(Posting Links for New Users)

Does it work in Whonix?

Valid question, will test today, but so far I don’t see why not, nothing extravagant.

Markdown manpage is on docs folder https://github.com/nyxnor/tor-ctrl/blob/master/docs/tor-ctrl.8.md

How would it be used without -c?

I did not remove it yet but to do that, I would not use getpots, I can make a hacky getopts for short options and assign the last $# to the command, so the command would be fixed as the last option to be shifted.

Or something like this Using getopt in C with non-option arguments - Stack Overflow but for shell, not c.

1 Like

deleted the post cause it was unrelated to tor-ctrl, it was related to vitor.

Tested on whonix-gateway with socat, it worked.

1 Like

removed the -c, but command must be the last positional argument.
it cant be in the middle because getopts would stop parsing there and not consider arguments after it, and that is not desired.

1 Like

Is getopts really necessary?

Might be a lot simpler. Example:

   ## Thanks to:
   ## http://mywiki.wooledge.org/BashFAQ/035

   while :
   do
       case $1 in
           -h | --help | -\?)
               help_cli
               EXIT_CODE="0"
               cleanup
               return 0
               ;;
           -v | --verbose)
               verbose="$(( $verbose + 1 ))"
               shift
               ;;
           -e | --debug)
               echo "$SCRIPTNAME debug output..."
               echo "Script running as $(whoami)"
               set -x
               CURL_VERBOSE=""
               shift
               ;;
           -f | --function)
               FUNCTION="$2"
               if [ "$FUNCTION" = "" ]; then
                  FUNCTION="none"
                  shift
               else
                  shift 2
               fi
               ;;
           -f | --mode)
               MODE="$2"
               shift 2
               ;;
           -m | --minimal)
               MINIMAL="1"
               shift
               ;;
           --)
               shift
               break
               ;;
           -*)
               echo "$SCRIPTNAME unknown option: $1" >&2
               EXIT_CODE="1"
               cleanup "1"
               return 0
               ;;
           *)
               break
               ;;
       esac
   done
   
   ## If there are input files (for example) that follow the options, they
   ## will remain in the "$@" positional parameters.

After all the parameters could use:

--

I.e.

tor-ctrl --one --two --three -- command

1 Like

happy to see some interest on tor-ctrl and if there is interest in long options without getopt which is limited, I can do that, or specify directly the benefits so I can make the changes.


The method above would have the same result as with getopts as -- would stop parsing every option after it, making the command the last option again. The only thing that would change is using long options?
With the changes made to the commit posted above, you don’t even need to put -- to stop option parsing, you can call tor-ctrl:

tor-ctrl -q -t 2 "GETCONF User"
tor-ctrl -q -t 2 -c "GETCONF User"
tor-ctrl -q -c "GETCONF User" -t 2

Maybe the benefit of the example you gave above is that shifting all the options and arguments and stop parsing with --, and getting the command with $@ would mean that the command does not have to be quoted anymore.


But using a custom getopts does not make things easier if you want to avoid syntax mistakes, getopts is not necessary, and it is possible use this hacky getopts I’ve built for another project here onionjuggler/onionjuggler-cli at a297a0a16bcbc90a009f1d7be95a44d0a049b2ec · nyxnor/onionjuggler · GitHub

The benefit is that it would parse arguments that begin with - which should be reserved for options (that fix is not applied on the method posted above nor in getopts).

It also can interpret short and long options as well as --option=arg.
-s socket, -s=socket, --socket socket, --socket=socket.

but it option requires an argument and the argument begins with - it will fail, example: -s -v

As for long vs short options, I don’t have a strong opinion. In the wiki and Whonix source code I try to use long options since these are usually easier to understand by users, “less magic”. Maybe it’s also because I don’t really understand yet why getopts would be needed at all. Ideally, none or needed or just in special cases.

Yes, I was thinking that. No more need for quotes. Which should it make a lot simpler if the command to be sent to Tor’s control protocol itself would include quotes. That avoid the need to have to double quote things.


To permit the new tor-ctrl to be pre-installed in Whonix, would it be possible to change to format to the same as used for GitHub - adrelanos/tor-ctrl: Tor control port command line tool (same as other packages under Whonix · GitHub)?

As for your examples, these seem to great to be just an “example”. Could also be part of the /usr/bin folder and just be part of the tor-ctrl package.

What would also be cool would be Tor settings auto detection or Whonix auto detection. i.e. just type for example in short in the command line

tor-ctrl signal newnym

and it just works.

Seems like could soon be worth it to re-vitalize tor-ctrl and re-install by default in Whonix now that there is a new upstream. :slight_smile:

1 Like

Yes, I was thinking that. No more need for quotes. Which should it make a lot simpler if the command to be sent to Tor’s control protocol itself would include quotes. That avoid the need to have to double quote things.

No double quotes is the next goal.

To permit the new tor-ctrl to be pre-installed in Whonix, would it be possible to change to format to the same as used for GitHub - adrelanos/tor-ctrl: Tor control port command line tool (same as other packages under github.com/Whonix)?

Yes, I can change the directory structure.

What would also be cool would be Tor settings auto detection or Whonix auto detection. i.e. just type for example in short in the command line

If user uses CookieAuthentication, the only remaining option to specify is the socket, which on debian and whonix is /run/tor/control, so for this, used some default variable names from here anon-gw-anonymizer-config/anon-verify at 0311c382dc74ec25eb777dbac0917829cbdc358a · Whonix/anon-gw-anonymizer-config · GitHub
to auto-detect the control socket (ControlPort/ControlSocket):

tor_control_detection(){
  ## TODO: fix posix
  ## grep options '-o' and '-h' are not posix, but present on Debian and OpenBSD so making an excuse

  ## minimal check for tor service manager file
  if test -f /lib/systemd/system/tor@default.service; then
    tor_start_command="$(grep "ExecStart=" /lib/systemd/system/tor@default.service | sed s/ExecStart=//g)"
    default_torrc="$(printf '%s\n' "${tor_start_command}" | grep -o -- "--defaults-torrc [^ ]*")"
    f_torrc="$(printf '%s\n' "${tor_start_command}" | grep -o -- "-f [^ ]*")"
  fi

  ## don't evaluate the result of verify-config as it will fail if not running as root or the tor user
  ## if 'f_torrc' is empty, tor will try: Default: @CONFDIR@/torrc, or $HOME/.torrc if that file is not found
  ## if 'default_torrc' is empty, tor will try: Default: @CONFDIR@/torrc-defaults.
  # shellcheck disable=SC2086
  result="$(tor --verify-config ${default_torrc} ${f_torrc} | grep -oE " Read configuration file [^ ]*| Including configuration file [^ ]*" | cut -d " " -f5 | sed "s/\"//;s/\"\.//")"

  ## only one option is needed, use head
  # shellcheck disable=SC2086
  tor_control_socket_alternative="$(grep -oEh "^ControlPort [^ ]*|^ControlSocket [^ ]*" ${result} | cut -d " " -f2 | sed "s/\"//g;s/unix\://" | head -n 1)"

  ## only modify 'tor_control_socket' if it is not empty, meaning not inserted as a cli option
  : "${tor_control_socket:="${tor_control_socket_alternative}"}"
}

this function is called and it will detect tor_control_socket=/run/tor/control on Whonix and Debian of course, if the variable is still empty, last resort is 127.0.0.1:9051 later on the script.

Seems like could soon be worth it to re-vitalize tor-ctrl and re-install by default in Whonix now that there is a new upstream. :slight_smile:

hehe, would be glad

1 Like

never did a debian package, should I just “copy” the files from here tor-ctrl/debian at master · adrelanos/tor-ctrl · GitHub ?

Edit:

learning Template:Build Documentation Build Package - Whonix

Edit:

just letting you know that it is not needed anymore to double quote commands :slight_smile:
https://github.com/nyxnor/tor-ctrl/commit/a81848377d3c2588a91011a0308684d10f86a8ca

Edit:

built the debian package
is this ok tor-ctrl/COPYING at d1711c5f5e279de8c2f3485f6e8344bcf0527fbc · nyxnor/tor-ctrl · GitHub ?

1 Like

Didn’t test yet but looks really good!

1 Like

Would be really helpful if this could be merged.

It’s more than new lines. I am not a big fan of perfect git commit messages. Hope it’s OK as is.

It’s just minor stuff. Not trying to nitpick That stuff comes from Debian’s lintian. (Except for the new lines at the end.)

issue is socat on Whonix, it does not occurs on debian.

report here https://github.com/nyxnor/tor-ctrl/issues/9#issuecomment-1013928468

commit here to change dependency s/socat/netcat-openbsd/ debian/control

netcat will be found before socat as the script was designed tor-ctrl/tor-ctrl at ab8f9d2b86f84bdc82402112f5bbe282df43e36e · nyxnor/tor-ctrl · GitHub

1 Like