mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-06 22:27:36 +02:00
cmd/tsidp,tsnet: update tsidp oidc-key store path (#16735)
The tsidp oidc-key.json ended up in the root directory or home dir of the user process running it. Update this to store it in a known location respecting the TS_STATE_DIR and flagDir options. Fixes #16734 Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
This commit is contained in:
parent
1cc842b389
commit
47b5f10165
@ -29,6 +29,7 @@
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -60,6 +61,9 @@ type ctxConn struct{
|
|||||||
// accessing the IDP over Funnel are persisted.
|
// accessing the IDP over Funnel are persisted.
|
||||||
const funnelClientsFile = "oidc-funnel-clients.json"
|
const funnelClientsFile = "oidc-funnel-clients.json"
|
||||||
|
|
||||||
|
// oidcKeyFile is where the OIDC private key is persisted.
|
||||||
|
const oidcKeyFile = "oidc-key.json"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
flagVerbose = flag.Bool("verbose", false, "be verbose")
|
flagVerbose = flag.Bool("verbose", false, "be verbose")
|
||||||
flagPort = flag.Int("port", 443, "port to listen on")
|
flagPort = flag.Int("port", 443, "port to listen on")
|
||||||
@ -80,12 +84,14 @@ func main() {
|
|||||||
var (
|
var (
|
||||||
lc *local.Client
|
lc *local.Client
|
||||||
st *ipnstate.Status
|
st *ipnstate.Status
|
||||||
|
rootPath string
|
||||||
err error
|
err error
|
||||||
watcherChan chan error
|
watcherChan chan error
|
||||||
cleanup func()
|
cleanup func()
|
||||||
|
|
||||||
lns []net.Listener
|
lns []net.Listener
|
||||||
)
|
)
|
||||||
|
|
||||||
if *flagUseLocalTailscaled {
|
if *flagUseLocalTailscaled {
|
||||||
lc = &local.Client{}
|
lc = &local.Client{}
|
||||||
st, err = lc.StatusWithoutPeers(ctx)
|
st, err = lc.StatusWithoutPeers(ctx)
|
||||||
@ -110,6 +116,15 @@ func main() {
|
|||||||
log.Fatalf("failed to listen on any of %v", st.TailscaleIPs)
|
log.Fatalf("failed to listen on any of %v", st.TailscaleIPs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if flagDir == nil || *flagDir == "" {
|
||||||
|
// use user config directory as storage for tsidp oidc key
|
||||||
|
configDir, err := os.UserConfigDir()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("getting user config directory: %v", err)
|
||||||
|
}
|
||||||
|
rootPath = filepath.Join(configDir, "tsidp")
|
||||||
|
}
|
||||||
|
|
||||||
// tailscaled needs to be setting an HTTP header for funneled requests
|
// tailscaled needs to be setting an HTTP header for funneled requests
|
||||||
// that older versions don't provide.
|
// that older versions don't provide.
|
||||||
// TODO(naman): is this the correct check?
|
// TODO(naman): is this the correct check?
|
||||||
@ -127,6 +142,8 @@ func main() {
|
|||||||
Hostname: *flagHostname,
|
Hostname: *flagHostname,
|
||||||
Dir: *flagDir,
|
Dir: *flagDir,
|
||||||
}
|
}
|
||||||
|
rootPath = ts.GetRootPath()
|
||||||
|
log.Printf("tsidp root path: %s", rootPath)
|
||||||
if *flagVerbose {
|
if *flagVerbose {
|
||||||
ts.Logf = log.Printf
|
ts.Logf = log.Printf
|
||||||
}
|
}
|
||||||
@ -157,7 +174,9 @@ func main() {
|
|||||||
lc: lc,
|
lc: lc,
|
||||||
funnel: *flagFunnel,
|
funnel: *flagFunnel,
|
||||||
localTSMode: *flagUseLocalTailscaled,
|
localTSMode: *flagUseLocalTailscaled,
|
||||||
|
rootPath: rootPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
if *flagPort != 443 {
|
if *flagPort != 443 {
|
||||||
srv.serverURL = fmt.Sprintf("https://%s:%d", strings.TrimSuffix(st.Self.DNSName, "."), *flagPort)
|
srv.serverURL = fmt.Sprintf("https://%s:%d", strings.TrimSuffix(st.Self.DNSName, "."), *flagPort)
|
||||||
} else {
|
} else {
|
||||||
@ -285,6 +304,7 @@ type idpServer struct {
|
|||||||
serverURL string // "https://foo.bar.ts.net"
|
serverURL string // "https://foo.bar.ts.net"
|
||||||
funnel bool
|
funnel bool
|
||||||
localTSMode bool
|
localTSMode bool
|
||||||
|
rootPath string // root path, used for storing state files
|
||||||
|
|
||||||
lazyMux lazy.SyncValue[*http.ServeMux]
|
lazyMux lazy.SyncValue[*http.ServeMux]
|
||||||
lazySigningKey lazy.SyncValue[*signingKey]
|
lazySigningKey lazy.SyncValue[*signingKey]
|
||||||
@ -819,8 +839,9 @@ func (s *idpServer) oidcSigner() (jose.Signer, error) {
|
|||||||
|
|
||||||
func (s *idpServer) oidcPrivateKey() (*signingKey, error) {
|
func (s *idpServer) oidcPrivateKey() (*signingKey, error) {
|
||||||
return s.lazySigningKey.GetErr(func() (*signingKey, error) {
|
return s.lazySigningKey.GetErr(func() (*signingKey, error) {
|
||||||
|
keyPath := filepath.Join(s.rootPath, oidcKeyFile)
|
||||||
var sk signingKey
|
var sk signingKey
|
||||||
b, err := os.ReadFile("oidc-key.json")
|
b, err := os.ReadFile(keyPath)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if err := sk.UnmarshalJSON(b); err == nil {
|
if err := sk.UnmarshalJSON(b); err == nil {
|
||||||
return &sk, nil
|
return &sk, nil
|
||||||
@ -835,7 +856,7 @@ func (s *idpServer) oidcPrivateKey() (*signingKey, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error marshaling key: %v", err)
|
log.Fatalf("Error marshaling key: %v", err)
|
||||||
}
|
}
|
||||||
if err := os.WriteFile("oidc-key.json", b, 0600); err != nil {
|
if err := os.WriteFile(keyPath, b, 0600); err != nil {
|
||||||
log.Fatalf("Error writing key: %v", err)
|
log.Fatalf("Error writing key: %v", err)
|
||||||
}
|
}
|
||||||
return &sk, nil
|
return &sk, nil
|
||||||
@ -869,7 +890,6 @@ func (s *idpServer) serveJWKS(w http.ResponseWriter, r *http.Request) {
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// openIDProviderMetadata is a partial representation of
|
// openIDProviderMetadata is a partial representation of
|
||||||
|
@ -1268,6 +1268,12 @@ func (s *Server) listen(network, addr string, lnOn listenOn) (net.Listener, erro
|
|||||||
return ln, nil
|
return ln, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetRootPath returns the root path of the tsnet server.
|
||||||
|
// This is where the state file and other data is stored.
|
||||||
|
func (s *Server) GetRootPath() string {
|
||||||
|
return s.rootPath
|
||||||
|
}
|
||||||
|
|
||||||
// CapturePcap can be called by the application code compiled with tsnet to save a pcap
|
// CapturePcap can be called by the application code compiled with tsnet to save a pcap
|
||||||
// of packets which the netstack within tsnet sees. This is expected to be useful during
|
// of packets which the netstack within tsnet sees. This is expected to be useful during
|
||||||
// debugging, probably not useful for production.
|
// debugging, probably not useful for production.
|
||||||
|
Loading…
Reference in New Issue
Block a user