client/web: use Home Assistant's X-Ingress-Path header

When running on Home Assistant, use the X-Ingress-Path header to set the
URLPrefix that is passed to the frontend.

Also fix handling of errNotUsingTailscale in the auth handler
(previously it falling through to a later case and returning a 500).
Instead, it's just a terminal state with no auth needed.

Also disable SSH on Home Assistant, since it causes problems on startup
and doesn't make much sense anyway for that platform.

Updates #10261

Signed-off-by: Will Norris <will@tailscale.com>
This commit is contained in:
Will Norris 2023-12-08 16:09:13 -08:00 committed by Will Norris
parent a4c7b0574a
commit 5a2e6a6f7d
1 changed files with 19 additions and 1 deletions

View File

@ -26,6 +26,7 @@ import (
"tailscale.com/client/tailscale/apitype"
"tailscale.com/clientupdate"
"tailscale.com/envknob"
"tailscale.com/hostinfo"
"tailscale.com/ipn"
"tailscale.com/ipn/ipnstate"
"tailscale.com/licenses"
@ -440,6 +441,9 @@ func (s *Server) serveAPIAuth(w http.ResponseWriter, r *http.Request) {
}
switch {
case sErr != nil && errors.Is(sErr, errNotUsingTailscale):
// Restricted to the readonly view, no auth action to take.
resp.AuthNeeded = ""
case sErr != nil && errors.Is(sErr, errNotOwner):
// Restricted to the readonly view, no auth action to take.
s.lc.IncrementCounter(r.Context(), "web_client_viewing_not_owner", 1)
@ -640,6 +644,12 @@ func (s *Server) serveGetNodeData(w http.ResponseWriter, r *http.Request) {
ACLAllowsAnyIncomingTraffic: s.aclsAllowAccess(filterRules),
}
if hostinfo.GetEnvType() == hostinfo.HomeAssistantAddOn && data.URLPrefix == "" {
// X-Ingress-Path is the path prefix in use for Home Assistant
// https://developers.home-assistant.io/docs/add-ons/presentation#ingress
data.URLPrefix = r.Header.Get("X-Ingress-Path")
}
cv, err := s.lc.CheckUpdate(r.Context())
if err != nil {
s.logf("could not check for updates: %v", err)
@ -711,13 +721,21 @@ func (s *Server) serveGetNodeData(w http.ResponseWriter, r *http.Request) {
}
func availableFeatures() map[string]bool {
return map[string]bool{
features := map[string]bool{
"advertise-exit-node": true, // available on all platforms
"advertise-routes": true, // available on all platforms
"use-exit-node": distro.Get() != distro.Synology, // see https://github.com/tailscale/tailscale/issues/1995
"ssh": envknob.CanRunTailscaleSSH() == nil,
"auto-update": version.IsUnstableBuild() && clientupdate.CanAutoUpdate(),
}
if hostinfo.GetEnvType() == hostinfo.HomeAssistantAddOn {
// Setting SSH on Home Assistant causes trouble on startup
// (since the flag is not being passed to `tailscale up`).
// Although Tailscale SSH does work here,
// it's not terribly useful since it's running in a separate container.
features["ssh"] = false
}
return features
}
// aclsAllowAccess returns whether tailnet ACLs (as expressed in the provided filter rules)