[Solved] Running Subdomains on .onion services

(Conor Burns) #12

Thanks for you reply I really appreciate your help!
I’ll try to do my best at providing the required configs and errors:


RunAsDaemon 1
HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80
HiddenServicePort 80
HiddenServicePort 80

Is this the right way to run multiple Subdomains for the same root domain with Tor?


(onion) {

  log /var/log/caddy/access.log {
    ipmask ffff:ffff:ffff:fff0::
  errors /var/log/caddy/error.log
  tls off
http://www.conorblc245kc43q.onion:80 :8868 {
  import onion
  redir https://http://conorblc245kc43q.onion:80{uri}
http://conorblc245kc43q.onion:80 :8869 {
  import onion
  root /var/www/onion
http://pgp.conorblc245kc43q.onion:80 :8867 {
  import onion
  root /var/www/pgp

Tor behavior when accessing http://conorblc245kc43q.onion: Everything alright

Tor behavior when accessing http://pgp.conorblc245kc43q.onion: Wrong site - serving the root site (not redirecting just serving the same content)

Tor behavior when accessing http://www.conorblc245kc43q.onion: Everything alright - redirecting to root

Now when I restart caddy it gets really crazy.
When I visit root everything is fine but when I visit www.xxxx.onion I get the content for the pgp subdomain and for the pgp subdomain I get the root redirect what www would normally do. And if refresh the site multiple times it will so sometimes load the root or the pgp or the www. It’s completely random.

I’m guessing that Tor listens on 80 on the outside and redirects that to one of the 3 ports randomly and then caddy does everything right and serves the content for that specified port. How would it be possible to fix Tor in a way that it gives caddy the right port.

(Matthew Fay) #13

Yeah, this is the impression that I’m getting.

I think it’s best to go simpler, not more complex. Lets strip down all the port confusion; just use 80 for everything, all subdomains.


RunAsDaemon 1
HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80

And then use Caddy to differentiate by hostname.

http://conorblc245kc43q.onion {
  # Config for root domain

http://www.conorblc245kc43q.onion {
  # Config for www subdomain

http://pgp.conorblc245kc43q.onion {
  # Config for pgp subdomain

(Conor Burns) #14

Ok great that works but why is caddy now able to listen on port 80 on 3 server blocks?

(Matthew Fay) #15

It was doing that in your earlier configurations, too. It’s generally referred to as virtual hosting, or vhosts. It combines all the sites that want to be served on the same port into one HTTP listener on port 80, and then when a client makes a request, Caddy uses the details of that request to determine which site to serve, much like other modern web servers.

(Conor Burns) #16

Ahh now that is genius! And it’s not able to do that for different ports am I right?

(Matthew Fay) #17

I mean, you can certainly serve the same site on different ports!

For example, this would serve your site over HTTP on ports 80 as well as 8080:

http://example.com, http://example.com:8080 {
  # Site configuration

You can serve different site versions for the same hostname on different ports instead, if you like:

http://example.com {
  # Config for port 80

http://example.com:8080 {
  # Config for port 8080

You can even have Caddy serve a different site entirely depending on which path the client requested.

http://example.com {
  # This site gets served for most requests

http://example.com/foo {
  # This site gets served if the path starts with `/foo`

The four aspects of the request you can use to determine which site to serve are the hostname (e.g. example.com, or subdomain.example.com), the path (e.g. /foo), the scheme (i.e. HTTP or HTTPS), and the port.

One important caveat: Caddy can’t have multiple schemes on the same port. You can’t serve a HTTPS site on a port that already serves HTTP.

(Conor Burns) #18

That’s great and if I want to serve
Would this still work with Tor or do I have to listen on 80 so caddy doesn’t complain that it’s not listening and 8080 so Tor can listen?

(Matthew Fay) #19

I’m not sure what ports Tor actually uses to communicate, but I’m assuming it’s treated as an additional interface of some kind.

Anyway, if you move all your sites to 8080, I think you’ll need to edit your .torrc.

Try HiddenServicePort 80 if you’re going to have Caddy listen on port 8080.

(Conor Burns) #20

Yeah that’s what I would love to do bit if I remember correctly caddy has to listen on 80 too so it doesn’t complain about not listening on that interface

(Matthew Fay) #21

You might be thinking of Automatic HTTPS.

When you’re letting Caddy manage your certificates, in order to requisition them, it needs to bind to ports 80 and/or 443. There’s ways of getting around that and still getting certificates (port detouring, DNS challenge, etc) but I don’t think they’ll be relevant to you; you’re only serving on HTTP, so Automatic HTTPS is disabled for those sites.

Unless you’re running another site in your Caddyfile that DOES quality for Automatic HTTPS, Caddy won’t complain about not getting port 80.

(Conor Burns) #22

I actually run DNS challenge because I got the letsencrypt ratelimit:

I also use wildcards for the smaller domains for the sake of simplicity.

(Matthew Fay) #23

Excellent! Caddy should then be quite happy to serve your sites on whatever port you like.

(Conor Burns) #24

That’s great thank you so much for your help!

And is it possible to minify my caddyfile by serving some of the Subdomains that serve static content with labels?

(Matthew Fay) #25

Do you mean that they serve the same static content?

If you’re serving the same content, you can add multiple labels to a single site definition, just like the first example I gave earlier: Running Subdomains on .onion services

(Conor Burns) #26

Like this:

  include wc
  root /var/www/all # in that directory are the directories stats, pgp, dev, pw with their index.html
  rewrite {
    to /{label1}{uri}

(Matthew Fay) #27

Ahh yeah, like the other thread we’ve been talking in :smiley:

You can do that. Based on that Caddyfile, when you browse to stats.conor-burns.com, it’ll serve content from /var/www/all/stats on your disk.

(Conor Burns) #28

Yeah exactly I tried that when I saw it in the thread but I get this error cannot convert domain to a valid wildcard

(Matthew Fay) #29

There should be more to that error message.

Can you post the full line, as well as your full Caddyfile (in particular, the content of the wc snippet)?

Wildcarding with HTTP is simple; with HTTPS, things get a bit more complicated with LetsEncrypt, but you’re already aware of that if you’re already using wildcard certs.

(Conor Burns) #30

Ok I pushed the config to GitHub and this is the error:

Main PID: 32140 (code=exited, status=1/FAILURE)

Mar 07 02:31:59 mail.conor-burns.com systemd[1]: Started Caddy HTTP/2 web server.
Mar 07 02:31:59 mail.conor-burns.com caddy[32140]: 2019/03/07 02:31:59 [INFO][FileStorage:/etc/ssl/caddy] Started certificate maintenance routine
Mar 07 02:31:59 mail.conor-burns.com caddy[32140]: 2019/03/07 02:31:59 /etc/caddy/Caddyfile:16 - Error during parsing: Cannot convert domain name '*.conor-burns.com' to a valid wildcard: already has a wildcard label
Mar 07 02:31:59 mail.conor-burns.com systemd[1]: caddy.service: Main process exited, code=exited, status=1/FAILURE
Mar 07 02:31:59 mail.conor-burns.com systemd[1]: caddy.service: Failed with result 'exit-code'.

(Matthew Fay) #31

What’s in the wc snippet?