Implemented Python setuptools build structure
This commit is contained in:
parent
c3506607c4
commit
156370a586
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -1,2 +1,6 @@
|
||||||
.vagrant
|
.vagrant
|
||||||
build
|
build
|
||||||
|
venv
|
||||||
|
dist
|
||||||
|
*.egg-info
|
||||||
|
__pycache__
|
||||||
|
|
21
LICENSE.md
Normal file
21
LICENSE.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Benjamin Dweck
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
5
requirements.txt
Normal file
5
requirements.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
wheel>=0.35.1
|
||||||
|
setuptools>=44.0.0
|
||||||
|
stem>=1.8.0
|
||||||
|
paho-mqtt>=1.5.1
|
||||||
|
PySocks>=1.7.1
|
25
setup.py
Normal file
25
setup.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import setuptools
|
||||||
|
|
||||||
|
with open("README.md", "r") as fh:
|
||||||
|
long_description = fh.read()
|
||||||
|
|
||||||
|
setuptools.setup(
|
||||||
|
name="torch-agent",
|
||||||
|
version="0.0.1",
|
||||||
|
author="B.J. Dweck",
|
||||||
|
author_email="bjdweck@gmail.com",
|
||||||
|
description="TORch: Iluminate the Way to your Node",
|
||||||
|
long_description=long_description,
|
||||||
|
long_description_content_type="text/markdown",
|
||||||
|
url="https://git.rudefox.io/bj/torch-agent",
|
||||||
|
packages=setuptools.find_packages(),
|
||||||
|
entry_points = {
|
||||||
|
'console_scripts': ['torch-agent=torch_agent:main'],
|
||||||
|
},
|
||||||
|
classifiers=[
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
],
|
||||||
|
python_requires='>=3.6',
|
||||||
|
)
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
from stem.control import Controller
|
|
||||||
import stem.connection
|
|
||||||
import paho.mqtt.client as mqtt
|
|
||||||
import ssl
|
|
||||||
import socks
|
|
||||||
import socket
|
|
||||||
import json
|
|
||||||
import configparser
|
|
||||||
import argparse
|
|
||||||
from datetime import datetime
|
|
||||||
from os import environ
|
|
||||||
|
|
||||||
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)')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
configPath = args.configPath
|
|
||||||
|
|
||||||
if "TORCH_CONFIG_DIR" in environ:
|
|
||||||
configPath = environ.get("TORCH_CONFIG_DIR")
|
|
||||||
|
|
||||||
if not configPath.endswith("/"):
|
|
||||||
configPath = configPath + "/"
|
|
||||||
|
|
||||||
print("Using torch configuration path: " + configPath)
|
|
||||||
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
config.read(configPath + "torch.conf")
|
|
||||||
|
|
||||||
torProxyPort = config['tor'].getint('ProxyPort', fallback = 9050)
|
|
||||||
torControllerPort = config['tor'].getint('ControllerPort', fallback = 9051)
|
|
||||||
|
|
||||||
sshPort = 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))
|
|
||||||
|
|
||||||
mqttRequireCertificate = mqttConfig.getboolean(
|
|
||||||
'RequireCertificate',
|
|
||||||
fallback = False)
|
|
||||||
|
|
||||||
mqttCaFile = configPath + mqttConfig.get('CaFile')
|
|
||||||
mqttCertFile = configPath + mqttConfig.get('CertFile')
|
|
||||||
mqttKeyFile = configPath + mqttConfig.get('KeyFile')
|
|
||||||
|
|
||||||
with Controller.from_port(port = torControllerPort) as controller:
|
|
||||||
|
|
||||||
protocolInfo = stem.connection.get_protocolinfo(controller)
|
|
||||||
|
|
||||||
stem.connection.authenticate_safecookie(
|
|
||||||
controller,
|
|
||||||
protocolInfo.cookie_path)
|
|
||||||
|
|
||||||
print("Connected to Tor on port %s" % (torControllerPort))
|
|
||||||
|
|
||||||
service = controller.create_ephemeral_hidden_service(
|
|
||||||
sshPort,
|
|
||||||
detached = True)
|
|
||||||
|
|
||||||
onionAddress = "%s.onion" % (service.service_id)
|
|
||||||
|
|
||||||
print("Created Tor Hidden Service for local port %s at %s" % (sshPort, onionAddress))
|
|
||||||
|
|
||||||
payload = {
|
|
||||||
'clientId': clientID,
|
|
||||||
'timestamp': datetime.now().strftime("%d-%b-%Y (%H:%M:%S.%f)"),
|
|
||||||
'onionAddress': onionAddress,
|
|
||||||
'sshPort': sshPort
|
|
||||||
}
|
|
||||||
|
|
||||||
client = mqtt.Client()
|
|
||||||
protocol = "mqtt"
|
|
||||||
|
|
||||||
if mqttRequireCertificate:
|
|
||||||
client.tls_set(
|
|
||||||
ca_certs = mqttCaFile,
|
|
||||||
certfile = mqttCertFile,
|
|
||||||
keyfile = mqttKeyFile,
|
|
||||||
cert_reqs=ssl.CERT_REQUIRED)
|
|
||||||
protocol = "mqtts"
|
|
||||||
|
|
||||||
if mqttBrokerHost.endswith(".onion"):
|
|
||||||
client.proxy_set(proxy_type=socks.SOCKS5, proxy_addr="localhost", proxy_port=torProxyPort)
|
|
||||||
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.disconnect()
|
|
||||||
print("Disconnected from MQTT Broker")
|
|
1
torch_agent/__init__.py
Normal file
1
torch_agent/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
__version__ = "0.0.1"
|
5
torch_agent/__main__.py
Normal file
5
torch_agent/__main__.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import sys
|
||||||
|
from torch_agent import main
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
97
torch_agent/torch_agent.py
Executable file
97
torch_agent/torch_agent.py
Executable file
|
@ -0,0 +1,97 @@
|
||||||
|
from stem.control import Controller
|
||||||
|
import stem.connection
|
||||||
|
import paho.mqtt.client as mqtt
|
||||||
|
import ssl
|
||||||
|
import socks
|
||||||
|
import socket
|
||||||
|
import json
|
||||||
|
import configparser
|
||||||
|
import argparse
|
||||||
|
from datetime import datetime
|
||||||
|
from os import environ
|
||||||
|
|
||||||
|
def main():
|
||||||
|
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)')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
configPath = args.configPath
|
||||||
|
|
||||||
|
if "TORCH_CONFIG_DIR" in environ:
|
||||||
|
configPath = environ.get("TORCH_CONFIG_DIR")
|
||||||
|
|
||||||
|
if not configPath.endswith("/"):
|
||||||
|
configPath = configPath + "/"
|
||||||
|
|
||||||
|
print("Using torch configuration path: " + configPath)
|
||||||
|
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(configPath + "torch.conf")
|
||||||
|
|
||||||
|
torProxyPort = config['tor'].getint('ProxyPort', fallback = 9050)
|
||||||
|
torControllerPort = config['tor'].getint('ControllerPort', fallback = 9051)
|
||||||
|
|
||||||
|
sshPort = 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))
|
||||||
|
|
||||||
|
mqttRequireCertificate = mqttConfig.getboolean(
|
||||||
|
'RequireCertificate',
|
||||||
|
fallback = False)
|
||||||
|
|
||||||
|
mqttCaFile = configPath + mqttConfig.get('CaFile')
|
||||||
|
mqttCertFile = configPath + mqttConfig.get('CertFile')
|
||||||
|
mqttKeyFile = configPath + mqttConfig.get('KeyFile')
|
||||||
|
|
||||||
|
with Controller.from_port(port = torControllerPort) as controller:
|
||||||
|
|
||||||
|
protocolInfo = stem.connection.get_protocolinfo(controller)
|
||||||
|
|
||||||
|
stem.connection.authenticate_safecookie(
|
||||||
|
controller,
|
||||||
|
protocolInfo.cookie_path)
|
||||||
|
|
||||||
|
print("Connected to Tor on port %s" % (torControllerPort))
|
||||||
|
|
||||||
|
service = controller.create_ephemeral_hidden_service(sshPort, detached = True)
|
||||||
|
|
||||||
|
onionAddress = "%s.onion" % (service.service_id)
|
||||||
|
|
||||||
|
print("Created Tor Hidden Service for local port %s at %s" % (sshPort, onionAddress))
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
'clientId': clientID,
|
||||||
|
'timestamp': datetime.now().strftime("%d-%b-%Y (%H:%M:%S.%f)"),
|
||||||
|
'onionAddress': onionAddress,
|
||||||
|
'sshPort': sshPort
|
||||||
|
}
|
||||||
|
|
||||||
|
client = mqtt.Client()
|
||||||
|
protocol = "mqtt"
|
||||||
|
|
||||||
|
if mqttRequireCertificate:
|
||||||
|
client.tls_set(
|
||||||
|
ca_certs = mqttCaFile,
|
||||||
|
certfile = mqttCertFile,
|
||||||
|
keyfile = mqttKeyFile,
|
||||||
|
cert_reqs=ssl.CERT_REQUIRED)
|
||||||
|
protocol = "mqtts"
|
||||||
|
|
||||||
|
if mqttBrokerHost.endswith(".onion"):
|
||||||
|
client.proxy_set(proxy_type=socks.SOCKS5, proxy_addr="localhost", proxy_port=torProxyPort)
|
||||||
|
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.disconnect()
|
||||||
|
print("Disconnected from MQTT Broker")
|
Loading…
Reference in New Issue
Block a user