Opened 3 years ago

Closed 2 years ago

#14320 closed enhancement (user disappeared)

Add Tor CLI tool

Reported by: federico3 Owned by: atagar
Priority: Medium Milestone:
Component: Core Tor/Stem Version:
Severity: Keywords:
Cc: Actual Points:
Parent ID: Points:
Reviewer: Sponsor:


A simple CLI tool based on Stem to create/delete/list hidden services.
It could be part of the Stem package.

Child Tickets

Attachments (3) (7.2 KB) - added by federico3 3 years ago.
Stem CLI v0.0.1 (2.9 KB) - added by federico3 3 years ago.
Simple functional test for the hidden service CLI
stem_add_hidden_service_auth.patch (5.0 KB) - added by federico3 3 years ago.

Download all attachments as: .zip

Change History (11)

comment:1 Changed 3 years ago by atagar

Neat! Maybe contact tor-dev@ to get thoughts on if folks would find this useful, and possible directions to go with it? I could see us possibly merging this with the tor-prompt, or keeping it as a separate script.

Iirc meejah's carml is another cli that includes some HS functionality, so we could take a peek at that too for ideas.

Changed 3 years ago by federico3

Attachment: added

Stem CLI v0.0.1

Changed 3 years ago by federico3

Simple functional test for the hidden service CLI

Changed 3 years ago by federico3


comment:2 Changed 3 years ago by atagar

Hi federico3, sorry this went so long without a reply! I'd be up for adding this to Stem if...

  1. We follow a similar patter to the tor-prompt (maybe calling this tor-hidden-service so we keep everything under a tor-* namespace?). This means a Stem patch that follows its style, and ideally is similar to the tor-prompt code (similar argument parsing, help output, tests). I'd be happy to work with you on this if we want to go this route.
  1. Solicit ideas from tor-dev@. I mentioned this earlier but don't think I've seen an email.

Here's some quick thoughts from a first glance.

hostname_fn = os.path.join(data_dir, dname, 'hostname')

Huh. When I added the hostname to create_hidden_service() I was sorely tempted to include it in get_hidden_service_conf() but wasn't a great fit due to blending tor-provided configuration data with stuff read from disk.

Right option is to have tor include the hostname in its GETCONF response (and maybe the key too). If that's a no-go then I'd be up for having a Stem method for getting this. For instance 'get_hidden_service_resource(hs_dir, filename)'. But expanding tor would definitely be better since this has been a pain point for years, and would be more reliable (*grumble* permissions *grumble*).

controller, data_dir = connect()
hidden_service_dir = os.path.join(data_dir,

Just to let you know if a hidden service path is relative then it's relative of the tor process' cwd, not its data directory. In our create_hidden_service() we expand one of these paths...

if not os.path.isabs(hs_path):
  cwd = stem.util.system.cwd(controller.get_pid(None))

  if cwd:
    hs_path = stem.util.system.expand_path(hs_path, cwd)

ap = ArgumentParser()

So, this is what ArgumentParser looks like. For what it's worth here's the pattern I used for tor-prompt and arm...

Personally I like it, but I do a lot more validation and customization than this.

comment:3 Changed 3 years ago by atagar

Hi federico3, it's been a couple weeks - would you care to proceed with this?

comment:4 Changed 3 years ago by federico3

atagar: as discussed on IRC, I think it make sense to see where the thread on ephemeral onion services on tor-dev@ goes.
This script is a good candidate to act as a wrapper for other applications and set up an ephemeral service for the execution.
Related to #6411

Last edited 3 years ago by federico3 (previous) (diff)

comment:5 Changed 2 years ago by atagar

Hi federico3, it's been a while. Just another bump to see where we'd like to go with this.

comment:6 Changed 2 years ago by atagar

Hi federico3, sorry about that! Missed that this included a Stem patch. Pushed a revised change that adds auth_type and client_names to create_hidden_service(). The hostname file's format changes when you provide client names so this adds a new hostname_for_client mapping of 'client => address'.

I'd be amenable to adding the cookie contents to the output of create_hidden_service() (thought about it when I first made the method, but decided to wait until we had a use for it). However, I'd rather avoid adding a new method for this unless there's a good reason for it. Reading from disk is a hack I hope will largely go away with the introduction of ephemeral services.

As for your script itself I'm a tad wary of adding it until we know how useful it is to users. This is why I keep nudging you to ask on tor-dev@ but happy to wait for the ephemeral services. If we do add it then I'd encourage you to give it a nice writeup on...

comment:7 Changed 2 years ago by atagar

Probably time for another periodic bump. :P

We now have ephemeral hidden services and your Stem patch - how would you like to proceed?

comment:8 Changed 2 years ago by atagar

Resolution: user disappeared
Status: newclosed
Note: See TracTickets for help on using tickets.