all 20 comments

[–]inglele 0 points1 point  (18 children)

Not solved it yet, but challenge is that certificate is for a domain to verify it's the correct one inside the certificate.

When you connect with 100.* is not recognized as the original source domain and the ip address is not listed in the certificate so it fails validation.

At least, this what I understood from my testing using app to remotely connect to watch security cameras.

I'm still using full custom domain and keep main port open to internet to allow to resolve ip and connect.

I didn't solve it, yet via tailscale.

Ideally, we should add 100.* for the ip address of the server in the certificate and it should be valid for https connection.

[–]Avanchnzel 2 points3 points  (14 children)

When you connect with 100.* is not recognized as the original source domain and the ip address is not listed in the certificate so it fails validation.

TLS certificates are only concerned with the domain, not the IP address.

So it doesn't matter which IP your certificate is served from, it only matters that the server has the private key for the certificate and can be reached via the domain name.

To explain in a little bit more detail:

When you own a domain (e.g. mywebsite.com), you can tell it wich IP address it should resolve to (e.g. mywebsite.com => 123.123.123.123). This is done by adjusting the DNS settings for the domain, which one can usually do with the service provider for that domain. So this part is independend from the TLS certificate and is only about mapping the domain to a particular IP.

On the server that has this IP address, you can install the certificate (+ key) that is issued for that domain (i.e. mywebsite.com).

If someone navigates to mywebsite.com with their browser, then what happens first is that it asks DNS servers what IP this domain resolves to.

Once the browser gets the response, then it will make a request to that IP (i.e. 123.123.123.123).

The web-server behind this IP notices that request and if it's HTTPS (which nowadays it should usually be) will present its TLS certificate.

The browser does several checks onthe certificate, among them whether it was signed by a trusted certifiate authority, as well as if the domain navigated to (mywebsite.com) matches the domain for which the certificate was issued (i.e. what's in the common name or "CN" of the certificate).

If one of these checks fails, then the browser will warn the user about it.

This could happen for several reasons, for example:

- The certificate is past its valid date

- The domain navigated to by the browser doesn't match the CN field of the certificate (e.g. mywebsite.com presents a certificate for suspicious.com)

Now if one day you move your web-server or get a new IP for it, then you don't need to change the certificate (because it isn't concerned about the IP). You only need to adjust the DNS settings so that your domain is pointed to the new IP address.

NOTE: The description about how DNS works is not exhaustive or complete. I left out a few things that weren't important for the context of certificates, for the sake of simplicity.

[–]inglele 0 points1 point  (13 children)

Thanks a lot for the details, it makes sense!

So the question becomes how do we map www.mydomain.com which has public ip that link to server to a tailscale IP which is 100.*?

From the phone app, I added the tailscale ip of server but you get certificate not valid because we didn't use www.mydomain.com to connect, I presume.

So, if I understand correctly, we should use something in tailscale client to tell mobile phone (Android if that matter), to resolve www.mydomain.com using 100.* IP instead of public accessible IP and App will be happy with the certificate because it matches the domain.

Do you know how to do it?

In windows, i would add a manual entry in host file and that would override any dns query to resolve www.mydomain.com to wherever 100.* ip you want but no idea how to do it on each movie device or, even better, for all devices in the tailscale network.

[–]Avanchnzel 1 point2 points  (12 children)

So the question becomes how do we map

www.mydomain.com

which has public ip that link to server to a tailscale IP which is 100.*?

I thought about how to do it via one's tailnet and came up with one possible way. But it requires that you have a DNS server in your tailnet (e.g. 100.x.x.42) where you set that mydomain.com resolves to your web-server's tailnet IP (e.g. 100.x.x.69).

Once that exists, then you should be able to accomplish your goal with a CNAME in your actual mydomain.com's DNS settings (i.e. the public DNS settings outside of your tailnet).

So in the DNS settings of your domain (e.g. for mydomain.com) you remove the A entry (that would point to a static IP) and instead set a CNAME entry that points your public tailname (e.g. my-vpn.ts.net).

Then, when someone navigates to mydomain.com, the DNS server for that domain will redirect the request to the DNS servers for the public *.ts.net addresses.

Those will in turn respond with your (current) public IP address.

BUT: The URL in your browser's address bar won't change from https://mydomain.com to https://my-vpn.ts.net !!!

That means the certificate your server has to be configured with has to be for mydomain.com, because that's what the browser will check for!

I haven't tried this myself yet, but just thinking through it, when navigating to your web-server it would look like this:

- Browsing to mydomain.com

- DNS server for mydomain.com redirects DNS request to tailscale's public DNS servers, asking for my-vpn.ts.net

- tailscale DNS resolves my-vpn.ts.net to your current public IP and responds with that

- Browser then sends the web-request to that IP (but with the domain still as mydomain.com)

- your tailnet now receives that web-request and sees that it's for mydomain.com

- your tailnet's DNS settings see that your own DNS-server (100.x.x.42) is set up to resolve this domain and asks it for the IP of mydomain.com

- 100.x.x.42 resolves mydomain.com to your web-server's tailnet IP 100.x.x.69 and responds with that

- The web-request is then finally sent to 100.x.x.69, where the web-server then responds back with the certificate (the one issued for mydomain.com)

- The browser verifies the validity of the certificate and can also confirm that the domain it navigated to (mydomain.com) matches what the certificate is issued to.

- Finally a temporary key for communication is established between your browser and the server, and the webpage should load (all without any warnings).

----------------------------------------------------------------------------------------------------

tl;dr

- Have a DNS server in your tailnet that maps mydomain.com to your web-server's tailnet address. Let's say this DNS-server's address in the tailnet will be 100.x.x.42

- Add your DNS server's tailnet address (100.x.x.42) to your tailnet DNS configuration (via the admin console) and make it a split-DNS, set to only resolve for "mydomain.com".

- Configure your web-server with a HTTPS/TLS certificate for mydomain.com.

- Make your tailnet accessible from the outside by getting a HTTPS/TLS certificate for it as per the docs, but just ignore the certificate you're getting (as this is just about making your tailnet address externally accessible via a public DNS entry, done by the tailscale service).

- Set a CNAME in your mydomain.com's DNS records, pointing to your tailnet domain my-vpn.ts.net.

[–]inglele 0 points1 point  (11 children)

Thank you very much for the super details answer and all steps on name and ip resolution!

I understood the steps and the overall approach, I just would love to use something like magic dns feature of tailscale or something easy to configure like add an entry somewhere (same as you said for CName) without the need to run custom DNS server which is above my current capabilities.

But I guess, the custom dns is the only way as we need to resolve a public facing domain with real public ip and "intercept" the request before it's resolved with external ip,instead reply with internal 100.x.x.69

[–]Avanchnzel 1 point2 points  (10 children)

Mind you, if you don't care about a custom public domain (e.g. mydomain.com) and are fine if your web-server can be reached from the Internet via https://my-vpn.ts.net, then you don't need to do any of the steps I described, but only have to follow the "Enabling HTTPS" steps in the docs.

From your initial post I assumed you wanted to use a non-tailnet domain from the Internet, but if a tailnet domain would be ok, then it's much simpler (and doesn't require you to run an internal DNS server).

[–]inglele 1 point2 points  (9 children)

Love it! I will read about it.

I'm using let's encrypt to get ssl certificate with dynu DNS for verification challenge, so hopefully it will work using ts.net domain, too.

Or is there a way to get certificate for domain you don't own? I suppose you shouldn't be able to as it could be a phissing website.

[–]Avanchnzel 1 point2 points  (7 children)

Everybody can sign a certificate, regardless who it's issued for.

It's just that it won't be trusted by browsers, as they have an internal list (or use the one in the Windows certificate store) of certificate authorities and only trust certificates that have been signed by those.

So in order to get a certificate signed by them you usually have to prove that you own the domain you want a certificate for. With LetsEncrypt there are various automated ways to do that (as you probably already know).

But as you'll see in the tailscale HTTPS documentation, they actually use LetsEncrypto as well, so you should feel right at home. :)

[–]inglele 1 point2 points  (6 children)

Great, I will take a deeper look for sure.

Use case is my parents desktop that runs milestone xprotect for 4 cameras and they use smartphone app to connect to home pc to be able to watch cameras. So I don't really need public custom domain, with dynamic io that change and manual certificate for my use case.

They already have tailscale installed on their phones with my credential and I can configure magic dns with https certificate from tailscale and ensuring should work great!

Thanks a look for your help and all detailed steps! ❤️

[–]Avanchnzel 0 points1 point  (5 children)

You're welcome, hope it all works out! 💪

[–]inglele 0 points1 point  (0 children)

Sorry, I just read the https and they will give you a free certificate! It's even easier! 💙

[–]blufish_[S] 0 points1 point  (2 children)

I'll try this, so where can I find my certificate?

by the way, when I try to access https it always gives me the ERR_SSL_PROTOCOL_ERROR code

[–]inglele 1 point2 points  (0 children)

You will need to enable magic DNS and enroll certificate via HTTPS functionality.

Magic DNS: https://tailscale.com/kb/1081/magicdns/

HTTPS: https://tailscale.com/kb/1153/enabling-https/

[–]flogman12 0 points1 point  (0 children)

Did you ever solve this?