diff options
Diffstat (limited to 'ipn/ipnlocal/local.go')
| -rw-r--r-- | ipn/ipnlocal/local.go | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index bcad6c64a..d235df451 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -12,6 +12,7 @@ import ( "io" "net" "net/http" + "net/url" "os" "os/exec" "os/user" @@ -3253,3 +3254,38 @@ func (b *LocalBackend) DoNoiseRequest(req *http.Request) (*http.Response, error) } return cc.DoNoiseRequest(req) } + +// ProxyAPIRequestOverNoise sends Tailscale API request r over the +// Noise channel, authenticated as the current node+machine key, to +// the control plane and copies its response back to w. +func (b *LocalBackend) ProxyAPIRequestOverNoise(w http.ResponseWriter, r *http.Request) { + var nodePub key.NodePublic + b.mu.Lock() + if nm := b.netMap; nm != nil { + nodePub = nm.NodeKey + } + b.mu.Unlock() + if nodePub.IsZero() { + http.Error(w, "no node public key", http.StatusBadGateway) + return + } + + outR := r.Clone(r.Context()) + outR.RequestURI = "" + outR.URL.Scheme = "https" + outR.URL.Host = "unused" + + outR.SetBasicAuth(url.QueryEscape(nodePub.String()), "") + res, err := b.DoNoiseRequest(outR) + if err != nil { + http.Error(w, "failed to make backend noise request: "+err.Error(), http.StatusBadGateway) + return + } + for k, vv := range res.Header { + for _, v := range vv { + w.Header().Add(k, v) + } + } + w.WriteHeader(res.StatusCode) + io.Copy(w, res.Body) +} |
