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

art at torproject.org art at torproject.org
Mon May 30 13:44:55 UTC 2016


commit 8ef4dc35b303d0b1e7d3e5ee0cc8a0f3e2eac240
Author: Joe Landers <joe at 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)
+





More information about the tor-commits mailing list