mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-19 02:00:45 +07:00
refactor: route Windows WG killswitch through TrafficGuard
This commit is contained in:
@@ -181,18 +181,28 @@ void VpnTrafficGuard::applyFirewall(const QString &gateway, const QString &local
|
||||
QJsonObject updatedConfig = m_config;
|
||||
IpcClient::withInterface([&](QSharedPointer<IpcInterfaceReplica> iface) {
|
||||
#ifdef Q_OS_WIN
|
||||
QList<QNetworkInterface> netInterfaces = QNetworkInterface::allInterfaces();
|
||||
for (int i = 0; i < netInterfaces.size(); i++) {
|
||||
for (int j=0; j < netInterfaces.at(i).addressEntries().size(); j++)
|
||||
{
|
||||
if (localAddress == netInterfaces.at(i).addressEntries().at(j).ip().toString()) {
|
||||
updatedConfig.insert("vpnAdapterIndex", netInterfaces.at(i).index());
|
||||
updatedConfig.insert("vpnGateway", gateway);
|
||||
updatedConfig.insert("vpnServer", NetworkUtilities::getIPAddress(updatedConfig.value(configKey::hostName).toString()));
|
||||
if (QVariant(updatedConfig.value(configKey::killSwitchOption).toString()).toBool()) {
|
||||
iface->enableKillSwitch(updatedConfig, netInterfaces.at(i).index());
|
||||
const QString ifname = updatedConfig.value("ifname").toString();
|
||||
if (!ifname.isEmpty()) {
|
||||
updatedConfig.insert("vpnGateway", gateway);
|
||||
updatedConfig.insert("vpnServer", NetworkUtilities::getIPAddress(updatedConfig.value(configKey::hostName).toString()));
|
||||
if (QVariant(updatedConfig.value(configKey::killSwitchOption).toString()).toBool()) {
|
||||
iface->enableKillSwitch(updatedConfig, 0);
|
||||
}
|
||||
iface->enablePeerTraffic(updatedConfig);
|
||||
} else {
|
||||
QList<QNetworkInterface> netInterfaces = QNetworkInterface::allInterfaces();
|
||||
for (int i = 0; i < netInterfaces.size(); i++) {
|
||||
for (int j=0; j < netInterfaces.at(i).addressEntries().size(); j++)
|
||||
{
|
||||
if (localAddress == netInterfaces.at(i).addressEntries().at(j).ip().toString()) {
|
||||
updatedConfig.insert("vpnAdapterIndex", netInterfaces.at(i).index());
|
||||
updatedConfig.insert("vpnGateway", gateway);
|
||||
updatedConfig.insert("vpnServer", NetworkUtilities::getIPAddress(updatedConfig.value(configKey::hostName).toString()));
|
||||
if (QVariant(updatedConfig.value(configKey::killSwitchOption).toString()).toBool()) {
|
||||
iface->enableKillSwitch(updatedConfig, netInterfaces.at(i).index());
|
||||
}
|
||||
iface->enablePeerTraffic(updatedConfig);
|
||||
}
|
||||
iface->enablePeerTraffic(updatedConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
#include "killswitch.h"
|
||||
#include "leakdetector.h"
|
||||
#include "logger.h"
|
||||
#include "windowsfirewall.h"
|
||||
@@ -103,14 +102,19 @@ bool WireguardUtilsWindows::addInterface(const InterfaceConfig& config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We don't want to pass a peer just yet, that will happen later with
|
||||
// a UAPI command in WireguardUtilsWindows::updatePeer(), so truncate
|
||||
// the config file to remove the [Peer] section.
|
||||
qsizetype peerStart = configString.indexOf("[Peer]", 0, Qt::CaseSensitive);
|
||||
if (peerStart >= 0) {
|
||||
configString.truncate(peerStart);
|
||||
}
|
||||
|
||||
qsizetype dnsStart = configString.indexOf("DNS = ");
|
||||
if (dnsStart >= 0) {
|
||||
qsizetype dnsEnd = configString.indexOf('\n', dnsStart);
|
||||
if (dnsEnd >= 0) {
|
||||
configString.remove(dnsStart, dnsEnd - dnsStart + 1);
|
||||
}
|
||||
}
|
||||
|
||||
m_ifname = config.m_ifname.isEmpty() ? s_defaultInterfaceName() : config.m_ifname;
|
||||
if (!m_tunnel.start(configString, m_ifname)) {
|
||||
logger.error() << "Failed to activate the tunnel service";
|
||||
@@ -126,14 +130,6 @@ bool WireguardUtilsWindows::addInterface(const InterfaceConfig& config) {
|
||||
m_luid = luid.Value;
|
||||
m_routeMonitor = new WindowsRouteMonitor(luid.Value, this);
|
||||
|
||||
if (config.m_killSwitchEnabled) {
|
||||
NET_IFINDEX ifindex;
|
||||
ConvertInterfaceLuidToIndex(&luid, &ifindex);
|
||||
m_firewall->allowAllTraffic();
|
||||
m_firewall->enableInterface(ifindex);
|
||||
KillSwitch::instance()->addAllowedRange({});
|
||||
}
|
||||
|
||||
logger.debug() << "Registration completed";
|
||||
return true;
|
||||
}
|
||||
@@ -143,7 +139,6 @@ bool WireguardUtilsWindows::deleteInterface() {
|
||||
m_routeMonitor->deleteLater();
|
||||
}
|
||||
|
||||
m_firewall->disableKillSwitch();
|
||||
m_tunnel.stop();
|
||||
return true;
|
||||
}
|
||||
@@ -154,10 +149,6 @@ bool WireguardUtilsWindows::updatePeer(const InterfaceConfig& config) {
|
||||
QByteArray pskKey =
|
||||
QByteArray::fromBase64(qPrintable(config.m_serverPskKey));
|
||||
|
||||
if (config.m_killSwitchEnabled) {
|
||||
// Enable the windows firewall for this peer.
|
||||
m_firewall->enablePeerTraffic(config);
|
||||
}
|
||||
logger.debug() << "Configuring peer" << publicKey.toHex()
|
||||
<< "via" << config.m_serverIpv4AddrIn;
|
||||
|
||||
@@ -194,9 +185,6 @@ bool WireguardUtilsWindows::deletePeer(const InterfaceConfig& config) {
|
||||
QByteArray publicKey =
|
||||
QByteArray::fromBase64(qPrintable(config.m_serverPublicKey));
|
||||
|
||||
// Disable the windows firewall for this peer.
|
||||
m_firewall->disablePeerTraffic(config.m_serverPublicKey);
|
||||
|
||||
QString message;
|
||||
QTextStream out(&message);
|
||||
out << "set=1\n";
|
||||
|
||||
@@ -146,8 +146,6 @@ void VpnConnection::wireTunnelSignals(Tunnel* tunnel, bool isActive)
|
||||
|
||||
if (isActive) {
|
||||
connect(tunnel, &Tunnel::bytesChanged, this, &VpnConnection::onBytesChanged);
|
||||
connect(tunnel, &Tunnel::addressesUpdated,
|
||||
m_trafficGuard.data(), &VpnTrafficGuard::applyFirewall);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,6 +214,7 @@ void VpnConnection::connectToVpn(const QString &serverId, DockerContainer contai
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
if (VpnProtocol::isWireGuardBased(container)) {
|
||||
const QString ifname = allocateIfname();
|
||||
config.insert("ifname", ifname);
|
||||
m_active = new Tunnel(ifname, container, config, resolvedRemote, this);
|
||||
wireTunnelSignals(m_active, /*isActive=*/true);
|
||||
wireDaemonReconnectSignals();
|
||||
@@ -561,8 +560,6 @@ void VpnConnection::onTunnelPrepared()
|
||||
m_active = m_staging;
|
||||
m_staging = nullptr;
|
||||
connect(m_active, &Tunnel::bytesChanged, this, &VpnConnection::onBytesChanged);
|
||||
connect(m_active, &Tunnel::addressesUpdated,
|
||||
m_trafficGuard.data(), &VpnTrafficGuard::applyFirewall);
|
||||
m_vpnConfiguration = m_active->config();
|
||||
m_remoteAddress = m_active->remoteAddress();
|
||||
m_trafficGuard->setConfig(m_vpnConfiguration);
|
||||
|
||||
@@ -14,6 +14,28 @@
|
||||
#ifdef Q_OS_WIN
|
||||
#include "../client/platforms/windows/daemon/windowsfirewall.h"
|
||||
#include "../client/platforms/windows/daemon/windowsdaemon.h"
|
||||
|
||||
namespace {
|
||||
int resolveVpnAdapterIndex(const QJsonObject& configStr) {
|
||||
int index = configStr.value("vpnAdapterIndex").toInt();
|
||||
if (index != 0) {
|
||||
return index;
|
||||
}
|
||||
const QString ifname = configStr.value("ifname").toString();
|
||||
if (ifname.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
NET_LUID luid;
|
||||
if (ConvertInterfaceAliasToLuid((wchar_t*)ifname.utf16(), &luid) != 0) {
|
||||
return 0;
|
||||
}
|
||||
NET_IFINDEX ifindex = 0;
|
||||
if (ConvertInterfaceLuidToIndex(&luid, &ifindex) != 0) {
|
||||
return 0;
|
||||
}
|
||||
return static_cast<int>(ifindex);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
@@ -223,7 +245,7 @@ bool KillSwitch::enablePeerTraffic(const QJsonObject &configStr) {
|
||||
config.m_serverPublicKey = "openvpn";
|
||||
config.m_serverIpv4Gateway = configStr.value("vpnGateway").toString();
|
||||
config.m_serverIpv4AddrIn = configStr.value("vpnServer").toString();
|
||||
int vpnAdapterIndex = configStr.value("vpnAdapterIndex").toInt();
|
||||
int vpnAdapterIndex = resolveVpnAdapterIndex(configStr);
|
||||
int inetAdapterIndex = configStr.value("inetAdapterIndex").toInt();
|
||||
|
||||
int splitTunnelType = configStr.value("splitTunnelType").toInt();
|
||||
@@ -282,10 +304,12 @@ bool KillSwitch::enablePeerTraffic(const QJsonObject &configStr) {
|
||||
|
||||
bool KillSwitch::enableKillSwitch(const QJsonObject &configStr, int vpnAdapterIndex) {
|
||||
#ifdef Q_OS_WIN
|
||||
Q_UNUSED(vpnAdapterIndex)
|
||||
const int resolvedIndex = resolveVpnAdapterIndex(configStr);
|
||||
if (configStr.value("splitTunnelType").toInt() != 0) {
|
||||
WindowsFirewall::create(this)->allowAllTraffic();
|
||||
}
|
||||
return WindowsFirewall::create(this)->enableInterface(vpnAdapterIndex);
|
||||
return WindowsFirewall::create(this)->enableInterface(resolvedIndex);
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
|
||||
|
||||
Reference in New Issue
Block a user