When is it advisable to use https with tailscale?

I have been trying out Tailscale using @BartButenaers' most excellent tailscale tutorial and, with that tutorial, tailscale is remarkably simple to use. In the tutorial the use of https is advised. It is not clear to me whether using https is of any benefit if one's tailnet is only a few machines used to access, for example, the node red dashboard and grafana, as the network traffic is already encrypted by tailscale.

Under what circumstances is there a significant benefit to using https with tailscale?

1 Like

Well deepseek says;

'HTTPS in Tailscale networks enhances security by adding application-layer encryption, service authentication, and compliance readiness, complementing Tailscale’s VPN-layer protections. This layered approach aligns with zero-trust principles and mitigates risks from both external and internal threats.'

EDIT - also gives browser confidence?

Can you give an example of a situation where security could be compromised if https is not in use?

That is true, but in practice, for the situation I described, does it actually make any significant difference?

I'm punching above my weight here, but... What if your laptop, tablet or phone was phished, and the attacker was then able to then gain access to your Tailscale network. The attacker could then snoop on unencrypted http traffic between devices within the tailnet.
Https would provide an additional layer to guard against such internal threats.

Note: There are restrictions that can partly mitigate internal threats within Tailscale itself - see tailscale ACL's

I don't know if it's significant for you, but it would stop browsers giving a 'Not Secure' warning - Seeing a “Not Secure” Warning in Chrome? Here’s Why and What to Do about It | DigiCert.com

Adding https to a tailscale network is not much more than ticking a box, tailscale then obtains the certificate, and renews it thereafter, so why wouln't you?

3 Likes

Tailscale is built on a VPN and all VPN's are only as strong as their weakest endpoint. So Paul is absolutely correct in what he says. If you have a Tailscale endpoint on a device that is then compromised through some other means, your entire Tailscale network is potentially compromised.

When working in commercial, high-value or highly sensitive environments, you should ALWAYS be using encrypted links internally as well as externally. And indeed, partitioning networks to prevent attackers from being able to move between segments to further reduce risk.

Obviously though, you should make your own risk-based decision as to whether you really need to do this or not.

Clearly that is true, but that is not the environment I described.

Again, that is true. If my phone is compromised then an attacker could get into my laptop or other parts of my system and cause havoc. However, I don't see how using https when accessing the node-red dashboard through the tailnet network would help in this situation.

No, I doubt it will make any difference to your situation. The reason for using https internally is to prevent CROSS-system attacks. In a simple network, you are very unlikely to get any benefit. As I said, this is more for commercial/enterprise networks rather than small home networks.

Still, there is no real downside to using HTTPS internally as long as you have set up automation to renew certificates. Let's Encrypt makes this trivial. Oh, and as long as you have a registered domain that you can use at least part of for your internal network.

If I understand correctly, the tutorial suggests keeping the internal access to node-red as http and just using https when accessing through the network, in which case I think tailscale handles the certificates for you.

1 Like

I didn't read it like that, I just used http to set my tailnet up, then activated https, and use https for all connections since, local network & public.

Yes it does, although the domain certificate is in the name of your tailnet which is confined to the name generated by Tailscale (ie you can't pick a bespoke domain name like mysite.com, it would be something like myserver.forest-bicolor.ts.net.

1 Like

Have you setup https in the node-red settings.js?

In Node-RED-Tailscale-Tutorial/docs/tailnet_serve_https.md at main · bartbutenaers/Node-RED-Tailscale-Tutorial · GitHub it suggests using https only for tailscale, node red itself is still accessible locally using http. Unless I am missing something.

No, https is not enabled in node-RED, as https is provided in a reverse proxy.

I read Bart's comment as meaning that you can of course not serve node-RED via Tailscale at all if you were really concerned about security, and instead just use your local IP for access. (just like what we advise non-tailscale users in the forum)
I don't know where it says "it suggests using https only for tailscale".

Yes, you still can access node-RED via it's local IP if you wish to, but I always use the https address, because my main server is a cloud server.

1 Like

The tutorial leaves node-red itself serving http, therefore, if you are using https for node-red access then you are using tailscale. Https will only work over tailscale in this setup.

I realised there is another advantage of using https, that it allows the client to install the dashboard as a PWA, so I gave it a go.

Unfortunately I have found a problem with using https, that it does not load third party nodes. Could someone else confirm whether this is the case for them too, if so I will submit an issue against the dashboard. There is already something similar with Docker installations I think.

In the browser console I am seeing, for example this failing with a 404 error
https://owlr.tailxxx.ts.net/resources/@colinl/node-red-dashboard-2-ui-gauge-classic/ui-gauge-classic.umd.js

Not sure what you mean by third party nodes...
If you can post a quick flow to show the problem Colin, I'll give it a try when I get home.

I mean the non-core contributed ui nodes. For example @colinl/node-red-dashboard-2-ui-gauge-classic

I have proxied /dashboard to the dashboard using
sudo tailscale serve --https=443 --bg --set-path /dashboard http://localhost:1880/dashboard

Here is a simple flow using that gauge

[{"id":"5c62f5086884aedd","type":"ui-gauge-classic","z":"997da33a0beedade","name":"test gauge.","group":"4f87bd59a15b847e","order":9,"width":"3","height":"3","min":"0","max":"10","sectors":[{"start":"0","color":"yellow"},{"start":"3","color":"red"},{"start":"7","color":"blue"}],"major_division":1,"minor_division":0.2,"value_decimal_places":1,"scale_decimal_places":"0","label":"","measurement":"Meas","units":"°C","needles":[{"topic":"A","color":"black","lengthPercent":"104"},{"topic":"B","color":"brown","lengthPercent":"70"}],"sweep_angle":"250","myclass":"testgauge","x":590,"y":5540,"wires":[]},{"id":"741630f01d14f08f","type":"inject","z":"997da33a0beedade","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"A","payload":"0","payloadType":"num","x":250,"y":5480,"wires":[["6737de28bc7b6e8e"]]},{"id":"69bfed7b7b3c6c37","type":"inject","z":"997da33a0beedade","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"A","payload":"5","payloadType":"num","x":250,"y":5440,"wires":[["6737de28bc7b6e8e"]]},{"id":"ce2440f1733ca433","type":"inject","z":"997da33a0beedade","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"B","payload":"0.6","payloadType":"num","x":250,"y":5520,"wires":[["6737de28bc7b6e8e"]]},{"id":"524ee77cc71000c6","type":"inject","z":"997da33a0beedade","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"B","payload":"4.5","payloadType":"num","x":250,"y":5600,"wires":[["6737de28bc7b6e8e"]]},{"id":"4f87bd59a15b847e","type":"ui-group","name":"test","page":"c6ff182a4185f2f2","width":"6","height":"1","order":1,"showTitle":false,"className":"","visible":"true","disabled":"false"},{"id":"c6ff182a4185f2f2","type":"ui-page","name":"Test page","ui":"ID-BASE-1","path":"/testpage","icon":"home","layout":"grid","theme":"f9b6670b127dc219","order":2,"className":"","visible":"true","disabled":"false"},{"id":"ID-BASE-1","type":"ui-base","name":"Dashboard","path":"/dashboard","includeClientData":true,"acceptsClientConfig":["ui-control","ui-notification","ui-gauge-classic"],"titleBarStyle":"default"},{"id":"f9b6670b127dc219","type":"ui-theme","name":"FlowForge Theme","colors":{"surface":"#152a47","primary":"#005aff","bgPage":"#ffffff","groupBg":"#ffffff","groupOutline":"#cc3e3e"},"sizes":{"pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px"}}]

I have posted an issue for this

I don't think it is a tailscale issue, it is the fact that the dashboard is proxied.

1 Like

A downside of using https is that it is necessary to use the full host name https://hostname.tailxxx.ts.net/..., whereas using http through the tailnet one can just use http://hostname/..., though one does also need to include the port, so for node-red http://hostname:1880/dashboard

Doesn't cause me a problem as I've bookmarked the url's in my browsers :wink:

As for the issue mentioned, I've just tried your flow, and it works ok for me, with no reported errors.
I'm accessing it via the tailscale https address, which like yours is proxied to avoid using the port number.

colin

Exactly how have you proxied it, and what url are you using in the browser, so I can replicate that?

Edit: What version of node-red and the dashboard are you using?

Same as you, and as described by Bart in his docs.
If I run tailscale serve status, I get;

|-- /dashboard   proxy http://localhost:7143/dashboard
|-- /flow_editor proxy http://localhost:7143/flow_editor

...and access it via the format - https://myserver.snake-color.ts.net/dashboard (words changed for the forum)

Tailscale v1.78.1
Dashboard 1.22.1
Node-RED 4.0.5