Add "tls load" frontend directive

This commit is contained in:
Simon Ser 2020-10-19 17:27:29 +02:00
parent a2bf967da7
commit b5b6bba5e4
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
3 changed files with 59 additions and 7 deletions

View File

@ -1,6 +1,7 @@
package tlstunnel package tlstunnel
import ( import (
"crypto/tls"
"fmt" "fmt"
"net" "net"
"net/url" "net/url"
@ -40,13 +41,23 @@ func parseFrontend(srv *Server, d *scfg.Directive) error {
return err return err
} }
unmanaged := false
tlsDirective := d.Children.Get("tls")
if tlsDirective != nil {
var err error
unmanaged, err = parseFrontendTLS(srv, tlsDirective)
if err != nil {
return err
}
}
for _, addr := range d.Params { for _, addr := range d.Params {
host, port, err := net.SplitHostPort(addr) host, port, err := net.SplitHostPort(addr)
if err != nil { if err != nil {
return fmt.Errorf("failed to parse frontend address %q: %v", addr, err) return fmt.Errorf("failed to parse frontend address %q: %v", addr, err)
} }
if host != "" { if host != "" && !unmanaged {
srv.ManagedNames = append(srv.ManagedNames, host) srv.ManagedNames = append(srv.ManagedNames, host)
} }
@ -96,6 +107,29 @@ func parseBackend(backend *Backend, d *scfg.Directive) error {
return nil return nil
} }
func parseFrontendTLS(srv *Server, d *scfg.Directive) (unmanaged bool, err error) {
for _, child := range d.Children {
switch child.Name {
case "load":
var certPath, keyPath string
if err := child.ParseParams(&certPath, &keyPath); err != nil {
return false, err
}
cert, err := tls.LoadX509KeyPair(certPath, keyPath)
if err != nil {
return false, fmt.Errorf("directive \"load\": %v", err)
}
srv.UnmanagedCerts = append(srv.UnmanagedCerts, cert)
unmanaged = true
default:
return false, fmt.Errorf("unknown %q directive", child.Name)
}
}
return unmanaged, nil
}
func parseTLS(srv *Server, d *scfg.Directive) error { func parseTLS(srv *Server, d *scfg.Directive) error {
for _, child := range d.Children { for _, child := range d.Children {
switch child.Name { switch child.Name {

View File

@ -18,7 +18,10 @@ import (
type Server struct { type Server struct {
Listeners map[string]*Listener // indexed by listening address Listeners map[string]*Listener // indexed by listening address
Frontends []*Frontend Frontends []*Frontend
ManagedNames []string ManagedNames []string
UnmanagedCerts []tls.Certificate
ACMEManager *certmagic.ACMEManager ACMEManager *certmagic.ACMEManager
ACMEConfig *certmagic.Config ACMEConfig *certmagic.Config
} }
@ -55,6 +58,12 @@ func (srv *Server) RegisterListener(addr string) *Listener {
} }
func (srv *Server) Start() error { func (srv *Server) Start() error {
for _, cert := range srv.UnmanagedCerts {
if err := srv.ACMEConfig.CacheUnmanagedTLSCertificate(cert, nil); err != nil {
return err
}
}
if err := srv.ACMEConfig.ManageAsync(context.Background(), srv.ManagedNames); err != nil { if err := srv.ACMEConfig.ManageAsync(context.Background(), srv.ManagedNames); err != nil {
return fmt.Errorf("failed to manage TLS certificates: %v", err) return fmt.Errorf("failed to manage TLS certificates: %v", err)
} }

View File

@ -55,9 +55,18 @@ The following directives are supported:
The _+proxy_ suffix can be added to the URI scheme to forward The _+proxy_ suffix can be added to the URI scheme to forward
connection metadata via the PROXY protocol. connection metadata via the PROXY protocol.
*tls* { ... }
Customise frontend-specific TLS configuration.
The tls directive supports the following sub-directives:
*load* <cert> <key>
Load certificates and private keys from PEM files.
This disables automatic TLS.
*tls* { ... } *tls* { ... }
Customise TLS configuration. Customise global TLS configuration.
The tls directive supports the following sub-directives: The tls directive supports the following sub-directives: