feat: Improve linux permission and tun handling

This commit is contained in:
Nova 2024-09-04 05:15:22 +03:30
parent 10c041f775
commit 497ad88aab
10 changed files with 44 additions and 31 deletions

View File

@ -3,14 +3,14 @@ module nekobox_core
go 1.19
require (
github.com/Mahdi-zarei/sing-box-extra v0.0.0-20240902015241-67553399f0d3
github.com/Mahdi-zarei/sing-box-extra v0.0.0-20240904000146-e1145d011ef6
github.com/matsuridayo/libneko v0.0.0-20230913024055-5277a5bfc889
github.com/sagernet/sing v0.5.0-beta.1
github.com/sagernet/sing-box v1.10.0-beta.5
grpc_server v1.0.0
)
replace github.com/sagernet/sing-box => github.com/Mahdi-zarei/sing-box v1.3.5-0.20240902015024-87ce1b5463e9
replace github.com/sagernet/sing-box => github.com/Mahdi-zarei/sing-box v1.3.5-0.20240903235116-2a7756b546b9
require (
berty.tech/go-libtor v1.0.385 // indirect

View File

@ -4,10 +4,10 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Mahdi-zarei/sing-box v1.3.5-0.20240902015024-87ce1b5463e9 h1:w7wKaq2iez2/EOgM+sc3Ti5EKkUyXFWcbWRIZehPjPE=
github.com/Mahdi-zarei/sing-box v1.3.5-0.20240902015024-87ce1b5463e9/go.mod h1:VjyGsaBUZ32vwYx8zVXOti3FNfhHvf/ep/e5kDpkkM0=
github.com/Mahdi-zarei/sing-box-extra v0.0.0-20240902015241-67553399f0d3 h1:tPH8SfROa4mANNfzf6zCC4g4IUE+ZsP37o2URg1YQSs=
github.com/Mahdi-zarei/sing-box-extra v0.0.0-20240902015241-67553399f0d3/go.mod h1:WDV7JVlC/tzRBv0iOMNe8z9exRu0uSc79vT/8vnAbAQ=
github.com/Mahdi-zarei/sing-box v1.3.5-0.20240903235116-2a7756b546b9 h1:By3CYAqbFLkIWOxmpeg5jbd6gIY+qCM9PvuwcYCrcos=
github.com/Mahdi-zarei/sing-box v1.3.5-0.20240903235116-2a7756b546b9/go.mod h1:VjyGsaBUZ32vwYx8zVXOti3FNfhHvf/ep/e5kDpkkM0=
github.com/Mahdi-zarei/sing-box-extra v0.0.0-20240904000146-e1145d011ef6 h1:p/sgsZ98PukqosSZPVjAy3yxmymKDi2DrS0X2lPC7a4=
github.com/Mahdi-zarei/sing-box-extra v0.0.0-20240904000146-e1145d011ef6/go.mod h1:02D/Khg/+qB8Cc8LVy3g1PdzrmS9RBytU3xbNVIMuzw=
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=

View File

@ -394,6 +394,20 @@ namespace NekoGui {
return fn;
}
QString FindNekorayRealPath() {
auto fn = QApplication::applicationDirPath() + "/";
#ifdef Q_OS_LINUX
fn += "launcher";
#elif Q_OS_WIN
fn += "nekoray.exe"
#else
fn += "nekoray"
#endif
auto fi = QFileInfo(fn);
if (fi.isSymLink()) return fi.symLinkTarget();
return fn;
}
short isAdminCache = -1;
// IsAdmin 主要判断:有无权限启动 Tun
@ -405,7 +419,7 @@ namespace NekoGui {
admin = Windows_IsInAdmin();
#else
#ifdef Q_OS_LINUX
admin |= Linux_GetCapString(FindNekoBoxCoreRealPath()).contains("cap_net_admin");
admin |= Linux_GetCapString(FindNekorayRealPath()).contains("cap_sys_admin");
#endif
admin |= geteuid() == 0;
#endif

View File

@ -14,6 +14,8 @@ namespace NekoGui {
QString FindNekoBoxCoreRealPath();
QString FindNekorayRealPath();
bool IsAdmin();
} // namespace NekoGui

View File

@ -220,7 +220,7 @@ namespace NekoGui_rpc {
return {reply.error().c_str()};
} else {
NOT_OK
return "";
return reply.error().c_str();
}
}

View File

@ -53,7 +53,12 @@ namespace NekoGui_sys {
}
QProcess::setEnvironment(env);
#ifdef Q_OS_LINUX
if (NekoGui::IsAdmin()) QProcess::startCommand("sudo " + program + " " + arguments.join(" "));
else QProcess::start(program, arguments);
#else
QProcess::start(program, arguments);
#endif
}
void ExternalProcess::Kill() {

View File

@ -53,6 +53,6 @@ void DialogVPNSettings::on_troubleshooting_clicked() {
tr("Reset"), tr("Cancel"), "",
1, 1);
if (r == 0) {
GetMainWindow()->StopVPNProcess(true);
GetMainWindow()->StopVPNProcess();
}
}

View File

@ -712,14 +712,12 @@ bool MainWindow::get_elevated_permissions() {
MessageBoxWarning(software_name, "Please install \"pkexec\" first.");
return false;
}
auto ret = Linux_Pkexec_SetCapString(NekoGui::FindNekoBoxCoreRealPath(), "cap_net_admin=ep");
if (ret == 0) {
this->exit_reason = 3;
on_menu_exit_triggered();
} else {
MessageBoxWarning(software_name, "Setcap for Tun mode failed.\n\n1. You may canceled the dialog.\n2. You may be using an incompatible environment like AppImage.");
if (QProcessEnvironment::systemEnvironment().contains("APPIMAGE")) {
MW_show_log("If you are using AppImage, it's impossible to start a Tun. Please use other package instead.");
auto n = QMessageBox::warning(GetMessageBoxParent(), software_name, tr("Please run Nekoray as admin"), QMessageBox::Yes | QMessageBox::No);
if (n == QMessageBox::Yes) {
auto ret = Linux_Pkexec_SetCapString(NekoGui::FindNekorayRealPath(), "cap_sys_admin=ep");
if (ret == 0) {
this->exit_reason = 3;
on_menu_exit_triggered();
}
}
#endif
@ -1755,10 +1753,10 @@ void MainWindow::RegisterHotkey(bool unregister) {}
void MainWindow::HotkeyEvent(const QString &key) {}
#endif
bool MainWindow::StopVPNProcess(bool unconditional) {
if (unconditional || vpn_pid != 0) {
bool MainWindow::StopVPNProcess() {
if (vpn_pid != 0) {
bool ok;
core_process->processId();
vpn_pid = core_process->processId();
#ifdef Q_OS_WIN
auto ret = WinCommander::runProcessElevated("taskkill", {"/IM", "nekobox_core.exe",
"/FI",
@ -1770,18 +1768,12 @@ bool MainWindow::StopVPNProcess(bool unconditional) {
p.start("osascript", {"-e", QString("do shell script \"%1\" with administrator privileges")
.arg("pkill -2 -U 0 nekobox_core")});
#else
if (unconditional) {
p.start("pkexec", {"killall", "-2", "nekobox_core"});
} else {
p.start("pkexec", {"pkill", "-2", "-P", Int2String(vpn_pid)});
}
p.start("pkexec", {"pkill", "-2", "-P", Int2String(vpn_pid)});
#endif
p.waitForFinished();
ok = p.exitCode() == 0;
#endif
if (!unconditional) {
ok ? vpn_pid = 0 : MessageBoxWarning(tr("Error"), tr("Failed to stop Tun process"));
}
ok ? vpn_pid = 0 : MessageBoxWarning(tr("Error"), tr("Failed to stop Tun process"));
return ok;
}
return true;

View File

@ -68,7 +68,7 @@ public:
void RegisterHotkey(bool unregister);
bool StopVPNProcess(bool unconditional = false);
bool StopVPNProcess();
void DownloadAssets(const QString &geoipUrl, const QString &geositeUrl);

View File

@ -248,11 +248,11 @@ void MainWindow::neko_start(int _id) {
if (error.contains("configure tun interface")) {
runOnUiThread([=] {
auto r = QMessageBox::information(this, tr("Tun device misbehaving"),
tr("If you have trouble starting VPN, you can force reset nekobox_core process here and then try starting the profile again."),
tr("If you have trouble starting VPN, you can force reset nekobox_core process here and then try starting the profile again. The error is %1").arg(error),
tr("Reset"), tr("Cancel"), "",
1, 1);
if (r == 0) {
GetMainWindow()->StopVPNProcess(true);
GetMainWindow()->StopVPNProcess();
}
});
return false;