add tls options

This commit is contained in:
ginuerzh 2023-10-29 10:27:13 +08:00
parent cffbecc3c0
commit e8d5e719a4
4 changed files with 203 additions and 26 deletions

View File

@ -99,11 +99,12 @@ type MetricsConfig struct {
} }
type TLSConfig struct { type TLSConfig struct {
CertFile string `yaml:"certFile,omitempty" json:"certFile,omitempty"` CertFile string `yaml:"certFile,omitempty" json:"certFile,omitempty"`
KeyFile string `yaml:"keyFile,omitempty" json:"keyFile,omitempty"` KeyFile string `yaml:"keyFile,omitempty" json:"keyFile,omitempty"`
CAFile string `yaml:"caFile,omitempty" json:"caFile,omitempty"` CAFile string `yaml:"caFile,omitempty" json:"caFile,omitempty"`
Secure bool `yaml:",omitempty" json:"secure,omitempty"` Secure bool `yaml:",omitempty" json:"secure,omitempty"`
ServerName string `yaml:"serverName,omitempty" json:"serverName,omitempty"` ServerName string `yaml:"serverName,omitempty" json:"serverName,omitempty"`
Options *TLSOptions `yaml:",omitempty" json:"options,omitempty"`
// for auto-generated default certificate. // for auto-generated default certificate.
Validity time.Duration `yaml:",omitempty" json:"validity,omitempty"` Validity time.Duration `yaml:",omitempty" json:"validity,omitempty"`
@ -111,6 +112,12 @@ type TLSConfig struct {
Organization string `yaml:",omitempty" json:"organization,omitempty"` Organization string `yaml:",omitempty" json:"organization,omitempty"`
} }
type TLSOptions struct {
MinVersion string `yaml:"minVersion,omitempty" json:"minVersion,omitempty"`
MaxVersion string `yaml:"maxVersion,omitempty" json:"maxVersion,omitempty"`
CipherSuites []string `yaml:"cipherSuites,omitempty" json:"cipherSuites,omitempty"`
}
type PluginConfig struct { type PluginConfig struct {
Type string `json:"type"` Type string `json:"type"`
Addr string `json:"addr"` Addr string `json:"addr"`

View File

@ -57,9 +57,7 @@ func ParseNode(hop string, cfg *config.NodeConfig) (*chain.Node, error) {
if tlsCfg.ServerName == "" { if tlsCfg.ServerName == "" {
tlsCfg.ServerName = serverName tlsCfg.ServerName = serverName
} }
tlsConfig, err := tls_util.LoadClientConfig( tlsConfig, err := tls_util.LoadClientConfig(tlsCfg)
tlsCfg.CertFile, tlsCfg.KeyFile, tlsCfg.CAFile,
tlsCfg.Secure, tlsCfg.ServerName)
if err != nil { if err != nil {
nodeLogger.Error(err) nodeLogger.Error(err)
return nil, err return nil, err
@ -99,9 +97,7 @@ func ParseNode(hop string, cfg *config.NodeConfig) (*chain.Node, error) {
if tlsCfg.ServerName == "" { if tlsCfg.ServerName == "" {
tlsCfg.ServerName = serverName tlsCfg.ServerName = serverName
} }
tlsConfig, err = tls_util.LoadClientConfig( tlsConfig, err = tls_util.LoadClientConfig(tlsCfg)
tlsCfg.CertFile, tlsCfg.KeyFile, tlsCfg.CAFile,
tlsCfg.Secure, tlsCfg.ServerName)
if err != nil { if err != nil {
nodeLogger.Error(err) nodeLogger.Error(err)
return nil, err return nil, err

View File

@ -55,8 +55,7 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
if tlsCfg == nil { if tlsCfg == nil {
tlsCfg = &config.TLSConfig{} tlsCfg = &config.TLSConfig{}
} }
tlsConfig, err := tls_util.LoadServerConfig( tlsConfig, err := tls_util.LoadServerConfig(tlsCfg)
tlsCfg.CertFile, tlsCfg.KeyFile, tlsCfg.CAFile)
if err != nil { if err != nil {
listenerLogger.Error(err) listenerLogger.Error(err)
return nil, err return nil, err
@ -149,8 +148,7 @@ func ParseService(cfg *config.ServiceConfig) (service.Service, error) {
if tlsCfg == nil { if tlsCfg == nil {
tlsCfg = &config.TLSConfig{} tlsCfg = &config.TLSConfig{}
} }
tlsConfig, err = tls_util.LoadServerConfig( tlsConfig, err = tls_util.LoadServerConfig(tlsCfg)
tlsCfg.CertFile, tlsCfg.KeyFile, tlsCfg.CAFile)
if err != nil { if err != nil {
handlerLogger.Error(err) handlerLogger.Error(err)
return nil, err return nil, err

View File

@ -6,9 +6,43 @@ import (
"errors" "errors"
"net" "net"
"os" "os"
"strings"
"time" "time"
"github.com/go-gost/core/logger" "github.com/go-gost/core/logger"
"github.com/go-gost/x/config"
)
const (
VersionTLS10 = "VersionTLS10"
VersionTLS11 = "VersionTLS11"
VersionTLS12 = "VersionTLS12"
VersionTLS13 = "VersionTLS13"
)
const (
TLS_RSA_WITH_RC4_128_SHA = "TLS_RSA_WITH_RC4_128_SHA"
TLS_RSA_WITH_3DES_EDE_CBC_SHA = "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
TLS_RSA_WITH_AES_128_CBC_SHA = "TLS_RSA_WITH_AES_128_CBC_SHA"
TLS_RSA_WITH_AES_256_CBC_SHA = "TLS_RSA_WITH_AES_256_CBC_SHA"
TLS_RSA_WITH_AES_128_CBC_SHA256 = "TLS_RSA_WITH_AES_128_CBC_SHA256"
TLS_RSA_WITH_AES_128_GCM_SHA256 = "TLS_RSA_WITH_AES_128_GCM_SHA256"
TLS_RSA_WITH_AES_256_GCM_SHA384 = "TLS_RSA_WITH_AES_256_GCM_SHA384"
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
TLS_ECDHE_RSA_WITH_RC4_128_SHA = "TLS_ECDHE_RSA_WITH_RC4_128_SHA"
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"
) )
// LoadDefaultConfig loads the certificate from cert & key files and optional CA file. // LoadDefaultConfig loads the certificate from cert & key files and optional CA file.
@ -33,19 +67,19 @@ func LoadDefaultConfig(certFile, keyFile, caFile string) (*tls.Config, error) {
} }
// LoadServerConfig loads the certificate from cert & key files and client CA file. // LoadServerConfig loads the certificate from cert & key files and client CA file.
func LoadServerConfig(certFile, keyFile, caFile string) (*tls.Config, error) { func LoadServerConfig(config *config.TLSConfig) (*tls.Config, error) {
if certFile == "" && keyFile == "" { if config.CertFile == "" && config.KeyFile == "" {
return nil, nil return nil, nil
} }
cert, err := tls.LoadX509KeyPair(certFile, keyFile) cert, err := tls.LoadX509KeyPair(config.CertFile, config.KeyFile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
cfg := &tls.Config{Certificates: []tls.Certificate{cert}} cfg := &tls.Config{Certificates: []tls.Certificate{cert}}
pool, err := loadCA(caFile) pool, err := loadCA(config.CAFile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -54,17 +88,88 @@ func LoadServerConfig(certFile, keyFile, caFile string) (*tls.Config, error) {
cfg.ClientAuth = tls.RequireAndVerifyClientCert cfg.ClientAuth = tls.RequireAndVerifyClientCert
} }
if opts := config.Options; opts != nil {
switch strings.ToLower(opts.MinVersion) {
case strings.ToLower(VersionTLS10):
cfg.MinVersion = tls.VersionTLS10
case strings.ToLower(VersionTLS11):
cfg.MinVersion = tls.VersionTLS11
case strings.ToLower(VersionTLS12):
cfg.MinVersion = tls.VersionTLS12
case strings.ToLower(VersionTLS13):
cfg.MinVersion = tls.VersionTLS13
}
switch strings.ToLower(opts.MaxVersion) {
case strings.ToLower(VersionTLS10):
cfg.MaxVersion = tls.VersionTLS10
case strings.ToLower(VersionTLS11):
cfg.MaxVersion = tls.VersionTLS11
case strings.ToLower(VersionTLS12):
cfg.MaxVersion = tls.VersionTLS12
case strings.ToLower(VersionTLS13):
cfg.MaxVersion = tls.VersionTLS13
}
for _, v := range opts.CipherSuites {
switch strings.ToLower(v) {
case strings.ToLower(TLS_RSA_WITH_RC4_128_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_RSA_WITH_RC4_128_SHA)
case strings.ToLower(TLS_RSA_WITH_3DES_EDE_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA)
case strings.ToLower(TLS_RSA_WITH_AES_128_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_RSA_WITH_AES_128_CBC_SHA)
case strings.ToLower(TLS_RSA_WITH_AES_256_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_RSA_WITH_AES_256_CBC_SHA)
case strings.ToLower(TLS_RSA_WITH_AES_128_CBC_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_RSA_WITH_AES_128_CBC_SHA256)
case strings.ToLower(TLS_RSA_WITH_AES_128_GCM_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_RSA_WITH_AES_128_GCM_SHA256)
case strings.ToLower(TLS_RSA_WITH_AES_256_GCM_SHA384):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_RSA_WITH_AES_256_GCM_SHA384)
case strings.ToLower(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA)
case strings.ToLower(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)
case strings.ToLower(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
case strings.ToLower(TLS_ECDHE_RSA_WITH_RC4_128_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA)
case strings.ToLower(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA)
case strings.ToLower(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)
case strings.ToLower(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)
case strings.ToLower(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256)
case strings.ToLower(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)
case strings.ToLower(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
case strings.ToLower(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
case strings.ToLower(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)
case strings.ToLower(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
case strings.ToLower(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)
case strings.ToLower(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256)
}
}
}
return cfg, nil return cfg, nil
} }
// LoadClientConfig loads the certificate from cert & key files and CA file. // LoadClientConfig loads the certificate from cert & key files and CA file.
func LoadClientConfig(certFile, keyFile, caFile string, verify bool, serverName string) (*tls.Config, error) { func LoadClientConfig(config *config.TLSConfig) (*tls.Config, error) {
var cfg *tls.Config var cfg *tls.Config
if certFile == "" && keyFile == "" { if config.CertFile == "" && config.KeyFile == "" {
cfg = &tls.Config{} cfg = &tls.Config{}
} else { } else {
cert, err := tls.LoadX509KeyPair(certFile, keyFile) cert, err := tls.LoadX509KeyPair(config.CertFile, config.KeyFile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -74,17 +179,88 @@ func LoadClientConfig(certFile, keyFile, caFile string, verify bool, serverName
} }
} }
rootCAs, err := loadCA(caFile) rootCAs, err := loadCA(config.CAFile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
cfg.RootCAs = rootCAs cfg.RootCAs = rootCAs
cfg.ServerName = serverName cfg.ServerName = config.ServerName
cfg.InsecureSkipVerify = !verify cfg.InsecureSkipVerify = !config.Secure
if opts := config.Options; opts != nil {
switch strings.ToLower(opts.MinVersion) {
case strings.ToLower(VersionTLS10):
cfg.MinVersion = tls.VersionTLS10
case strings.ToLower(VersionTLS11):
cfg.MinVersion = tls.VersionTLS11
case strings.ToLower(VersionTLS12):
cfg.MinVersion = tls.VersionTLS12
case strings.ToLower(VersionTLS13):
cfg.MinVersion = tls.VersionTLS13
}
switch strings.ToLower(opts.MaxVersion) {
case strings.ToLower(VersionTLS10):
cfg.MaxVersion = tls.VersionTLS10
case strings.ToLower(VersionTLS11):
cfg.MaxVersion = tls.VersionTLS11
case strings.ToLower(VersionTLS12):
cfg.MaxVersion = tls.VersionTLS12
case strings.ToLower(VersionTLS13):
cfg.MaxVersion = tls.VersionTLS13
}
for _, v := range opts.CipherSuites {
switch strings.ToLower(v) {
case strings.ToLower(TLS_RSA_WITH_RC4_128_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_RSA_WITH_RC4_128_SHA)
case strings.ToLower(TLS_RSA_WITH_3DES_EDE_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA)
case strings.ToLower(TLS_RSA_WITH_AES_128_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_RSA_WITH_AES_128_CBC_SHA)
case strings.ToLower(TLS_RSA_WITH_AES_256_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_RSA_WITH_AES_256_CBC_SHA)
case strings.ToLower(TLS_RSA_WITH_AES_128_CBC_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_RSA_WITH_AES_128_CBC_SHA256)
case strings.ToLower(TLS_RSA_WITH_AES_128_GCM_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_RSA_WITH_AES_128_GCM_SHA256)
case strings.ToLower(TLS_RSA_WITH_AES_256_GCM_SHA384):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_RSA_WITH_AES_256_GCM_SHA384)
case strings.ToLower(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA)
case strings.ToLower(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)
case strings.ToLower(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
case strings.ToLower(TLS_ECDHE_RSA_WITH_RC4_128_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA)
case strings.ToLower(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA)
case strings.ToLower(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)
case strings.ToLower(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)
case strings.ToLower(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256)
case strings.ToLower(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)
case strings.ToLower(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
case strings.ToLower(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
case strings.ToLower(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)
case strings.ToLower(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
case strings.ToLower(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)
case strings.ToLower(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256):
cfg.CipherSuites = append(cfg.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256)
}
}
}
// If the root ca is given, but skip verify, we verify the certificate manually. // If the root ca is given, but skip verify, we verify the certificate manually.
if cfg.RootCAs != nil && !verify { if cfg.RootCAs != nil && !config.Secure {
cfg.VerifyConnection = func(state tls.ConnectionState) error { cfg.VerifyConnection = func(state tls.ConnectionState) error {
opts := x509.VerifyOptions{ opts := x509.VerifyOptions{
Roots: cfg.RootCAs, Roots: cfg.RootCAs,