mirror of
https://github.com/tailscale/tailscale.git
synced 2025-01-05 23:07:44 +00:00
ipn/ipnserver: add TS_PERMIT_CERT_UID envknob to give webservers cert access
So you can run Caddy etc as a non-root user and let it have access to get certs. Updates caddyserver/caddy#4541 Change-Id: Iecc5922274530e2b00ba107d4b536580f374109b Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
508f332bb2
commit
ca774c3249
@ -32,6 +32,7 @@
|
||||
"inet.af/netaddr"
|
||||
"inet.af/peercred"
|
||||
"tailscale.com/control/controlclient"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/ipnlocal"
|
||||
"tailscale.com/ipn/localapi"
|
||||
@ -445,6 +446,26 @@ func (s *Server) localAPIPermissions(ci connIdentity) (read, write bool) {
|
||||
return false, false
|
||||
}
|
||||
|
||||
// connCanFetchCerts reports whether ci is allowed to fetch HTTPS
|
||||
// certs from this server when it wouldn't otherwise be able to.
|
||||
//
|
||||
// That is, this reports whether ci should grant additional
|
||||
// capabilities over what the conn would otherwise be able to do.
|
||||
//
|
||||
// For now this only returns true on Unix machines when
|
||||
// TS_PERMIT_CERT_UID is set the to the userid of the peer
|
||||
// connection. It's intended to give your non-root webserver access
|
||||
// (www-data, caddy, nginx, etc) to certs.
|
||||
func (s *Server) connCanFetchCerts(ci connIdentity) bool {
|
||||
if ci.IsUnixSock && ci.Creds != nil {
|
||||
connUID, ok := ci.Creds.UserID()
|
||||
if ok && connUID == envknob.String("TS_PERMIT_CERT_UID") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// registerDisconnectSub adds ch as a subscribe to connection disconnect
|
||||
// events. If add is false, the subscriber is removed.
|
||||
func (s *Server) registerDisconnectSub(ch chan<- struct{}, add bool) {
|
||||
@ -1075,6 +1096,7 @@ func (psc *protoSwitchConn) Close() error {
|
||||
func (s *Server) localhostHandler(ci connIdentity) http.Handler {
|
||||
lah := localapi.NewHandler(s.b, s.logf, s.backendLogID)
|
||||
lah.PermitRead, lah.PermitWrite = s.localAPIPermissions(ci)
|
||||
lah.PermitCert = s.connCanFetchCerts(ci)
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.HasPrefix(r.URL.Path, "/localapi/") {
|
||||
|
@ -66,7 +66,7 @@ func (h *Handler) certDir() (string, error) {
|
||||
var acmeDebug = envknob.Bool("TS_DEBUG_ACME")
|
||||
|
||||
func (h *Handler) serveCert(w http.ResponseWriter, r *http.Request) {
|
||||
if !h.PermitWrite {
|
||||
if !h.PermitWrite && !h.PermitCert {
|
||||
http.Error(w, "cert access denied", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
@ -52,8 +52,15 @@ type Handler struct {
|
||||
PermitRead bool
|
||||
|
||||
// PermitWrite is whether mutating HTTP handlers are allowed.
|
||||
// If PermitWrite is true, everything is allowed.
|
||||
// It effectively means that the user is root or the admin
|
||||
// (operator user).
|
||||
PermitWrite bool
|
||||
|
||||
// PermitCert is whether the client is additionally granted
|
||||
// cert fetching access.
|
||||
PermitCert bool
|
||||
|
||||
b *ipnlocal.LocalBackend
|
||||
logf logger.Logf
|
||||
backendLogID string
|
||||
|
Loading…
x
Reference in New Issue
Block a user