mafik / gatekeeper

DHCP & DNS server optimized for home gateways.
MIT License
78 stars 2 forks source link

HTTPS support #3

Open DemiMarie opened 1 year ago

DemiMarie commented 1 year ago

Right now it does not appear that the Web UI supports HTTPS. This is a request for HTTPS support. Another option would be to listen on an AF_UNIX socket and rely on a proxy.

mafik commented 1 year ago

Thanks for sharing ideas! I think getting https to work would be pretty awesome. I think I may not get to this anytime soon but I'll keep this issue around.

DemiMarie commented 1 year ago

I think a proxy (nginx?) would be the simplest solution. The proxy can also implement authentication.

mafik commented 1 year ago

Right, this kind of https, I'd say, is the default one that anyone with some spare time could set up. It doesn't really need any extra support from the Gatekeeper side (maybe parsing an extra header if we ever need the original client IP). I was thinking more of something more automated (that's the whole point of Gatekeeper). I was considering a few different options:

Fixed domain

  1. Get a domain like "mygatekeeper.io" (but nice & short)
  2. Get a certificate for it
  3. Distribute this certificate to all Gatekeeper instances.
  4. Each Gatekeeper instance would then associate "mygatekeeper.io" with it's own IP.
  5. Result would be that everybody would be able to access their local Gatekeeper instance under this domain name.

Technically HTTPS is orthogonal to this "fixed domain" feature, but it adds a nice bit of polish. The security provided by this variant also wouldn't be as high as regular HTTPS because the cert would have to be public. So the connection would be confidential but the origin not authenticated. Origin authentication in HTTPS is more of a security theater due to large number of CAs so maybe that doesn't matter much anyway.

Maintenance cost: depends on the domain name. Something between 10$/year (cheap domains) and 27 000$/year (single-letter domains).

Carrier-provided domain

  1. Identify the interface that provides internet access & get its IP.
  2. Perform in-addr.arpa query to get the carrier-provided domain (something like "staticline123.yourcarrier.net").
  3. Verify that this domain name actually points to our public IP.
  4. Perform the letsencrypt domain verification to obtain a certificate for this domain.
  5. Associate the carrier-provided domain with it's own IP on the managed network.
  6. Redirect all HTTP requests to this domain.
  7. Result is that everybody who opens their gateway IP would be redirected to this domain & get a secure connection.

Same as above, HTTPS is kind of orthogonal here but a really nice addition. In this approach we get the full security of HTTPS connection (only a single Gatekeeper instance has access to its certificate). Some things could go wrong along the way - one example might be the lack of in-addr.arpa record for the public IP. Or lack the public IP in the first place - although with some luck this should work even behind carrier NAT.

Maintenance cost: zero

Dynamic DNS

  1. Set up a centralized domain. Let's say "gatekeeper.net".
  2. Run a single publicly accessible DNS as an authority for that domain.
  3. Each Gatekeeper instance calls this DNS and requests a subdomain.
  4. In each request for a subdomain, Gatekeeper sends its public host key (generated randmly on first run).
  5. The central server verifies that the calling instance has the matching private key.
  6. The central server assigns a random domain to the provided public key. For example "jumping-panda.gatekeeper.net".
  7. The central server adds a DNS record that associates the assigned domain to the requesting IP.
  8. Continue the same way as in "Carrier-provided domain" from step 3.

There are the most moving pieces here and will take some effort to implement. It combines the features of the two other options. The traffic on the central DNS authority would be negligible because it would only be used to obtain letsencrypt certificate for each Gatekeeper instance, every couple of months. The assigned domain would mostly be used within the private network & served by the local Gatekeeper instance.

Maintenance cost: cost of domain + cost of running the public DNS authority (20$ / month)


Overall none of these three options actually exclude the other. They all essentially do two things: 1. Get a domain name. 2. Verify that domain name. But in slightly different ways. I'd probably start with the "Carrier-provided domain" approach because it's the one that doesn't require any centralized infrastructure. Once that's working we could move on to others.

DemiMarie commented 1 year ago

“Fixed domain” is actually forbidden. Whichever CA issued the certificate distributed as part of Gatekeeper would be obliged to revoke it.

The “dynamic DNS” approach is actually an extremely interesting one. I recommend having the dynamic domain name be computed by hashing the Subject Public Key Info of the certificate using the same algorithm Tor uses to calculate onion service domain names. This has the massive advantage that one can verify the certificate knowing only the domain name. In the future, clients could start hard-coding this behavior, such that if a domain has the proper suffix (such as .local) and corresponds to the server’s public key, the connection is considered secure.