This commit is contained in:
emdee@spm.plastiras.org 2024-01-17 20:35:20 +00:00
parent 91465abf2a
commit b9bdb02067
13 changed files with 213 additions and 52 deletions

View File

@ -22,6 +22,8 @@ install::
test::
echo src/${MOD}/check_digests.py
TOR_CONTROLLER_PASSWORD=${PASS} src/${MOD}/check_digests.py
echo src/${MOD}/connection_resolution.py
sudo env TOR_CONTROLLER_PASSWORD=${PASS} src/${MOD}/connection_resolution.py
# broken because this site fails: http://128.31.0.39:9131/tor/status-vote
# ${PYTHON_EXE_MSYS} src/${MOD}/compare_flags.py
# cant use from make: waits for the cmdline to to terminate

View File

@ -35,6 +35,13 @@ and maatuska, with a special interest in the 'Running' flag.
https://stem.torproject.org/tutorials/examples/compare_flags.html
### 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.
### exit_used Exit Used
Determine The Exit You're Using

View File

@ -122,5 +122,3 @@ if __name__ == '__main__':
LOG.exception(f"Exception in iMain {e}")
i = 1
sys.exit(i)

View File

@ -18,7 +18,7 @@ import stem.descriptor
import stem.descriptor.remote
import stem.directory
from tor_controller import set_socks_proxy
from tor_controller import set_socks_proxy, unset_socks_proxy
def iMain():
# Query all authority votes asynchronously.
@ -70,4 +70,10 @@ def iMain():
if __name__ == '__main__':
set_socks_proxy()
sys.exit(iMain())
try:
i = iMain()
except KeyboardInterrupt as e:
i = 0
finally:
unset_socks_proxy()
sys.exit(i)

View File

@ -0,0 +1,77 @@
__doc__ = """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, with a few caveats...
Connection resolvers are platform specific. We support several platforms but
not all.
By default Tor runs with a feature called DisableDebuggerAttachment. This
prevents debugging applications like gdb from analyzing Tor unless it is run as
root. Unfortunately this also alters the permissions of the Tor process /proc
contents breaking numerous system tools (including our resolvers). To use this
function you need to either run as root (discouraged) or add
DisableDebuggerAttachment 0 to your torrc.
Please note that if you operate an exit relay it is highly discouraged for you
to look at or record this information. Not only is doing so eavesdropping, but
likely also a violation of wiretap laws.
With that out of the way, how do you look up this information? Below is a
simple script that dumps Tor's present connections.
https://stem.torproject.org/tutorials/east_of_the_sun.html
"""
import os
import sys
import logging
from stem.util.connection import get_connections, system_resolvers
from stem.util.system import pid_by_name
LOG = logging.getLogger()
def iMain (lArgs=None):
resolvers = system_resolvers()
if not resolvers:
LOG.error("Stem doesn't support any connection resolvers on our platform.")
return 1
picked_resolver = resolvers[0] # lets just opt for the first
LOG.info("Our platform supports connection resolution via: %s (picked %s)" % (', '.join(resolvers), picked_resolver))
tor_pids = pid_by_name('tor', multiple = True)
if not tor_pids:
LOG.warn("Unable to get tor's pid. Is it running?")
return 1
if len(tor_pids) > 1:
LOG.info("You're running %i instances of tor, picking the one with pid %i" % (len(tor_pids), tor_pids[0]))
else:
LOG.info("Tor is running with pid %i" % tor_pids[0])
LOG.info("Connections:\n")
for conn in get_connections(picked_resolver, process_pid = tor_pids[0], process_name = 'tor'):
LOG.info(" %s:%s => %s:%s" % (conn.local_address, conn.local_port, conn.remote_address, conn.remote_port))
return 0
if __name__ == '__main__':
from stem_examples.stem_utils import vsetup_logging
if os.environ.get('DEBUG', ''):
log_level = 10
else:
log_level = 20
vsetup_logging(LOG, log_level)
try:
i = iMain(sys.argv[1:])
except KeyboardInterrupt as e:
i = 0
except Exception as e:
LOG.exception(f"Exception {e}")
i = 1
sys.exit(i)

View File

@ -75,6 +75,7 @@ if __name__ == '__main__':
except KeyboardInterrupt as e:
i = 0
except Exception as e:
LOG.exception(f"Exception {e}")
i = 1
sys.exit(i)

View File

@ -26,7 +26,6 @@ import logging
from stem.control import Controller
from stem_examples.tor_controller import get_controller
from stem_examples.stem_utils import vsetup_logging
LOG = logging.getLogger()
@ -76,6 +75,7 @@ def lMain(lArgs=None, timeout=None):
return lRetval
if __name__ == '__main__':
from stem_examples.stem_utils import vsetup_logging
if os.environ.get('DEBUG', ''):
log_level = 10
else:
@ -86,6 +86,7 @@ if __name__ == '__main__':
if l: print(l)
i = 0
except KeyboardInterrupt as e:
LOG.exception(f"Exception {e}")
i = 0
except Exception as e:
i = 1

View File

@ -19,7 +19,7 @@ import os
from stem import StreamStatus
from stem.control import EventType, Controller
from tor_controller import set_socks_proxy
# from tor_controller import set_socks_proxy, unset_socks_proxy
from stem_examples.tor_controller import get_controller
from stem_examples.stem_utils import vsetup_logging

View File

@ -16,17 +16,15 @@ import logging
from stem.descriptor.remote import DescriptorDownloader
from stem.version import Version
from tor_controller import set_socks_proxy
from tor_controller import set_socks_proxy, unset_socks_proxy
LOG = logging.getLogger()
def iMain():
set_socks_proxy()
downloader = DescriptorDownloader(use_mirrors=True)
count, with_contact = 0, 0
elts = downloader.get_server_descriptors()
LOG.info(f"Checking for outdated relays len server_descriptors={len(list(elts))}...")
print("")
for desc in elts:
if desc.tor_version < Version('0.2.3.0'):
@ -36,20 +34,18 @@ def iMain():
LOG.info(' %-15s %s' % (desc.tor_version, desc.contact.decode("utf-8", "replace")))
with_contact += 1
print("")
LOG.info("%i outdated relays found, %i had contact information" % (count, with_contact))
# http://vt5hknv6sblkgf22.onion/tutorials/examples/outdated_relays.htmlhttp://vt5hknv6sblkgf22.onion/tutorials/examples/outdated_relays.html
return 0
if __name__ == '__main__':
set_socks_proxy()
from stem_examples.stem_utils import vsetup_logging
LOG = logging.getLogger()
if os.environ.get('DEBUG', ''):
log_level = 10
else:
log_level = 20
vsetup_logging(LOG, log_level)
LOG.setLevel(logging.DEBUG)
try:
l = iMain()
if l: print(l)
@ -57,5 +53,8 @@ if __name__ == '__main__':
except KeyboardInterrupt as e:
i = 0
except Exception as e:
LOG.exception(f"Exception {e}")
i = 1
finally:
unset_socks_proxy()
sys.exit(i)

View File

@ -171,6 +171,7 @@ if __name__ == '__main__':
except KeyboardInterrupt as e:
i = 0
except Exception as e:
LOG.exception(f"Exception {e}")
i = 1
sys.exit(i)

View File

@ -12,10 +12,14 @@ tor is at.
import sys
import os
import re
import logging
import socket
from stem.connection import connect
from stem_examples.tor_controller import get_controller
LOG = logging.getLogger()
def iMain(lArgs=None):
password = os.environ.get('TOR_CONTROLLER_PASSWORD')
if os.path.exists('/run/tor/control'):
@ -23,10 +27,6 @@ def iMain(lArgs=None):
else:
controller = get_controller(password=password, port=9051)
# controller.connect()
bootstrap_status = controller.get_info("status/bootstrap-phase")
## Possible answer, if network cable has been removed:
## 250-status/bootstrap-phase=WARN BOOTSTRAP PROGRESS=80 TAG=conn_or SUMMARY="Connecting to the Tor network" WARNING="No route to host" REASON=NOROUTE COUNT=26 RECOMMENDATION=warn
@ -38,18 +38,23 @@ def iMain(lArgs=None):
## TODO: parse the messages above.
LOG.info(format(bootstrap_status))
try:
bootstrap_status = controller.get_info("status/bootstrap-phase")
LOG.info(format(bootstrap_status))
progress_percent = re.match('.* PROGRESS=([0-9]+).*', bootstrap_status)
exit_code = int(progress_percent.group(1))
progress_percent = re.match('.* PROGRESS=([0-9]+).*', bootstrap_status)
exit_code = int(progress_percent.group(1))
controller.close()
return exit_code
controller.close()
except socket.error as e:
# Error while receiving a control message (SocketClosed): received exception "read of closed file"
return 0
except Exception as e:
raise
return 0
if __name__ == '__main__':
from stem_examples.stem_utils import vsetup_logging
LOG = logging.getLogger()
if os.environ.get('DEBUG', ''):
log_level = 10
else:
@ -57,12 +62,10 @@ if __name__ == '__main__':
vsetup_logging(LOG, log_level)
LOG.setLevel(logging.DEBUG)
try:
l = iMain()
if l: print(l)
i = 0
i = iMain()
except KeyboardInterrupt as e:
i = 0
except Exception as e:
LOG.exception(f"Exception {e}")
i = 1
sys.exit(i)

View File

@ -12,7 +12,7 @@ def set_socks_proxy(SOCKS5_PROXY_HOST='127.0.0.1', SOCKS5_PROXY_PORT=9050):
try:
import socks # you need to install pysocks (see above)
# Remove this if you don't plan to "deactivate" the proxy later
default_socket = socket.socket
socks._socket = socket.socket
# Set up a proxy
socks.set_default_proxy(socks.SOCKS5, SOCKS5_PROXY_HOST, SOCKS5_PROXY_PORT)
@ -21,6 +21,14 @@ def set_socks_proxy(SOCKS5_PROXY_HOST='127.0.0.1', SOCKS5_PROXY_PORT=9050):
return False
return True
def unset_socks_proxy():
import socks # you need to install pysocks (see above)
# Remove this if you don't plan to "deactivate" the proxy later
socks.socket = socket._socket
# Set up a proxy
socks.set_default_proxy(socks.SOCKS5, None, None)
def get_controller(password=None, address='127.0.0.1', port=9051, unix='/run/tor/control'):
if unix and os.path.exists(unix):
# print(unix)

View File

@ -3,28 +3,74 @@
== stem_examples tor testing ==
This is a Python doctest file that is executable documentation.
stem_examples is a set of small scripts that tell you about your
running tor instance.
Pass the controller password if needed as an environment variable:
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:
>>> import os
>>> assert os.environ['TOR_CONTROLLER_PASSWORD']
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.
Add our code to the PYTHONPATH
>>> import sys
>>> sys.path.append(os.path.join(os.getcwd(), 'src', 'stem_examples'))
We'll need the settings defined in {{{/usr/local/etc/testforge/testforge.yml}}}
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:
>>> print("yaml", file=sys.stderr)
>>> import yaml
>>> sFacts = open('/usr/local/etc/testforge/testforge.yml').read()
>>> assert sFacts
>>> dFacts = yaml.safe_load(sFacts)
>>> try:
... sFacts = open('/usr/local/etc/testforge/testforge.yml').read()
... except:
... dFacts = {
... HTTPS_PROXYHOST: "127.0.0.1",
... HTTPS_PROXYPORT: 9128,
... HTTPS_PROXYTYPE: "http",
... SOCKS_PROXYHOST: "127.0.0.1",
... SOCKS_PROXYPORT: 9050,
... SOCKS_PROXYTYPE: "socks5",
... }
... else:
... assert sFacts
... dFacts = yaml.safe_load(sFacts)
FixMe: use the settings for the ports and directories below.
>>> import os
>>> os.environ['http_proxy'] = 'http://'+dFacts['HTTP_PROXYHOST']+':'+str(dFacts['HTTP_PROXYPORT'])
>>> os.environ['https_proxy'] = 'http://'+dFacts['HTTPS_PROXYHOST']+':'+str(dFacts['HTTPS_PROXYPORT'])
>>> os.environ['socks_proxy'] = 'socks5://'+dFacts['SOCKS_PROXYHOST']+':'+str(dFacts['SOCKS_PROXYPORT'])
@ -40,16 +86,17 @@ We test 3 known hidden services: Facebook, DuckDuckGo and .
>>> lKNOWN_ONIONS = [
... 'facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd', # facebook
... 'duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad', # ddg
... 'zkaan2xfbuxia2wpf7ofnkbz6r5zdbbvxbunvp5g2iebopbfc4iqmbad', # hks
... ]
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
hs-descriptor 3
0
hs-descriptor 3
descriptor-lifetime ...
<BLANKLINE>
<BLANKLINE>
### exit_used Determine The Exit You're Using
@ -69,11 +116,31 @@ The following provides a summary of your relay's inbound and outbound connection
You must be root or tor to run this:
relay_connections.iMain(["--ctrlport", "9051"])
## outdated_relays
## 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
>>> connection_resolution.iMain() #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
0
INFO Our platform supports connection resolution via: ...
<BLANKLINE>
## 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>
@ -85,18 +152,9 @@ relay_connections.iMain(["--ctrlport", "9051"])
A script by adrelanos@riseup.net to check what percentage of boostrapping
tor is at. This fails under doctest but not from the cmdline
>> tor_bootstrap_check.iMain() #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
NOTICE ...
<BLANKLINE>
control_port = stem.socket.ControlPort(address, port)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/stem/socket.py", line 503, in __init__
self.connect()
File "/usr/local/lib/python3.11/site-packages/stem/socket.py", line 172, in connect
self._socket = self._make_socket()
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/stem/socket.py", line 538, in _make_socket
raise stem.SocketError(exc)
stem.SocketError: Socket error: 0x01: General SOCKS server failure
>>> tor_bootstrap_check.iMain() #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
0
NOTICE ...
<BLANKLINE>