mirror of
https://github.com/tailscale/tailscale.git
synced 2025-01-07 08:07:42 +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/netaddr"
|
||||||
"inet.af/peercred"
|
"inet.af/peercred"
|
||||||
"tailscale.com/control/controlclient"
|
"tailscale.com/control/controlclient"
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/ipn/ipnlocal"
|
"tailscale.com/ipn/ipnlocal"
|
||||||
"tailscale.com/ipn/localapi"
|
"tailscale.com/ipn/localapi"
|
||||||
@ -445,6 +446,26 @@ func (s *Server) localAPIPermissions(ci connIdentity) (read, write bool) {
|
|||||||
return false, false
|
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
|
// registerDisconnectSub adds ch as a subscribe to connection disconnect
|
||||||
// events. If add is false, the subscriber is removed.
|
// events. If add is false, the subscriber is removed.
|
||||||
func (s *Server) registerDisconnectSub(ch chan<- struct{}, add bool) {
|
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 {
|
func (s *Server) localhostHandler(ci connIdentity) http.Handler {
|
||||||
lah := localapi.NewHandler(s.b, s.logf, s.backendLogID)
|
lah := localapi.NewHandler(s.b, s.logf, s.backendLogID)
|
||||||
lah.PermitRead, lah.PermitWrite = s.localAPIPermissions(ci)
|
lah.PermitRead, lah.PermitWrite = s.localAPIPermissions(ci)
|
||||||
|
lah.PermitCert = s.connCanFetchCerts(ci)
|
||||||
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if strings.HasPrefix(r.URL.Path, "/localapi/") {
|
if strings.HasPrefix(r.URL.Path, "/localapi/") {
|
||||||
|
@ -66,7 +66,7 @@ func (h *Handler) certDir() (string, error) {
|
|||||||
var acmeDebug = envknob.Bool("TS_DEBUG_ACME")
|
var acmeDebug = envknob.Bool("TS_DEBUG_ACME")
|
||||||
|
|
||||||
func (h *Handler) serveCert(w http.ResponseWriter, r *http.Request) {
|
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)
|
http.Error(w, "cert access denied", http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -52,8 +52,15 @@ type Handler struct {
|
|||||||
PermitRead bool
|
PermitRead bool
|
||||||
|
|
||||||
// PermitWrite is whether mutating HTTP handlers are allowed.
|
// 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
|
PermitWrite bool
|
||||||
|
|
||||||
|
// PermitCert is whether the client is additionally granted
|
||||||
|
// cert fetching access.
|
||||||
|
PermitCert bool
|
||||||
|
|
||||||
b *ipnlocal.LocalBackend
|
b *ipnlocal.LocalBackend
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
backendLogID string
|
backendLogID string
|
||||||
|
Loading…
x
Reference in New Issue
Block a user