mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-18 20:51:45 +00:00
tsnet,client/tailscale: add APIClient which runs API over Noise.
Updates tailscale/corp#4383 Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit is contained in:
parent
e8a11f6181
commit
630bcb5b67
@ -18,6 +18,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"tailscale.com/types/key"
|
||||||
)
|
)
|
||||||
|
|
||||||
// I_Acknowledge_This_API_Is_Unstable must be set true to use this package
|
// I_Acknowledge_This_API_Is_Unstable must be set true to use this package
|
||||||
@ -90,6 +93,29 @@ func (c *Client) setAuth(r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nodeKeyAuth is an AuthMethod for NewClient that authenticates requests
|
||||||
|
// using a node key over the Noise protocol.
|
||||||
|
type nodeKeyAuth key.NodePublic
|
||||||
|
|
||||||
|
func (k nodeKeyAuth) modifyRequest(req *http.Request) {
|
||||||
|
// QueryEscape the node key since it has a colon in it.
|
||||||
|
nk := url.QueryEscape(key.NodePublic(k).String())
|
||||||
|
req.SetBasicAuth(nk, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNoiseClient is a convenience method for instantiating a new Client
|
||||||
|
// that uses the Noise protocol for authentication.
|
||||||
|
//
|
||||||
|
// tailnet is the globally unique identifier for a Tailscale network, such
|
||||||
|
// as "example.com" or "user@gmail.com".
|
||||||
|
func NewNoiseClient(tailnet string, noiseRoundTripper http.RoundTripper, nk key.NodePublic) *Client {
|
||||||
|
return &Client{
|
||||||
|
tailnet: tailnet,
|
||||||
|
auth: nodeKeyAuth(nk),
|
||||||
|
HTTPClient: &http.Client{Transport: noiseRoundTripper},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NewClient is a convenience method for instantiating a new Client.
|
// NewClient is a convenience method for instantiating a new Client.
|
||||||
//
|
//
|
||||||
// tailnet is the globally unique identifier for a Tailscale network, such
|
// tailnet is the globally unique identifier for a Tailscale network, such
|
||||||
|
@ -3736,6 +3736,20 @@ func (b *LocalBackend) magicConn() (*magicsock.Conn, error) {
|
|||||||
return mc, nil
|
return mc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type noiseRoundTripper struct {
|
||||||
|
*LocalBackend
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n noiseRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
return n.LocalBackend.DoNoiseRequest(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoiseRoundTripper returns an http.RoundTripper that uses the LocalBackend's
|
||||||
|
// DoNoiseRequest method.
|
||||||
|
func (b *LocalBackend) NoiseRoundTripper() http.RoundTripper {
|
||||||
|
return noiseRoundTripper{b}
|
||||||
|
}
|
||||||
|
|
||||||
// DoNoiseRequest sends a request to URL over the control plane
|
// DoNoiseRequest sends a request to URL over the control plane
|
||||||
// Noise connection.
|
// Noise connection.
|
||||||
func (b *LocalBackend) DoNoiseRequest(req *http.Request) (*http.Response, error) {
|
func (b *LocalBackend) DoNoiseRequest(req *http.Request) (*http.Response, error) {
|
||||||
|
@ -9,6 +9,7 @@ package tsnet
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
@ -481,6 +482,25 @@ func getTSNetDir(logf logger.Logf, confDir, prog string) (string, error) {
|
|||||||
return newPath, nil
|
return newPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// APIClient returns a tailscale.Client that can be used to make authenticated
|
||||||
|
// requests to the Tailscale control server.
|
||||||
|
// It requires the user to set tailscale.I_Acknowledge_This_API_Is_Unstable.
|
||||||
|
func (s *Server) APIClient() (*tailscale.Client, error) {
|
||||||
|
if !tailscale.I_Acknowledge_This_API_Is_Unstable {
|
||||||
|
return nil, errors.New("use of Client without setting I_Acknowledge_This_API_Is_Unstable")
|
||||||
|
}
|
||||||
|
if err := s.Start(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
nm := s.lb.NetMap()
|
||||||
|
if nm == nil {
|
||||||
|
return nil, errors.New("no netmap, not logged in?")
|
||||||
|
}
|
||||||
|
c := tailscale.NewNoiseClient(nm.Domain, s.lb.NoiseRoundTripper(), nm.NodeKey)
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Listen announces only on the Tailscale network.
|
// Listen announces only on the Tailscale network.
|
||||||
// It will start the server if it has not been started yet.
|
// It will start the server if it has not been started yet.
|
||||||
func (s *Server) Listen(network, addr string) (net.Listener, error) {
|
func (s *Server) Listen(network, addr string) (net.Listener, error) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user