Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
fuss:tor [2023/03/03 03:48] – [Monitoring Tor Instances with Monit] officefuss:tor [2025/02/26 04:25] (current) office
Line 232: Line 232:
  
 The previous configuration line will turn on debug logging and will send all messages to the system log. The previous configuration line will turn on debug logging and will send all messages to the system log.
 +
 +
 +====== Monitoring tor Health Status ======
 +
 +When scaling up and using load balancing and high availability it is important to have a decisive way to determine whether a backend service is alive or not. Usually checks vary from "weak", for example, checking the PID of the process required, to "strong" assumptions, for example, checking whether the service responds properly, with stronger results always being more preferred. 
 +
 +In case of tor, given the inner workings, the strongest way perhaps to know whether tor is available, is to check whether a circuit has been established, which should indicate whether a client using tor as a proxy will be able to request an address through tor.
 +
 +In order to do that, the tor control port and password have to be defined in the tor configuration file (usually at ''/etc/torrc''). First, a tor password must be generated in order to be able to access the tor control port by using the following command:
 +<code bash>
 +tor --hash-password "tor"
 +</code>
 +which will result in a password generated on the standard output:
 +<code>
 +16:9F840FFC85EF83CE60469C431DC9FF43DB889305B7653C2CB653302594
 +</code>
 +
 +The password will then be added to the tor configuration:
 +<code>
 +ControlPort 8050
 +HashedControlPassword 16:9F840FFC85EF83CE60469C431DC9FF43DB889305B7653C2CB653302594
 +</code>
 +
 +After restarting tor the control port can be accessed via TCP and the status of the circuit can be checked. Here is a full TCP transcript using netcat:
 +<code>
 +$ nc -nv 192.168.1.1 8050
 +Connection to 172.16.1.81 8050 port [tcp/*] succeeded!
 +AUTHENTICATE "tor"
 +250 OK
 +GETINFO status/circuit-established
 +250-status/circuit-established=1
 +250 OK
 +
 +</code>
 +where:
 +  * ''192.168.1.1'' is the IP of the machine running the tor instance,
 +  * ''8050'' is the port opened by tor that can be configured via the ''ControlPort'' configuration directive in ''torrc''
 +
 +The useful string to look for in the responses is ''250-status/circuit-established=1'' and the value ''1'' indicates that a tor circuit is established.
 + 
 +===== Monitoring Tor Instances with Monit =====
 +
 +With the configuration in place, tor is restarted and the following monit configuration is created:
 +<code>
 +###########################################################################
 +##  Copyright (C) Wizardry and Steamworks 2023 - License: GNU GPLv3      ##
 +###########################################################################
 +
 +check process tor-01 with pidfile /var/run/tor-instances/01/tor.pid
 +   start program  "/bin/systemctl restart tor@01"
 +   stop program  "/bin/systemctl stop tor@01"
 +   if failed host 127.0.0.1 port 9050 type tcp then restart
 +   if failed host 127.0.0.1 port 8050 type tcp and
 +      # password is: tor surrounded by quotes 0x22
 +      send "AUTHENTICATE \0x22tor\0x22\n"
 +         expect "250 OK"
 +      send "GETINFO status/circuit-established\n"
 +         expect "250-status/circuit-established=1"
 +      retry 1
 +      timeout 5 seconds
 +      then restart
 +
 +</code>
 +that will restart tor in case a circuit is not built within two minutes (60 seconds standard monit check time and times two for one more retry).
 +
 +===== Monitoring tor Instances using Expect =====
 +
 +A more versatile variation of the [[/fuss/tor#monitoring_tor_instances_with_monit|monit tor monitoring system]] is to use good old "expect" in order to make sure that tor has an established circuit and to take action.
 +
 +<code>
 +#!/usr/bin/expect -f
 +###########################################################################
 +##  Copyright (C) Wizardry and Steamworks 2024 - License: MIT            ##
 +###########################################################################
 +# This is an "expect" script that checks whether tor has established a    #
 +# circuit and sets the return status depending on whether it has or not.  #
 +#                                                                         #
 +# In other words, iff. the script returns 0, then tor has an established  #
 +# circuit; otherwise no circuit has been established.                     #
 +#                                                                         #
 +# Requirements:                                                           #
 +#   * expect (TCL program)                                                #
 +#   * tor must expose a control port and must have a control password     #
 +#                                                                         #
 +# In order to generate a control password, issue: tor --hash-password PWD #
 +# where PWD is the desired control port password. After that, amend the   #
 +# tor configuration file to set the control port address, port and pass:  #
 +#                                                                         #
 +# ControlPort 0.0.0.0:8050                                                #
 +# HashedControlPassword 16:A482ADEAAWF43EE...                             #
 +#                                                                         #
 +# Running: ./this-script ADDRESS PORT PASSWORD                            #
 +# where:                                                                  #
 +#   * ADDRESS is the tor listening control address,                       #
 +#   * PORT is the tor listening control port,                             #
 +#   * PASSWORD is the plaintext control password                          #
 +#                                                                         #
 +# after which the return status can be checked on the shell with:         #
 +# echo $?                                                                 #
 +###########################################################################
 +
 +set address [lindex $argv 0];
 +set port [lindex $argv 1];
 +set password [lindex $argv 2];
 +
 +set timeout 5
 +spawn telnet $address $port
 +
 +send "AUTHENTICATE \"$password\"\n"
 +expect "250 OK\r\n"
 +send "GETINFO status/circuit-established\n"
 +expect {
 +    timeout {
 +        exit 1
 +    }
 +    -ex "250-status/circuit-established=1\r\n250 OK\r\n"
 +}
 +
 +</code>
  
 ====== Load-Balancing Multiple Tor Instances via HAProxy ====== ====== Load-Balancing Multiple Tor Instances via HAProxy ======
Line 262: Line 381:
         bind    0.0.0.0:9050         bind    0.0.0.0:9050
         balance leastconn         balance leastconn
- +        server socks5-1 127.0.0.1:9051 check 
-server socks5-1 127.0.0.1:9051 check +        server socks5-2 127.0.0.1:9052 check
-server socks5-2 127.0.0.1:9052 check+
  
 </code> </code>
Line 274: Line 392:
 Finally, by pointing an application at the HAProxy port ''9050'', the connection should be spread amongst the declared SOCKS backend servers. Depending on the distribution configuration, the log files can be observed to make sure that the traffic is properly redirected. Finally, by pointing an application at the HAProxy port ''9050'', the connection should be spread amongst the declared SOCKS backend servers. Depending on the distribution configuration, the log files can be observed to make sure that the traffic is properly redirected.
  
-====== Monitoring Tor Instances with Monit ======+===== Availability =====
  
-Tor can be elaborately monitored and restarted automatically in case it is necessary to ensure that tor instances stay up and runningAside from the usual check that the tor OR port is available at a given address, an ''expect''-like script can be embedded inside the monit template in order to additionally check that tor has an established circuit and is not indefinitely stuck.+Based on [[/fuss/tor#monitoring_tor_health_status|checking the tor status]], it is also possible to make backend checks stronger in order to determine whether a certain tor instance should be used or notThe HAProxy configuration proposed just uses a port check on the tor socks port in order to determine whether the tor instance is running, however that check is weak, checking just connectivity, and it is possible to make the check stronger by polling tor for the circuit status.
  
-First, a tor password must be generated in order to be able to access the tor control port by using the following command: +The tor configuration must be updated in order to open up port ''8050'' as a control port as well as specify the password as hash:
-<code bash> +
-tor --hash-password "tor" +
-</code> +
-which will result in password generated on the standard output:+
 <code> <code>
-16:9F840FFC85EF83CE60469C431DC9FF43DB889305B7653C2CB653302594+ControlPort 8050 
 +HashedControlPassword 16:9F840FFC85EF83CE60469C431DC9FF43DB889305B7653C2CB653302594
 </code> </code>
  
-The password will then be added to the tor configuration+For each additional tor instance, a program will be running that will serve the tor circuit status over TCP
-<code> +<code bash
-ControlPort 0.0.0.0:8051 +socat TCP-LISTEN:7050,fork,reuseaddr exec:"/usr/local/bin/tor-check-circuit 127.0.0.1 8050 tor
-HashedControlPassword 16:9F840FFC85EF83CE60469C431DC9FF43DB889305B7653C2CB653302594+
 </code> </code>
 +where:
 +  * ''7050'' is a port that a client can connect to in order to find out the status of the tor circuit,
 +  * ''tor-check-circuit'' is a script that uses "expect" to check tor for the tor circuit and an example thereof can be found [[/assets/docker/build/tor-snowflake#tor-check-circuit|on the tor Docker build page]],
 +  * ''8050'' will be the port opened up by each tor configuration (usually ''torrc'') by specifying ''ControlPort 8050''
  
-With the configuration in place, tor is restarted and the following monit configuration is created:+Finally the HAProxy configuration file should be changed to:
 <code> <code>
-########################################################################### +defaults 
-##  Copyright (C) Wizardry and Steamworks 2023 - License: GNU GPLv3      ## +        mode tcp 
-###########################################################################+        option redispatch
  
-check process tor-01 with pidfile /var/run/tor-instances/01/tor.pid +listen socks5-balance 
-   start program  "/bin/systemctl restart tor@01" +        bind    0.0.0.0:9050 
-   stop program  "/bin/systemctl stop tor@01" +        balance leastconn 
-   if failed host 127.0.0.1 port 9051 type tcp then restart +        server socks5-1 127.0.0.1:9051 check weight 100 agent-check agent-port 7050 agent-inter 1s 
-   if failed host 127.0.0.1 port 8051 type tcp and +        server socks5-2 127.0.0.1:9052 check weight 100 agent-check agent-port 7050 agent-inter 1s
-      # password istor surrounded by quotes 0x22 +
-      send "AUTHENTICATE \0x22tor\0x22\n" +
-         expect "250 OK" +
-      send "GETINFO status/circuit-established\n" +
-         expect "250-status/circuit-established=1" +
-      retry 1 +
-      timeout 5 seconds +
-      then restart+
  
 </code> </code>
-that will restart tor in case a circuit is not built within two minutes (60 seconds standard monit check time and times two for one more retry).+ 
 +The mechanism will ensure that each ''socat'' instance will return either ''100'' when a circuit is established and ''0'' otherwise, which, in turn, will allow HAProxy to dynamically change the weight of the given tor instance. 
 + 
 +Incidentally, the same same balancing scheme has been used for [[/networking/leveraging_docker_swarm_for_high-availability_and_load-balancing_services|load-balancing Apache servers within Docker containers]] and the same principle is leveraged here, just that the ''tor-check-circuit'' script will only return ''100'' or ''0'' with weights only varying from "available" (100to "none" (0), instead of actual "weights" using the full range between ''0'' and ''100''.
  

fuss/tor.1677815287.txt.gz · Last modified: 2023/03/03 03:48 by office

Wizardry and Steamworks

© 2025 Wizardry and Steamworks

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.