diff --git a/requires.txt b/requires.txt index ec1567a..3844b4a 100644 --- a/requires.txt +++ b/requires.txt @@ -1,4 +1,3 @@ setuptools>=50.3.2 stem>=1.8.0 -paho-mqtt>=1.5.1 -PySocks>=1.7.1 +paho-mqtt>=1.5.1 \ No newline at end of file diff --git a/setup.py b/setup.py index 2092866..4db95e5 100644 --- a/setup.py +++ b/setup.py @@ -18,9 +18,8 @@ setuptools.setup( install_requires=[ 'stem', 'paho-mqtt>=1.5.1', - 'PySocks', ], - entry_points = { + entry_points={ 'console_scripts': ['torch-agent=torch_agent.torch_agent:main'], }, classifiers=[ @@ -29,4 +28,3 @@ setuptools.setup( ], python_requires='>=3.6', ) - diff --git a/torch_agent/torch_agent.py b/torch_agent/torch_agent.py index 94e2bf6..15fd3e6 100755 --- a/torch_agent/torch_agent.py +++ b/torch_agent/torch_agent.py @@ -1,8 +1,8 @@ from stem.control import Controller import stem.connection import paho.mqtt.client as mqtt +from paho.mqtt.client import socks import ssl -import socks import socket import json import configparser @@ -10,88 +10,89 @@ import argparse from datetime import datetime from os import environ + def main(): - parser = argparse.ArgumentParser(description='Broadcast SSH hidden service hostname via MQTT') + parser = argparse.ArgumentParser(description='Broadcast SSH hidden service hostname via MQTT') - parser.add_argument('--config-dir', nargs='?', dest='configPath', default='/etc/torch', - help='configuration directory (default: /etc/torch)') + parser.add_argument('--config-dir', nargs='?', dest='configPath', default='/etc/torch', + help='configuration directory (default: /etc/torch)') - args = parser.parse_args() + args = parser.parse_args() - configPath = args.configPath + config_path = args.configPath - if "TORCH_CONFIG_DIR" in environ: - configPath = environ.get("TORCH_CONFIG_DIR") + if "TORCH_CONFIG_DIR" in environ: + config_path = environ.get("TORCH_CONFIG_DIR") - if not configPath.endswith("/"): - configPath = configPath + "/" + if not config_path.endswith("/"): + config_path = config_path + "/" - print("Using torch configuration path: " + configPath) + print("Using torch configuration path: " + config_path) - config = configparser.ConfigParser() - config.read(configPath + "torch.conf") + config = configparser.ConfigParser() + config.read(config_path + "torch.conf") - torProxyPort = config['tor'].getint('ProxyPort', fallback = 9050) - torControllerPort = config['tor'].getint('ControllerPort', fallback = 9051) + tor_proxy_port = config['tor'].getint('ProxyPort', fallback=9050) + tor_controller_port = config['tor'].getint('ControllerPort', fallback=9051) - sshPort = config['ssh'].getint('Port', fallback = 22) + ssh_port = config['ssh'].getint('Port', fallback=22) - mqttConfig = config['mqtt'] - mqttBrokerHost = mqttConfig.get('BrokerHost', fallback = "localhost") - mqttBrokerPort = mqttConfig.getint('BrokerPort', fallback = 1883) - clientID = mqttConfig.get('ClientID', fallback = socket.gethostname()) - mqttTopic = mqttConfig.get('Topic', fallback = "torch/%s/onion_url" % (clientID)) + mqtt_config = config['mqtt'] + mqtt_broker_host = mqtt_config.get('BrokerHost', fallback="localhost") + mqtt_broker_port = mqtt_config.getint('BrokerPort', fallback=1883) + client_id = mqtt_config.get('ClientID', fallback=socket.gethostname()) + mqtt_topic = mqtt_config.get('Topic', fallback="torch/%s/onion_url" % client_id) - mqttRequireCertificate = mqttConfig.getboolean( - 'RequireCertificate', - fallback = False) + mqtt_require_certificate = mqtt_config.getboolean( + 'RequireCertificate', + fallback=False) - mqttCaFile = configPath + mqttConfig.get('CaFile') - mqttCertFile = configPath + mqttConfig.get('CertFile') - mqttKeyFile = configPath + mqttConfig.get('KeyFile') + mqtt_ca_file = config_path + mqtt_config.get('CaFile') + mqtt_cert_file = config_path + mqtt_config.get('CertFile') + mqtt_key_file = config_path + mqtt_config.get('KeyFile') - with Controller.from_port(port = torControllerPort) as controller: - - protocolInfo = stem.connection.get_protocolinfo(controller) + with Controller.from_port(port=tor_controller_port) as controller: - stem.connection.authenticate_safecookie( - controller, - protocolInfo.cookie_path) - - print("Connected to Tor on port %s" % (torControllerPort)) + protocol_info = stem.connection.get_protocolinfo(controller) - service = controller.create_ephemeral_hidden_service(sshPort, detached = True) + stem.connection.authenticate_safecookie( + controller, + protocol_info.cookie_path) - onionAddress = "%s.onion" % (service.service_id) + print("Connected to Tor on port %s" % tor_controller_port) - print("Created Tor Hidden Service for local port %s at %s" % (sshPort, onionAddress)) + service = controller.create_ephemeral_hidden_service(ssh_port, detached=True) - payload = { - 'clientId': clientID, - 'timestamp': datetime.now().strftime("%d-%b-%Y (%H:%M:%S.%f)"), - 'onionAddress': onionAddress, - 'sshPort': sshPort + onion_address = "%s.onion" % service.service_id + + print("Created Tor Hidden Service for local port %s at %s" % (ssh_port, onion_address)) + + payload = { + 'clientId': client_id, + 'timestamp': datetime.now().strftime("%d-%b-%Y (%H:%M:%S.%f)"), + 'onionAddress': onion_address, + 'sshPort': ssh_port } - client = mqtt.Client() - protocol = "mqtt" + client = mqtt.Client() + protocol = "mqtt" - if mqttRequireCertificate: - client.tls_set( - ca_certs = mqttCaFile, - certfile = mqttCertFile, - keyfile = mqttKeyFile, + if mqtt_require_certificate: + client.tls_set( + ca_certs=mqtt_ca_file, + certfile=mqtt_cert_file, + keyfile=mqtt_key_file, cert_reqs=ssl.CERT_REQUIRED) - protocol = "mqtts" + protocol = "mqtts" - if mqttBrokerHost.endswith(".onion"): - client.proxy_set(proxy_type=socks.SOCKS5, proxy_addr="localhost", proxy_port=torProxyPort) - client.tls_insecure_set(True) + if mqtt_broker_host.endswith(".onion"): + client.proxy_set(proxy_type=socks.SOCKS5, proxy_addr="localhost", proxy_port=tor_proxy_port) + client.tls_insecure_set(True) - client.connect(mqttBrokerHost, mqttBrokerPort, 60) - client.publish(mqttTopic, json.dumps(payload)) - print("Connected to MQTT Broker at %s://%s:%s/%s" % (protocol, mqttBrokerHost, mqttBrokerPort, mqttTopic)) - print("Published payload: " + json.dumps(payload)) + client.connect(mqtt_broker_host, mqtt_broker_port, 60) + client.publish(mqtt_topic, json.dumps(payload)) + print("Connected to MQTT Broker at %s://%s:%s/%s" % (protocol, mqtt_broker_host, mqtt_broker_port, mqtt_topic)) + print("Published payload: " + json.dumps(payload)) - client.disconnect() - print("Disconnected from MQTT Broker") + client.disconnect() + print("Disconnected from MQTT Broker")