mirror of https://github.com/caddyserver/caddy.git
reverse_proxy: Add tls_trusted_ca_certs to Caddyfile (#2936)
Allows specifying ca certs with by filename in `reverse_proxy.transport`. Example ``` reverse_proxy /api api:443 { transport http { tls tls_trusted_ca_certs certs/rootCA.pem } } ```
This commit is contained in:
parent
78e98c40d3
commit
21f1f95e7b
|
@ -425,6 +425,7 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
||||||
// tls_client_auth <cert_file> <key_file>
|
// tls_client_auth <cert_file> <key_file>
|
||||||
// tls_insecure_skip_verify
|
// tls_insecure_skip_verify
|
||||||
// tls_timeout <duration>
|
// tls_timeout <duration>
|
||||||
|
// tls_trusted_ca_certs <cert_files...>
|
||||||
// keepalive [off|<duration>]
|
// keepalive [off|<duration>]
|
||||||
// keepalive_idle_conns <max_count>
|
// keepalive_idle_conns <max_count>
|
||||||
// }
|
// }
|
||||||
|
@ -501,6 +502,17 @@ func (h *HTTPTransport) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
||||||
}
|
}
|
||||||
h.TLS.HandshakeTimeout = caddy.Duration(dur)
|
h.TLS.HandshakeTimeout = caddy.Duration(dur)
|
||||||
|
|
||||||
|
case "tls_trusted_ca_certs":
|
||||||
|
args := d.RemainingArgs()
|
||||||
|
if len(args) == 0 {
|
||||||
|
return d.ArgErr()
|
||||||
|
}
|
||||||
|
if h.TLS == nil {
|
||||||
|
h.TLS = new(TLSConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
h.TLS.RootCAPemFiles = args
|
||||||
|
|
||||||
case "keepalive":
|
case "keepalive":
|
||||||
if !d.NextArg() {
|
if !d.NextArg() {
|
||||||
return d.ArgErr()
|
return d.ArgErr()
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -166,6 +167,9 @@ func (h *HTTPTransport) setScheme(req *http.Request) {
|
||||||
|
|
||||||
// Cleanup implements caddy.CleanerUpper and closes any idle connections.
|
// Cleanup implements caddy.CleanerUpper and closes any idle connections.
|
||||||
func (h HTTPTransport) Cleanup() error {
|
func (h HTTPTransport) Cleanup() error {
|
||||||
|
if h.Transport == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
h.Transport.CloseIdleConnections()
|
h.Transport.CloseIdleConnections()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -174,6 +178,8 @@ func (h HTTPTransport) Cleanup() error {
|
||||||
// TLS configuration for the transport/client.
|
// TLS configuration for the transport/client.
|
||||||
type TLSConfig struct {
|
type TLSConfig struct {
|
||||||
RootCAPool []string `json:"root_ca_pool,omitempty"`
|
RootCAPool []string `json:"root_ca_pool,omitempty"`
|
||||||
|
// Added to the same pool as above, but brought in from files
|
||||||
|
RootCAPemFiles []string `json:"root_ca_pem_files,omitempty"`
|
||||||
// TODO: Should the client cert+key config use caddytls.CertificateLoader modules?
|
// TODO: Should the client cert+key config use caddytls.CertificateLoader modules?
|
||||||
ClientCertificateFile string `json:"client_certificate_file,omitempty"`
|
ClientCertificateFile string `json:"client_certificate_file,omitempty"`
|
||||||
ClientCertificateKeyFile string `json:"client_certificate_key_file,omitempty"`
|
ClientCertificateKeyFile string `json:"client_certificate_key_file,omitempty"`
|
||||||
|
@ -203,7 +209,7 @@ func (t TLSConfig) MakeTLSClientConfig() (*tls.Config, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// trusted root CAs
|
// trusted root CAs
|
||||||
if len(t.RootCAPool) > 0 {
|
if len(t.RootCAPool) > 0 || len(t.RootCAPemFiles) > 0 {
|
||||||
rootPool := x509.NewCertPool()
|
rootPool := x509.NewCertPool()
|
||||||
for _, encodedCACert := range t.RootCAPool {
|
for _, encodedCACert := range t.RootCAPool {
|
||||||
caCert, err := decodeBase64DERCert(encodedCACert)
|
caCert, err := decodeBase64DERCert(encodedCACert)
|
||||||
|
@ -212,6 +218,14 @@ func (t TLSConfig) MakeTLSClientConfig() (*tls.Config, error) {
|
||||||
}
|
}
|
||||||
rootPool.AddCert(caCert)
|
rootPool.AddCert(caCert)
|
||||||
}
|
}
|
||||||
|
for _, pemFile := range t.RootCAPemFiles {
|
||||||
|
pemData, err := ioutil.ReadFile(pemFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed reading ca cert: %v", err)
|
||||||
|
}
|
||||||
|
rootPool.AppendCertsFromPEM(pemData)
|
||||||
|
|
||||||
|
}
|
||||||
cfg.RootCAs = rootPool
|
cfg.RootCAs = rootPool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue