[oonib/master] easily swappable {TCP, TLS, onion} endpoints

commit 8ef4dc35b303d0b1e7d3e5ee0cc8a0f3e2eac240 Author: Joe Landers <joe@joelanders.net> Date: Wed May 4 22:45:37 2016 +0200 easily swappable {TCP, TLS, onion} endpoints --- gen-ssl-key-cert.sh | 13 ++++++ oonib.conf.example | 13 +++++- oonib/onion.py | 10 +---- oonib/oonibackend.py | 125 ++++++++++++++++++++++++++++----------------------- 4 files changed, 93 insertions(+), 68 deletions(-) diff --git a/gen-ssl-key-cert.sh b/gen-ssl-key-cert.sh new file mode 100755 index 0000000..2a50766 --- /dev/null +++ b/gen-ssl-key-cert.sh @@ -0,0 +1,13 @@ +#!/bin/sh +set -eu + +if [ ! -d private ] +then + mkdir private +fi + +openssl req -x509 -newkey rsa:2048 \ + -keyout private/ssl-key.pem -out private/ssl-cert.pem \ + -days 400 -nodes -subj '/CN=selfie' + +cat private/ssl-key.pem private/ssh-cert.pem > private/ssl-key-and-cert.pem diff --git a/oonib.conf.example b/oonib.conf.example index 7821dc1..0a5f4a5 100644 --- a/oonib.conf.example +++ b/oonib.conf.example @@ -7,7 +7,6 @@ main: bouncer_file: data/bouncer.yaml logfile: null - tor_datadir: null database_uri: 'sqlite://oonib_test_db.db' db_threadpool_size: 10 tor_binary: null @@ -28,7 +27,17 @@ main: debug: false stale_time: 3600 - tor_hidden_service: true + tor_hidden_service: false + tor_datadir: test_datadir + + bouncer_endpoints: + - {type: tls, port: 10443, cert: "private/ssl-key-and-cert.pem"} + - {type: tcp, port: 10080} + - {type: onion, hsdir: bouncer} + + collector_endpoints: + - {type: tls, port: 11443, cert: "private/ssl-key-and-cert.pem"} + report_file_template: '{iso8601_timestamp}-{test_name}-{report_id}-{probe_asn}-{probe_cc}-probe-0.2.0.{ext}' helpers: http-return-json-headers: diff --git a/oonib/onion.py b/oonib/onion.py index c06dc6b..262e672 100644 --- a/oonib/onion.py +++ b/oonib/onion.py @@ -53,7 +53,7 @@ def txSetupFailed(failure): log.err("Setup failed") log.exception(failure) -def startTor(torconfig): +def configTor(torconfig): def updates(prog, tag, summary): print("%d%%: %s" % (prog, summary)) @@ -89,11 +89,3 @@ def startTor(torconfig): config.main.socks_port = socks_port torconfig.save() - - if config.main.tor_binary is not None: - d = launch_tor(torconfig, reactor, - tor_binary=config.main.tor_binary, - progress_updates=updates) - else: - d = launch_tor(torconfig, reactor, progress_updates=updates) - return d diff --git a/oonib/oonibackend.py b/oonib/oonibackend.py index a392b82..1c6a23a 100644 --- a/oonib/oonibackend.py +++ b/oonib/oonibackend.py @@ -11,14 +11,14 @@ from distutils.version import LooseVersion from oonib.api import ooniBackend, ooniBouncer from oonib.config import config -from oonib.onion import startTor +from oonib.onion import configTor from oonib.testhelpers import dns_helpers, ssl_helpers from oonib.testhelpers import http_helpers, tcp_helpers import os from twisted.application import internet, service -from twisted.internet import reactor +from twisted.internet import reactor, endpoints, defer, ssl, protocol from twisted.names import dns from txtorcon import TCPHiddenServiceEndpoint, TorConfig @@ -102,60 +102,71 @@ if config.helpers['http-return-json-headers'].port: multiService.addService(http_return_request_helper) http_return_request_helper.startService() -# add the tor collector service here +def getHSEndpoint(endpoint_config): + hsdir = os.path.join(torconfig.DataDirectory, endpoint_config['hsdir']) + if LooseVersion(txtorcon_version) >= LooseVersion('0.10.0'): + return TCPHiddenServiceEndpoint.global_tor(reactor, + 80, + hidden_service_dir=hsdir) + else: + return TCPHiddenServiceEndpoint.global_tor(reactor, + 80, + data_dir=hsdir) + +def getTCPEndpoint(endpoint_config): + return endpoints.TCP4ServerEndpoint(reactor, endpoint_config['port']) + +def getTLSEndpoint(endpoint_config): + with open(endpoint_config['cert'], 'r') as f: + cert_data = f.read() + certificate = ssl.PrivateCertificate.loadPEM(cert_data) + print certificate.inspect() + return endpoints.SSL4ServerEndpoint(reactor, + endpoint_config['port'], + certificate.options()) + +def getEndpoint(endpoint_config): + if endpoint_config['type'] == 'onion': + return getHSEndpoint(endpoint_config) + elif endpoint_config['type'] == 'tcp': + return getTCPEndpoint(endpoint_config) + elif endpoint_config['type'] == 'tls': + return getTLSEndpoint(endpoint_config) + else: + raise Exception("unknown endpoint type") + +class Echo(protocol.Protocol): + def dataReceived(self, data): + self.transport.write('server echoes ' + data) + +def createService(endpoint, role, endpoint_config): + if role == 'bouncer': + factory = ooniBouncer + elif role == 'collector': + factory = ooniBackend + else: + raise Exception("unknown service type") + + service = internet.StreamServerEndpointService( + endpoint, factory + ) + service.setName("-".join([endpoint_config['type'], role])) + multiService.addService(service) + service.startService() + if config.main.tor_hidden_service: torconfig = TorConfig() - d = startTor(torconfig) - - def getHSEndpoint(data_dir): - if LooseVersion(txtorcon_version) >= LooseVersion('0.10.0'): - return TCPHiddenServiceEndpoint(reactor, - torconfig, - 80, - hidden_service_dir=data_dir) - else: - return TCPHiddenServiceEndpoint(reactor, - torconfig, - 80, - data_dir=data_dir) - - def printOnionEndpoint(endpointService): - print ("Exposed %s Tor hidden service on httpo://%s" % - (endpointService.name, endpointService.endpoint.onion_uri)) - - def addCollector(torControlProtocol): - data_dir = os.path.join(torconfig.DataDirectory, 'collector') - collector_service = internet.StreamServerEndpointService( - getHSEndpoint(data_dir), ooniBackend - ) - collector_service.setName('collector') - multiService.addService(collector_service) - collector_service.startService() - return collector_service - - d.addCallback(addCollector) - d.addCallback(printOnionEndpoint) - - if ooniBouncer: - def addBouncer(torControlProtocol): - data_dir = os.path.join(torconfig.DataDirectory, 'bouncer') - bouncer_service = internet.StreamServerEndpointService( - getHSEndpoint(data_dir), ooniBouncer - ) - bouncer_service.setName('bouncer') - multiService.addService(bouncer_service) - bouncer_service.startService() - return bouncer_service - - d.addCallback(addBouncer) - d.addCallback(printOnionEndpoint) -else: - if ooniBouncer: - bouncer_service = internet.TCPServer(8888, ooniBouncer, - interface="127.0.0.1") - multiService.addService(bouncer_service) - bouncer_service.startService() - collector_service = internet.TCPServer(8889, ooniBackend, - interface="127.0.0.1") - multiService.addService(collector_service) - collector_service.startService() + configTor(torconfig) + +if config.main.bouncer_endpoints: + for endpoint_config in config.main.bouncer_endpoints: + print "Starting bouncer with config %s" % endpoint_config + endpoint = getEndpoint(endpoint_config) + createService(endpoint, 'bouncer', endpoint_config) + +if config.main.bouncer_endpoints: + for endpoint_config in config.main.collector_endpoints: + print "Starting collector with config %s" % endpoint_config + endpoint = getEndpoint(endpoint_config) + createService(endpoint, 'collector', endpoint_config) +
participants (1)
-
art@torproject.org