2024-01-14 15:28:53 +01:00
|
|
|
# -*-mode: doctest; tab-width: 0; py-indent-offset: 4; coding: utf-8-unix -*-
|
|
|
|
|
|
|
|
== stem_examples tor testing ==
|
|
|
|
|
|
|
|
This is a Python doctest file that is executable documentation.
|
2024-01-17 21:35:20 +01:00
|
|
|
stem_examples is a set of small scripts that tell you about your
|
|
|
|
running tor instance.
|
2024-01-14 15:28:53 +01:00
|
|
|
|
2024-01-17 21:35:20 +01:00
|
|
|
Onionoo is a web-based protocol to learn about currently running Tor
|
|
|
|
relays and bridges. Onionoo itself was not designed as a service for
|
|
|
|
human beings---at least not directly. Onionoo provides the data for
|
|
|
|
other applications and websites which in turn present Tor network
|
|
|
|
status information to humans: https://metrics.torproject.org/onionoo.html
|
|
|
|
|
|
|
|
You can see the status of tor relays at https://torstatus.rueckgr.at/
|
|
|
|
The code for that site is at https://github.com/paulchen/torstatus
|
|
|
|
You can get a list of exit relays that are marked bad with:
|
|
|
|
wget --post-data='SR=FBadExit&SO=Asc&FBadExit=1' 'https://torstatus.rueckgr.at/'
|
|
|
|
|
|
|
|
It is assumed that you are running a tor that has its torrc configured with:
|
|
|
|
|
|
|
|
ControlPort 127.0.0.1:9051
|
|
|
|
|
|
|
|
and/or
|
|
|
|
|
|
|
|
ControlSocket /run/tor/control
|
|
|
|
ControlSocketsGroupWritable 1
|
|
|
|
|
|
|
|
We can authenticate with a password. To set a password first get its hash...
|
|
|
|
|
|
|
|
% tor --hash-password "my_password"
|
|
|
|
16:E600ADC1B52C80BB6022A0E999A7734571A451EB6AE50FED489B72E3DF
|
|
|
|
|
|
|
|
and use that for the HashedControlPassword in your torrc.
|
|
|
|
|
|
|
|
HashedControlPassword 16:E600ADC1B52C80BB6022A0E999A7734571A451EB6AE50FED489B72E3DF
|
|
|
|
|
|
|
|
so that you have some security on the Control connection.
|
|
|
|
Pass the controller password to these scripts as an environment variable:
|
2024-01-14 15:28:53 +01:00
|
|
|
|
|
|
|
>>> import os
|
|
|
|
>>> assert os.environ['TOR_CONTROLLER_PASSWORD']
|
|
|
|
|
2024-01-17 21:35:20 +01:00
|
|
|
If you are using /run/tor/control you will also need to run the scripts as the user
|
|
|
|
that has rw access to that socket, usually tor or debian-tor.
|
|
|
|
|
2024-01-14 15:28:53 +01:00
|
|
|
Add our code to the PYTHONPATH
|
|
|
|
>>> import sys
|
|
|
|
>>> sys.path.append(os.path.join(os.getcwd(), 'src', 'stem_examples'))
|
|
|
|
|
2024-01-17 21:35:20 +01:00
|
|
|
We'll used the settings defined in {{{/usr/local/etc/testforge/testforge.yml}}}
|
|
|
|
If you don't have one, make it with the settings from your torrc:
|
2024-01-14 15:28:53 +01:00
|
|
|
|
|
|
|
>>> print("yaml", file=sys.stderr)
|
|
|
|
>>> import yaml
|
2024-01-17 21:35:20 +01:00
|
|
|
>>> try:
|
2024-02-04 04:29:52 +01:00
|
|
|
... sFacts = open('/usr/local/etc/testforge/testforge.yml').read()
|
|
|
|
... assert sFacts, sFacts
|
2024-01-17 21:35:20 +01:00
|
|
|
... except:
|
2024-02-04 04:29:52 +01:00
|
|
|
... dFacts = dict(
|
|
|
|
... HTTPS_PROXYHOST="127.0.0.1",
|
|
|
|
... HTTPS_PROXYPORT=9128,
|
|
|
|
... HTTPS_PROXYTYPE="http",
|
|
|
|
... SOCKS_PROXYHOST="127.0.0.1",
|
|
|
|
... SOCKS_PROXYPORT=9050,
|
|
|
|
... SOCKS_PROXYTYPE="socks5",
|
|
|
|
... )
|
2024-01-17 21:35:20 +01:00
|
|
|
... else:
|
2024-02-04 04:29:52 +01:00
|
|
|
... dFacts = yaml.safe_load(sFacts)
|
2024-01-14 15:28:53 +01:00
|
|
|
|
2024-02-04 04:29:52 +01:00
|
|
|
|
2024-01-14 15:28:53 +01:00
|
|
|
FixMe: use the settings for the ports and directories below.
|
|
|
|
|
|
|
|
>>> import os
|
|
|
|
>>> os.environ['https_proxy'] = 'http://'+dFacts['HTTPS_PROXYHOST']+':'+str(dFacts['HTTPS_PROXYPORT'])
|
|
|
|
>>> os.environ['socks_proxy'] = 'socks5://'+dFacts['SOCKS_PROXYHOST']+':'+str(dFacts['SOCKS_PROXYPORT'])
|
|
|
|
|
|
|
|
### compare_flags Comparing Directory Authority Flags
|
|
|
|
### introduction_points Introduction Points
|
|
|
|
|
|
|
|
>>> print("introduction_points", file=sys.stderr)
|
|
|
|
>>> import introduction_points
|
|
|
|
|
|
|
|
The introduction points are the ways of connecting to hidden services.
|
|
|
|
We test 3 known hidden services: Facebook, DuckDuckGo and .
|
|
|
|
|
|
|
|
>>> lKNOWN_ONIONS = [
|
|
|
|
... 'facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd', # facebook
|
|
|
|
... 'duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad', # ddg
|
|
|
|
... ]
|
|
|
|
|
|
|
|
We wil expect to get back the hidden service version, the descriptor-lifetime
|
|
|
|
and then the descriptor-signing-key-cert:
|
|
|
|
|
|
|
|
>>> introduction_points.iMain(lKNOWN_ONIONS) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
|
2024-01-17 21:35:20 +01:00
|
|
|
0
|
|
|
|
|
2024-02-04 04:29:52 +01:00
|
|
|
hs-descriptor 3
|
2024-01-14 15:28:53 +01:00
|
|
|
descriptor-lifetime ...
|
2024-01-17 21:35:20 +01:00
|
|
|
<BLANKLINE>
|
2024-01-14 15:28:53 +01:00
|
|
|
|
|
|
|
### exit_used Determine The Exit You're Using
|
|
|
|
|
|
|
|
Lets say you're using Tor and one day you run into something odd. Maybe a
|
|
|
|
misconfigured relay, or maybe one that's being malicious.
|
|
|
|
How can you figure out what exit you're using?
|
|
|
|
|
|
|
|
>>> print("exit_used", file=sys.stderr)
|
|
|
|
>>> import exit_used
|
2024-02-04 04:29:52 +01:00
|
|
|
>>> exit_used.iMain([])
|
2024-01-14 15:28:53 +01:00
|
|
|
|
|
|
|
## relay_connections Connection Summary
|
|
|
|
|
|
|
|
>>> print("relay_connections", file=sys.stderr)
|
|
|
|
>>> import relay_connections
|
2024-02-04 04:29:52 +01:00
|
|
|
>>> relay_connections.iMain([]) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
|
|
|
|
+------------------------------+------+------+
|
|
|
|
...
|
|
|
|
+------------------------------+------+------+
|
|
|
|
<BLANKLINE>
|
2024-01-14 15:28:53 +01:00
|
|
|
|
|
|
|
The following provides a summary of your relay's inbound and outbound connections.
|
|
|
|
You must be root or tor to run this:
|
|
|
|
relay_connections.iMain(["--ctrlport", "9051"])
|
|
|
|
|
2024-01-17 21:35:20 +01:00
|
|
|
## connection_resolution Connection Resolution
|
|
|
|
|
|
|
|
Connection information is a useful tool for learning more about network
|
|
|
|
applications like Tor. Our stem.util.connection.get_connections() function
|
|
|
|
provides an easy method for accessing this information.
|
|
|
|
|
|
|
|
>>> print("connection_resolution", file=sys.stderr)
|
|
|
|
>>> import connection_resolution
|
2024-02-04 04:29:52 +01:00
|
|
|
>>> connection_resolution.iMain([]) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
|
2024-01-17 21:35:20 +01:00
|
|
|
0
|
|
|
|
|
|
|
|
INFO Our platform supports connection resolution via: ...
|
|
|
|
<BLANKLINE>
|
|
|
|
|
2024-01-14 15:28:53 +01:00
|
|
|
## tor_bootstrap_check
|
|
|
|
|
|
|
|
>>> print("tor_bootstrap_check", file=sys.stderr)
|
|
|
|
>>> import tor_bootstrap_check
|
|
|
|
|
|
|
|
A script by adrelanos@riseup.net to check what percentage of boostrapping
|
|
|
|
tor is at. This fails under doctest but not from the cmdline
|
|
|
|
|
2024-02-04 04:29:52 +01:00
|
|
|
>>> tor_bootstrap_check.iMain([]) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
|
2024-01-17 21:35:20 +01:00
|
|
|
0
|
|
|
|
|
|
|
|
NOTICE ...
|
|
|
|
<BLANKLINE>
|
2024-01-14 15:28:53 +01:00
|
|
|
|
2024-02-04 04:29:52 +01:00
|
|
|
## check_digests
|
|
|
|
|
|
|
|
>>> print("check_digests", file=sys.stderr)
|
|
|
|
>>> from check_digests import iMain
|
|
|
|
>>> sKNOWN_ONION = 'facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd' # facebook
|
|
|
|
>>> from stem_examples.introduction_points import lMain as lIPMain
|
2024-02-05 15:26:19 +01:00
|
|
|
>>> lArgs = []
|
|
|
|
>>> import stem_examples.support_testing as ts; with ts.ignoreStdout():
|
2024-02-04 04:29:52 +01:00
|
|
|
... lArgs = lIPMain([sKNOWN_ONION])
|
|
|
|
>>> iMain(lArgs)
|
|
|
|
0
|
|
|
|
|
2024-02-05 15:26:19 +01:00
|
|
|
## interpreter
|
|
|
|
|
|
|
|
>>> print("interpreter", file=sys.stderr)
|
|
|
|
>>> import interpreter
|
|
|
|
>>> lArgs = ['GETINFO', 'version']
|
|
|
|
>>> interpreter.iMain(lArgs) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
|
|
|
|
250-version=0.4.8.10
|
|
|
|
250 OK
|
|
|
|
<BLANKLINE>
|
|
|
|
0
|
|
|
|
|
2024-02-04 04:29:52 +01:00
|
|
|
## outdated_relays List Outdated Relays
|
|
|
|
|
|
|
|
Time marches on. Tor makes new releases, and at some point needs to drop
|
|
|
|
support for old ones. Below is the script we used on ticket 9476 to reach out
|
|
|
|
to relay operators that needed to upgrade.
|
|
|
|
|
|
|
|
>>> print("outdated_relays", file=sys.stderr)
|
|
|
|
>>> import outdated_relays
|
|
|
|
>>> outdated_relays.iMain([]) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
|
|
|
|
0
|
|
|
|
|
|
|
|
Checking for outdated relays ...
|
|
|
|
<BLANKLINE>
|
|
|
|
|