mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-05 21:57:18 +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"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -60,6 +61,9 @@ type ctxConn struct{
|
||||
// accessing the IDP over Funnel are persisted.
|
||||
const funnelClientsFile = "oidc-funnel-clients.json"
|
||||
|
||||
// oidcKeyFile is where the OIDC private key is persisted.
|
||||
const oidcKeyFile = "oidc-key.json"
|
||||
|
||||
var (
|
||||
flagVerbose = flag.Bool("verbose", false, "be verbose")
|
||||
flagPort = flag.Int("port", 443, "port to listen on")
|
||||
@ -80,12 +84,14 @@ func main() {
|
||||
var (
|
||||
lc *local.Client
|
||||
st *ipnstate.Status
|
||||
rootPath string
|
||||
err error
|
||||
watcherChan chan error
|
||||
cleanup func()
|
||||
|
||||
lns []net.Listener
|
||||
)
|
||||
|
||||
if *flagUseLocalTailscaled {
|
||||
lc = &local.Client{}
|
||||
st, err = lc.StatusWithoutPeers(ctx)
|
||||
@ -110,6 +116,15 @@ func main() {
|
||||
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
|
||||
// that older versions don't provide.
|
||||
// TODO(naman): is this the correct check?
|
||||
@ -127,6 +142,8 @@ func main() {
|
||||
Hostname: *flagHostname,
|
||||
Dir: *flagDir,
|
||||
}
|
||||
rootPath = ts.GetRootPath()
|
||||
log.Printf("tsidp root path: %s", rootPath)
|
||||
if *flagVerbose {
|
||||
ts.Logf = log.Printf
|
||||
}
|
||||
@ -157,7 +174,9 @@ func main() {
|
||||
lc: lc,
|
||||
funnel: *flagFunnel,
|
||||
localTSMode: *flagUseLocalTailscaled,
|
||||
rootPath: rootPath,
|
||||
}
|
||||
|
||||
if *flagPort != 443 {
|
||||
srv.serverURL = fmt.Sprintf("https://%s:%d", strings.TrimSuffix(st.Self.DNSName, "."), *flagPort)
|
||||
} else {
|
||||
@ -285,6 +304,7 @@ type idpServer struct {
|
||||
serverURL string // "https://foo.bar.ts.net"
|
||||
funnel bool
|
||||
localTSMode bool
|
||||
rootPath string // root path, used for storing state files
|
||||
|
||||
lazyMux lazy.SyncValue[*http.ServeMux]
|
||||
lazySigningKey lazy.SyncValue[*signingKey]
|
||||
@ -819,8 +839,9 @@ func (s *idpServer) oidcSigner() (jose.Signer, error) {
|
||||
|
||||
func (s *idpServer) oidcPrivateKey() (*signingKey, error) {
|
||||
return s.lazySigningKey.GetErr(func() (*signingKey, error) {
|
||||
keyPath := filepath.Join(s.rootPath, oidcKeyFile)
|
||||
var sk signingKey
|
||||
b, err := os.ReadFile("oidc-key.json")
|
||||
b, err := os.ReadFile(keyPath)
|
||||
if err == nil {
|
||||
if err := sk.UnmarshalJSON(b); err == nil {
|
||||
return &sk, nil
|
||||
@ -835,7 +856,7 @@ func (s *idpServer) oidcPrivateKey() (*signingKey, error) {
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
return &sk, nil
|
||||
@ -869,7 +890,6 @@ func (s *idpServer) serveJWKS(w http.ResponseWriter, r *http.Request) {
|
||||
}); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
// of packets which the netstack within tsnet sees. This is expected to be useful during
|
||||
// debugging, probably not useful for production.
|
||||
|
Loading…
Reference in New Issue
Block a user