mirror of
https://git.sr.ht/~emersion/tlstunnel
synced 2024-11-19 15:53:50 +01:00
Add client_auth directive
This commit is contained in:
parent
c888547e5b
commit
c3623f6b38
39
config.go
39
config.go
@ -39,7 +39,8 @@ type frontendConfig struct {
|
|||||||
} `scfg:"listen"`
|
} `scfg:"listen"`
|
||||||
Backend *backendConfig `scfg:"backend"`
|
Backend *backendConfig `scfg:"backend"`
|
||||||
TLS struct {
|
TLS struct {
|
||||||
Load *[2]string `scfg:"load"`
|
Load *[2]string `scfg:"load"`
|
||||||
|
ClientAuth *[2]string `scfg:"client_auth"`
|
||||||
} `scfg:"tls"`
|
} `scfg:"tls"`
|
||||||
Protocol []string `scfg:"protocol"`
|
Protocol []string `scfg:"protocol"`
|
||||||
}
|
}
|
||||||
@ -129,6 +130,25 @@ func parseFrontend(srv *Server, cfg *frontendConfig) error {
|
|||||||
srv.UnmanagedCerts = append(srv.UnmanagedCerts, cert)
|
srv.UnmanagedCerts = append(srv.UnmanagedCerts, cert)
|
||||||
unmanaged = true
|
unmanaged = true
|
||||||
}
|
}
|
||||||
|
if cfg.TLS.ClientAuth != nil {
|
||||||
|
clientAuth, err := parseClientAuth(cfg.TLS.ClientAuth[0])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf(`directive "tls.client_auth": %w`, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
clientCAs, err := os.ReadFile(cfg.TLS.ClientAuth[1])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf(`directive "tls.client_auth": %w`, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pool := x509.NewCertPool()
|
||||||
|
if ok := pool.AppendCertsFromPEM(clientCAs); !ok {
|
||||||
|
return fmt.Errorf("failed to append to client pool")
|
||||||
|
}
|
||||||
|
|
||||||
|
frontend.ClientAuth = clientAuth
|
||||||
|
frontend.ClientCAs = pool
|
||||||
|
}
|
||||||
|
|
||||||
frontend.Protocols = cfg.Protocol
|
frontend.Protocols = cfg.Protocol
|
||||||
|
|
||||||
@ -292,3 +312,20 @@ func parseTLSOnDemand(srv *Server, cfg *tlsOnDemandConfig) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseClientAuth(clientAuth string) (tls.ClientAuthType, error) {
|
||||||
|
var auth tls.ClientAuthType
|
||||||
|
switch clientAuth {
|
||||||
|
case "request":
|
||||||
|
auth = tls.RequestClientCert
|
||||||
|
case "require":
|
||||||
|
auth = tls.RequireAnyClientCert
|
||||||
|
case "verify":
|
||||||
|
auth = tls.RequireAnyClientCert
|
||||||
|
case "require_and_verify":
|
||||||
|
auth = tls.RequireAndVerifyClientCert
|
||||||
|
default:
|
||||||
|
return auth, fmt.Errorf("unknown client auth %s", clientAuth)
|
||||||
|
}
|
||||||
|
return auth, nil
|
||||||
|
}
|
||||||
|
11
server.go
11
server.go
@ -3,6 +3,7 @@ package tlstunnel
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -312,6 +313,10 @@ func (ln *Listener) handle(conn net.Conn) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tlsConfig.NextProtos = append(tlsConfig.NextProtos, fe.Protocols...)
|
tlsConfig.NextProtos = append(tlsConfig.NextProtos, fe.Protocols...)
|
||||||
|
if fe.ClientAuth != tls.NoClientCert {
|
||||||
|
tlsConfig.ClientAuth = fe.ClientAuth
|
||||||
|
tlsConfig.ClientCAs = fe.ClientCAs
|
||||||
|
}
|
||||||
return tlsConfig, nil
|
return tlsConfig, nil
|
||||||
}
|
}
|
||||||
tlsConn := tls.Server(conn, tlsConfig)
|
tlsConn := tls.Server(conn, tlsConfig)
|
||||||
@ -362,8 +367,10 @@ func (ln *Listener) matchFrontend(serverName string) (*Frontend, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Frontend struct {
|
type Frontend struct {
|
||||||
Backend Backend
|
Backend Backend
|
||||||
Protocols []string
|
Protocols []string
|
||||||
|
ClientAuth tls.ClientAuthType
|
||||||
|
ClientCAs *x509.CertPool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fe *Frontend) handle(downstream net.Conn, tlsState *tls.ConnectionState) error {
|
func (fe *Frontend) handle(downstream net.Conn, tlsState *tls.ConnectionState) error {
|
||||||
|
@ -93,6 +93,17 @@ The following directives are supported:
|
|||||||
|
|
||||||
This disables automatic TLS.
|
This disables automatic TLS.
|
||||||
|
|
||||||
|
*client_auth* <type> <cert>
|
||||||
|
Configures client authentication.
|
||||||
|
|
||||||
|
The available verification types are the following:
|
||||||
|
request, require, verify, require_and_verify. They are
|
||||||
|
defined here:
|
||||||
|
https://pkg.go.dev/crypto/tls#ClientAuthType.
|
||||||
|
|
||||||
|
The certificate must be a PEM file and is used as a CA to validate
|
||||||
|
client certificates.
|
||||||
|
|
||||||
*protocol* <name>...
|
*protocol* <name>...
|
||||||
List of supported application-layer protocols.
|
List of supported application-layer protocols.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user