mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-09-28 10:40:14 +00:00
Merge tag 'v1.14.0'
This commit is contained in:
@@ -121,7 +121,7 @@ func (h *Inbound) UpdateUsers(users []option.SSHUser) {
|
||||
h.service.UpdateUsers(users)
|
||||
}
|
||||
|
||||
func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
func (h *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
metadata.Inbound = h.Tag()
|
||||
metadata.InboundType = h.Type()
|
||||
serverConn, channels, requests, err := ssh.NewServerConn(conn, h.serverConfig)
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/service/filemanager"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
@@ -35,13 +36,15 @@ var _ adapter.InterfaceUpdateListener = (*Outbound)(nil)
|
||||
|
||||
type Outbound struct {
|
||||
outbound.Adapter
|
||||
ctx context.Context
|
||||
logger logger.ContextLogger
|
||||
dialer N.Dialer
|
||||
serverAddr M.Socksaddr
|
||||
user string
|
||||
hostKey []ssh.PublicKey
|
||||
hostKeyAlgorithms []string
|
||||
cipher []string
|
||||
mac []string
|
||||
kexAlgorithm []string
|
||||
clientVersion string
|
||||
authMethod []ssh.AuthMethod
|
||||
clientAccess sync.Mutex
|
||||
@@ -56,12 +59,14 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
}
|
||||
outbound := &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeSSH, tag, []string{N.NetworkTCP}, options.DialerOptions),
|
||||
ctx: ctx,
|
||||
logger: logger,
|
||||
dialer: outboundDialer,
|
||||
serverAddr: options.ServerOptions.Build(),
|
||||
user: options.User,
|
||||
hostKeyAlgorithms: options.HostKeyAlgorithms,
|
||||
cipher: options.Cipher,
|
||||
mac: options.MAC,
|
||||
kexAlgorithm: options.KexAlgorithm,
|
||||
clientVersion: options.ClientVersion,
|
||||
}
|
||||
if outbound.serverAddr.Port == 0 {
|
||||
@@ -82,7 +87,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
privateKey = []byte(strings.Join(options.PrivateKey, "\n"))
|
||||
} else {
|
||||
var err error
|
||||
privateKey, err = os.ReadFile(os.ExpandEnv(options.PrivateKeyPath))
|
||||
privateKey, err = filemanager.ReadFile(ctx, os.ExpandEnv(options.PrivateKeyPath))
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "read private key")
|
||||
}
|
||||
@@ -121,7 +126,7 @@ func randomVersion() string {
|
||||
return version
|
||||
}
|
||||
|
||||
func (s *Outbound) connect() (*ssh.Client, error) {
|
||||
func (s *Outbound) connect(ctx context.Context) (client *ssh.Client, err error) {
|
||||
if s.client != nil {
|
||||
return s.client, nil
|
||||
}
|
||||
@@ -133,10 +138,24 @@ func (s *Outbound) connect() (*ssh.Client, error) {
|
||||
return s.client, nil
|
||||
}
|
||||
|
||||
conn, err := s.dialer.DialContext(s.ctx, N.NetworkTCP, s.serverAddr)
|
||||
conn, err := s.dialer.DialContext(ctx, N.NetworkTCP, s.serverAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ctx.Done() != nil {
|
||||
handshakeConn := conn
|
||||
stopContext := context.AfterFunc(ctx, func() {
|
||||
_ = handshakeConn.Close()
|
||||
})
|
||||
defer func() {
|
||||
if !stopContext() {
|
||||
s.client = nil
|
||||
s.clientConn = nil
|
||||
client = nil
|
||||
err = ctx.Err()
|
||||
}
|
||||
}()
|
||||
}
|
||||
config := &ssh.ClientConfig{
|
||||
User: s.user,
|
||||
Auth: s.authMethod,
|
||||
@@ -155,13 +174,22 @@ func (s *Outbound) connect() (*ssh.Client, error) {
|
||||
return E.New("host key mismatch, server send ", key.Type(), " ", base64.StdEncoding.EncodeToString(serverKey))
|
||||
},
|
||||
}
|
||||
if len(s.cipher) > 0 {
|
||||
config.Ciphers = s.cipher
|
||||
}
|
||||
if len(s.mac) > 0 {
|
||||
config.MACs = s.mac
|
||||
}
|
||||
if len(s.kexAlgorithm) > 0 {
|
||||
config.KeyExchanges = s.kexAlgorithm
|
||||
}
|
||||
clientConn, chans, reqs, err := ssh.NewClientConn(conn, s.serverAddr.Addr.String(), config)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
return nil, E.Cause(err, "connect to ssh server")
|
||||
}
|
||||
|
||||
client := ssh.NewClient(clientConn, chans, reqs)
|
||||
client = ssh.NewClient(clientConn, chans, reqs)
|
||||
|
||||
s.clientConn = conn
|
||||
s.client = client
|
||||
@@ -178,7 +206,7 @@ func (s *Outbound) connect() (*ssh.Client, error) {
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (s *Outbound) InterfaceUpdated() {
|
||||
func (s *Outbound) InterfaceUpdated(ctx context.Context) {
|
||||
common.Close(s.clientConn)
|
||||
}
|
||||
|
||||
@@ -187,7 +215,7 @@ func (s *Outbound) Close() error {
|
||||
}
|
||||
|
||||
func (s *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||
client, err := s.connect()
|
||||
client, err := s.connect(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user