throne: 1.0.13 -> 1.1.1-unstable-2026-03-28
This commit is contained in:
@@ -23,7 +23,7 @@ in
|
||||
enable = lib.mkEnableOption "TUN mode of Throne";
|
||||
|
||||
setuid = lib.mkEnableOption ''
|
||||
setting suid bit for throne-core to run as root, which is less
|
||||
setting suid bit for ThroneCore to run as root, which is less
|
||||
secure than default setcap method but closer to upstream assumptions.
|
||||
Enable this if you find the default setcap method configured in
|
||||
this module doesn't work for you
|
||||
@@ -36,8 +36,8 @@ in
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
security.wrappers.throne-core = lib.mkIf cfg.tunMode.enable {
|
||||
source = "${cfg.package}/share/throne/Core";
|
||||
security.wrappers."ThroneCore" = lib.mkIf cfg.tunMode.enable {
|
||||
source = "${cfg.package}/share/throne/ThroneCore";
|
||||
owner = "root";
|
||||
group = "root";
|
||||
setuid = lib.mkIf cfg.tunMode.setuid true;
|
||||
@@ -49,7 +49,7 @@ in
|
||||
|
||||
# avoid resolvectl password prompt popping up three times
|
||||
# https://github.com/SagerNet/sing-tun/blob/0686f8c4f210f4e7039c352d42d762252f9d9cf5/tun_linux.go#L1062
|
||||
# We use a hack here to determine whether the requested process is throne-core
|
||||
# We use a hack here to determine whether the requested process is ThroneCore
|
||||
# Detect whether its capabilities contain at least `net_admin` and `net_raw`.
|
||||
# This does not reduce security, as we can already bypass `resolved` with them.
|
||||
# Alternatives to consider:
|
||||
@@ -61,7 +61,7 @@ in
|
||||
# change its own cmdline. `/proc/<pid>/exe` is reliable but kernel forbids
|
||||
# checking that entry of process from different users, and polkit runs `spawn`
|
||||
# as an unprivileged user.
|
||||
# 3. Put throne-core into a systemd service, and let polkit check service name.
|
||||
# 3. Put ThroneCore into a systemd service, and let polkit check service name.
|
||||
# This is the most secure and convenient way but requires heavy modification
|
||||
# to Throne source code. Would be good to let upstream support that eventually.
|
||||
security.polkit.extraConfig =
|
||||
@@ -69,6 +69,7 @@ in
|
||||
''
|
||||
polkit.addRule(function(action, subject) {
|
||||
const allowedActionIds = [
|
||||
"org.freedesktop.resolve1.revert",
|
||||
"org.freedesktop.resolve1.set-domains",
|
||||
"org.freedesktop.resolve1.set-default-route",
|
||||
"org.freedesktop.resolve1.set-dns-servers"
|
||||
|
||||
@@ -1,42 +1,40 @@
|
||||
diff --git a/server.go b/server.go
|
||||
index e2f2ab3..f81812f 100644
|
||||
index 4499a6d..4c14d1a 100644
|
||||
--- a/server.go
|
||||
+++ b/server.go
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/sagernet/sing-box/experimental/clashapi"
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
+ "golang.org/x/sys/unix"
|
||||
"github.com/sagernet/sing/service"
|
||||
"github.com/throneproj/clash2singbox/convert"
|
||||
"github.com/throneproj/clash2singbox/model"
|
||||
"github.com/throneproj/clash2singbox/model/clash"
|
||||
@@ -349,12 +350,25 @@ func (s *server) CompileGeoSiteToSrs(in *gen.CompileGeoSiteToSrsRequest, out *ge
|
||||
}
|
||||
"github.com/xtls/xray-core/core"
|
||||
)
|
||||
@@ -462,6 +463,27 @@ func (s *server) IsPrivileged(ctx context.Context, _ *gen.EmptyReq) (*gen.IsPriv
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *server) IsPrivileged(in *gen.EmptyReq, out *gen.IsPrivilegedResponse) error {
|
||||
- if runtime.GOOS == "windows" {
|
||||
- out.HasPrivilege = To(false)
|
||||
- return nil
|
||||
+ ret := false
|
||||
+ if runtime.GOOS == "windows" || os.Geteuid() == 0 {
|
||||
+ ret = true
|
||||
+ } else if runtime.GOOS == "linux" {
|
||||
+ 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: To(false),
|
||||
+ }, nil
|
||||
+ }
|
||||
}
|
||||
|
||||
- out.HasPrivilege = To(os.Geteuid() == 0)
|
||||
+ out.HasPrivilege = To(ret)
|
||||
return nil
|
||||
+
|
||||
+ // CAP_NET_ADMIN = 12
|
||||
+ return &gen.IsPrivilegedResponse{
|
||||
+ HasPrivilege: To((data[0].Effective & (1 << unix.CAP_NET_ADMIN)) != 0),
|
||||
+ }, nil
|
||||
+ }
|
||||
+
|
||||
return &gen.IsPrivilegedResponse{HasPrivilege: To(os.Geteuid() == 0)}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
diff --git a/src/sys/linux/AutoRun.cpp b/src/sys/linux/AutoRun.cpp
|
||||
index 1fafe35..fe04c75 100644
|
||||
--- a/src/sys/linux/AutoRun.cpp
|
||||
+++ b/src/sys/linux/AutoRun.cpp
|
||||
@@ -31,18 +31,9 @@ void AutoRun_SetEnabled(bool enable) {
|
||||
QString desktopFileLocation = userAutoStartPath + appName + QLatin1String(".desktop");
|
||||
QStringList appCmdList;
|
||||
|
||||
- if (QProcessEnvironment::systemEnvironment().contains("APPIMAGE")) {
|
||||
- appCmdList << QProcessEnvironment::systemEnvironment().value("APPIMAGE");
|
||||
- } else {
|
||||
- appCmdList << QApplication::applicationFilePath();
|
||||
- }
|
||||
-
|
||||
+ appCmdList << "Throne";
|
||||
appCmdList << "-tray";
|
||||
|
||||
- if (Configs::dataManager->settingsRepo->flag_use_appdata) {
|
||||
- appCmdList << "-appdata";
|
||||
- }
|
||||
-
|
||||
if (enable) {
|
||||
if (!QDir().exists(userAutoStartPath) && !QDir().mkpath(userAutoStartPath)) {
|
||||
// qCWarning(lcUtility) << "Could not create autostart folder"
|
||||
@@ -1,42 +1,42 @@
|
||||
diff --git a/src/global/Configs.cpp b/src/global/Configs.cpp
|
||||
index e7bec9c..f0dfe53 100644
|
||||
index 37b69be..2d458f3 100644
|
||||
--- a/src/global/Configs.cpp
|
||||
+++ b/src/global/Configs.cpp
|
||||
@@ -404,6 +404,12 @@ namespace Configs {
|
||||
// System Utils
|
||||
@@ -45,6 +45,12 @@ namespace Configs {
|
||||
}
|
||||
|
||||
QString FindCoreRealPath() {
|
||||
+ // find in PATH first
|
||||
+ QString path_for_nixos = QStandardPaths::findExecutable("throne-core");
|
||||
+ QString path_for_nixos = QStandardPaths::findExecutable("ThroneCore");
|
||||
+ if (!path_for_nixos.isEmpty()) {
|
||||
+ return path_for_nixos;
|
||||
+ }
|
||||
+
|
||||
auto fn = QApplication::applicationDirPath() + "/Core";
|
||||
auto fn = QApplication::applicationDirPath() + "/ThroneCore";
|
||||
#ifdef Q_OS_WIN
|
||||
fn += ".exe";
|
||||
diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp
|
||||
index d31c311..ce4c357 100644
|
||||
index 9acfee4..c0c313a 100644
|
||||
--- a/src/ui/mainwindow.cpp
|
||||
+++ b/src/ui/mainwindow.cpp
|
||||
@@ -151,8 +151,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
Configs::dataStore->core_port = MkPort();
|
||||
if (Configs::dataStore->core_port <= 0) Configs::dataStore->core_port = 19810;
|
||||
@@ -163,8 +163,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
Configs::dataManager->settingsRepo->core_port = MkPort();
|
||||
if (Configs::dataManager->settingsRepo->core_port <= 0) Configs::dataManager->settingsRepo->core_port = 19810;
|
||||
|
||||
- auto core_path = QApplication::applicationDirPath() + "/";
|
||||
- core_path += "Core";
|
||||
- core_path += "ThroneCore";
|
||||
+ auto core_path = Configs::FindCoreRealPath();
|
||||
|
||||
QStringList args;
|
||||
args.push_back("-port");
|
||||
@@ -1045,6 +1044,15 @@ bool MainWindow::get_elevated_permissions(int reason) {
|
||||
@@ -1296,6 +1295,15 @@ bool MainWindow::get_elevated_permissions(int reason) {
|
||||
return true;
|
||||
}
|
||||
if (Configs::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 throne-core. If you are using NixOS, please install Throne via `programs.throne.enable` and then set the `programs.throne.tunMode.enable` option to elevate privileges."),
|
||||
+ tr("Due to the read-only property of the Nix store, we cannot set suid for ThroneCore. If you are using NixOS, please install Throne via `programs.throne.enable` and then set the `programs.throne.tunMode.enable` option to elevate privileges."),
|
||||
+ QMessageBox::Ok
|
||||
+ );
|
||||
+ return false;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
protobuf,
|
||||
protoc-gen-go,
|
||||
protorpc,
|
||||
protoc-gen-go-grpc,
|
||||
|
||||
cmake,
|
||||
copyDesktopItems,
|
||||
@@ -19,23 +19,20 @@
|
||||
|
||||
# override if you want to have more up-to-date rulesets
|
||||
throne-srslist ? fetchurl {
|
||||
url = "https://raw.githubusercontent.com/throneproj/routeprofiles/0fca735ff2759422c407ac04fac819aef2fc88f9/srslist.h";
|
||||
hash = "sha256-G2WUStxFtN0fbZm/KoD9ldUvkMWf9cDA+9fvYt8dcqo=";
|
||||
url = "https://raw.githubusercontent.com/throneproj/routeprofiles/05793e2da7ca10a7acb2494f60a27ac5f7ec924c/srslist.h";
|
||||
hash = "sha256-NHer5Vy1zBL9yJlVDLVFNRG4ITzb2GTjmt718KsSrGw=";
|
||||
},
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "throne";
|
||||
version = "1.0.13";
|
||||
version = "1.1.1-unstable-2026-03-28";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "throneproj";
|
||||
repo = "Throne";
|
||||
# the release CI job was triggered on the xhttp branch (https://github.com/throneproj/Throne/actions/runs/20588046213),
|
||||
# but the 1.0.13 tag was wrongly created on the dev branch
|
||||
# we'll use the revision that was used for the job as well
|
||||
rev = "3b737ec8cf29e03e4b7d5a09b1f502bdb8ef52e2";
|
||||
hash = "sha256-OVgmhiKL4BaFYBeUqIX3LRNa54zq5oYyNMUYwKNvo1A=";
|
||||
rev = "f53bb73790782a9a9b7bfeb30c8d6e6bcc2b05f0";
|
||||
hash = "sha256-hEjbzS0JV5OA0c9kWTFGc5kv04qzobN0TFBjMJZ1ohc=";
|
||||
};
|
||||
|
||||
strictDeps = true;
|
||||
@@ -54,33 +51,36 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
|
||||
env.INPUT_VERSION = finalAttrs.version;
|
||||
|
||||
cmakeFlags = [
|
||||
# makes sure the app uses the user's config directory to store it's non-static content
|
||||
# it's essentially the same as always setting the -appdata flag when running the program
|
||||
(lib.cmakeBool "NKR_PACKAGE" true)
|
||||
];
|
||||
# suppress errors in 3rdparty/simple-protobuf
|
||||
env.NIX_CFLAGS_COMPILE = "-Wno-error=maybe-uninitialized";
|
||||
|
||||
patches = [
|
||||
# disable suid request as it cannot be applied to throne-core in nix store
|
||||
# and prompt users to use NixOS module instead. And use throne-core from PATH
|
||||
# disable suid request as it cannot be applied to ThroneCore in nix store
|
||||
# and prompt users to use NixOS module instead. And use ThroneCore from PATH
|
||||
# to make use of security wrappers
|
||||
./nixos-disable-setuid-request.patch
|
||||
|
||||
# sets the Exec field of the auto-run .desktop file to use the Throne binary from PATH
|
||||
./fix-autorun-desktop-exec.patch
|
||||
];
|
||||
|
||||
preBuild = ''
|
||||
ln -s ${throne-srslist} ./srslist.h
|
||||
'';
|
||||
|
||||
# we'll wrap manually
|
||||
dontWrapQtApps = true;
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
install -Dm755 Throne -t "$out/share/throne/"
|
||||
install -Dm644 "$src/res/public/Throne.png" -t "$out/share/icons/hicolor/512x512/apps/"
|
||||
|
||||
mkdir -p "$out/bin"
|
||||
ln -s "$out/share/throne/Throne" "$out/bin/"
|
||||
makeQtWrapper "$out/share/throne/Throne" "$out/bin/Throne" \
|
||||
--append-flag "-appdata" # use writable config dir
|
||||
|
||||
ln -s ${finalAttrs.passthru.core}/bin/Core "$out/share/throne/Core"
|
||||
ln -s ${finalAttrs.passthru.core}/bin/ThroneCore "$out/share/throne/ThroneCore"
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
@@ -108,18 +108,18 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
];
|
||||
|
||||
proxyVendor = true;
|
||||
vendorHash = "sha256-cPo/2bUXEF9jomr0Pnty7ZutAaC0TFG397FSIqefrjw=";
|
||||
vendorHash = "sha256-HNd0HI4JRPZiiSxDzOKgyAOW7tzZPCTPvOC5t+3yhoQ=";
|
||||
|
||||
nativeBuildInputs = [
|
||||
protobuf
|
||||
protoc-gen-go
|
||||
protorpc
|
||||
protoc-gen-go-grpc
|
||||
];
|
||||
|
||||
# taken from script/build_go.sh
|
||||
preBuild = ''
|
||||
pushd gen
|
||||
protoc -I . --go_out=. --protorpc_out=. libcore.proto
|
||||
protoc -I . --go_out=. --go-grpc_out=. libcore.proto
|
||||
popd
|
||||
|
||||
VERSION_SINGBOX=$(go list -m -f '{{.Version}}' github.com/sagernet/sing-box)
|
||||
@@ -130,6 +130,9 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
ldflags = [
|
||||
"-w"
|
||||
"-s"
|
||||
"-X"
|
||||
"internal/godebug.defaultGODEBUG=multipathtcp=0"
|
||||
"-checklinkname=0"
|
||||
];
|
||||
|
||||
tags = [
|
||||
@@ -140,10 +143,12 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
"with_utls"
|
||||
"with_dhcp"
|
||||
"with_tailscale"
|
||||
"badlinkname"
|
||||
"tfogo_checklinkname"
|
||||
];
|
||||
};
|
||||
|
||||
# this tricks nix-update into also updating the vendorHash of throne-core
|
||||
# this tricks nix-update into also updating the vendorHash of passthru.core
|
||||
passthru.goModules = finalAttrs.passthru.core.goModules;
|
||||
|
||||
meta = {
|
||||
|
||||
Reference in New Issue
Block a user