Windows OpenVPN/OpenVPN+Cloak killswitch feature

This commit is contained in:
Mykola Baibuz 2023-11-29 22:50:36 +02:00
parent dd233f77fc
commit c3fdd977b1
5 changed files with 105 additions and 8 deletions

View file

@ -4,6 +4,7 @@
#include <QRandomGenerator>
#include <QTcpServer>
#include <QTcpSocket>
#include <QNetworkInterface>
#include "logger.h"
#include "openvpnprotocol.h"
@ -53,6 +54,11 @@ void OpenVpnProtocol::stop()
QThread::msleep(10);
m_managementServer.stop();
}
#ifdef Q_OS_WIN
IpcClient::Interface()->disableKillSwitch();
#endif
setConnectionState(Vpn::ConnectionState::Disconnected);
}
@ -85,13 +91,13 @@ void OpenVpnProtocol::killOpenVpnProcess()
void OpenVpnProtocol::readOpenVpnConfiguration(const QJsonObject &configuration)
{
if (configuration.contains(ProtocolProps::key_proto_config_data(Proto::OpenVpn))) {
m_configData = configuration;
QJsonObject jConfig = configuration.value(ProtocolProps::key_proto_config_data(Proto::OpenVpn)).toObject();
m_configFile.open();
m_configFile.write(jConfig.value(config_key::config).toString().toUtf8());
m_configFile.close();
m_configFileName = m_configFile.fileName();
qDebug().noquote() << QString("Set config data") << m_configFileName;
}
}
@ -320,14 +326,25 @@ void OpenVpnProtocol::updateVpnGateway(const QString &line)
// line looks like
// PUSH: Received control message: 'PUSH_REPLY,route 10.8.0.1,topology net30,ping 10,ping-restart
// 120,ifconfig 10.8.0.6 10.8.0.5,peer-id 0,cipher AES-256-GCM'
QStringList params = line.split(",");
for (const QString &l : params) {
if (l.contains("ifconfig")) {
if (l.split(" ").size() == 3) {
m_vpnLocalAddress = l.split(" ").at(1);
m_vpnGateway = l.split(" ").at(2);
#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 (m_vpnLocalAddress == netInterfaces.at(i).addressEntries().at(j).ip().toString()) {
IpcClient::Interface()->enableKillSwitch(netInterfaces.at(i).index());
m_configData.insert("vpnGateway", m_vpnGateway);
IpcClient::Interface()->enablePeerTraffic(m_configData);
}
}
}
#endif
qDebug() << QString("Set vpn local address %1, gw %2").arg(m_vpnLocalAddress).arg(vpnGateway());
}
}

View file

@ -44,6 +44,7 @@ private:
ManagementServer m_managementServer;
QString m_configFileName;
QJsonObject m_configData;
QTemporaryFile m_configFile;
uint selectMgmtPort();

View file

@ -1,5 +1,7 @@
#include <QtCore>
#include <QString>
#include <QJsonObject>
#include "../client/daemon/interfaceconfig.h"
class IpcInterface
{
@ -22,5 +24,8 @@ class IpcInterface
SLOT( bool copyWireguardConfig(const QString &sourcePath) );
SLOT( bool isWireguardRunning() );
SLOT( bool isWireguardConfigExists(const QString &configPath) );
SLOT( bool enableKillSwitch(int vpnAdapterIndex) );
SLOT( bool disableKillSwitch() );
SLOT( bool enablePeerTraffic(const QJsonObject &configStr));
};

View file

@ -8,8 +8,11 @@
#include "router.h"
#include "logger.h"
#include "../client/protocols/protocols_defs.h"
#ifdef Q_OS_WIN
#include "tapcontroller_win.h"
#include "../client/platforms/windows/daemon/windowsfirewall.h"
#endif
IpcServer::IpcServer(QObject *parent):
@ -22,15 +25,14 @@ int IpcServer::createPrivilegedProcess()
qDebug() << "IpcServer::createPrivilegedProcess";
#endif
#ifdef Q_OS_WIN
WindowsFirewall::instance()->init();
#endif
m_localpid++;
ProcessDescriptor pd(this);
// pd.serverNode->setHostUrl(QUrl(amnezia::getIpcProcessUrl(m_localpid)));
// pd.serverNode->enableRemoting(pd.ipcProcess.data());
//pd.localServer = QSharedPointer<QLocalServer>(new QLocalServer(this));
pd.localServer->setSocketOptions(QLocalServer::WorldAccessOption);
if (!pd.localServer->listen(amnezia::getIpcProcessUrl(m_localpid))) {
@ -223,3 +225,70 @@ bool IpcServer::isWireguardConfigExists(const QString &configPath)
return QFileInfo::exists(configPath);
}
bool IpcServer::enableKillSwitch(int vpnAdapterIndex)
{
#ifdef Q_OS_WIN
return WindowsFirewall::instance()->enableKillSwitch(vpnAdapterIndex);
#endif
return true;
}
bool IpcServer::disableKillSwitch()
{
#ifdef Q_OS_WIN
return WindowsFirewall::instance()->disableKillSwitch();
#endif
return true;
}
bool IpcServer::enablePeerTraffic(const QJsonObject &configStr)
{
#ifdef Q_OS_WIN
InterfaceConfig config;
config.m_dnsServer = configStr.value(amnezia::config_key::dns1).toString();
config.m_serverPublicKey = "openvpn";
config.m_serverIpv4Gateway = configStr.value("vpnGateway").toString();
int splitTunnelType = configStr.value("splitTunnelType").toInt();
QJsonArray splitTunnelSites = configStr.value("splitTunnelSites").toArray();
qDebug() << "splitTunnelType " << splitTunnelType << "splitTunnelSites " << splitTunnelSites;
QStringList AllowedIPAddesses;
// Use APP split tunnel
if (splitTunnelType == 0 || splitTunnelType == 2) {
config.m_allowedIPAddressRanges.append(
IPAddress(QHostAddress("0.0.0.0"), 0));
config.m_allowedIPAddressRanges.append(
IPAddress(QHostAddress("::"), 0));
}
if (splitTunnelType == 1) {
for (auto v : splitTunnelSites) {
QString ipRange = v.toString();
qDebug() << "ipRange " << ipRange;
if (ipRange.split('/').size() > 1){
config.m_allowedIPAddressRanges.append(
IPAddress(QHostAddress(ipRange.split('/')[0]), atoi(ipRange.split('/')[1].toLocal8Bit())));
} else {
config.m_allowedIPAddressRanges.append(
IPAddress(QHostAddress(ipRange), 32));
}
}
}
config.m_excludedAddresses.append(configStr.value(amnezia::config_key::hostName).toString());
if (splitTunnelType == 2) {
for (auto v : splitTunnelSites) {
QString ipRange = v.toString();
config.m_excludedAddresses.append(ipRange);
}
}
return WindowsFirewall::instance()->enablePeerTraffic(config);
#endif
return true;
}

View file

@ -4,6 +4,8 @@
#include <QLocalServer>
#include <QObject>
#include <QRemoteObjectNode>
#include <QJsonObject>
#include "../client/daemon/interfaceconfig.h"
#include "ipc.h"
#include "ipcserverprocess.h"
@ -28,6 +30,9 @@ public:
virtual bool copyWireguardConfig(const QString &sourcePath) override;
virtual bool isWireguardRunning() override;
virtual bool isWireguardConfigExists(const QString &configPath) override;
virtual bool enableKillSwitch(int vpnAdapterIndex) override;
virtual bool disableKillSwitch() override;
virtual bool enablePeerTraffic(const QJsonObject &configStr) override;
private:
int m_localpid = 0;