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
import (
"crypto/tls"
"fmt"
"net"
"net/url"
@ -40,13 +41,23 @@ func parseFrontend(srv *Server, d *scfg.Directive) error {
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 {
host, port, err := net.SplitHostPort(addr)
if err != nil {
return fmt.Errorf("failed to parse frontend address %q: %v", addr, err)
}
if host != "" {
if host != "" && !unmanaged {
srv.ManagedNames = append(srv.ManagedNames, host)
}
@ -96,6 +107,29 @@ func parseBackend(backend *Backend, d *scfg.Directive) error {
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 {
for _, child := range d.Children {
switch child.Name {

View File

@ -16,11 +16,14 @@ import (
)
type Server struct {
Listeners map[string]*Listener // indexed by listening address
Frontends []*Frontend
ManagedNames []string
ACMEManager *certmagic.ACMEManager
ACMEConfig *certmagic.Config
Listeners map[string]*Listener // indexed by listening address
Frontends []*Frontend
ManagedNames []string
UnmanagedCerts []tls.Certificate
ACMEManager *certmagic.ACMEManager
ACMEConfig *certmagic.Config
}
func NewServer() *Server {
@ -55,6 +58,12 @@ func (srv *Server) RegisterListener(addr string) *Listener {
}
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 {
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
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* { ... }
Customise TLS configuration.
Customise global TLS configuration.
The tls directive supports the following sub-directives: