cmd/stdiscosrv: Support deploying behind Caddyserver (#8092)

This commit is contained in:
Kebin Liu 2022-01-05 22:17:13 +08:00 committed by GitHub
parent c00c6b3957
commit 083fa1803a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 21 additions and 10 deletions

View File

@ -10,8 +10,10 @@ import (
"bytes" "bytes"
"context" "context"
"crypto/tls" "crypto/tls"
"encoding/base64"
"encoding/json" "encoding/json"
"encoding/pem" "encoding/pem"
"errors"
"fmt" "fmt"
"log" "log"
"math/rand" "math/rand"
@ -229,10 +231,10 @@ func (s *apiSrv) handleGET(ctx context.Context, w http.ResponseWriter, req *http
func (s *apiSrv) handlePOST(ctx context.Context, remoteAddr *net.TCPAddr, w http.ResponseWriter, req *http.Request) { func (s *apiSrv) handlePOST(ctx context.Context, remoteAddr *net.TCPAddr, w http.ResponseWriter, req *http.Request) {
reqID := ctx.Value(idKey).(requestID) reqID := ctx.Value(idKey).(requestID)
rawCert := certificateBytes(req) rawCert, err := certificateBytes(req)
if rawCert == nil { if err != nil {
if debug { if debug {
log.Println(reqID, "no certificates") log.Println(reqID, "no certificates:", err)
} }
announceRequestsTotal.WithLabelValues("no_certificate").Inc() announceRequestsTotal.WithLabelValues("no_certificate").Inc()
w.Header().Set("Retry-After", errorRetryAfterString()) w.Header().Set("Retry-After", errorRetryAfterString())
@ -304,9 +306,9 @@ func handlePing(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(204) w.WriteHeader(204)
} }
func certificateBytes(req *http.Request) []byte { func certificateBytes(req *http.Request) ([]byte, error) {
if req.TLS != nil && len(req.TLS.PeerCertificates) > 0 { if req.TLS != nil && len(req.TLS.PeerCertificates) > 0 {
return req.TLS.PeerCertificates[0].Raw return req.TLS.PeerCertificates[0].Raw, nil
} }
var bs []byte var bs []byte
@ -319,7 +321,7 @@ func certificateBytes(req *http.Request) []byte {
hdr, err := url.QueryUnescape(hdr) hdr, err := url.QueryUnescape(hdr)
if err != nil { if err != nil {
// Decoding failed // Decoding failed
return nil return nil, err
} }
bs = []byte(hdr) bs = []byte(hdr)
@ -338,6 +340,15 @@ func certificateBytes(req *http.Request) []byte {
} }
} }
} }
} else if hdr := req.Header.Get("X-Tls-Client-Cert-Der-Base64"); hdr != "" {
// Caddy {tls_client_certificate_der_base64}
hdr, err := base64.StdEncoding.DecodeString(hdr)
if err != nil {
// Decoding failed
return nil, err
}
bs = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: hdr})
} else if hdr := req.Header.Get("X-Forwarded-Tls-Client-Cert"); hdr != "" { } else if hdr := req.Header.Get("X-Forwarded-Tls-Client-Cert"); hdr != "" {
// Traefik 2 passtlsclientcert // Traefik 2 passtlsclientcert
// The certificate is in PEM format with url encoding but without newlines // The certificate is in PEM format with url encoding but without newlines
@ -346,7 +357,7 @@ func certificateBytes(req *http.Request) []byte {
hdr, err := url.QueryUnescape(hdr) hdr, err := url.QueryUnescape(hdr)
if err != nil { if err != nil {
// Decoding failed // Decoding failed
return nil return nil, err
} }
for i := 64; i < len(hdr); i += 65 { for i := 64; i < len(hdr); i += 65 {
@ -359,16 +370,16 @@ func certificateBytes(req *http.Request) []byte {
} }
if bs == nil { if bs == nil {
return nil return nil, errors.New("empty certificate header")
} }
block, _ := pem.Decode(bs) block, _ := pem.Decode(bs)
if block == nil { if block == nil {
// Decoding failed // Decoding failed
return nil return nil, errors.New("certificate decode result is empty")
} }
return block.Bytes return block.Bytes, nil
} }
// fixupAddresses checks the list of addresses, removing invalid ones and // fixupAddresses checks the list of addresses, removing invalid ones and