fix: outbound freedom for xray on linux

This commit is contained in:
cd-amn
2026-04-07 23:52:06 +04:00
parent bf3d11e5c4
commit b8629032d6
4 changed files with 26 additions and 0 deletions

View File

@@ -32,6 +32,7 @@
#include "linuxfirewall.h" #include "linuxfirewall.h"
#include "logger.h" #include "logger.h"
#include "xray_defs.h"
#include <QProcess> #include <QProcess>
#define BRAND_CODE "amn" #define BRAND_CODE "amn"
@@ -282,6 +283,10 @@ void LinuxFirewall::install()
QStringLiteral("-o tun2+ -j ACCEPT"), QStringLiteral("-o tun2+ -j ACCEPT"),
}); });
installAnchor(Both, QStringLiteral("130.allowMarkedXray"), {
QStringLiteral("-m mark --mark %1 -j ACCEPT").arg(amnezia::xray::xrayTrafficMark),
});
installAnchor(IPv4, QStringLiteral("120.blockNets"), {}); installAnchor(IPv4, QStringLiteral("120.blockNets"), {});
installAnchor(IPv4, QStringLiteral("110.allowNets"), {}); installAnchor(IPv4, QStringLiteral("110.allowNets"), {});
@@ -358,6 +363,7 @@ void LinuxFirewall::uninstall()
uninstallAnchor(IPv6, QStringLiteral("250.blockIPv6")); uninstallAnchor(IPv6, QStringLiteral("250.blockIPv6"));
uninstallAnchor(Both, QStringLiteral("200.allowVPN")); uninstallAnchor(Both, QStringLiteral("200.allowVPN"));
uninstallAnchor(IPv4, QStringLiteral("120.blockNets")); uninstallAnchor(IPv4, QStringLiteral("120.blockNets"));
uninstallAnchor(Both, QStringLiteral("130.allowMarkedXray"));
uninstallAnchor(IPv4, QStringLiteral("110.allowNets")); uninstallAnchor(IPv4, QStringLiteral("110.allowNets"));
uninstallAnchor(Both, QStringLiteral("100.blockAll")); uninstallAnchor(Both, QStringLiteral("100.blockAll"));

View File

@@ -81,6 +81,7 @@ bool KillSwitch::disableKillSwitch() {
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("100.blockAll"), true); LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("100.blockAll"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("110.allowNets"), false); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("110.allowNets"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("120.blockNets"), false); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("120.blockNets"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("130.allowMarkedXray"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("200.allowVPN"), false); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("200.allowVPN"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv6, QStringLiteral("250.blockIPv6"), true); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv6, QStringLiteral("250.blockIPv6"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("290.allowDHCP"), false); LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("290.allowDHCP"), false);
@@ -93,6 +94,7 @@ bool KillSwitch::disableKillSwitch() {
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("100.blockAll"), false); LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("100.blockAll"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("110.allowNets"), false); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("110.allowNets"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("120.blockNets"), false); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("120.blockNets"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("130.allowMarkedXray"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("200.allowVPN"), false); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("200.allowVPN"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv6, QStringLiteral("250.blockIPv6"), false); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv6, QStringLiteral("250.blockIPv6"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("290.allowDHCP"), true); LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("290.allowDHCP"), true);
@@ -140,6 +142,7 @@ bool KillSwitch::disableAllTraffic() {
LinuxFirewall::install(); LinuxFirewall::install();
} }
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("100.blockAll"), true); LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("100.blockAll"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("130.allowMarkedXray"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("000.allowLoopback"), true); LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("000.allowLoopback"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv6, QStringLiteral("250.blockIPv6"), true); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv6, QStringLiteral("250.blockIPv6"), true);
#endif #endif
@@ -276,15 +279,18 @@ bool KillSwitch::enableKillSwitch(const QJsonObject &configStr, int vpnAdapterIn
bool blockAll = 0; bool blockAll = 0;
bool allowNets = 0; bool allowNets = 0;
bool blockNets = 0; bool blockNets = 0;
bool allowMarkedXray = 0;
QStringList allownets; QStringList allownets;
QStringList blocknets; QStringList blocknets;
if (splitTunnelType == 0) { if (splitTunnelType == 0) {
blockAll = true; blockAll = true;
allowNets = true; allowNets = true;
allowMarkedXray = true;
allownets.append(configStr.value("vpnServer").toString()); allownets.append(configStr.value("vpnServer").toString());
} else if (splitTunnelType == 1) { } else if (splitTunnelType == 1) {
blockNets = true; blockNets = true;
allowMarkedXray = true;
for (auto v : splitTunnelSites) { for (auto v : splitTunnelSites) {
blocknets.append(v.toString()); blocknets.append(v.toString());
} }
@@ -310,6 +316,7 @@ bool KillSwitch::enableKillSwitch(const QJsonObject &configStr, int vpnAdapterIn
LinuxFirewall::updateAllowNets(allownets); LinuxFirewall::updateAllowNets(allownets);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("120.blockNets"), blockAll); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("120.blockNets"), blockAll);
LinuxFirewall::updateBlockNets(blocknets); LinuxFirewall::updateBlockNets(blocknets);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("130.allowMarkedXray"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("200.allowVPN"), true); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("200.allowVPN"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv6, QStringLiteral("250.blockIPv6"), true); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv6, QStringLiteral("250.blockIPv6"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("290.allowDHCP"), true); LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("290.allowDHCP"), true);

View File

@@ -25,6 +25,7 @@
#endif #endif
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
#include <sys/socket.h> #include <sys/socket.h>
#include "xray_defs.h"
#endif #endif
bool Xray::startXray(const QString &cfg) bool Xray::startXray(const QString &cfg)
@@ -99,6 +100,7 @@ void Xray::sockCallback(uintptr_t fd)
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
if (!m_defaultIfaceName.isEmpty()) { if (!m_defaultIfaceName.isEmpty()) {
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, m_defaultIfaceName.data(), m_defaultIfaceName.size()); setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, m_defaultIfaceName.data(), m_defaultIfaceName.size());
setsockopt(fd, SOL_SOCKET, SO_MARK, &amnezia::xray::xrayTrafficMark, sizeof(amnezia::xray::xrayTrafficMark));
} }
#endif #endif
} }

View File

@@ -0,0 +1,11 @@
#ifndef XRAY_DEFS_H
#define XRAY_DEFS_H
namespace amnezia
{
namespace xray
{
constexpr unsigned int xrayTrafficMark = 0x82;
}
}
#endif // XRAY_DEFS_H