parent
64285842fe
commit
e8f71081cb
|
@ -51,6 +51,11 @@ func parseFrontend(srv *Server, d *scfg.Directive) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protocolDirective := d.Children.Get("protocol")
|
||||||
|
if protocolDirective != nil {
|
||||||
|
frontend.Protocols = protocolDirective.Params
|
||||||
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
|
65
server.go
65
server.go
|
@ -133,35 +133,68 @@ func (ln *Listener) handle(conn net.Conn) error {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
// TODO: setup timeouts
|
// TODO: setup timeouts
|
||||||
tlsConn := tls.Server(conn, ln.Server.ACMEConfig.TLSConfig())
|
tlsConfig := ln.Server.ACMEConfig.TLSConfig()
|
||||||
|
getConfigForClient := tlsConfig.GetConfigForClient
|
||||||
|
tlsConfig.GetConfigForClient = func(hello *tls.ClientHelloInfo) (*tls.Config, error) {
|
||||||
|
// Call previous GetConfigForClient function, if any
|
||||||
|
var tlsConfig *tls.Config
|
||||||
|
if getConfigForClient != nil {
|
||||||
|
var err error
|
||||||
|
tlsConfig, err = getConfigForClient(hello)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tlsConfig = ln.Server.ACMEConfig.TLSConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
fe, err := ln.matchFrontend(hello.ServerName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsConfig.NextProtos = fe.Protocols
|
||||||
|
return tlsConfig, nil
|
||||||
|
}
|
||||||
|
tlsConn := tls.Server(conn, tlsConfig)
|
||||||
if err := tlsConn.Handshake(); err != nil {
|
if err := tlsConn.Handshake(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsState := tlsConn.ConnectionState()
|
tlsState := tlsConn.ConnectionState()
|
||||||
|
fe, err := ln.matchFrontend(tlsState.ServerName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
fe, ok := ln.Frontends[tlsState.ServerName]
|
return fe.handle(tlsConn, &tlsState)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ln *Listener) matchFrontend(serverName string) (*Frontend, error) {
|
||||||
|
fe, ok := ln.Frontends[serverName]
|
||||||
if !ok {
|
if !ok {
|
||||||
// match wildcard certificates, allowing only a single, non-partial wildcard, in the left-most label
|
// Match wildcard certificates, allowing only a single, non-partial
|
||||||
i := strings.IndexByte(tlsState.ServerName, '.')
|
// wildcard, in the left-most label
|
||||||
// don't allow wildcards with only a TLD (eg *.com)
|
i := strings.IndexByte(serverName, '.')
|
||||||
if i >= 0 && strings.IndexByte(tlsState.ServerName[i+1:], '.') >= 0 {
|
// Don't allow wildcards with only a TLD (e.g. *.com)
|
||||||
fe, ok = ln.Frontends["*"+tlsState.ServerName[i:]]
|
if i >= 0 && strings.IndexByte(serverName[i+1:], '.') >= 0 {
|
||||||
|
fe, ok = ln.Frontends["*"+serverName[i:]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
fe, ok = ln.Frontends[""]
|
fe, ok = ln.Frontends[""]
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("can't find frontend for server name %q", tlsState.ServerName)
|
return nil, fmt.Errorf("can't find frontend for server name %q", serverName)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fe.handle(tlsConn, &tlsState)
|
return fe, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Frontend struct {
|
type Frontend struct {
|
||||||
Server *Server
|
Server *Server
|
||||||
Backend Backend
|
Backend Backend
|
||||||
|
Protocols []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fe *Frontend) handle(downstream net.Conn, tlsState *tls.ConnectionState) error {
|
func (fe *Frontend) handle(downstream net.Conn, tlsState *tls.ConnectionState) error {
|
||||||
|
@ -184,6 +217,9 @@ func (fe *Frontend) handle(downstream net.Conn, tlsState *tls.ConnectionState) e
|
||||||
if tlsState.ServerName != "" {
|
if tlsState.ServerName != "" {
|
||||||
tlvs = append(tlvs, authorityTLV(tlsState.ServerName))
|
tlvs = append(tlvs, authorityTLV(tlsState.ServerName))
|
||||||
}
|
}
|
||||||
|
if tlsState.NegotiatedProtocol != "" {
|
||||||
|
tlvs = append(tlvs, alpnTLV(tlsState.NegotiatedProtocol))
|
||||||
|
}
|
||||||
if tlv, err := sslTLV(tlsState); err != nil {
|
if tlv, err := sslTLV(tlsState); err != nil {
|
||||||
return fmt.Errorf("failed to set PROXY protocol header SSL TLV: %v", err)
|
return fmt.Errorf("failed to set PROXY protocol header SSL TLV: %v", err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -228,6 +264,13 @@ func authorityTLV(name string) proxyproto.TLV {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func alpnTLV(proto string) proxyproto.TLV {
|
||||||
|
return proxyproto.TLV{
|
||||||
|
Type: proxyproto.PP2_TYPE_ALPN,
|
||||||
|
Value: []byte(proto),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func sslTLV(state *tls.ConnectionState) (proxyproto.TLV, error) {
|
func sslTLV(state *tls.ConnectionState) (proxyproto.TLV, error) {
|
||||||
pp2ssl := tlvparse.PP2SSL{
|
pp2ssl := tlvparse.PP2SSL{
|
||||||
Client: tlvparse.PP2_BITFIELD_CLIENT_SSL, // all of our connections are TLS
|
Client: tlvparse.PP2_BITFIELD_CLIENT_SSL, // all of our connections are TLS
|
||||||
|
|
|
@ -66,6 +66,21 @@ The following directives are supported:
|
||||||
|
|
||||||
This disables automatic TLS.
|
This disables automatic TLS.
|
||||||
|
|
||||||
|
*protocol* <name>...
|
||||||
|
List of supported application-layer protocols.
|
||||||
|
|
||||||
|
The first protocol which is also supported by the client is negociated.
|
||||||
|
|
||||||
|
The protocols will be advertised via the TLS ALPN extension. See the
|
||||||
|
IANA registry for a list of protocol names:
|
||||||
|
https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
|
||||||
|
|
||||||
|
For instance, for an HTTP server supporting HTTP/1 and HTTP/2:
|
||||||
|
|
||||||
|
```
|
||||||
|
protocol h2 http/1.1 http/1.0
|
||||||
|
```
|
||||||
|
|
||||||
*tls* { ... }
|
*tls* { ... }
|
||||||
Customise global TLS configuration.
|
Customise global TLS configuration.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue