sish icon indicating copy to clipboard operation
sish copied to clipboard

Restricting custom domains to specific SSH keys

Open wdhdev opened this issue 1 year ago • 13 comments

I am having some trouble setting up custom domains and restricting them to specific SSH keys.

For context this is my setup:

  • sish domain: t.hrsn.net - this is the domain used in the SSH command to connect to sish and is the default hostname when not using a custom domain (e.g. tunnel123.t.hrsn.net).
  • Custom domain: t.wdh.gg - this is the domain I'm trying to restrict to a specific SSH key. A CNAME record is configured for t.wdh.gg and *.t.wdh.gg pointing to t.hrsn.net.
  • Cloudflare proxy is disabled.
  • I am using Docker compose to host sish.

In my config file I have the following:

bind-any-host: false
bind-hosts: t.wdh.gg

Now, this config works and I can setup subdomains on t.wdh.gg like tunnel123.t.wdh.gg however even though I have a TXT record set at _sish.t.wdh.gg with the content:

SHA256:yQ2G5ra7npl6ROKw3BJQWULROIG37u14aMfbfKoWFqQ

Even though that TXT record is in place, anyone regardless if they are using that SSH key are able to use t.wdh.gg subdomains even though it should be restricted to that specific key.

I have tried the following, none of which worked:

  • Removing the bind-hosts key entirely, however when attempting to use a subdomain of t.wdh.gg like tunnel123.t.wdh.gg it would instead bind to tunnel123.t.wdh.gg.t.hrsn.net.
  • Removing the SHA256: bit from the TXT record, which did not work.
  • Using the old DNS configuration by creating the following TXT record at t.wdh.gg (attempted with and without the SHA256: bit):
sish=SHA256:yQ2G5ra7npl6ROKw3BJQWULROIG37u14aMfbfKoWFqQ

Please let me know how I can setup custom domains and restrict them using TXT records to specific SSH keys. Thanks!

wdhdev avatar Sep 07 '24 09:09 wdhdev

Hey @antoniomika, no rush, but are you able to look into this? Thanks 😄

wdhdev avatar Sep 12 '24 01:09 wdhdev

Are you using the main branch version? When I have that running and try to bind without the TXT being set to the current key, it will bind to a subdomain instead.

EpicEric avatar Sep 20 '24 12:09 EpicEric

I'm using v2.16.0.

wdhdev avatar Sep 20 '24 23:09 wdhdev

@EpicEric Are you able to share your config and exactly what you put in the TXT record?

wdhdev avatar Sep 20 '24 23:09 wdhdev

The documentation referring to the _sish record is in accordance with this change, which hasn't been released in a tagged version yet. I believe you still need to use sish=SSHFINGERPRINT in your case.

I'm running sish with these options:

# compose.yml
services:
  sish:
    # ... snip ...
    image: docker.io/antoniomika/sish@main
    command: |
      --ssh-address=:22
      --http-address=:80
      --https-address=:443
      --authentication-keys-directory=/pubkeys
      --private-keys-directory=/keys
      --https-certificate-directory=/ssl
      --https-ondemand-certificate=true
      --https-ondemand-certificate-accept-terms=true
      [email protected]
      --https=true
      --force-https=true
      --log-to-client=true
      --idle-connection=false
      --bind-random-aliases=false
      --bind-random-ports=false
      --bind-random-subdomains=false
      --bind-random-subdomains-length=6
      --http-load-balancer=true
      --tcp-load-balancer=true
      --alias-load-balancer=true
      --time-format=2006-01-02T15:04:05
      --domain=my.domain

I believe the only relevant option is --bind-random-aliases=false.

EpicEric avatar Sep 21 '24 00:09 EpicEric

Even when using the Docker image you are using, no matter whether I'm using the old TXT record or new one, it still allows anyone to bind to it.

This is my full config:

authentication-keys-directory: "/pubkeys"
banned-subdomains: localhost, www
bind-any-host: false
bind-hosts: t.hrsn.dev,t.wdh.gg
bind-random-aliases: false
bind-random-ports: true
bind-random-subdomains: false
bind-random-subdomains-length: 12
domain: "t.hrsn.net"
http-address: "tcp://107.150.46.51:80,tcp6://[2604:4300:a:149::6d96:2e33]:80"
https: true
https-address: "tcp://107.150.46.51:443,tcp6://[2604:4300:a:149::6d96:2e33]:443"
https-certificate-directory: "/ssl"
port-bind-range: 1000-1999
private-keys-directory: "/keys"
redirect-root: true
redirect-root-location: https://hrsn.net/#tunnels
ssh-address: "tcp://107.150.46.51:2222,tcp6://[2604:4300:a:149::6d96:2e33]:2222"
tcp-address: "tcp://107.150.46.51,tcp6://[2604:4300:a:149::6d96:2e33]"

This is my Docker compose file:

services:
  sish:
    image: antoniomika/sish:main
    container_name: sish
    volumes:
      - /etc/letsencrypt:/etc/letsencrypt
      - ./pubkeys:/pubkeys
      - ./keys:/keys
      - ./ssl:/ssl
      - ./config.yml:/config.yml:ro
    command: |
      --config=/config.yml
    network_mode: host
    restart: always

A couple questions:

  • For the SSH key fingerprint, do we get it from the private key that the user has or do we retrieve it from the public key on the server? I have been using the fingerprint of the private key.
  • For the TXT record, do we include the SHA256: bit or not?
  • I'm assuming the TXT record goes on the host listed under bind-hosts, so in my case _sish.t.wdh.gg, is this correct?

wdhdev avatar Sep 21 '24 03:09 wdhdev

  • It has to be from either of the user's key. Both generate the same fingerprint: image
  • Yes.
  • Also yes.

A friend who's using sish has run into a similar issue, and --bind-any-hosts fixed it in his case, although the root cause couldn't be determined yet.

EpicEric avatar Sep 21 '24 13:09 EpicEric

Actually, reading on the documentation for --bind-hosts, it seems that you must specify the root host, i.e. "Requested hosts should be subdomains of a host in this list". So perhaps changing your config to bind-hosts: t.hrsn.dev,wdh.gg could do the trick.

EpicEric avatar Sep 21 '24 13:09 EpicEric

A friend who's using sish has run into a similar issue, and --bind-any-hosts fixed it in his case, although the root cause couldn't be determined yet.

So I should set that option to true and remove the bind-hosts bit?

FYI, I intend to host subdomains on t.wdh.gg, not wdh.gg, (e.g. tunnel123.t.wdh.gg).

wdhdev avatar Sep 21 '24 13:09 wdhdev

You can leave that as is, then.

EpicEric avatar Sep 21 '24 13:09 EpicEric

With the current implementation of verifyDNS, _sish.t.wdh.gg will only apply for t.wdh.gg, not any subdomains. The appropriate TXT entries would have to be added for each subdomain as well.

Going through the code, I believe the option you'll want is force-requested-subdomains: true. This should error when the user doesn't have the appropriate permission to bind to it.

EpicEric avatar Sep 21 '24 14:09 EpicEric

I tried that option with both types of TXT records, and it didn't work, not sure why. I also tried both with and without bind-any-host enabled.

Is it possible that the TXT record verification system is just completely broken?

wdhdev avatar Sep 22 '24 00:09 wdhdev

It definitely works for me, as it doesn't let me bind on a subdomain if the TXT is missing. I'm not really sure what else could be causing this issue, unfortunately.

EpicEric avatar Sep 22 '24 01:09 EpicEric