mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-06-13 21:54:13 +08:00
Merge a6c7c736c2aa51ac451f5ef2f03166fe8ab0a746 into a947f3af6ec78a17d69c52bb07224506ee048428
This commit is contained in:
commit
543d70db3a
@ -48,6 +48,7 @@ type InboundContext struct {
|
||||
ProcessInfo *process.Info
|
||||
QueryType uint16
|
||||
FakeIP bool
|
||||
IPCIDRMatchSource bool
|
||||
|
||||
// rule cache
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
||||
==仅客户端==
|
||||
|
@ -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"`
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user