Over the River and Through the Wood
===================================

`Hidden services <https://www.torproject.org/docs/hidden-services.html.en>`_ give you a way of providing a service without exposing your address. These services are only accessible through Tor or `Tor2web <https://tor2web.org/>`_, and useful for a surprising number of things...

  * Hosting an anonymized site. This is usually the first thing that comes to mind, and something we'll demonstrate in a sec.
  * Providing an endpoint Tor users can reach without exiting the Tor network. This eliminates the risk of an unreliable or malicious exit getting in the way. A great example of this is `Facebook <http://arstechnica.com/security/2014/10/facebook-offers-hidden-service-to-tor-users/>`_.
  * Personal services. For instance you can host your home SSH server as a hidden service to prevent eavesdroppers from knowing where you live while traveling abroad.

Hidden services can be `configured through your torrc <https://www.torproject.org/docs/tor-manual.html.en#_hidden_service_options>`_, but Stem also provides some methods to easily work with them...

  * :func:`~stem.control.Controller.create_hidden_service`
  * :func:`~stem.control.Controller.remove_hidden_service`
  * :func:`~stem.control.Controller.get_hidden_service_conf`
  * :func:`~stem.control.Controller.set_hidden_service_conf`

The main threat to your anonymity when running a hidden service is the service itself. Debug information for instance might leak your real address, undermining what Tor provides. This includes the following example, **do not rely on it not to leak**.

But with that out of the way lets take a look at a simple `Flask <http://flask.pocoo.org/>`_ example based on one by `Jordan Wright <https://jordan-wright.github.io/blog/2014/10/06/creating-tor-hidden-services-with-python/>`_...

::

  import os
  import shutil

  from stem.control import Controller
  from flask import Flask

  app = Flask(__name__)


  @app.route('/')
  def index():
    return "<h1>Hi Grandma!</h1>"


  print ' * Connecting to tor'

  with Controller.from_port() as controller:
    controller.authenticate()

    # All hidden services have a directory on disk. Lets put ours in tor's data
    # directory.

    hidden_service_dir = os.path.join(controller.get_conf('DataDirectory', '/tmp'), 'hello_world')

    # Create a hidden service where visitors of port 80 get redirected to local
    # port 5000 (this is where Flask runs by default).

    print " * Creating our hidden service in %s" % hidden_service_dir
    result = controller.create_hidden_service(hidden_service_dir, 80, target_port = 5000)

    # The hostname is only available when we can read the hidden service
    # directory. This requires us to be running with the same user as tor.

    if result.hostname:
      print " * Our service is available at %s, press ctrl+c to quit" % result.hostname
    else:
      print " * Unable to determine our service's hostname, probably due to being unable to read the hidden service directory"

    try:
      app.run()
    finally:
      # Shut down the hidden service and clean it off disk. Note that you *don't*
      # want to delete the hidden service directory if you'd like to have this
      # same *.onion address in the future.

      print " * Shutting down our hidden service"
      controller.remove_hidden_service(hidden_service_dir)
      shutil.rmtree(hidden_service_dir)

Now if we run this...

::

  % python example.py 
   * Connecting to tor
   * Creating our hidden service in /home/atagar/.tor/hello_world
   * Our service is available at uxiuaxejc3sxrb6i.onion, press ctrl+c to quit
   * Running on http://127.0.0.1:5000/
  127.0.0.1 - - [15/Dec/2014 13:05:43] "GET / HTTP/1.1" 200 -
   * Shutting down our hidden service

... we'll have a service we can visit via the `Tor Browser Bundle <https://www.torproject.org/download/download-easy.html.en>`_...

.. image:: /_static/hidden_service.png

