boxdd: Add insecure mode

This commit is contained in:
世界
2026-07-15 19:31:11 +08:00
parent 52f372c536
commit e34b57c3b0
61 changed files with 1058 additions and 288 deletions
+8 -1
View File
@@ -7,6 +7,7 @@ import (
"net/http/httputil"
"net/netip"
"net/url"
"os"
"time"
"github.com/sagernet/sing-box/adapter"
@@ -26,6 +27,7 @@ import (
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/service"
"github.com/sagernet/sing/service/filemanager"
)
func RegisterInbound(registry *inbound.Registry) {
@@ -73,7 +75,12 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
if options.Masquerade != nil && options.Masquerade.Type != "" {
switch options.Masquerade.Type {
case C.Hysterai2MasqueradeTypeFile:
masqueradeHandler = http.FileServer(http.Dir(options.Masquerade.FileOptions.Directory))
masqueradeDirectory := filemanager.BasePath(ctx, os.ExpandEnv(options.Masquerade.FileOptions.Directory))
_, err = filemanager.ReadDir(ctx, masqueradeDirectory)
if err != nil && !os.IsNotExist(err) {
return nil, E.Cause(err, "read masquerade directory")
}
masqueradeHandler = http.FileServer(http.Dir(masqueradeDirectory))
case C.Hysterai2MasqueradeTypeProxy:
masqueradeURL, err := url.Parse(options.Masquerade.ProxyOptions.URL)
if err != nil {
+3 -3
View File
@@ -6,7 +6,6 @@ import (
"context"
"encoding/pem"
"net"
"os"
"strings"
"github.com/sagernet/cronet-go"
@@ -25,6 +24,7 @@ import (
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/uot"
"github.com/sagernet/sing/service"
"github.com/sagernet/sing/service/filemanager"
mDNS "github.com/miekg/dns"
)
@@ -109,7 +109,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
if len(options.TLS.Certificate) > 0 {
trustedRootCertificates = strings.Join(options.TLS.Certificate, "\n")
} else if options.TLS.CertificatePath != "" {
content, err := os.ReadFile(options.TLS.CertificatePath)
content, err := filemanager.ReadFile(ctx, options.TLS.CertificatePath)
if err != nil {
return nil, E.Cause(err, "read certificate")
}
@@ -146,7 +146,7 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
if len(options.TLS.ECH.Config) > 0 {
echConfig = []byte(strings.Join(options.TLS.ECH.Config, "\n"))
} else if options.TLS.ECH.ConfigPath != "" {
content, err := os.ReadFile(options.TLS.ECH.ConfigPath)
content, err := filemanager.ReadFile(ctx, options.TLS.ECH.ConfigPath)
if err != nil {
return nil, E.Cause(err, "read ECH config")
}
+2 -1
View File
@@ -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"
)
@@ -88,7 +89,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")
}
+11 -1
View File
@@ -151,6 +151,16 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
}
stateDirectory = filemanager.BasePath(ctx, os.ExpandEnv(stateDirectory))
stateDirectory, _ = filepath.Abs(stateDirectory)
mkdirErr := filemanager.MkdirAll(ctx, stateDirectory, 0o700)
if mkdirErr != nil {
return nil, E.Cause(mkdirErr, "create state directory")
}
if options.SSHServer != nil && options.SSHServer.Enabled {
err := adapter.CheckSecurityFeature(ctx, "Tailscale `ssh_server`")
if err != nil {
return nil, err
}
}
for _, advertiseRoute := range options.AdvertiseRoutes {
if advertiseRoute.Addr().IsUnspecified() && advertiseRoute.Bits() == 0 {
return nil, E.New("`advertise_routes` cannot be default, use `advertise_exit_node` instead.")
@@ -435,7 +445,7 @@ func (t *Endpoint) postStart() error {
}
t.filter = localBackend.ExportFilter()
if sshEnabled {
sshServer, err := tailssh.New(t.server, t.platformInterface, t.sshServerOptions, t.logger)
sshServer, err := tailssh.New(t.ctx, t.server, t.platformInterface, t.sshServerOptions, t.logger)
if err != nil {
return E.Cause(err, "create SSH server")
}
+7 -7
View File
@@ -15,7 +15,6 @@ import (
"net/http"
"net/netip"
"net/url"
"os"
"path"
"path/filepath"
"strings"
@@ -28,6 +27,7 @@ import (
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
"github.com/sagernet/sing/service/filemanager"
tsDNS "github.com/sagernet/tailscale/net/dns"
"github.com/sagernet/tailscale/tailcfg"
"github.com/sagernet/tailscale/tsnet"
@@ -93,7 +93,7 @@ type activeSession struct {
cancel context.CancelFunc
}
func New(tsnetServer *tsnet.Server, platformInterface adapter.PlatformInterface, options *option.TailscaleSSHServerOptions, logger logger.ContextLogger) (*Server, error) {
func New(ctx context.Context, tsnetServer *tsnet.Server, platformInterface adapter.PlatformInterface, options *option.TailscaleSSHServerOptions, logger logger.ContextLogger) (*Server, error) {
s := &Server{
tsnetServer: tsnetServer,
platformInterface: platformInterface,
@@ -104,7 +104,7 @@ func New(tsnetServer *tsnet.Server, platformInterface adapter.PlatformInterface,
done: make(chan struct{}),
activeConns: make(map[*activeSession]struct{}),
}
s.serverCtx, s.serverCancel = context.WithCancel(context.Background())
s.serverCtx, s.serverCancel = context.WithCancel(ctx)
hostSigner, err := s.loadOrGenerateHostKey()
if err != nil {
return nil, err
@@ -132,7 +132,7 @@ func (s *Server) loadOrGenerateHostKey() (gossh.Signer, error) {
if isPrivilegedUser() {
systemKey := systemHostKeyPath()
if systemKey != "" {
keyData, err := os.ReadFile(systemKey)
keyData, err := filemanager.ReadFile(s.serverCtx, systemKey)
if err == nil {
signer, parseErr := gossh.ParsePrivateKey(keyData)
if parseErr == nil {
@@ -144,7 +144,7 @@ func (s *Server) loadOrGenerateHostKey() (gossh.Signer, error) {
}
}
keyPath := filepath.Join(s.tsnetServer.Dir, "ssh_host_ed25519_key")
keyData, err := os.ReadFile(keyPath)
keyData, err := filemanager.ReadFile(s.serverCtx, keyPath)
if err == nil {
signer, parseErr := gossh.ParsePrivateKey(keyData)
if parseErr == nil {
@@ -163,11 +163,11 @@ func (s *Server) loadOrGenerateHostKey() (gossh.Signer, error) {
}
pemData := pem.EncodeToMemory(keyBytes)
dir := filepath.Dir(keyPath)
err = os.MkdirAll(dir, 0o700)
err = filemanager.MkdirAll(s.serverCtx, dir, 0o700)
if err != nil {
return nil, err
}
err = os.WriteFile(keyPath, pemData, 0o600)
err = filemanager.WriteFile(s.serverCtx, keyPath, pemData, 0o600)
if err != nil {
return nil, err
}
+35 -21
View File
@@ -20,8 +20,8 @@ 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/common/rw"
"github.com/sagernet/sing/protocol/socks"
"github.com/sagernet/sing/service/filemanager"
"github.com/cretz/bine/control"
"github.com/cretz/bine/tor"
@@ -46,36 +46,50 @@ type Outbound struct {
func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TorOutboundOptions) (adapter.Outbound, error) {
var startConf tor.StartConf
startConf.DataDir = os.ExpandEnv(options.DataDirectory)
startConf.TempDataDirBase = os.TempDir()
startConf.ExtraArgs = options.ExtraArgs
if options.DataDirectory != "" {
dataDirAbs, _ := filepath.Abs(startConf.DataDir)
if geoIPPath := filepath.Join(dataDirAbs, "geoip"); rw.IsFile(geoIPPath) && !common.Contains(options.ExtraArgs, "--GeoIPFile") {
options.ExtraArgs = append(options.ExtraArgs, "--GeoIPFile", geoIPPath)
}
if geoIP6Path := filepath.Join(dataDirAbs, "geoip6"); rw.IsFile(geoIP6Path) && !common.Contains(options.ExtraArgs, "--GeoIPv6File") {
options.ExtraArgs = append(options.ExtraArgs, "--GeoIPv6File", geoIP6Path)
}
}
if options.ExecutablePath != "" {
startConf.ExePath = options.ExecutablePath
startConf.ProcessCreator = nil
startConf.UseEmbeddedControlConn = false
}
if startConf.DataDir != "" {
torrcFile := filepath.Join(startConf.DataDir, "torrc")
err := rw.MkdirParent(torrcFile)
startConf.DataDir = filemanager.BasePath(ctx, startConf.DataDir)
}
startConf.TempDataDirBase = filemanager.TempPath(ctx)
if startConf.DataDir != "" {
err := filemanager.MkdirAll(ctx, startConf.DataDir, 0o755)
if err != nil {
return nil, err
}
if !rw.IsFile(torrcFile) {
err := os.WriteFile(torrcFile, []byte(""), 0o600)
dataDirAbs, _ := filepath.Abs(startConf.DataDir)
geoIPPath := filepath.Join(dataDirAbs, "geoip")
geoIPInfo, err := filemanager.Stat(ctx, geoIPPath)
if err == nil && !geoIPInfo.IsDir() && !common.Contains(options.ExtraArgs, "--GeoIPFile") {
options.ExtraArgs = append(options.ExtraArgs, "--GeoIPFile", geoIPPath)
}
geoIP6Path := filepath.Join(dataDirAbs, "geoip6")
geoIP6Info, err := filemanager.Stat(ctx, geoIP6Path)
if err == nil && !geoIP6Info.IsDir() && !common.Contains(options.ExtraArgs, "--GeoIPv6File") {
options.ExtraArgs = append(options.ExtraArgs, "--GeoIPv6File", geoIP6Path)
}
torrcFile := filepath.Join(startConf.DataDir, "torrc")
torrcInfo, err := filemanager.Stat(ctx, torrcFile)
if os.IsNotExist(err) {
err = filemanager.WriteFile(ctx, torrcFile, []byte(""), 0o600)
if err != nil {
return nil, err
}
} else if err != nil {
return nil, err
} else if torrcInfo.IsDir() {
return nil, E.New("Tor configuration path is a directory: ", torrcFile)
}
startConf.TorrcFile = torrcFile
}
startConf.ExtraArgs = options.ExtraArgs
if options.ExecutablePath != "" {
err := adapter.CheckSecurityFeature(ctx, "Tor `executable_path`")
if err != nil {
return nil, err
}
startConf.ExePath = options.ExecutablePath
startConf.ProcessCreator = nil
startConf.UseEmbeddedControlConn = false
}
outboundDialer, err := dialer.New(ctx, options.DialerOptions, false)
if err != nil {
return nil, err