This commit is contained in:
emdee@spm.plastiras.org 2024-02-04 03:29:52 +00:00
parent b9bdb02067
commit df8ea68e4d
10 changed files with 225 additions and 131 deletions

View File

@ -2,6 +2,7 @@
PREFIX=/usr/local PREFIX=/usr/local
PYTHON_EXE_MSYS=${PREFIX}/bin/python3.sh PYTHON_EXE_MSYS=${PREFIX}/bin/python3.sh
PIP_EXE_MSYS=${PREFIX}/bin/pip3.sh
LOCAL_DOCTEST=${PREFIX}/bin/toxcore_run_doctest3.bash LOCAL_DOCTEST=${PREFIX}/bin/toxcore_run_doctest3.bash
DOCTEST=${LOCAL_DOCTEST} DOCTEST=${LOCAL_DOCTEST}
MOD=stem_examples MOD=stem_examples
@ -12,6 +13,9 @@ check::
lint:: lint::
sh .pylint.sh sh .pylint.sh
xinstall::
${PIP_EXE_MSYS} install --target ${PREFIX}/lib/python3.11/site-packages/ --upgrade .
rsync:: rsync::
bash .rsync.sh bash .rsync.sh
@ -22,6 +26,8 @@ install::
test:: test::
echo src/${MOD}/check_digests.py echo src/${MOD}/check_digests.py
TOR_CONTROLLER_PASSWORD=${PASS} src/${MOD}/check_digests.py TOR_CONTROLLER_PASSWORD=${PASS} src/${MOD}/check_digests.py
echo src/${MOD}/interpreter.py
TOR_CONTROLLER_PASSWORD=${PASS} src/${MOD}/interpreter.py
echo src/${MOD}/connection_resolution.py echo src/${MOD}/connection_resolution.py
sudo env TOR_CONTROLLER_PASSWORD=${PASS} 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 # broken because this site fails: http://128.31.0.39:9131/tor/status-vote

View File

@ -34,9 +34,8 @@ packages=find:
where=src where=src
[options.entry_points] [options.entry_points]
console_scripts = #console_scripts =
phantompy = phantompy.__main__:iMain # exclude_badExits = exclude_badExits:iMain
exclude_badExits = exclude_badExits:iMain
[easy_install] [easy_install]
zip_ok = false zip_ok = false

View File

@ -110,9 +110,9 @@ if __name__ == '__main__':
else: else:
sKNOWN_ONION = 'facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd' # facebook sKNOWN_ONION = 'facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd' # facebook
LOG.info("Getting some FPs from a sKNOWN_ONION") LOG.info("Getting some FPs from a sKNOWN_ONION")
from stem_examples.introduction_points import lMain from stem_examples.introduction_points import lMain as lIPMain
with ignoreStdout(): with ignoreStdout():
lArgs = lMain([sKNOWN_ONION]) lArgs = lIPMain([sKNOWN_ONION])
LOG.info(f"Got {len(lArgs)} FPs from a sKNOWN_ONION") LOG.info(f"Got {len(lArgs)} FPs from a sKNOWN_ONION")
i = iMain(lArgs) i = iMain(lArgs)

View File

@ -20,7 +20,9 @@ from stem_examples.tor_controller import get_controller
global COUNT, IMAX global COUNT, IMAX
COUNT=0 COUNT=0
IMAX = 0 global IMAX
IMAX = 10
LOG = logging.getLogger()
def stream_event(controller, event): def stream_event(controller, event):
global COUNT, IMAX global COUNT, IMAX
@ -42,7 +44,7 @@ def stream_event(controller, event):
LOG.info("") LOG.info("")
def iMain(): def iMain(lArgs=None):
password = os.environ.get('TOR_CONTROLLER_PASSWORD') password = os.environ.get('TOR_CONTROLLER_PASSWORD')
if os.path.exists('/run/tor/control'): if os.path.exists('/run/tor/control'):
@ -50,16 +52,14 @@ def iMain():
else: else:
controller = get_controller(password=password, port=9051) controller = get_controller(password=password, port=9051)
if IMAX > 0: if IMAX <= 0:
LOG.info("Please wait for requests for tor exits. Press 'enter' to end.") LOG.info("Please wait for requests for tor exits. Press 'enter' to end.")
print("") print("")
stream_listener = functools.partial(stream_event, controller) stream_listener = functools.partial(stream_event, controller)
controller.add_event_listener(stream_listener, EventType.STREAM) controller.add_event_listener(stream_listener, EventType.STREAM)
input()
if __name__ == '__main__': if __name__ == '__main__':
from stem_examples.stem_utils import vsetup_logging from stem_examples.stem_utils import vsetup_logging
LOG = logging.getLogger()
if len(sys.argv) > 1: if len(sys.argv) > 1:
IMAX = int(sys.argv[1]) IMAX = int(sys.argv[1])
else: else:
@ -69,13 +69,17 @@ if __name__ == '__main__':
else: else:
log_level = 20 log_level = 20
vsetup_logging(LOG, log_level) vsetup_logging(LOG, log_level)
if len(sys.argv) > 1:
IMAX = int(sys.argv[1])
del sys.argv[1]
try: try:
iMain() iMain()
input()
i = 0 i = 0
except KeyboardInterrupt as e: except KeyboardInterrupt as e:
i = 0 i = 0
except Exception as e: except Exception as e:
LOG.exception(f"Exception {e}") LOG.exception(f"Exception {e}", exc_info=True)
i = 1 i = 1
sys.exit(i) sys.exit(i)

View File

@ -0,0 +1,57 @@
#!/usr/local/bin/python3.sh
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
__doc__ = """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.
https://stem.torproject.org/tutorials/examples/outdated_relays.html
"""
import os
import sys
import logging
import stem.interpreter.commands
from stem.descriptor.remote import DescriptorDownloader
from stem_examples.tor_controller import get_controller
from stem.version import Version
from tor_controller import set_socks_proxy, unset_socks_proxy
LOG = logging.getLogger()
def iMain(lArgs=None):
if not lArgs:
lArgs = ['GETINFO' 'version']
password = os.environ.get('TOR_CONTROLLER_PASSWORD')
if os.path.exists('/run/tor/control'):
controller = get_controller(password=password, unix='/run/tor/control')
else:
controller = get_controller(password=password, port=9051)
interpreter = stem.interpreter.commands.ControlInterpreter(controller)
run_cmd = ' '.join(lArgs)
interpreter.run_command(run_cmd, print_response = True)
return 0
if __name__ == '__main__':
# set_socks_proxy()
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:
l = iMain(sys.argv[1:])
if l: print(l)
i = 0
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

@ -22,7 +22,6 @@ from stem.control import EventType, Controller
# from tor_controller import set_socks_proxy, unset_socks_proxy # from tor_controller import set_socks_proxy, unset_socks_proxy
from stem_examples.tor_controller import get_controller from stem_examples.tor_controller import get_controller
from stem_examples.stem_utils import vsetup_logging
global LOG global LOG
import logging import logging
@ -34,7 +33,7 @@ def sMapaddressResolv(target, iPort=9051):
if os.path.exists('/run/tor/control'): if os.path.exists('/run/tor/control'):
controller = get_controller(password=password, unix='/run/tor/control') controller = get_controller(password=password, unix='/run/tor/control')
else: else:
controller = get_controller(password=password, port=9051) controller = get_controller(password=password, port=iPort)
map_dict = {"0.0.0.0": target} map_dict = {"0.0.0.0": target}
map_ret = controller.map_address(map_dict) map_ret = controller.map_address(map_dict)
@ -44,6 +43,7 @@ def sMapaddressResolv(target, iPort=9051):
LOG.exception(e) LOG.exception(e)
if __name__ == '__main__': if __name__ == '__main__':
from stem_examples.stem_utils import vsetup_logging
if os.environ.get('DEBUG', ''): if os.environ.get('DEBUG', ''):
log_level = 10 log_level = 10
else: else:

View File

@ -20,7 +20,7 @@ from tor_controller import set_socks_proxy, unset_socks_proxy
LOG = logging.getLogger() LOG = logging.getLogger()
def iMain(): def iMain(lArgs=None):
downloader = DescriptorDownloader(use_mirrors=True) downloader = DescriptorDownloader(use_mirrors=True)
count, with_contact = 0, 0 count, with_contact = 0, 0
elts = downloader.get_server_descriptors() elts = downloader.get_server_descriptors()
@ -47,7 +47,7 @@ if __name__ == '__main__':
log_level = 20 log_level = 20
vsetup_logging(LOG, log_level) vsetup_logging(LOG, log_level)
try: try:
l = iMain() l = iMain([])
if l: print(l) if l: print(l)
i = 0 i = 0
except KeyboardInterrupt as e: except KeyboardInterrupt as e:

View File

@ -21,14 +21,14 @@ import stem.connection
import stem.util.system import stem.util.system
import stem.util.str_tools import stem.util.str_tools
from stem.control import Listener from stem.control import Listener, Controller
from stem.control import Controller
from stem.util.connection import get_connections, port_usage, is_valid_ipv4_address from stem.util.connection import get_connections, port_usage, is_valid_ipv4_address
from stem_examples.tor_controller import get_controller from stem_examples.tor_controller import get_controller
global LOG
import logging import logging
global LOG
LOG = logging.getLogger()
HEADER_LINE = " {version} uptime: {uptime} flags: {flags}\n" HEADER_LINE = " {version} uptime: {uptime} flags: {flags}\n"
@ -44,109 +44,86 @@ OUTBOUND_EXIT = 'Outbound exit traffic'
OUTBOUND_UNKNOWN = 'Outbound uncategorized' OUTBOUND_UNKNOWN = 'Outbound uncategorized'
def iMain(lArgs=None): def iMain(lArgs=None):
if lArgs is None: if lArgs is None:
lArgs = sys.argv[1:] lArgs = sys.argv[1:]
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("--ctrlport", default=9051, type=int, help="default: 9051") parser.add_argument("--ctrlport", default=9051, type=int, help="default: 9051")
parser.add_argument("--resolver", help="default: autodetected") parser.add_argument("--resolver", help="default: autodetected")
args = parser.parse_args(lArgs) args = parser.parse_args(lArgs)
password = os.environ.get('TOR_CONTROLLER_PASSWORD') password = os.environ.get('TOR_CONTROLLER_PASSWORD')
control_port = int(args.ctrlport) if args.ctrlport else 'default' control_port = int(args.ctrlport) if args.ctrlport else 'default'
if False and os.path.exists('/run/tor/control'): if False and os.path.exists('/run/tor/control'):
controller = get_controller(password=password, unix='/run/tor/control') controller = get_controller(password=password, unix='/run/tor/control')
else:
controller = get_controller(password=password, port=control_port)
if not controller:
return 1
desc = controller.get_network_status(default=None)
pid = controller.get_pid()
version = str(controller.get_version()).split()[0],
uptime = stem.util.str_tools.short_time_label(time.time() - stem.util.system.start_time(pid))
LOG.info(HEADER_LINE.format(
version=version,
uptime=uptime,
flags = ', '.join(desc.flags if desc else ['none']),
))
policy = controller.get_exit_policy()
relays = {} # address => [orports...]
for desc in controller.get_network_statuses():
relays.setdefault(desc.address, []).append(desc.or_port)
# categorize our connections
categories = collections.OrderedDict((
(INBOUND_ORPORT, []),
(INBOUND_DIRPORT, []),
(INBOUND_CONTROLPORT, []),
(OUTBOUND_ORPORT, []),
(OUTBOUND_EXIT, []),
(OUTBOUND_UNKNOWN, []),
))
exit_connections = {} # port => [connections]
for conn in get_connections(resolver = args.resolver, process_pid = pid):
if conn.protocol == 'udp':
continue
if conn.local_port in controller.get_ports(Listener.OR, []):
categories[INBOUND_ORPORT].append(conn)
elif conn.local_port in controller.get_ports(Listener.DIR, []):
categories[INBOUND_DIRPORT].append(conn)
elif conn.local_port in controller.get_ports(Listener.CONTROL, []):
categories[INBOUND_CONTROLPORT].append(conn)
elif conn.remote_port in relays.get(conn.remote_address, []):
categories[OUTBOUND_ORPORT].append(conn)
elif policy.can_exit_to(conn.remote_address, conn.remote_port):
categories[OUTBOUND_EXIT].append(conn)
exit_connections.setdefault(conn.remote_port, []).append(conn)
else: else:
categories[OUTBOUND_UNKNOWN].append(conn) controller = get_controller(password=password, port=control_port)
print(DIV) if not controller:
print(COLUMN % ('Type', 'IPv4', 'IPv6')) return 1
print(DIV)
total_ipv4, total_ipv6 = 0, 0 desc = controller.get_network_status(default=None)
pid = controller.get_pid()
version = str(controller.get_version()).split()[0],
uptime = stem.util.str_tools.short_time_label(time.time() - stem.util.system.start_time(pid))
for label, connections in categories.items(): LOG.info(HEADER_LINE.format(
if len(connections) == 0: version=version,
continue uptime=uptime,
flags = ', '.join(desc.flags if desc else ['none']),
))
ipv4_count = len([conn for conn in connections if is_valid_ipv4_address(conn.remote_address)]) policy = controller.get_exit_policy()
ipv6_count = len(connections) - ipv4_count relays = {} # address => [orports...]
total_ipv4, total_ipv6 = total_ipv4 + ipv4_count, total_ipv6 + ipv6_count for desc in controller.get_network_statuses():
print(COLUMN % (label, ipv4_count, ipv6_count)) relays.setdefault(desc.address, []).append(desc.or_port)
print(DIV) # categorize our connections
print(COLUMN % ('Total', total_ipv4, total_ipv6))
print(DIV) categories = collections.OrderedDict((
print('') (INBOUND_ORPORT, []),
(INBOUND_DIRPORT, []),
(INBOUND_CONTROLPORT, []),
(OUTBOUND_ORPORT, []),
(OUTBOUND_EXIT, []),
(OUTBOUND_UNKNOWN, []),
))
exit_connections = {} # port => [connections]
for conn in get_connections(resolver = args.resolver, process_pid = pid):
if conn.protocol == 'udp':
continue
if conn.local_port in controller.get_ports(Listener.OR, []):
categories[INBOUND_ORPORT].append(conn)
elif conn.local_port in controller.get_ports(Listener.DIR, []):
categories[INBOUND_DIRPORT].append(conn)
elif conn.local_port in controller.get_ports(Listener.CONTROL, []):
categories[INBOUND_CONTROLPORT].append(conn)
elif conn.remote_port in relays.get(conn.remote_address, []):
categories[OUTBOUND_ORPORT].append(conn)
elif policy.can_exit_to(conn.remote_address, conn.remote_port):
categories[OUTBOUND_EXIT].append(conn)
exit_connections.setdefault(conn.remote_port, []).append(conn)
else:
categories[OUTBOUND_UNKNOWN].append(conn)
if exit_connections:
print(DIV) print(DIV)
print(COLUMN % ('Exit Port', 'IPv4', 'IPv6')) print(COLUMN % ('Type', 'IPv4', 'IPv6'))
print(DIV) print(DIV)
total_ipv4, total_ipv6 = 0, 0 total_ipv4, total_ipv6 = 0, 0
for port in sorted(exit_connections): for label, connections in categories.items():
connections = exit_connections[port] if len(connections) == 0:
continue
ipv4_count = len([conn for conn in connections if is_valid_ipv4_address(conn.remote_address)]) ipv4_count = len([conn for conn in connections if is_valid_ipv4_address(conn.remote_address)])
ipv6_count = len(connections) - ipv4_count ipv6_count = len(connections) - ipv4_count
total_ipv4, total_ipv6 = total_ipv4 + ipv4_count, total_ipv6 + ipv6_count total_ipv4, total_ipv6 = total_ipv4 + ipv4_count, total_ipv6 + ipv6_count
usage = port_usage(port)
label = '%s (%s)' % (port, usage) if usage else port
print(COLUMN % (label, ipv4_count, ipv6_count)) print(COLUMN % (label, ipv4_count, ipv6_count))
print(DIV) print(DIV)
@ -154,6 +131,28 @@ def iMain(lArgs=None):
print(DIV) print(DIV)
print('') print('')
if exit_connections:
print(DIV)
print(COLUMN % ('Exit Port', 'IPv4', 'IPv6'))
print(DIV)
total_ipv4, total_ipv6 = 0, 0
for port in sorted(exit_connections):
connections = exit_connections[port]
ipv4_count = len([conn for conn in connections if is_valid_ipv4_address(conn.remote_address)])
ipv6_count = len(connections) - ipv4_count
total_ipv4, total_ipv6 = total_ipv4 + ipv4_count, total_ipv6 + ipv6_count
usage = port_usage(port)
label = '%s (%s)' % (port, usage) if usage else port
print(COLUMN % (label, ipv4_count, ipv6_count))
print(DIV)
print(COLUMN % ('Total', total_ipv4, total_ipv6))
print(DIV)
print('')
if __name__ == '__main__': if __name__ == '__main__':
from stem_examples.stem_utils import vsetup_logging from stem_examples.stem_utils import vsetup_logging
@ -165,7 +164,7 @@ if __name__ == '__main__':
vsetup_logging(LOG, log_level) vsetup_logging(LOG, log_level)
LOG.setLevel(logging.DEBUG) LOG.setLevel(logging.DEBUG)
try: try:
l = iMain() l = iMain([])
if l: print(l) if l: print(l)
i = 0 i = 0
except KeyboardInterrupt as e: except KeyboardInterrupt as e:

View File

@ -60,9 +60,8 @@ if __name__ == '__main__':
else: else:
log_level = 20 log_level = 20
vsetup_logging(LOG, log_level) vsetup_logging(LOG, log_level)
LOG.setLevel(logging.DEBUG)
try: try:
i = iMain() i = iMain([])
except KeyboardInterrupt as e: except KeyboardInterrupt as e:
i = 0 i = 0
except Exception as e: except Exception as e:

View File

@ -54,20 +54,21 @@ If you don't have one, make it with the settings from your torrc:
>>> print("yaml", file=sys.stderr) >>> print("yaml", file=sys.stderr)
>>> import yaml >>> import yaml
>>> try: >>> try:
... sFacts = open('/usr/local/etc/testforge/testforge.yml').read() ... sFacts = open('/usr/local/etc/testforge/testforge.yml').read()
... assert sFacts, sFacts
... except: ... except:
... dFacts = { ... dFacts = dict(
... HTTPS_PROXYHOST: "127.0.0.1", ... HTTPS_PROXYHOST="127.0.0.1",
... HTTPS_PROXYPORT: 9128, ... HTTPS_PROXYPORT=9128,
... HTTPS_PROXYTYPE: "http", ... HTTPS_PROXYTYPE="http",
... SOCKS_PROXYHOST: "127.0.0.1", ... SOCKS_PROXYHOST="127.0.0.1",
... SOCKS_PROXYPORT: 9050, ... SOCKS_PROXYPORT=9050,
... SOCKS_PROXYTYPE: "socks5", ... SOCKS_PROXYTYPE="socks5",
... } ... )
... else: ... else:
... assert sFacts ... dFacts = yaml.safe_load(sFacts)
... dFacts = yaml.safe_load(sFacts)
FixMe: use the settings for the ports and directories below. FixMe: use the settings for the ports and directories below.
>>> import os >>> import os
@ -94,7 +95,7 @@ and then the descriptor-signing-key-cert:
>>> introduction_points.iMain(lKNOWN_ONIONS) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE >>> introduction_points.iMain(lKNOWN_ONIONS) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
0 0
hs-descriptor 3 hs-descriptor 3
descriptor-lifetime ... descriptor-lifetime ...
<BLANKLINE> <BLANKLINE>
@ -106,11 +107,17 @@ How can you figure out what exit you're using?
>>> print("exit_used", file=sys.stderr) >>> print("exit_used", file=sys.stderr)
>>> import exit_used >>> import exit_used
>>> exit_used.iMain([])
## relay_connections Connection Summary ## relay_connections Connection Summary
>>> print("relay_connections", file=sys.stderr) >>> print("relay_connections", file=sys.stderr)
>>> import relay_connections >>> import relay_connections
>>> relay_connections.iMain([]) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+------------------------------+------+------+
...
+------------------------------+------+------+
<BLANKLINE>
The following provides a summary of your relay's inbound and outbound connections. The following provides a summary of your relay's inbound and outbound connections.
You must be root or tor to run this: You must be root or tor to run this:
@ -124,25 +131,22 @@ provides an easy method for accessing this information.
>>> print("connection_resolution", file=sys.stderr) >>> print("connection_resolution", file=sys.stderr)
>>> import connection_resolution >>> import connection_resolution
>>> connection_resolution.iMain() #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE >>> connection_resolution.iMain([]) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
0 0
INFO Our platform supports connection resolution via: ... INFO Our platform supports connection resolution via: ...
<BLANKLINE> <BLANKLINE>
## outdated_relays List Outdated Relays ## interpreter
Time marches on. Tor makes new releases, and at some point needs to drop >>> print("interpreter", file=sys.stderr)
support for old ones. Below is the script we used on ticket 9476 to reach out >>> import interpreter
to relay operators that needed to upgrade. >>> lArgs = ['GETINFO', 'version']
>>> interpreter.iMain(lArgs) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
>>> print("outdated_relays", file=sys.stderr) 250-version=0.4.8.10
>>> import outdated_relays 250 OK
>>> outdated_relays.iMain() #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
0
Checking for outdated relays ...
<BLANKLINE> <BLANKLINE>
0
## tor_bootstrap_check ## tor_bootstrap_check
@ -152,9 +156,35 @@ to relay operators that needed to upgrade.
A script by adrelanos@riseup.net to check what percentage of boostrapping 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 is at. This fails under doctest but not from the cmdline
>>> tor_bootstrap_check.iMain() #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE >>> tor_bootstrap_check.iMain([]) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
0 0
NOTICE ... NOTICE ...
<BLANKLINE> <BLANKLINE>
## check_digests
>>> print("check_digests", file=sys.stderr)
>>> from support_testing import ignoreStdout
>>> from check_digests import iMain
>>> sKNOWN_ONION = 'facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd' # facebook
>>> from stem_examples.introduction_points import lMain as lIPMain
>>> with ignoreStdout():
... lArgs = lIPMain([sKNOWN_ONION])
>>> iMain(lArgs)
0
## 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>