[tor-dev] RFC: Ephemeral Hidden Services via the Control Port

Yawning Angel yawning at schwanenlied.me
Sat Feb 14 00:45:24 UTC 2015


Hi,

The Warning: DO NOT USE MY BRANCH YET, IT HAS HAD MINIMAL TESTING AND
             REVIEW.  IT IS NOT DONE.  IT WILL BROADCAST YOUR SECRETS
             TO THE NSA'S ORBITAL SPACE STATION.

Trac Ticket: https://trac.torproject.org/projects/tor/ticket/6411
Branch: https://github.com/Yawning/tor/compare/feature6411

With that out of the way, I've been poking at implementing a way to add
hidden services at runtime via the control port.  I'm calling this
"ephemeral hidden services" because the HS state is not written out to
disk, and they disappear when the tor damon is shutdown.

Yes, this means that if you run "kittensomgmewmew.onion" and are scared
of the NSA's persistent attempts to extract your hidden service key,
via ultrasonic laser beamed from their satellites, you could run your
tor instance entirely in a ram disk, and load the HS key manually each
time from a USB token you wear around your neck.

What I've come up with looks like this:

  ADD_EPH_HS - Adds a new ephemeral hidden service.

    The syntax is:

      "ADD_EPH_HS" keytype:keyblob SP 1*(port SP addrPort) CRLF
      keytype = "RSA1024", "NEW"
      keyblob = opaque ascii serialized key material, or an algorithm
                specifier, in the case of "keytype" == "NEW".
      port = the "VIRTPORT"
      addrPort = the "TARGET"

    A hidden service is created using the key and list of port/targets,
    that will persist till configuration reload or the termination of
    the tor process.

    The currently supported keytypes and keyblobs are:

      "RSA1024" - The keyblob contains the Base64 encoding of the
        PKCS#1 layout DER representation of a 1024 bit RSA private
        key.

      "NEW" - The tor instance should generate a key with the keytype
        specified in the keyblob parameter.  A type of "BEST" will
        generate a key using the best supported algorithm.

    Returns:

      "250-ServiceID=serviceID" - The hidden service's onion address
        without the ".onion" suffix.

      "250-PrivateKey=keytype:keyblob" - The newly generated hidden
        service's private key, if a keytype of "NEW" was specified.

      "250 OK" - Everything went well.

    Proper key management, is left as an exercise for the application
    invoking the controller command.

  DEL_EPH_HS - Removes an existing ephemeral hidden service.

    The syntax is:

      "DEL_EPH_HS" serviceID CRLF
      serviceID = the hidden service identifier, without the trailing
                  ".onion" suffix

    The hidden service specified by the given service ID is removed, and
    the intro points are closed.  Existing connections are left as is,
    and it is up to the application to close them if it wishes to do so.

Examples:

 * Adding a new ephemeral hidden service, with a pre-generated RSA key:
    > ADD_EPH_HS RSA1024:[Base64 blob] 80 127.0.0.1:8080
    < 250-ServiceID=blahblahblahblah
    < 250 OK

   Hidden service is reachable at blahblahblahblah.onion:80

  * Adding a new ephemeral hidden service, tor generates a new RSA key:
    > ADD_EPH_HS NEW:RSA1024 22 127.0.0.1:22
    < 250-ServiceID=hogehogehogehoge
    < 250-PrivateKey=RSA1024:[Base64 blob]
    < 250 OK

    Hidden service is reachable at hogehogehogehoge.onion:22.  At a
    later date, the value passed back as "PrivateKey" can be used to
    re-create the hidden service.

  * Add a new ephemeral hidden service, tor picks the algorithm:
    > ADD_EPH_HS NEW:BEST 1245 192.168.1.5:23
    < 250-ServiceID=hemohemohemohemo
    < 250-PrivateKey=Ed25519:[Base64 blob]
    < 250 OK

    Hidden service is reachable at hemohemohemohemo:23. (nb: Ed25519 key
    support is not actually implemented yet, and is used as an example
    of a better algorithm.)

  * Remove the hidden service configured in the first example:
    > DEL_EPH_HS blahblahblahblah
    < 250 OK

  Note: ADD_EPH_HS can take more than one VIRTPORT/TARGET pair at once,
  the examples only show one pair for brevity.

This does not support `HiddenServiceAuthorizeClient` yet in any way
(neither basic nor stealth).  It may in the future, but coming up with
a sane interface for it is way more pain than I am willing to
self-inflict at the moment.

Design question that I want feedback on, primarily from control port
library maintainers, and authors of applications that use the control
port:

 * meejah suggested that ephemeral hidden services should have their
   lifetime tied to the originating control port connection.  I think
   this is a good idea, but this would be the only control port command
   that does this sort of thing.

   My motivations for strongly considering implementing this is that, I
   don't think that adding a command to enumerate hidden services is a
   good idea (SketchORChat has no business in seeing what hidden
   services JankORFileSharing is using), and that this will automate
   cleanup in the event of an application crashing, or not removing
   it's hidden services before terminating.

 * Does this interface expose enough functionality, in a way that is
   intuitive and easy to use? (The initial version I was planning on
   proposing made key generation entirely the application's problem,
   but nickm convinced me otherwise).

Questions, comments, feedback appreciated,

-- 
Yawning Angel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.torproject.org/pipermail/tor-dev/attachments/20150214/e4ce440c/attachment.sig>


More information about the tor-dev mailing list