mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-06 22:40:31 -05:00
proxy: ability to use client certs in reverse proxy (#2914)
* ability to use client certs in reverse proxy * changed to http3.RoundTripper after review
This commit is contained in:
parent
6f9a39525a
commit
5ec503386c
2 changed files with 39 additions and 0 deletions
|
@ -337,6 +337,26 @@ func (rp *ReverseProxy) UseOwnCACertificates(CaCertPool *x509.CertPool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UseClientCertificates is used to facilitate HTTPS proxying
|
||||||
|
// with locally provided certificate.
|
||||||
|
func (rp *ReverseProxy) UseClientCertificates(keyPair *tls.Certificate) {
|
||||||
|
if transport, ok := rp.Transport.(*http.Transport); ok {
|
||||||
|
if transport.TLSClientConfig == nil {
|
||||||
|
transport.TLSClientConfig = &tls.Config{}
|
||||||
|
}
|
||||||
|
transport.TLSClientConfig.Certificates = []tls.Certificate{ *keyPair }
|
||||||
|
// No http2.ConfigureTransport() here.
|
||||||
|
// For now this is only added in places where
|
||||||
|
// an http.Transport is actually created.
|
||||||
|
} else if transport, ok := rp.Transport.(*http3.RoundTripper); ok {
|
||||||
|
if transport.TLSClientConfig == nil {
|
||||||
|
transport.TLSClientConfig = &tls.Config{}
|
||||||
|
}
|
||||||
|
transport.TLSClientConfig.Certificates = []tls.Certificate{ *keyPair }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ServeHTTP serves the proxied request to the upstream by performing a roundtrip.
|
// ServeHTTP serves the proxied request to the upstream by performing a roundtrip.
|
||||||
// It is designed to handle websocket connection upgrades as well.
|
// It is designed to handle websocket connection upgrades as well.
|
||||||
func (rp *ReverseProxy) ServeHTTP(rw http.ResponseWriter, outreq *http.Request, respUpdateFn respUpdateFn) error {
|
func (rp *ReverseProxy) ServeHTTP(rw http.ResponseWriter, outreq *http.Request, respUpdateFn respUpdateFn) error {
|
||||||
|
|
|
@ -76,6 +76,7 @@ type staticUpstream struct {
|
||||||
CaCertPool *x509.CertPool
|
CaCertPool *x509.CertPool
|
||||||
upstreamHeaderReplacements headerReplacements
|
upstreamHeaderReplacements headerReplacements
|
||||||
downstreamHeaderReplacements headerReplacements
|
downstreamHeaderReplacements headerReplacements
|
||||||
|
ClientKeyPair *tls.Certificate
|
||||||
}
|
}
|
||||||
|
|
||||||
type srvResolver interface {
|
type srvResolver interface {
|
||||||
|
@ -267,6 +268,10 @@ func (u *staticUpstream) NewHost(host string) (*UpstreamHost, error) {
|
||||||
uh.ReverseProxy.UseOwnCACertificates(u.CaCertPool)
|
uh.ReverseProxy.UseOwnCACertificates(u.CaCertPool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if u.ClientKeyPair != nil {
|
||||||
|
uh.ReverseProxy.UseClientCertificates(u.ClientKeyPair)
|
||||||
|
}
|
||||||
|
|
||||||
return uh, nil
|
return uh, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,6 +569,20 @@ func parseBlock(c *caddyfile.Dispenser, u *staticUpstream, hasSrv bool) error {
|
||||||
return c.Errf("unable to parse timeout duration '%s'", c.Val())
|
return c.Errf("unable to parse timeout duration '%s'", c.Val())
|
||||||
}
|
}
|
||||||
u.Timeout = dur
|
u.Timeout = dur
|
||||||
|
case "tls_client":
|
||||||
|
if !c.NextArg() {
|
||||||
|
return c.ArgErr()
|
||||||
|
}
|
||||||
|
clientCertFile := c.Val()
|
||||||
|
if !c.NextArg() {
|
||||||
|
return c.ArgErr()
|
||||||
|
}
|
||||||
|
clientKeyFile := c.Val()
|
||||||
|
clientKeyPair, err := tls.LoadX509KeyPair(clientCertFile, clientKeyFile)
|
||||||
|
if (err != nil) {
|
||||||
|
return c.Errf("unable to load keypair from certfile:%s keyfile:%s", clientCertFile, clientKeyFile)
|
||||||
|
}
|
||||||
|
u.ClientKeyPair = &clientKeyPair
|
||||||
default:
|
default:
|
||||||
return c.Errf("unknown property '%s'", c.Val())
|
return c.Errf("unknown property '%s'", c.Val())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue