Created
February 20, 2017 09:57
-
-
Save felipedau/7c4b9bb8f9e553cf7db7013a71abbccd to your computer and use it in GitHub Desktop.
Ephemeral hidden services with stem and txtorcon
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
from twisted.internet import reactor, defer | |
from twisted.internet.endpoints import TCP4ServerEndpoint | |
from twisted.web import server, resource | |
from twisted.internet.task import react | |
from stem.control import Controller | |
CONTROL_PORT = 9051 | |
LISTEN_IP = '127.0.0.1' | |
HS_PORT = 80 | |
SV_PORT = 8080 | |
WAIT_TIME = 40 | |
class Simple(resource.Resource): | |
isLeaf = True | |
def render_GET(self, request): | |
return ("<html>Hello, world! I'm a stem ephemeral hidden " | |
"service running on a non-Whonix system!</html>") | |
def start_site(reactor): | |
print "Starting site" | |
site = server.Site(Simple()) | |
sv_endpoint = TCP4ServerEndpoint(reactor, SV_PORT, interface=LISTEN_IP) | |
return sv_endpoint.listen(site) | |
@defer.inlineCallbacks | |
def main(reactor): | |
yield start_site(reactor) | |
d = defer.Deferred() | |
try: | |
with open('key', 'r') as f: | |
key_info = f.readline().strip() | |
except IOError: | |
key_info = key_type = key = None | |
else: | |
key_type, key = key_info.split(':') | |
controller = Controller.from_port(port=CONTROL_PORT) | |
try: | |
controller.authenticate() | |
except Exception as e: | |
print e.title, e.message | |
else: | |
hs_string = '%s %s:%d' % (HS_PORT, LISTEN_IP, SV_PORT) | |
print "Adding ephemeral service", hs_string | |
print "(this can take some time; please be patient)" | |
response = controller.create_ephemeral_hidden_service( | |
ports={HS_PORT: hs_string.split()[1]}, | |
key_type=key_type or 'NEW', | |
key_content=key or 'BEST', | |
await_publication=True) | |
key_type = key_type or response.private_key_type | |
key = key or response.private_key | |
if not key_info: | |
with open('key', 'w') as f: | |
f.write('{}:{}'.format(key_type, key)) | |
service_id = response.content()[0][2].split('=')[1] | |
hostname = service_id + '.onion' | |
print "Added ephemeral HS to Tor:", hostname | |
def remove(): | |
print "Removing the hiddenservice" | |
print 'Key type was', key_type | |
print "Private key was" | |
print key | |
controller.remove_ephemeral_hidden_service(service_id) | |
d.callback(None) | |
reactor.callLater(WAIT_TIME, remove) | |
print "waiting {} seconds".format(WAIT_TIME) | |
yield d | |
react(main) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
from twisted.internet import reactor, defer | |
from twisted.internet.endpoints import TCP4ClientEndpoint, TCP4ServerEndpoint | |
from twisted.web import server, resource | |
from twisted.internet.task import react | |
import txtorcon | |
CONTROL_PORT = 9051 | |
LISTEN_IP = '127.0.0.1' | |
HS_PORT = 80 | |
SV_PORT = 8080 | |
WAIT_TIME = 40 | |
class Simple(resource.Resource): | |
isLeaf = True | |
def render_GET(self, request): | |
return ("<html>Hello, world! I'm a txtorcon ephemeral hidden " | |
"service running on a non-Whonix system!</html>") | |
def start_site(reactor): | |
print "Starting site" | |
site = server.Site(Simple()) | |
sv_endpoint = TCP4ServerEndpoint(reactor, SV_PORT, interface=LISTEN_IP) | |
return sv_endpoint.listen(site) | |
@defer.inlineCallbacks | |
def main(reactor): | |
yield start_site(reactor) | |
d = defer.Deferred() | |
try: | |
with open('key', 'r') as f: | |
key_info = f.readline().strip() | |
except IOError: | |
key_info = None | |
ep = TCP4ClientEndpoint(reactor, '127.0.0.1', CONTROL_PORT) | |
tor = yield txtorcon.connect(reactor, ep) | |
print("Connected to {tor} via localhost:{port}".format( | |
tor=tor, | |
port=CONTROL_PORT, | |
)) | |
hs_string = '%s %s:%d' % (HS_PORT, LISTEN_IP, SV_PORT) | |
print "Adding ephemeral service", hs_string | |
print "(this can take some time; please be patient)" | |
hs = txtorcon.EphemeralHiddenService([hs_string], | |
key_info or 'NEW:BEST') | |
yield hs.add_to_tor(tor._protocol) | |
print "Added ephemeral HS to Tor:", hs.hostname | |
if not key_info: | |
with open('key', 'w') as f: | |
f.write(hs.private_key) | |
@defer.inlineCallbacks | |
def remove(): | |
print "Removing the hiddenservice. Private key was" | |
print key_info or hs.private_key | |
yield hs.remove_from_tor(tor._protocol) | |
d.callback(None) | |
reactor.callLater(WAIT_TIME, remove) | |
print "waiting {} seconds".format(WAIT_TIME) | |
yield d | |
react(main) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment