Merge a6c7c736c2aa51ac451f5ef2f03166fe8ab0a746 into a947f3af6ec78a17d69c52bb07224506ee048428

This commit is contained in:
jose-C2OaWi 2023-12-04 15:44:38 +00:00 committed by GitHub
commit 543d70db3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 210 additions and 31 deletions

View File

@ -48,6 +48,7 @@ type InboundContext struct {
ProcessInfo *process.Info
QueryType uint16
FakeIP bool
IPCIDRMatchSource bool
// rule cache

View File

@ -128,5 +128,40 @@ func NewSTDClient(ctx context.Context, serverAddress string, options option.Outb
}
tlsConfig.RootCAs = certPool
}
if options.ClientAuth {
// explicitly call mutual verification
var cert []byte
var key []byte
if len(options.ClientCertificate) > 0 {
cert = []byte(strings.Join(options.ClientCertificate, "\n"))
} else if options.ClientCertificatePath != "" {
content, err := os.ReadFile(options.ClientCertificatePath)
if err != nil {
return nil, E.Cause(err, "read client certificate")
}
cert = content
}
if len(options.ClientKey) > 0 {
key = []byte(strings.Join(options.ClientKey, "\n"))
} else if options.ClientKeyPath != "" {
content, err := os.ReadFile(options.ClientKeyPath)
if err != nil {
return nil, E.Cause(err, "read client key")
}
key = content
}
if cert == nil {
return nil, E.New("missing client certificate")
} else if key == nil {
return nil, E.New("missing client key")
}
keyPair, err := tls.X509KeyPair(cert, key)
if err != nil {
return nil, E.New(err, "parse x509 key pair")
}
tlsConfig.Certificates = []tls.Certificate{keyPair}
}
return &STDClientConfig{&tlsConfig}, nil
}

View File

@ -3,6 +3,7 @@ package tls
import (
"context"
"crypto/tls"
"crypto/x509"
"net"
"os"
"strings"
@ -212,6 +213,7 @@ func NewSTDServer(ctx context.Context, logger log.Logger, options option.Inbound
}
var certificate []byte
var key []byte
var clientca []byte
if acmeService == nil {
if len(options.Certificate) > 0 {
certificate = []byte(strings.Join(options.Certificate, "\n"))
@ -249,6 +251,29 @@ func NewSTDServer(ctx context.Context, logger log.Logger, options option.Inbound
tlsConfig.Certificates = []tls.Certificate{keyPair}
}
}
if options.ClientAuth {
// require client authentication
tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
if len(options.ClientCA) > 0 {
clientca = []byte(strings.Join(options.ClientCA, "\n"))
} else if options.ClientCAPath != "" {
content, err := os.ReadFile(options.ClientCAPath)
if err != nil {
return nil, E.Cause(err, "read client CA")
}
clientca = content
}
// add client ca certpool
if len(clientca) > 0 {
certPool := x509.NewCertPool()
if !certPool.AppendCertsFromPEM(clientca) {
return nil, E.New("failed to parse client CA:\n\n", clientca)
}
tlsConfig.ClientCAs = certPool
}
} else {
tlsConfig.ClientAuth = tls.NoClientCert
}
return &STDServerConfig{
config: tlsConfig,
logger: logger,
@ -257,5 +282,6 @@ func NewSTDServer(ctx context.Context, logger log.Logger, options option.Inbound
key: key,
certificatePath: options.CertificatePath,
keyPath: options.KeyPath,
watcher: &fsnotify.Watcher{},
}, nil
}

View File

@ -12,6 +12,9 @@
"certificate_path": "",
"key": [],
"key_path": "",
"clientAuth": false,
"clientCA": [],
"clientCA_path": "",
"acme": {
"domain": [],
"data_directory": "",
@ -64,8 +67,13 @@
"min_version": "",
"max_version": "",
"cipher_suites": [],
"certificate": "",
"certificate": [],
"certificate_path": "",
"clientAuth": false,
"client_key": [],
"client_key_path": "",
"client_certificate": [],
"client_certificate_path": "",
"ech": {
"enabled": false,
"pq_signature_schemes_enabled": false,
@ -189,6 +197,46 @@ The server private key line array, in PEM format.
The path to the server private key, in PEM format.
#### clientAuth
Enable TLS Client Authentication
#### clientCA
==Server only==
The server's client CA Certificate line array, in PEM format.
#### clientCA_path
==Server only==
The path to the server's client CA certificate, in PEM format.
#### client_certificate
==Client only==
The client certificate line array, in PEM format.
#### certificate_path
==Client only==
The path to the client certificate, in PEM format.
#### client_key
==Client only==
The client private key line array, in PEM format.
#### client_key_path
==Client only==
The path to the client private, in PEM format.
## Custom TLS support
!!! info "QUIC support"

View File

@ -12,6 +12,9 @@
"certificate_path": "",
"key": [],
"key_path": "",
"clientAuth": false,
"clientCA": [],
"clientCA_path": "",
"acme": {
"domain": [],
"data_directory": "",
@ -66,6 +69,11 @@
"cipher_suites": [],
"certificate": [],
"certificate_path": "",
"clientAuth": false,
"client_key": [],
"client_key_path": "",
"client_certificate": [],
"client_certificate_path": "",
"ech": {
"enabled": false,
"pq_signature_schemes_enabled": false,
@ -189,6 +197,46 @@ TLS 版本值:
服务器 PEM 私钥路径。
#### clientAuth
启用客户端验证
#### clientCA
==仅服务器==
服务器 PEM 验证客户端 CA 证书行数组
#### clientCA_path
==仅服务器==
服务器 PEM 验证客户端 CA 证书路径
#### client_certificate
==仅客户端==
客户端 PEM 证书行数组。
#### certificate_path
==仅客户端==
客户端 PEM 证书路径。
#### client_key
==仅客户端==
客户端 PEM 私钥行数组。
#### client_key_path
==仅客户端==
客户端 PEM 私钥路径。
#### utls
==仅客户端==

View File

@ -12,6 +12,10 @@ type InboundTLSOptions struct {
CertificatePath string `json:"certificate_path,omitempty"`
Key Listable[string] `json:"key,omitempty"`
KeyPath string `json:"key_path,omitempty"`
ClientAuth bool `json:"clientAuth,omitempty"`
// , Requireandverify
ClientCA Listable[string] `json:"clientCA,omitempty"`
ClientCAPath string `json:"clientCA_path,omitempty"`
ACME *InboundACMEOptions `json:"acme,omitempty"`
ECH *InboundECHOptions `json:"ech,omitempty"`
Reality *InboundRealityOptions `json:"reality,omitempty"`
@ -28,6 +32,11 @@ type OutboundTLSOptions struct {
CipherSuites Listable[string] `json:"cipher_suites,omitempty"`
Certificate Listable[string] `json:"certificate,omitempty"`
CertificatePath string `json:"certificate_path,omitempty"`
ClientAuth bool `json:"clientAuth,omitempty"`
ClientKey Listable[string] `json:"client_key,omitempty"`
ClientKeyPath string `json:"client_key_path,omitempty"`
ClientCertificate Listable[string] `json:"client_certificate,omitempty"`
ClientCertificatePath string `json:"client_certificate_path,omitempty"`
ECH *OutboundECHOptions `json:"ech,omitempty"`
UTLS *OutboundUTLSOptions `json:"utls,omitempty"`
Reality *OutboundRealityOptions `json:"reality,omitempty"`

View File

@ -597,6 +597,18 @@ func (r *Router) Start() error {
return nil
}
func (r *Router) PostStart() error {
if len(r.ruleSets) > 0 {
for i, ruleSet := range r.ruleSets {
err := ruleSet.PostStart()
if err != nil {
return E.Cause(err, "post start rule-set[", i, "]")
}
}
}
return nil
}
func (r *Router) Close() error {
monitor := taskmonitor.New(r.logger, C.DefaultStopTimeout)
var err error