diff --git a/pkgs/by-name/ne/nekoray/core-also-check-capabilities.patch b/pkgs/by-name/ne/nekoray/core-also-check-capabilities.patch new file mode 100644 index 000000000000..d477100b172f --- /dev/null +++ b/pkgs/by-name/ne/nekoray/core-also-check-capabilities.patch @@ -0,0 +1,43 @@ +diff --git a/server.go b/server.go +index c2a6be0..8aeca1c 100644 +--- a/server.go ++++ b/server.go +@@ -11,6 +11,7 @@ import ( + E "github.com/sagernet/sing/common/exceptions" + "github.com/sagernet/sing/common/metadata" + "github.com/sagernet/sing/service" ++ "golang.org/x/sys/unix" + "log" + "nekobox_core/gen" + "nekobox_core/internal/boxbox" +@@ -359,13 +360,25 @@ func (s *server) CompileGeoSiteToSrs(ctx context.Context, in *gen.CompileGeoSite + } + + func (s *server) IsPrivileged(ctx context.Context, _ *gen.EmptyReq) (*gen.IsPrivilegedResponse, error) { +- if runtime.GOOS == "windows" { +- return &gen.IsPrivilegedResponse{ +- HasPrivilege: false, +- }, nil ++ ret := false ++ if runtime.GOOS == "windows" || os.Geteuid() == 0 { ++ ret = true ++ } else if runtime.GOOS == "linux" { ++ caps := unix.CapUserHeader{ ++ Version: unix.LINUX_CAPABILITY_VERSION_3, ++ Pid: 0, // current ++ } ++ var data [2]unix.CapUserData ++ err := unix.Capget(&caps, &data[0]) ++ if err != nil { ++ ret = false ++ } else { ++ // CAP_NET_ADMIN = 12 ++ ret = (data[0].Effective & (1 << unix.CAP_NET_ADMIN)) != 0 ++ } + } + +- return &gen.IsPrivilegedResponse{HasPrivilege: os.Geteuid() == 0}, nil ++ return &gen.IsPrivilegedResponse{HasPrivilege: ret}, nil + } + + func (s *server) SpeedTest(ctx context.Context, in *gen.SpeedTestRequest) (*gen.SpeedTestResponse, error) { diff --git a/pkgs/by-name/ne/nekoray/nixos-disable-setuid-request.patch b/pkgs/by-name/ne/nekoray/nixos-disable-setuid-request.patch new file mode 100644 index 000000000000..ade76eb9decd --- /dev/null +++ b/pkgs/by-name/ne/nekoray/nixos-disable-setuid-request.patch @@ -0,0 +1,47 @@ +diff --git a/src/global/NekoGui.cpp b/src/global/NekoGui.cpp +index 7943d7a..5bb20cc 100644 +--- a/src/global/NekoGui.cpp ++++ b/src/global/NekoGui.cpp +@@ -355,6 +355,12 @@ namespace NekoGui { + // System Utils + + QString FindNekoBoxCoreRealPath() { ++ // find in PATH first ++ QString path = QStandardPaths::findExecutable("nekobox_core"); ++ if (!path.isEmpty()) { ++ return path; ++ } ++ + auto fn = QApplication::applicationDirPath() + "/nekobox_core"; + auto fi = QFileInfo(fn); + if (fi.isSymLink()) return fi.symLinkTarget(); +diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp +index 9aa46b2..ba7137a 100644 +--- a/src/ui/mainwindow.cpp ++++ b/src/ui/mainwindow.cpp +@@ -125,8 +125,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi + NekoGui::dataStore->core_port = MkPort(); + if (NekoGui::dataStore->core_port <= 0) NekoGui::dataStore->core_port = 19810; + +- auto core_path = QApplication::applicationDirPath() + "/"; +- core_path += "nekobox_core"; ++ auto core_path = NekoGui::FindNekoBoxCoreRealPath(); + + QStringList args; + args.push_back("nekobox"); +@@ -844,6 +843,15 @@ bool MainWindow::get_elevated_permissions(int reason) { + return true; + } + if (NekoGui::IsAdmin()) return true; ++ QMessageBox::critical( ++ GetMessageBoxParent(), ++ tr("Unable to elevate privileges when installed with Nix"), ++ tr("Due to the read-only property of Nix store, we cannot set suid for nekobox_core. If you are using NixOS, please set `programs.nekoray.tunMode.enable` option to elevate privileges."), ++ QMessageBox::Ok ++ ); ++ return false; ++ // The following code isn't effective, preserve to avoid merge conflict ++ + #ifdef Q_OS_LINUX + if (!Linux_HavePkexec()) { + MessageBoxWarning(software_name, "Please install \"pkexec\" first."); diff --git a/pkgs/by-name/ne/nekoray/package.nix b/pkgs/by-name/ne/nekoray/package.nix index 3a5927a83f28..bc7765a50af3 100644 --- a/pkgs/by-name/ne/nekoray/package.nix +++ b/pkgs/by-name/ne/nekoray/package.nix @@ -60,6 +60,11 @@ stdenv.mkDerivation (finalAttrs: { # we already package those two files in nixpkgs # we can't place file at that location using our builder so we must change the search directory to be relative to the built executable ./search-for-geodata-in-install-location.patch + + # disable suid request as it cannot be applied to nekobox_core in nix store + # and prompt users to use NixOS module instead. And use nekobox_core from PATH + # to make use of security wrappers + ./nixos-disable-setuid-request.patch ]; installPhase = '' @@ -99,6 +104,11 @@ stdenv.mkDerivation (finalAttrs: { inherit (finalAttrs) version src; sourceRoot = "${finalAttrs.src.name}/core/server"; + patches = [ + # also check cap_net_admin so we don't have to set suid + ./core-also-check-capabilities.patch + ]; + vendorHash = "sha256-CTI9wDPJ9dYpUwvszY2nRfi+NW0nO8imt9lsQ7Nd1Q8="; # ldflags and tags are taken from script/build_go.sh