mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-30 22:34:15 -05:00
reverse_proxy: Implement remaining TLS config for proxy to backend
This commit is contained in:
parent
ccfb12347b
commit
4a1e1649bc
1 changed files with 81 additions and 5 deletions
|
@ -15,8 +15,13 @@
|
|||
package reverseproxy
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/caddyserver/caddy/v2"
|
||||
|
@ -76,7 +81,12 @@ func (h *HTTPTransport) Provision(ctx caddy.Context) error {
|
|||
|
||||
if h.TLS != nil {
|
||||
rt.TLSHandshakeTimeout = time.Duration(h.TLS.HandshakeTimeout)
|
||||
// TODO: rest of TLS config
|
||||
|
||||
var err error
|
||||
rt.TLSClientConfig, err = h.TLS.MakeTLSClientConfig()
|
||||
if err != nil {
|
||||
return fmt.Errorf("making TLS client config: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if h.KeepAlive != nil {
|
||||
|
@ -103,13 +113,79 @@ func (h HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
|||
return h.RoundTripper.RoundTrip(req)
|
||||
}
|
||||
|
||||
func defaultTLSConfig() *tls.Config {
|
||||
return &tls.Config{
|
||||
NextProtos: []string{"h2", "http/1.1"}, // TODO: ensure this makes HTTP/2 work
|
||||
}
|
||||
}
|
||||
|
||||
type TLSConfig struct {
|
||||
CAPool []string `json:"ca_pool,omitempty"`
|
||||
ClientCertificate string `json:"client_certificate,omitempty"`
|
||||
RootCAPool []string `json:"root_ca_pool,omitempty"`
|
||||
// TODO: Should the client cert+key config use caddytls.CertificateLoader modules?
|
||||
ClientCertificateFile string `json:"client_certificate_file,omitempty"`
|
||||
ClientCertificateKeyFile string `json:"client_certificate_key_file,omitempty"`
|
||||
InsecureSkipVerify bool `json:"insecure_skip_verify,omitempty"`
|
||||
HandshakeTimeout caddy.Duration `json:"handshake_timeout,omitempty"`
|
||||
}
|
||||
|
||||
// MakeTLSClientConfig returns a tls.Config usable by a client to a backend.
|
||||
// If there is no custom TLS configuration, a nil config may be returned.
|
||||
func (t TLSConfig) MakeTLSClientConfig() (*tls.Config, error) {
|
||||
cfg := new(tls.Config)
|
||||
|
||||
// client auth
|
||||
if t.ClientCertificateFile != "" && t.ClientCertificateKeyFile == "" {
|
||||
return nil, fmt.Errorf("client_certificate_file specified without client_certificate_key_file")
|
||||
}
|
||||
if t.ClientCertificateFile == "" && t.ClientCertificateKeyFile != "" {
|
||||
return nil, fmt.Errorf("client_certificate_key_file specified without client_certificate_file")
|
||||
}
|
||||
if t.ClientCertificateFile != "" && t.ClientCertificateKeyFile != "" {
|
||||
cert, err := tls.LoadX509KeyPair(t.ClientCertificateFile, t.ClientCertificateKeyFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loading client certificate key pair: %v", err)
|
||||
}
|
||||
cfg.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
|
||||
// trusted root CAs
|
||||
if len(t.RootCAPool) > 0 {
|
||||
rootPool := x509.NewCertPool()
|
||||
for _, encodedCACert := range t.RootCAPool {
|
||||
caCert, err := decodeBase64DERCert(encodedCACert)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing CA certificate: %v", err)
|
||||
}
|
||||
rootPool.AddCert(caCert)
|
||||
}
|
||||
cfg.RootCAs = rootPool
|
||||
}
|
||||
|
||||
// throw all security out the window
|
||||
cfg.InsecureSkipVerify = t.InsecureSkipVerify
|
||||
|
||||
// only return a config if it's not empty
|
||||
if reflect.DeepEqual(cfg, new(tls.Config)) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
cfg.NextProtos = []string{"h2", "http/1.1"} // TODO: ensure that this actually enables HTTP/2
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
// decodeBase64DERCert base64-decodes, then DER-decodes, certStr.
|
||||
func decodeBase64DERCert(certStr string) (*x509.Certificate, error) {
|
||||
// decode base64
|
||||
derBytes, err := base64.StdEncoding.DecodeString(certStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// parse the DER-encoded certificate
|
||||
return x509.ParseCertificate(derBytes)
|
||||
}
|
||||
|
||||
type KeepAlive struct {
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
ProbeInterval caddy.Duration `json:"probe_interval,omitempty"`
|
||||
|
|
Loading…
Reference in a new issue