mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-11-10 21:21:02 +08:00
Reject Tailscale SSH user switch without privilege
This commit is contained in:
3 files changed
+49
-4
No files matched your search
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
gliderssh "github.com/sagernet/gliderssh"
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
func isPrivilegedUser() bool {
|
||||
@@ -21,10 +22,21 @@ func requestedUserMatchesProcess(localUser *adapter.PlatformUser) (bool, error)
|
||||
return localUser.Uid == os.Getuid() && localUser.Gid == os.Getgid(), nil
|
||||
}
|
||||
|
||||
// verifyShellIdentity is a no-op on Unix: spawned shells and sftp-server drop to the
|
||||
// requested user via setCredential, so the child already runs as that user.
|
||||
func verifyShellIdentity(_ adapter.PlatformInterface, _ *adapter.PlatformUser) error {
|
||||
return nil
|
||||
func verifyShellIdentity(platformInterface adapter.PlatformInterface, localUser *adapter.PlatformUser) error {
|
||||
if platformInterface != nil && platformInterface.UsePlatformShell() {
|
||||
return nil
|
||||
}
|
||||
match, err := requestedUserMatchesProcess(localUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if match {
|
||||
return nil
|
||||
}
|
||||
if !isPrivilegedUser() {
|
||||
return E.New("switching to local user ", localUser.Username, " requires sing-box to run as root")
|
||||
}
|
||||
return checkSwitchUserPrivilege(localUser)
|
||||
}
|
||||
|
||||
func systemHostKeyPath() string {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
//go:build with_gvisor && linux
|
||||
|
||||
package tailssh
|
||||
|
||||
import (
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func checkSwitchUserPrivilege(localUser *adapter.PlatformUser) error {
|
||||
header := unix.CapUserHeader{Version: unix.LINUX_CAPABILITY_VERSION_3}
|
||||
var data [2]unix.CapUserData
|
||||
err := unix.Capget(&header, &data[0])
|
||||
if err != nil {
|
||||
return E.Cause(err, "query process capabilities")
|
||||
}
|
||||
const required = 1<<unix.CAP_SETUID | 1<<unix.CAP_SETGID
|
||||
if data[0].Effective&required != required {
|
||||
return E.New("switching to local user ", localUser.Username, " requires CAP_SETUID and CAP_SETGID")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
//go:build with_gvisor && !windows && !linux
|
||||
|
||||
package tailssh
|
||||
|
||||
import "github.com/sagernet/sing-box/adapter"
|
||||
|
||||
func checkSwitchUserPrivilege(_ *adapter.PlatformUser) error {
|
||||
return nil
|
||||
}
|
||||
Reference in new issue
Block a user