validate client certificate of frpc for tcpmux
This commit is contained in:
parent
184223cb2f
commit
2b91ac4d18
@ -649,6 +649,7 @@ transport.tls.force = true
|
|||||||
transport.tls.certFile = "certificate.crt"
|
transport.tls.certFile = "certificate.crt"
|
||||||
transport.tls.keyFile = "certificate.key"
|
transport.tls.keyFile = "certificate.key"
|
||||||
transport.tls.trustedCaFile = "ca.crt"
|
transport.tls.trustedCaFile = "ca.crt"
|
||||||
|
transport.tls.clientCertSubjectRegex = "CN=client.com(.+)"
|
||||||
```
|
```
|
||||||
|
|
||||||
You will need **a root CA cert** and **at least one SSL/TLS certificate**. It **can** be self-signed or regular (such as Let's Encrypt or another SSL/TLS certificate provider).
|
You will need **a root CA cert** and **at least one SSL/TLS certificate**. It **can** be self-signed or regular (such as Let's Encrypt or another SSL/TLS certificate provider).
|
||||||
|
@ -80,6 +80,9 @@ type TLSConfig struct {
|
|||||||
// ServerName specifies the custom server name of tls certificate. By
|
// ServerName specifies the custom server name of tls certificate. By
|
||||||
// default, server name if same to ServerAddr.
|
// default, server name if same to ServerAddr.
|
||||||
ServerName string `json:"serverName,omitempty"`
|
ServerName string `json:"serverName,omitempty"`
|
||||||
|
// ClientCertificateSubjectRegex specifies the regex that is used to validate the client certificate subject.
|
||||||
|
// If it's not set, the validation of the subject is disabled.
|
||||||
|
ClientCertificateSubjectRegex string `json:"clientCertSubjectRegex,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type LogConfig struct {
|
type LogConfig struct {
|
||||||
|
@ -17,7 +17,10 @@ package net
|
|||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
v1 "github.com/fatedier/frp/pkg/config/v1"
|
||||||
|
"github.com/fatedier/frp/pkg/util/log"
|
||||||
"net"
|
"net"
|
||||||
|
"regexp"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
libnet "github.com/fatedier/golib/net"
|
libnet "github.com/fatedier/golib/net"
|
||||||
@ -55,3 +58,35 @@ func CheckAndEnableTLSServerConnWithTimeout(
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsClientCertificateSubjectValid(c net.Conn, tlsConfig v1.TLSServerConfig) bool {
|
||||||
|
subjectRegex := tlsConfig.ClientCertificateSubjectRegex
|
||||||
|
regex, err := regexp.Compile(subjectRegex)
|
||||||
|
if err != nil {
|
||||||
|
log.Trace("Client certificate subject validation is disabled")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsConn, ok := c.(*tls.Conn)
|
||||||
|
if !ok {
|
||||||
|
log.Warn("Skip client certificate subject validation because its not a tls connection")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
state := tlsConn.ConnectionState()
|
||||||
|
log.Trace("Validating client certificate subject using regex: %v", subjectRegex)
|
||||||
|
if len(state.PeerCertificates) == 0 {
|
||||||
|
log.Warn("No client certificates found in TLS connection, the verification was probably called to early.")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range state.PeerCertificates {
|
||||||
|
subject := fmt.Sprintf("%v", v.Subject)
|
||||||
|
if !regex.MatchString(subject) {
|
||||||
|
log.Warn("Client certificate subject %v doesn't match regex %v", v.Subject, subjectRegex)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
log.Trace("Client certificate subject is valid")
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
@ -484,6 +484,13 @@ func (svr *Service) HandleListener(l net.Listener) {
|
|||||||
session.Close()
|
session.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Has to be called after session.AcceptStream() so that the client certificates are available
|
||||||
|
if !utilnet.IsClientCertificateSubjectValid(c, svr.cfg.Transport.TLS) {
|
||||||
|
session.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
go svr.handleConnection(ctx, stream)
|
go svr.handleConnection(ctx, stream)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user