Wireguard protocol + refactoring
This commit is contained in:
parent
8bdfe1741a
commit
2f6fb0d557
41 changed files with 1245 additions and 152 deletions
|
|
@ -15,7 +15,9 @@ HEADERS += \
|
||||||
../ipc/ipc.h \
|
../ipc/ipc.h \
|
||||||
configurators/cloak_configurator.h \
|
configurators/cloak_configurator.h \
|
||||||
configurators/shadowsocks_configurator.h \
|
configurators/shadowsocks_configurator.h \
|
||||||
|
configurators/ssh_configurator.h \
|
||||||
configurators/vpn_configurator.h \
|
configurators/vpn_configurator.h \
|
||||||
|
configurators/wireguard_configurator.h \
|
||||||
core/defs.h \
|
core/defs.h \
|
||||||
core/errorstrings.h \
|
core/errorstrings.h \
|
||||||
core/ipcclient.h \
|
core/ipcclient.h \
|
||||||
|
|
@ -29,6 +31,7 @@ HEADERS += \
|
||||||
protocols/openvpnovercloakprotocol.h \
|
protocols/openvpnovercloakprotocol.h \
|
||||||
protocols/protocols_defs.h \
|
protocols/protocols_defs.h \
|
||||||
protocols/shadowsocksvpnprotocol.h \
|
protocols/shadowsocksvpnprotocol.h \
|
||||||
|
protocols/wireguardprotocol.h \
|
||||||
settings.h \
|
settings.h \
|
||||||
ui/Controls/SlidingStackedWidget.h \
|
ui/Controls/SlidingStackedWidget.h \
|
||||||
ui/mainwindow.h \
|
ui/mainwindow.h \
|
||||||
|
|
@ -43,7 +46,9 @@ HEADERS += \
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
configurators/cloak_configurator.cpp \
|
configurators/cloak_configurator.cpp \
|
||||||
configurators/shadowsocks_configurator.cpp \
|
configurators/shadowsocks_configurator.cpp \
|
||||||
|
configurators/ssh_configurator.cpp \
|
||||||
configurators/vpn_configurator.cpp \
|
configurators/vpn_configurator.cpp \
|
||||||
|
configurators/wireguard_configurator.cpp \
|
||||||
core/errorstrings.cpp \
|
core/errorstrings.cpp \
|
||||||
core/ipcclient.cpp \
|
core/ipcclient.cpp \
|
||||||
configurators/openvpn_configurator.cpp \
|
configurators/openvpn_configurator.cpp \
|
||||||
|
|
@ -56,6 +61,7 @@ SOURCES += \
|
||||||
protocols/openvpnovercloakprotocol.cpp \
|
protocols/openvpnovercloakprotocol.cpp \
|
||||||
protocols/protocols_defs.cpp \
|
protocols/protocols_defs.cpp \
|
||||||
protocols/shadowsocksvpnprotocol.cpp \
|
protocols/shadowsocksvpnprotocol.cpp \
|
||||||
|
protocols/wireguardprotocol.cpp \
|
||||||
settings.cpp \
|
settings.cpp \
|
||||||
ui/Controls/SlidingStackedWidget.cpp \
|
ui/Controls/SlidingStackedWidget.cpp \
|
||||||
ui/mainwindow.cpp \
|
ui/mainwindow.cpp \
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@
|
||||||
#include <QTemporaryDir>
|
#include <QTemporaryDir>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
#include <utils.h>
|
|
||||||
|
|
||||||
#include "core/server_defs.h"
|
#include "core/server_defs.h"
|
||||||
#include "protocols/protocols_defs.h"
|
#include "protocols/protocols_defs.h"
|
||||||
#include "core/scripts_registry.h"
|
#include "core/scripts_registry.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
QString OpenVpnConfigurator::getEasyRsaShPath()
|
QString OpenVpnConfigurator::getEasyRsaShPath()
|
||||||
{
|
{
|
||||||
|
|
@ -227,7 +227,7 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(QString config)
|
||||||
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
|
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
|
||||||
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
|
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
|
||||||
|
|
||||||
if (m_settings().routeMode() == Settings::VpnOnlyForwardSites) {
|
if (m_settings().routeMode() != Settings::VpnAllSites) {
|
||||||
config.replace("redirect-gateway def1 bypass-dhcp", "");
|
config.replace("redirect-gateway def1 bypass-dhcp", "");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -266,40 +266,6 @@ QString OpenVpnConfigurator::processConfigWithExportSettings(QString config)
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OpenVpnConfigurator::convertOpenSShKey(const QString &key)
|
|
||||||
{
|
|
||||||
QProcess p;
|
|
||||||
p.setProcessChannelMode(QProcess::MergedChannels);
|
|
||||||
|
|
||||||
QTemporaryFile tmp;
|
|
||||||
#ifdef QT_DEBUG
|
|
||||||
tmp.setAutoRemove(false);
|
|
||||||
#endif
|
|
||||||
tmp.open();
|
|
||||||
tmp.write(key.toUtf8());
|
|
||||||
tmp.close();
|
|
||||||
|
|
||||||
// ssh-keygen -p -P "" -N "" -m pem -f id_ssh
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
p.setProcessEnvironment(prepareEnv());
|
|
||||||
p.setProgram("cmd.exe");
|
|
||||||
p.setNativeArguments(QString("/C \"ssh-keygen.exe -p -P \"\" -N \"\" -m pem -f \"%1\"\"").arg(tmp.fileName()));
|
|
||||||
#else
|
|
||||||
p.setProgram("ssh-keygen");
|
|
||||||
p.setArguments(QStringList() << "-p" << "-P" << "" << "-N" << "" << "-m" << "pem" << "-f" << tmp.fileName());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
p.start();
|
|
||||||
p.waitForFinished();
|
|
||||||
|
|
||||||
qDebug().noquote() << "OpenVpnConfigurator::convertOpenSShKey" << p.exitCode() << p.exitStatus() << p.readAll();
|
|
||||||
|
|
||||||
tmp.open();
|
|
||||||
|
|
||||||
return tmp.readAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode OpenVpnConfigurator::signCert(DockerContainer container,
|
ErrorCode OpenVpnConfigurator::signCert(DockerContainer container,
|
||||||
const ServerCredentials &credentials, QString clientId)
|
const ServerCredentials &credentials, QString clientId)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,6 @@ public:
|
||||||
static QString processConfigWithLocalSettings(QString config);
|
static QString processConfigWithLocalSettings(QString config);
|
||||||
static QString processConfigWithExportSettings(QString config);
|
static QString processConfigWithExportSettings(QString config);
|
||||||
|
|
||||||
static QString convertOpenSShKey(const QString &key);
|
|
||||||
|
|
||||||
static ErrorCode signCert(DockerContainer container,
|
static ErrorCode signCert(DockerContainer container,
|
||||||
const ServerCredentials &credentials, QString clientId);
|
const ServerCredentials &credentials, QString clientId);
|
||||||
|
|
||||||
|
|
|
||||||
95
client/configurators/ssh_configurator.cpp
Normal file
95
client/configurators/ssh_configurator.cpp
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
#include "ssh_configurator.h"
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QString>
|
||||||
|
#include <QTemporaryDir>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTemporaryFile>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTextEdit>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include <qtimer.h>
|
||||||
|
|
||||||
|
#include "core/server_defs.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
using namespace QSsh;
|
||||||
|
|
||||||
|
|
||||||
|
QString SshConfigurator::convertOpenSShKey(const QString &key)
|
||||||
|
{
|
||||||
|
QProcess p;
|
||||||
|
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
|
||||||
|
QTemporaryFile tmp;
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
tmp.setAutoRemove(false);
|
||||||
|
#endif
|
||||||
|
tmp.open();
|
||||||
|
tmp.write(key.toUtf8());
|
||||||
|
tmp.close();
|
||||||
|
|
||||||
|
// ssh-keygen -p -P "" -N "" -m pem -f id_ssh
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
p.setProcessEnvironment(prepareEnv());
|
||||||
|
p.setProgram("cmd.exe");
|
||||||
|
p.setNativeArguments(QString("/C \"ssh-keygen.exe -p -P \"\" -N \"\" -m pem -f \"%1\"\"").arg(tmp.fileName()));
|
||||||
|
#else
|
||||||
|
p.setProgram("ssh-keygen");
|
||||||
|
p.setArguments(QStringList() << "-p" << "-P" << "" << "-N" << "" << "-m" << "pem" << "-f" << tmp.fileName());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
p.start();
|
||||||
|
p.waitForFinished();
|
||||||
|
|
||||||
|
qDebug().noquote() << "OpenVpnConfigurator::convertOpenSShKey" << p.exitCode() << p.exitStatus() << p.readAll();
|
||||||
|
|
||||||
|
tmp.open();
|
||||||
|
|
||||||
|
return tmp.readAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SshConfigurator::openSshTerminal(const ServerCredentials &credentials)
|
||||||
|
{
|
||||||
|
QProcess *p = new QProcess();
|
||||||
|
p->setReadChannelMode(QProcess::SeparateChannels);
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
p->setProcessEnvironment(prepareEnv());
|
||||||
|
p->setProgram(qApp->applicationDirPath() + "\\cygwin\\putty.exe");
|
||||||
|
|
||||||
|
if (credentials.password.contains("PRIVATE KEY")) {
|
||||||
|
// todo: connect by key
|
||||||
|
// p->setNativeArguments(QString("%1@%2")
|
||||||
|
// .arg(credentials.userName).arg(credentials.hostName).arg(credentials.password));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p->setNativeArguments(QString("%1@%2 -pw %3")
|
||||||
|
.arg(credentials.userName).arg(credentials.hostName).arg(credentials.password));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
p.setProgram("/bin/bash");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
p->startDetached();
|
||||||
|
}
|
||||||
|
|
||||||
|
QProcessEnvironment SshConfigurator::prepareEnv()
|
||||||
|
{
|
||||||
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||||
|
QString pathEnvVar = env.value("PATH");
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
pathEnvVar.clear();
|
||||||
|
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\cygwin;");
|
||||||
|
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn;");
|
||||||
|
#else
|
||||||
|
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
env.insert("PATH", pathEnvVar);
|
||||||
|
//qDebug().noquote() << "ENV PATH" << pathEnvVar;
|
||||||
|
return env;
|
||||||
|
}
|
||||||
20
client/configurators/ssh_configurator.h
Normal file
20
client/configurators/ssh_configurator.h
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef SSH_CONFIGURATOR_H
|
||||||
|
#define SSH_CONFIGURATOR_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
|
||||||
|
#include "core/defs.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include "core/servercontroller.h"
|
||||||
|
|
||||||
|
class SshConfigurator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static QProcessEnvironment prepareEnv();
|
||||||
|
static QString convertOpenSShKey(const QString &key);
|
||||||
|
static void openSshTerminal(const ServerCredentials &credentials);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SSH_CONFIGURATOR_H
|
||||||
178
client/configurators/wireguard_configurator.cpp
Normal file
178
client/configurators/wireguard_configurator.cpp
Normal file
|
|
@ -0,0 +1,178 @@
|
||||||
|
#include "wireguard_configurator.h"
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QString>
|
||||||
|
#include <QTemporaryDir>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTemporaryFile>
|
||||||
|
|
||||||
|
#include "sftpdefs.h"
|
||||||
|
|
||||||
|
#include "core/server_defs.h"
|
||||||
|
#include "protocols/protocols_defs.h"
|
||||||
|
#include "core/scripts_registry.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
QProcessEnvironment WireguardConfigurator::prepareEnv()
|
||||||
|
{
|
||||||
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||||
|
QString pathEnvVar = env.value("PATH");
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
pathEnvVar.clear();
|
||||||
|
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\wireguard;");
|
||||||
|
#else
|
||||||
|
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
env.insert("PATH", pathEnvVar);
|
||||||
|
qDebug().noquote() << "ENV PATH" << pathEnvVar;
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
|
WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
|
||||||
|
{
|
||||||
|
ConnectionData connData;
|
||||||
|
|
||||||
|
QString program;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
program = QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\wireguard\\wg.exe";
|
||||||
|
#else
|
||||||
|
program = QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS/wg";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Priv
|
||||||
|
{
|
||||||
|
QProcess p;
|
||||||
|
p.setProcessEnvironment(prepareEnv());
|
||||||
|
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
p.setProgram(program);
|
||||||
|
|
||||||
|
p.setArguments(QStringList() << "genkey");
|
||||||
|
|
||||||
|
p.start();
|
||||||
|
p.waitForFinished();
|
||||||
|
|
||||||
|
connData.clientPrivKey = QString(p.readAll());
|
||||||
|
connData.clientPrivKey.replace("\r", "");
|
||||||
|
connData.clientPrivKey.replace("\n", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pub
|
||||||
|
{
|
||||||
|
QProcess p;
|
||||||
|
p.setProcessEnvironment(prepareEnv());
|
||||||
|
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
p.setProgram(program);
|
||||||
|
|
||||||
|
p.setArguments(QStringList() << "pubkey");
|
||||||
|
|
||||||
|
p.start();
|
||||||
|
p.write(connData.clientPrivKey.toUtf8());
|
||||||
|
p.closeWriteChannel();
|
||||||
|
p.waitForFinished();
|
||||||
|
|
||||||
|
connData.clientPubKey = QString(p.readAll());
|
||||||
|
connData.clientPubKey.replace("\r", "");
|
||||||
|
connData.clientPubKey.replace("\n", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return connData;
|
||||||
|
}
|
||||||
|
|
||||||
|
WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardConfig(const ServerCredentials &credentials,
|
||||||
|
DockerContainer container, ErrorCode *errorCode)
|
||||||
|
{
|
||||||
|
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
|
||||||
|
connData.host = credentials.hostName;
|
||||||
|
|
||||||
|
if (connData.clientPrivKey.isEmpty() || connData.clientPubKey.isEmpty()) {
|
||||||
|
if (errorCode) *errorCode = ErrorCode::EasyRsaExecutableMissing;
|
||||||
|
return connData;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode e = ErrorCode::NoError;
|
||||||
|
connData.serverPubKey = ServerController::getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPublicKeyPath, &e);
|
||||||
|
connData.serverPubKey.replace("\n", "");
|
||||||
|
if (e) {
|
||||||
|
if (errorCode) *errorCode = e;
|
||||||
|
return connData;
|
||||||
|
}
|
||||||
|
|
||||||
|
connData.pskKey = ServerController::getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPskKeyPath, &e);
|
||||||
|
connData.pskKey.replace("\n", "");
|
||||||
|
|
||||||
|
if (e) {
|
||||||
|
if (errorCode) *errorCode = e;
|
||||||
|
return connData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString configPart = QString(
|
||||||
|
"[Peer]\n"
|
||||||
|
"PublicKey = %1\n"
|
||||||
|
"PresharedKey = %2\n"
|
||||||
|
"AllowedIPs = $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR\n\n").
|
||||||
|
arg(connData.clientPubKey).
|
||||||
|
arg(connData.pskKey);
|
||||||
|
|
||||||
|
configPart = ServerController::replaceVars(configPart, ServerController::genVarsForScript(credentials, container));
|
||||||
|
|
||||||
|
qDebug().noquote() << "Adding wg conf part to server" << configPart;
|
||||||
|
|
||||||
|
e = ServerController::uploadTextFileToContainer(container, credentials, configPart,
|
||||||
|
protocols::wireguard::serverConfigPath, QSsh::SftpOverwriteMode::SftpAppendToExisting);
|
||||||
|
|
||||||
|
if (e) {
|
||||||
|
if (errorCode) *errorCode = e;
|
||||||
|
return connData;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = ServerController::runScript(ServerController::sshParams(credentials),
|
||||||
|
ServerController::replaceVars("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip /opt/amnezia/wireguard/wg0.conf)'",
|
||||||
|
ServerController::genVarsForScript(credentials, container)));
|
||||||
|
|
||||||
|
return connData;
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings &WireguardConfigurator::m_settings()
|
||||||
|
{
|
||||||
|
static Settings s;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials,
|
||||||
|
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||||
|
{
|
||||||
|
QString config = ServerController::replaceVars(amnezia::scriptData(ProtocolScriptType::wireguard_template, container),
|
||||||
|
ServerController::genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
|
ConnectionData connData = prepareWireguardConfig(credentials, container, errorCode);
|
||||||
|
if (errorCode && *errorCode) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
config.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", connData.clientPrivKey);
|
||||||
|
config.replace("$WIREGUARD_SERVER_PUBLIC_KEY", connData.serverPubKey);
|
||||||
|
config.replace("$WIREGUARD_PSK", connData.pskKey);
|
||||||
|
|
||||||
|
qDebug().noquote() << config;
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WireguardConfigurator::processConfigWithLocalSettings(QString config)
|
||||||
|
{
|
||||||
|
// TODO replace DNS if it already set
|
||||||
|
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
|
||||||
|
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WireguardConfigurator::processConfigWithExportSettings(QString config)
|
||||||
|
{
|
||||||
|
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
|
||||||
|
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
41
client/configurators/wireguard_configurator.h
Normal file
41
client/configurators/wireguard_configurator.h
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef WIREGUARD_CONFIGURATOR_H
|
||||||
|
#define WIREGUARD_CONFIGURATOR_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
|
||||||
|
#include "core/defs.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include "core/servercontroller.h"
|
||||||
|
|
||||||
|
class WireguardConfigurator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct ConnectionData {
|
||||||
|
QString clientPrivKey; // client private key
|
||||||
|
QString clientPubKey; // client public key
|
||||||
|
QString serverPubKey; // tls-auth key
|
||||||
|
QString pskKey; // preshared key
|
||||||
|
QString host; // host ip
|
||||||
|
};
|
||||||
|
|
||||||
|
static QString genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
|
static QString processConfigWithLocalSettings(QString config);
|
||||||
|
static QString processConfigWithExportSettings(QString config);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
static QProcessEnvironment prepareEnv();
|
||||||
|
|
||||||
|
static ConnectionData prepareWireguardConfig(const ServerCredentials &credentials,
|
||||||
|
DockerContainer container, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
|
static ConnectionData genClientKeys();
|
||||||
|
|
||||||
|
static Settings &m_settings();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WIREGUARD_CONFIGURATOR_H
|
||||||
|
|
@ -13,7 +13,7 @@ struct ServerCredentials
|
||||||
QString password;
|
QString password;
|
||||||
int port = 22;
|
int port = 22;
|
||||||
|
|
||||||
bool isValid() { return !hostName.isEmpty() && !userName.isEmpty() && !password.isEmpty() && port > 0; }
|
bool isValid() const { return !hostName.isEmpty() && !userName.isEmpty() && !password.isEmpty() && port > 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ErrorCode
|
enum ErrorCode
|
||||||
|
|
@ -44,6 +44,7 @@ enum ErrorCode
|
||||||
OpenVpnConfigMissing,
|
OpenVpnConfigMissing,
|
||||||
OpenVpnManagementServerError,
|
OpenVpnManagementServerError,
|
||||||
EasyRsaError,
|
EasyRsaError,
|
||||||
|
ConfigMissing,
|
||||||
|
|
||||||
// Distro errors
|
// Distro errors
|
||||||
OpenVpnExecutableMissing,
|
OpenVpnExecutableMissing,
|
||||||
|
|
@ -51,6 +52,7 @@ enum ErrorCode
|
||||||
ShadowSocksExecutableMissing,
|
ShadowSocksExecutableMissing,
|
||||||
CloakExecutableMissing,
|
CloakExecutableMissing,
|
||||||
AmneziaServiceConnectionFailed,
|
AmneziaServiceConnectionFailed,
|
||||||
|
ExecutableMissing,
|
||||||
|
|
||||||
// VPN errors
|
// VPN errors
|
||||||
OpenVpnAdaptersInUseError,
|
OpenVpnAdaptersInUseError,
|
||||||
|
|
@ -69,6 +71,7 @@ const char key_openvpn_config_data[] = "openvpn_config_data";
|
||||||
const char key_openvpn_config_path[] = "openvpn_config_path";
|
const char key_openvpn_config_path[] = "openvpn_config_path";
|
||||||
const char key_shadowsocks_config_data[] = "shadowsocks_config_data";
|
const char key_shadowsocks_config_data[] = "shadowsocks_config_data";
|
||||||
const char key_cloak_config_data[] = "cloak_config_data";
|
const char key_cloak_config_data[] = "cloak_config_data";
|
||||||
|
const char key_wireguard_config_data[] = "wireguard_config_data";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ QSharedPointer<IpcProcessInterfaceReplica> IpcClient::CreatePrivilegedProcess()
|
||||||
qWarning() << "IpcProcessInterfaceReplica replica is not connected!";
|
qWarning() << "IpcProcessInterfaceReplica replica is not connected!";
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(pd->ipcProcess.data(), &IpcProcessInterfaceReplica::destroyed, pd->ipcProcess.data(), [pd](){
|
QObject::connect(pd->ipcProcess.data(), &IpcProcessInterfaceReplica::destroyed, pd->ipcProcess.data(), [pd](){
|
||||||
pd->replicaNode->deleteLater();
|
pd->replicaNode->deleteLater();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ QString amnezia::scriptName(ProtocolScriptType type)
|
||||||
case ProtocolScriptType::configure_container: return QLatin1String("configure_container.sh");
|
case ProtocolScriptType::configure_container: return QLatin1String("configure_container.sh");
|
||||||
case ProtocolScriptType::container_startup: return QLatin1String("start.sh");
|
case ProtocolScriptType::container_startup: return QLatin1String("start.sh");
|
||||||
case ProtocolScriptType::openvpn_template: return QLatin1String("template.ovpn");
|
case ProtocolScriptType::openvpn_template: return QLatin1String("template.ovpn");
|
||||||
|
case ProtocolScriptType::wireguard_template: return QLatin1String("template.conf");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ enum ProtocolScriptType {
|
||||||
run_container,
|
run_container,
|
||||||
configure_container,
|
configure_container,
|
||||||
container_startup,
|
container_startup,
|
||||||
openvpn_template
|
openvpn_template,
|
||||||
|
wireguard_template
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,8 @@ ErrorCode ServerController::runScript(const SshConnectionParameters &sshParams,
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
|
ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
|
||||||
const ServerCredentials &credentials, const QString &file, const QString &path)
|
const ServerCredentials &credentials, const QString &file, const QString &path,
|
||||||
|
QSsh::SftpOverwriteMode overwriteMode)
|
||||||
{
|
{
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
QString tmpFileName = QString("/tmp/%1.tmp").arg(Utils::getRandomString(16));
|
QString tmpFileName = QString("/tmp/%1.tmp").arg(Utils::getRandomString(16));
|
||||||
|
|
@ -132,11 +133,29 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
|
||||||
stdOut += data + "\n";
|
stdOut += data + "\n";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (overwriteMode == QSsh::SftpOverwriteMode::SftpOverwriteExisting) {
|
||||||
e = runScript(sshParams(credentials),
|
e = runScript(sshParams(credentials),
|
||||||
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(path),
|
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(path),
|
||||||
genVarsForScript(credentials, container)), cbReadStd, cbReadStd);
|
genVarsForScript(credentials, container)), cbReadStd, cbReadStd);
|
||||||
|
|
||||||
if (e) return e;
|
if (e) return e;
|
||||||
|
}
|
||||||
|
else if (overwriteMode == QSsh::SftpOverwriteMode::SftpAppendToExisting) {
|
||||||
|
e = runScript(sshParams(credentials),
|
||||||
|
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(tmpFileName),
|
||||||
|
genVarsForScript(credentials, container)), cbReadStd, cbReadStd);
|
||||||
|
|
||||||
|
if (e) return e;
|
||||||
|
|
||||||
|
e = runScript(sshParams(credentials),
|
||||||
|
replaceVars(QString("sudo docker exec -i $CONTAINER_NAME sh -c \"cat %1 >> %2\"").arg(tmpFileName).arg(path),
|
||||||
|
genVarsForScript(credentials, container)), cbReadStd, cbReadStd);
|
||||||
|
|
||||||
|
if (e) return e;
|
||||||
|
}
|
||||||
|
else return ErrorCode::NotImplementedError;
|
||||||
|
|
||||||
|
|
||||||
if (stdOut.contains("Error: No such container:")) {
|
if (stdOut.contains("Error: No such container:")) {
|
||||||
return ErrorCode::ServerContainerMissingError;
|
return ErrorCode::ServerContainerMissingError;
|
||||||
}
|
}
|
||||||
|
|
@ -199,15 +218,16 @@ QString ServerController::getTextFileFromContainer(DockerContainer container,
|
||||||
if (errorCode) *errorCode = fromSshProcessExitStatus(exitStatus);
|
if (errorCode) *errorCode = fromSshProcessExitStatus(exitStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (errorCode) *errorCode = ErrorCode::NoError;
|
||||||
return proc->readAllStandardOutput();
|
return proc->readAllStandardOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials)
|
ErrorCode ServerController::checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials)
|
||||||
{
|
{
|
||||||
QString caCert = ServerController::getTextFileFromContainer(container,
|
QString caCert = ServerController::getTextFileFromContainer(container,
|
||||||
credentials, amnezia::protocols::openvpn::caCertPath);
|
credentials, protocols::openvpn::caCertPath);
|
||||||
QString taKey = ServerController::getTextFileFromContainer(container,
|
QString taKey = ServerController::getTextFileFromContainer(container,
|
||||||
credentials, amnezia::protocols::openvpn::taKeyPath);
|
credentials, protocols::openvpn::taKeyPath);
|
||||||
|
|
||||||
if (!caCert.isEmpty() && !taKey.isEmpty()) {
|
if (!caCert.isEmpty() && !taKey.isEmpty()) {
|
||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
|
|
@ -217,7 +237,8 @@ ErrorCode ServerController::checkOpenVpnServer(DockerContainer container, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data, const QString &remotePath)
|
ErrorCode ServerController::uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data, const QString &remotePath,
|
||||||
|
QSsh::SftpOverwriteMode overwriteMode)
|
||||||
{
|
{
|
||||||
SshConnection *client = connectToHost(sshParams(credentials));
|
SshConnection *client = connectToHost(sshParams(credentials));
|
||||||
if (client->state() != SshConnection::State::Connected) {
|
if (client->state() != SshConnection::State::Connected) {
|
||||||
|
|
@ -508,11 +529,12 @@ ErrorCode ServerController::startupContainerWorker(const ServerCredentials &cred
|
||||||
genVarsForScript(credentials, container, config)));
|
genVarsForScript(credentials, container, config)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerController::Vars ServerController:: genVarsForScript(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
|
ServerController::Vars ServerController::genVarsForScript(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
|
||||||
{
|
{
|
||||||
const QJsonObject &openvpnConfig = config.value(config_key::openvpn).toObject();
|
const QJsonObject &openvpnConfig = config.value(config_key::openvpn).toObject();
|
||||||
const QJsonObject &cloakConfig = config.value(config_key::cloak).toObject();
|
const QJsonObject &cloakConfig = config.value(config_key::cloak).toObject();
|
||||||
const QJsonObject &ssConfig = config.value(config_key::shadowsocks).toObject();
|
const QJsonObject &ssConfig = config.value(config_key::shadowsocks).toObject();
|
||||||
|
const QJsonObject &wireguarConfig = config.value(config_key::wireguard).toObject();
|
||||||
//
|
//
|
||||||
|
|
||||||
Vars vars;
|
Vars vars;
|
||||||
|
|
@ -520,20 +542,20 @@ ServerController::Vars ServerController:: genVarsForScript(const ServerCredent
|
||||||
vars.append({{"$REMOTE_HOST", credentials.hostName}});
|
vars.append({{"$REMOTE_HOST", credentials.hostName}});
|
||||||
|
|
||||||
// OpenVPN vars
|
// OpenVPN vars
|
||||||
vars.append({{"$VPN_SUBNET_IP", openvpnConfig.value(config_key::subnet_address).toString(amnezia::protocols::vpnDefaultSubnetAddress) }});
|
vars.append({{"$OPENVPN_SUBNET_IP", openvpnConfig.value(config_key::subnet_address).toString(protocols::openvpn::defaultSubnetAddress) }});
|
||||||
vars.append({{"$VPN_SUBNET_MASK_VAL", openvpnConfig.value(config_key::subnet_mask_val).toString(amnezia::protocols::vpnDefaultSubnetMaskVal) }});
|
vars.append({{"$OPENVPN_SUBNET_CIDR", openvpnConfig.value(config_key::subnet_cidr).toString(protocols::openvpn::defaultSubnetCidr) }});
|
||||||
vars.append({{"$VPN_SUBNET_MASK", openvpnConfig.value(config_key::subnet_mask).toString(amnezia::protocols::vpnDefaultSubnetMask) }});
|
vars.append({{"$OPENVPN_SUBNET_MASK", openvpnConfig.value(config_key::subnet_mask).toString(protocols::openvpn::defaultSubnetMask) }});
|
||||||
|
|
||||||
vars.append({{"$OPENVPN_PORT", openvpnConfig.value(config_key::port).toString(amnezia::protocols::openvpn::defaultPort) }});
|
vars.append({{"$OPENVPN_PORT", openvpnConfig.value(config_key::port).toString(protocols::openvpn::defaultPort) }});
|
||||||
vars.append({{"$OPENVPN_TRANSPORT_PROTO", openvpnConfig.value(config_key::transport_proto).toString(amnezia::protocols::openvpn::defaultTransportProto) }});
|
vars.append({{"$OPENVPN_TRANSPORT_PROTO", openvpnConfig.value(config_key::transport_proto).toString(protocols::openvpn::defaultTransportProto) }});
|
||||||
|
|
||||||
bool isNcpDisabled = openvpnConfig.value(config_key::ncp_disable).toBool(amnezia::protocols::openvpn::defaultNcpDisable);
|
bool isNcpDisabled = openvpnConfig.value(config_key::ncp_disable).toBool(protocols::openvpn::defaultNcpDisable);
|
||||||
vars.append({{"$OPENVPN_NCP_DISABLE", isNcpDisabled ? protocols::openvpn::ncpDisableString : "" }});
|
vars.append({{"$OPENVPN_NCP_DISABLE", isNcpDisabled ? protocols::openvpn::ncpDisableString : "" }});
|
||||||
|
|
||||||
vars.append({{"$OPENVPN_CIPHER", openvpnConfig.value(config_key::cipher).toString(amnezia::protocols::openvpn::defaultCipher) }});
|
vars.append({{"$OPENVPN_CIPHER", openvpnConfig.value(config_key::cipher).toString(protocols::openvpn::defaultCipher) }});
|
||||||
vars.append({{"$OPENVPN_HASH", openvpnConfig.value(config_key::hash).toString(amnezia::protocols::openvpn::defaultHash) }});
|
vars.append({{"$OPENVPN_HASH", openvpnConfig.value(config_key::hash).toString(protocols::openvpn::defaultHash) }});
|
||||||
|
|
||||||
bool isTlsAuth = openvpnConfig.value(config_key::tls_auth).toBool(amnezia::protocols::openvpn::defaultTlsAuth);
|
bool isTlsAuth = openvpnConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth);
|
||||||
vars.append({{"$OPENVPN_TLS_AUTH", isTlsAuth ? protocols::openvpn::tlsAuthString : "" }});
|
vars.append({{"$OPENVPN_TLS_AUTH", isTlsAuth ? protocols::openvpn::tlsAuthString : "" }});
|
||||||
if (!isTlsAuth) {
|
if (!isTlsAuth) {
|
||||||
// erase $OPENVPN_TA_KEY, so it will not set in OpenVpnConfigurator::genOpenVpnConfig
|
// erase $OPENVPN_TA_KEY, so it will not set in OpenVpnConfigurator::genOpenVpnConfig
|
||||||
|
|
@ -541,9 +563,9 @@ ServerController::Vars ServerController:: genVarsForScript(const ServerCredent
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShadowSocks vars
|
// ShadowSocks vars
|
||||||
vars.append({{"$SHADOWSOCKS_SERVER_PORT", ssConfig.value(config_key::port).toString(amnezia::protocols::shadowsocks::defaultPort) }});
|
vars.append({{"$SHADOWSOCKS_SERVER_PORT", ssConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort) }});
|
||||||
vars.append({{"$SHADOWSOCKS_LOCAL_PORT", ssConfig.value(config_key::local_port).toString(amnezia::protocols::shadowsocks::defaultLocalProxyPort) }});
|
vars.append({{"$SHADOWSOCKS_LOCAL_PORT", ssConfig.value(config_key::local_port).toString(protocols::shadowsocks::defaultLocalProxyPort) }});
|
||||||
vars.append({{"$SHADOWSOCKS_CIPHER", ssConfig.value(config_key::cipher).toString(amnezia::protocols::shadowsocks::defaultCipher) }});
|
vars.append({{"$SHADOWSOCKS_CIPHER", ssConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher) }});
|
||||||
|
|
||||||
vars.append({{"$CONTAINER_NAME", amnezia::containerToString(container)}});
|
vars.append({{"$CONTAINER_NAME", amnezia::containerToString(container)}});
|
||||||
vars.append({{"$DOCKERFILE_FOLDER", "/opt/amnezia/" + amnezia::containerToString(container)}});
|
vars.append({{"$DOCKERFILE_FOLDER", "/opt/amnezia/" + amnezia::containerToString(container)}});
|
||||||
|
|
@ -552,6 +574,14 @@ ServerController::Vars ServerController:: genVarsForScript(const ServerCredent
|
||||||
vars.append({{"$CLOAK_SERVER_PORT", cloakConfig.value(config_key::port).toString(protocols::cloak::defaultPort) }});
|
vars.append({{"$CLOAK_SERVER_PORT", cloakConfig.value(config_key::port).toString(protocols::cloak::defaultPort) }});
|
||||||
vars.append({{"$FAKE_WEB_SITE_ADDRESS", cloakConfig.value(config_key::site).toString(protocols::cloak::defaultRedirSite) }});
|
vars.append({{"$FAKE_WEB_SITE_ADDRESS", cloakConfig.value(config_key::site).toString(protocols::cloak::defaultRedirSite) }});
|
||||||
|
|
||||||
|
// Wireguard vars
|
||||||
|
vars.append({{"$WIREGUARD_SUBNET_IP", openvpnConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) }});
|
||||||
|
vars.append({{"$WIREGUARD_SUBNET_CIDR", openvpnConfig.value(config_key::subnet_cidr).toString(protocols::wireguard::defaultSubnetCidr) }});
|
||||||
|
vars.append({{"$WIREGUARD_SUBNET_MASK", openvpnConfig.value(config_key::subnet_mask).toString(protocols::wireguard::defaultSubnetMask) }});
|
||||||
|
|
||||||
|
vars.append({{"$WIREGUARD_SERVER_PORT", wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) }});
|
||||||
|
|
||||||
|
|
||||||
QString serverIp = Utils::getIPAddress(credentials.hostName);
|
QString serverIp = Utils::getIPAddress(credentials.hostName);
|
||||||
if (!serverIp.isEmpty()) {
|
if (!serverIp.isEmpty()) {
|
||||||
vars.append({{"$SERVER_IP_ADDRESS", serverIp}});
|
vars.append({{"$SERVER_IP_ADDRESS", serverIp}});
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "protocols/protocols_defs.h"
|
#include "protocols/protocols_defs.h"
|
||||||
|
|
||||||
|
#include "sftpdefs.h"
|
||||||
|
|
||||||
using namespace amnezia;
|
using namespace amnezia;
|
||||||
|
|
||||||
|
|
@ -35,10 +36,12 @@ public:
|
||||||
|
|
||||||
static ErrorCode checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials);
|
static ErrorCode checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials);
|
||||||
|
|
||||||
static ErrorCode uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data, const QString &remotePath);
|
static ErrorCode uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data,
|
||||||
|
const QString &remotePath, QSsh::SftpOverwriteMode overwriteMode = QSsh::SftpOverwriteMode::SftpOverwriteExisting);
|
||||||
|
|
||||||
static ErrorCode uploadTextFileToContainer(DockerContainer container,
|
static ErrorCode uploadTextFileToContainer(DockerContainer container,
|
||||||
const ServerCredentials &credentials, const QString &file, const QString &path);
|
const ServerCredentials &credentials, const QString &file, const QString &path,
|
||||||
|
QSsh::SftpOverwriteMode overwriteMode = QSsh::SftpOverwriteMode::SftpOverwriteExisting);
|
||||||
|
|
||||||
static QString getTextFileFromContainer(DockerContainer container,
|
static QString getTextFileFromContainer(DockerContainer container,
|
||||||
const ServerCredentials &credentials, const QString &path, ErrorCode *errorCode = nullptr);
|
const ServerCredentials &credentials, const QString &path, ErrorCode *errorCode = nullptr);
|
||||||
|
|
@ -54,9 +57,10 @@ public:
|
||||||
static Vars genVarsForScript(const ServerCredentials &credentials, DockerContainer container = DockerContainer::None, const QJsonObject &config = QJsonObject());
|
static Vars genVarsForScript(const ServerCredentials &credentials, DockerContainer container = DockerContainer::None, const QJsonObject &config = QJsonObject());
|
||||||
|
|
||||||
static QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr);
|
static QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr);
|
||||||
private:
|
|
||||||
static QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams);
|
static QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
static ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container);
|
static ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container);
|
||||||
static ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
|
static ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
|
||||||
static ErrorCode buildContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
|
static ErrorCode buildContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#define APPLICATION_NAME "AmneziaVPN"
|
#define APPLICATION_NAME "AmneziaVPN"
|
||||||
#define SERVICE_NAME "AmneziaVPN-service"
|
#define SERVICE_NAME "AmneziaVPN-service"
|
||||||
#define ORGANIZATION_NAME "AmneziaVPN.ORG"
|
#define ORGANIZATION_NAME "AmneziaVPN.ORG"
|
||||||
#define APP_MAJOR_VERSION "1.7.4"
|
#define APP_MAJOR_VERSION "1.7.5"
|
||||||
#define APP_VERSION "1.7.4.0"
|
#define APP_VERSION "1.7.5.3"
|
||||||
|
|
||||||
#endif // DEFINES_H
|
#endif // DEFINES_H
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,16 @@
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "openvpnprotocol.h"
|
#include "defines.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "openvpnprotocol.h"
|
||||||
|
|
||||||
|
|
||||||
OpenVpnProtocol::OpenVpnProtocol(const QJsonObject &configuration, QObject* parent) :
|
OpenVpnProtocol::OpenVpnProtocol(const QJsonObject &configuration, QObject* parent) :
|
||||||
VpnProtocol(configuration, parent)
|
VpnProtocol(configuration, parent)
|
||||||
{
|
{
|
||||||
|
Utils::initializePath(defaultConfigPath());
|
||||||
|
|
||||||
readOpenVpnConfiguration(configuration);
|
readOpenVpnConfiguration(configuration);
|
||||||
connect(&m_managementServer, &ManagementServer::readyRead, this, &OpenVpnProtocol::onReadyReadDataFromManagementServer);
|
connect(&m_managementServer, &ManagementServer::readyRead, this, &OpenVpnProtocol::onReadyReadDataFromManagementServer);
|
||||||
}
|
}
|
||||||
|
|
@ -22,6 +26,17 @@ OpenVpnProtocol::~OpenVpnProtocol()
|
||||||
QThread::msleep(200);
|
QThread::msleep(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString OpenVpnProtocol::defaultConfigFileName()
|
||||||
|
{
|
||||||
|
qDebug() << "OpenVpnProtocol::defaultConfigFileName" << defaultConfigPath() + QString("/%1.ovpn").arg(APPLICATION_NAME);
|
||||||
|
return defaultConfigPath() + QString("/%1.ovpn").arg(APPLICATION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString OpenVpnProtocol::defaultConfigPath()
|
||||||
|
{
|
||||||
|
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/config";
|
||||||
|
}
|
||||||
|
|
||||||
void OpenVpnProtocol::stop()
|
void OpenVpnProtocol::stop()
|
||||||
{
|
{
|
||||||
qDebug() << "OpenVpnProtocol::stop()";
|
qDebug() << "OpenVpnProtocol::stop()";
|
||||||
|
|
@ -81,7 +96,7 @@ void OpenVpnProtocol::readOpenVpnConfiguration(const QJsonObject &configuration)
|
||||||
QFileInfo file(m_configFileName);
|
QFileInfo file(m_configFileName);
|
||||||
|
|
||||||
if (file.fileName().isEmpty()) {
|
if (file.fileName().isEmpty()) {
|
||||||
m_configFileName = Utils::defaultVpnConfigFileName();
|
m_configFileName = defaultConfigFileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug().noquote() << QString("Set config file: '%1'").arg(configPath());
|
qDebug().noquote() << QString("Set config file: '%1'").arg(configPath());
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ public:
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
ErrorCode checkAndSetupTapDriver();
|
ErrorCode checkAndSetupTapDriver();
|
||||||
|
static QString defaultConfigFileName();
|
||||||
|
static QString defaultConfigPath();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void onReadyReadDataFromManagementServer();
|
void onReadyReadDataFromManagementServer();
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ constexpr char block_outside_dns[] = "block_outside_dns";
|
||||||
|
|
||||||
constexpr char subnet_address[] = "subnet_address";
|
constexpr char subnet_address[] = "subnet_address";
|
||||||
constexpr char subnet_mask[] = "subnet_mask";
|
constexpr char subnet_mask[] = "subnet_mask";
|
||||||
constexpr char subnet_mask_val[] = "subnet_mask_val";
|
constexpr char subnet_cidr[] = "subnet_cidr";
|
||||||
|
|
||||||
// proto config keys
|
// proto config keys
|
||||||
constexpr char last_config[] = "last_config";
|
constexpr char last_config[] = "last_config";
|
||||||
|
|
@ -55,14 +55,16 @@ constexpr char amnezia_wireguard[] = "amnezia-wireguard";
|
||||||
|
|
||||||
namespace protocols {
|
namespace protocols {
|
||||||
|
|
||||||
constexpr char vpnDefaultSubnetAddress[] = "10.8.0.0";
|
|
||||||
constexpr char vpnDefaultSubnetMask[] = "255.255.255.0";
|
|
||||||
constexpr char vpnDefaultSubnetMaskVal[] = "24";
|
|
||||||
|
|
||||||
constexpr char UDP[] = "udp"; // case sens
|
constexpr char UDP[] = "udp"; // case sens
|
||||||
constexpr char TCP[] = "tcp";
|
constexpr char TCP[] = "tcp";
|
||||||
|
|
||||||
namespace openvpn {
|
namespace openvpn {
|
||||||
|
constexpr char defaultSubnetAddress[] = "10.8.0.0";
|
||||||
|
constexpr char defaultSubnetMask[] = "255.255.255.0";
|
||||||
|
constexpr char defaultSubnetCidr[] = "24";
|
||||||
|
|
||||||
constexpr char caCertPath[] = "/opt/amnezia/openvpn/pki/ca.crt";
|
constexpr char caCertPath[] = "/opt/amnezia/openvpn/pki/ca.crt";
|
||||||
constexpr char clientCertPath[] = "/opt/amnezia/openvpn/pki/issued";
|
constexpr char clientCertPath[] = "/opt/amnezia/openvpn/pki/issued";
|
||||||
constexpr char taKeyPath[] = "/opt/amnezia/openvpn/ta.key";
|
constexpr char taKeyPath[] = "/opt/amnezia/openvpn/ta.key";
|
||||||
|
|
@ -96,6 +98,17 @@ constexpr char defaultCipher[] = "chacha20-ietf-poly1305";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace wireguard {
|
||||||
|
constexpr char defaultSubnetAddress[] = "10.8.1.0";
|
||||||
|
constexpr char defaultSubnetMask[] = "255.255.255.0";
|
||||||
|
constexpr char defaultSubnetCidr[] = "24";
|
||||||
|
|
||||||
|
constexpr char defaultPort[] = "51820";
|
||||||
|
constexpr char serverConfigPath[] = "/opt/amnezia/wireguard/wg0.conf";
|
||||||
|
constexpr char serverPublicKeyPath[] = "/opt/amnezia/wireguard/wireguard_server_public_key.key";
|
||||||
|
constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace protocols
|
} // namespace protocols
|
||||||
|
|
|
||||||
232
client/protocols/wireguardprotocol.cpp
Normal file
232
client/protocols/wireguardprotocol.cpp
Normal file
|
|
@ -0,0 +1,232 @@
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QTcpSocket>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
#include "wireguardprotocol.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
WireguardProtocol::WireguardProtocol(const QJsonObject &configuration, QObject* parent) :
|
||||||
|
VpnProtocol(configuration, parent)
|
||||||
|
{
|
||||||
|
//m_configFile.setFileTemplate(QDir::tempPath() + QDir::separator() + serviceName() + ".conf");
|
||||||
|
m_configFile.setFileName(QDir::tempPath() + QDir::separator() + serviceName() + ".conf");
|
||||||
|
readWireguardConfiguration(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
WireguardProtocol::~WireguardProtocol()
|
||||||
|
{
|
||||||
|
qDebug() << "WireguardProtocol::~WireguardProtocol()";
|
||||||
|
WireguardProtocol::stop();
|
||||||
|
QThread::msleep(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireguardProtocol::stop()
|
||||||
|
{
|
||||||
|
if (!QFileInfo::exists(wireguardExecPath())) {
|
||||||
|
qCritical() << "Wireguard executable missing!";
|
||||||
|
setLastError(ErrorCode::ExecutableMissing);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_wireguardStopProcess = IpcClient::CreatePrivilegedProcess();
|
||||||
|
|
||||||
|
if (!m_wireguardStopProcess) {
|
||||||
|
qCritical() << "IpcProcess replica is not created!";
|
||||||
|
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_wireguardStopProcess->waitForSource(1000);
|
||||||
|
if (!m_wireguardStopProcess->isInitialized()) {
|
||||||
|
qWarning() << "IpcProcess replica is not connected!";
|
||||||
|
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_wireguardStopProcess->setProgram(wireguardExecPath());
|
||||||
|
|
||||||
|
|
||||||
|
QStringList arguments({"/uninstalltunnelservice", serviceName(), });
|
||||||
|
m_wireguardStopProcess->setArguments(arguments);
|
||||||
|
|
||||||
|
qDebug() << arguments.join(" ");
|
||||||
|
|
||||||
|
connect(m_wireguardStopProcess.data(), &IpcProcessInterfaceReplica::errorOccurred, this, [this](QProcess::ProcessError error) {
|
||||||
|
qDebug() << "WireguardProtocol::WireguardProtocol errorOccurred" << error;
|
||||||
|
setConnectionState(ConnectionState::Disconnected);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_wireguardStopProcess.data(), &IpcProcessInterfaceReplica::stateChanged, this, [this](QProcess::ProcessState newState) {
|
||||||
|
qDebug() << "WireguardProtocol::WireguardProtocol Stop stateChanged" << newState;
|
||||||
|
});
|
||||||
|
|
||||||
|
m_wireguardStopProcess->start();
|
||||||
|
|
||||||
|
setConnectionState(VpnProtocol::Disconnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireguardProtocol::readWireguardConfiguration(const QJsonObject &configuration)
|
||||||
|
{
|
||||||
|
if (configuration.contains(config::key_wireguard_config_data)) {
|
||||||
|
if (!m_configFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||||
|
qCritical() << "Failed to save wireguard config to" << m_configFile.fileName();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_isConfigLoaded = true;
|
||||||
|
|
||||||
|
m_configFile.write(configuration.value(config::key_wireguard_config_data).toString().toUtf8());
|
||||||
|
m_configFile.close();
|
||||||
|
m_configFileName = m_configFile.fileName();
|
||||||
|
|
||||||
|
qDebug().noquote() << QString("Set config data") << m_configFileName;
|
||||||
|
qDebug().noquote() << QString("Set config data") << configuration.value(config::key_wireguard_config_data).toString().toUtf8();
|
||||||
|
}
|
||||||
|
// else if (configuration.contains(config::key_wireguard_config_path)) {
|
||||||
|
// m_configFileName = configuration.value(config::key_wireguard_config_path).toString();
|
||||||
|
// QFileInfo file(m_configFileName);
|
||||||
|
|
||||||
|
// if (file.fileName().isEmpty()) {
|
||||||
|
// m_configFileName = defaultConfigFileName();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// qDebug().noquote() << QString("Set config file: '%1'").arg(configPath());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
//bool WireguardProtocol::openVpnProcessIsRunning() const
|
||||||
|
//{
|
||||||
|
// return Utils::processIsRunning("openvpn");
|
||||||
|
//}
|
||||||
|
|
||||||
|
QString WireguardProtocol::configPath() const
|
||||||
|
{
|
||||||
|
return m_configFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireguardProtocol::updateRouteGateway(QString line)
|
||||||
|
{
|
||||||
|
// TODO: fix for macos
|
||||||
|
line = line.split("ROUTE_GATEWAY", QString::SkipEmptyParts).at(1);
|
||||||
|
if (!line.contains("/")) return;
|
||||||
|
m_routeGateway = line.split("/", QString::SkipEmptyParts).first();
|
||||||
|
m_routeGateway.replace(" ", "");
|
||||||
|
qDebug() << "Set VPN route gateway" << m_routeGateway;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WireguardProtocol::wireguardExecPath() const
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
return Utils::executable("wireguard/wireguard", true);
|
||||||
|
#else
|
||||||
|
return Utils::executable("/wireguard", true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode WireguardProtocol::start()
|
||||||
|
{
|
||||||
|
if (!m_isConfigLoaded) {
|
||||||
|
setLastError(ErrorCode::ConfigMissing);
|
||||||
|
return lastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
//qDebug() << "Start OpenVPN connection";
|
||||||
|
WireguardProtocol::stop();
|
||||||
|
|
||||||
|
if (!QFileInfo::exists(wireguardExecPath())) {
|
||||||
|
setLastError(ErrorCode::ExecutableMissing);
|
||||||
|
return lastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!QFileInfo::exists(configPath())) {
|
||||||
|
setLastError(ErrorCode::ConfigMissing);
|
||||||
|
return lastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
setConnectionState(ConnectionState::Connecting);
|
||||||
|
|
||||||
|
m_wireguardStartProcess = IpcClient::CreatePrivilegedProcess();
|
||||||
|
|
||||||
|
if (!m_wireguardStartProcess) {
|
||||||
|
//qWarning() << "IpcProcess replica is not created!";
|
||||||
|
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||||
|
return ErrorCode::AmneziaServiceConnectionFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_wireguardStartProcess->waitForSource(1000);
|
||||||
|
if (!m_wireguardStartProcess->isInitialized()) {
|
||||||
|
qWarning() << "IpcProcess replica is not connected!";
|
||||||
|
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||||
|
return ErrorCode::AmneziaServiceConnectionFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_wireguardStartProcess->setProgram(wireguardExecPath());
|
||||||
|
|
||||||
|
|
||||||
|
QStringList arguments({"/installtunnelservice", configPath(), });
|
||||||
|
m_wireguardStartProcess->setArguments(arguments);
|
||||||
|
|
||||||
|
qDebug() << arguments.join(" ");
|
||||||
|
|
||||||
|
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::errorOccurred, this, [this](QProcess::ProcessError error) {
|
||||||
|
qDebug() << "WireguardProtocol::WireguardProtocol errorOccurred" << error;
|
||||||
|
setConnectionState(ConnectionState::Disconnected);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::stateChanged, this, [this](QProcess::ProcessState newState) {
|
||||||
|
qDebug() << "WireguardProtocol::WireguardProtocol stateChanged" << newState;
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::finished, this, [this]() {
|
||||||
|
setConnectionState(ConnectionState::Connected);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::readyRead, this, [this]() {
|
||||||
|
QRemoteObjectPendingReply<QByteArray> reply = m_wireguardStartProcess->readAll();
|
||||||
|
reply.waitForFinished(1000);
|
||||||
|
qDebug() << "WireguardProtocol::WireguardProtocol readyRead" << reply.returnValue();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::readyReadStandardOutput, this, [this]() {
|
||||||
|
QRemoteObjectPendingReply<QByteArray> reply = m_wireguardStartProcess->readAllStandardOutput();
|
||||||
|
reply.waitForFinished(1000);
|
||||||
|
qDebug() << "WireguardProtocol::WireguardProtocol readAllStandardOutput" << reply.returnValue();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::readyReadStandardError, this, [this]() {
|
||||||
|
QRemoteObjectPendingReply<QByteArray> reply = m_wireguardStartProcess->readAllStandardError();
|
||||||
|
reply.waitForFinished(1000);
|
||||||
|
qDebug() << "WireguardProtocol::WireguardProtocol readAllStandardError" << reply.returnValue();
|
||||||
|
});
|
||||||
|
|
||||||
|
m_wireguardStartProcess->start();
|
||||||
|
|
||||||
|
return ErrorCode::NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WireguardProtocol::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);
|
||||||
|
|
||||||
|
// qDebug() << QString("Set vpn local address %1, gw %2").arg(m_vpnLocalAddress).arg(vpnGateway());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WireguardProtocol::serviceName() const
|
||||||
|
{
|
||||||
|
return "AmneziaVPN.WireGuard0";
|
||||||
|
}
|
||||||
46
client/protocols/wireguardprotocol.h
Normal file
46
client/protocols/wireguardprotocol.h
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef WIREGUARDPROTOCOL_H
|
||||||
|
#define WIREGUARDPROTOCOL_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QString>
|
||||||
|
#include <QTemporaryFile>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "vpnprotocol.h"
|
||||||
|
#include "core/ipcclient.h"
|
||||||
|
|
||||||
|
class WireguardProtocol : public VpnProtocol
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit WireguardProtocol(const QJsonObject& configuration, QObject* parent = nullptr);
|
||||||
|
virtual ~WireguardProtocol() override;
|
||||||
|
|
||||||
|
ErrorCode start() override;
|
||||||
|
void stop() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString configPath() const;
|
||||||
|
QString wireguardExecPath() const;
|
||||||
|
//bool openVpnProcessIsRunning() const;
|
||||||
|
void readWireguardConfiguration(const QJsonObject &configuration);
|
||||||
|
|
||||||
|
void updateRouteGateway(QString line);
|
||||||
|
void updateVpnGateway(const QString &line);
|
||||||
|
QString serviceName() const;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_configFileName;
|
||||||
|
QFile m_configFile;
|
||||||
|
|
||||||
|
QSharedPointer<IpcProcessInterfaceReplica> m_wireguardStartProcess;
|
||||||
|
QSharedPointer<IpcProcessInterfaceReplica> m_wireguardStopProcess;
|
||||||
|
|
||||||
|
bool m_isConfigLoaded = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WIREGUARDPROTOCOL_H
|
||||||
|
|
@ -62,5 +62,10 @@
|
||||||
<file>server_scripts/openvpn_shadowsocks/start.sh</file>
|
<file>server_scripts/openvpn_shadowsocks/start.sh</file>
|
||||||
<file>server_scripts/openvpn_shadowsocks/template.ovpn</file>
|
<file>server_scripts/openvpn_shadowsocks/template.ovpn</file>
|
||||||
<file>images/folder.png</file>
|
<file>images/folder.png</file>
|
||||||
|
<file>server_scripts/wireguard/configure_container.sh</file>
|
||||||
|
<file>server_scripts/wireguard/Dockerfile</file>
|
||||||
|
<file>server_scripts/wireguard/run_container.sh</file>
|
||||||
|
<file>server_scripts/wireguard/start.sh</file>
|
||||||
|
<file>server_scripts/wireguard/template.conf</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ ca /opt/amnezia/openvpn/ca.crt \\n\
|
||||||
cert /opt/amnezia/openvpn/AmneziaReq.crt \\n\
|
cert /opt/amnezia/openvpn/AmneziaReq.crt \\n\
|
||||||
key /opt/amnezia/openvpn/AmneziaReq.key \\n\
|
key /opt/amnezia/openvpn/AmneziaReq.key \\n\
|
||||||
dh /opt/amnezia/openvpn/dh.pem \\n\
|
dh /opt/amnezia/openvpn/dh.pem \\n\
|
||||||
server $VPN_SUBNET_IP $VPN_SUBNET_MASK \\n\
|
server $OPENVPN_SUBNET_IP $OPENVPN_SUBNET_MASK \\n\
|
||||||
ifconfig-pool-persist ipp.txt \\n\
|
ifconfig-pool-persist ipp.txt \\n\
|
||||||
duplicate-cn \\n\
|
duplicate-cn \\n\
|
||||||
keepalive 10 120 \\n\
|
keepalive 10 120 \\n\
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
# This scripts copied from Amnezia client to Docker container to /opt/amnezia and launched every time container starts
|
# This scripts copied from Amnezia client to Docker container to /opt/amnezia and launched every time container starts
|
||||||
|
|
||||||
echo "Container startup"
|
echo "Container startup"
|
||||||
|
ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up
|
||||||
|
|
||||||
if [ ! -c /dev/net/tun ]; then mkdir -p /dev/net; mknod /dev/net/tun c 10 200; fi
|
if [ ! -c /dev/net/tun ]; then mkdir -p /dev/net; mknod /dev/net/tun c 10 200; fi
|
||||||
|
|
||||||
|
|
@ -12,10 +13,10 @@ iptables -A FORWARD -i tun0 -j ACCEPT
|
||||||
iptables -A OUTPUT -o tun0 -j ACCEPT
|
iptables -A OUTPUT -o tun0 -j ACCEPT
|
||||||
|
|
||||||
# Allow forwarding traffic only from the VPN.
|
# Allow forwarding traffic only from the VPN.
|
||||||
iptables -A FORWARD -i tun0 -o eth0 -s $VPN_SUBNET_IP/$VPN_SUBNET_MASK_VAL -j ACCEPT
|
iptables -A FORWARD -i tun0 -o eth0 -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -j ACCEPT
|
||||||
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
|
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||||
|
|
||||||
iptables -t nat -A POSTROUTING -s $VPN_SUBNET_IP/$VPN_SUBNET_MASK_VAL -o eth0 -j MASQUERADE
|
iptables -t nat -A POSTROUTING -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -o eth0 -j MASQUERADE
|
||||||
|
|
||||||
# kill daemons in case of restart
|
# kill daemons in case of restart
|
||||||
killall -KILL openvpn
|
killall -KILL openvpn
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ ca /opt/amnezia/openvpn/ca.crt \\n\
|
||||||
cert /opt/amnezia/openvpn/AmneziaReq.crt \\n\
|
cert /opt/amnezia/openvpn/AmneziaReq.crt \\n\
|
||||||
key /opt/amnezia/openvpn/AmneziaReq.key \\n\
|
key /opt/amnezia/openvpn/AmneziaReq.key \\n\
|
||||||
dh /opt/amnezia/openvpn/dh.pem \\n\
|
dh /opt/amnezia/openvpn/dh.pem \\n\
|
||||||
server $VPN_SUBNET_IP $VPN_SUBNET_MASK \\n\
|
server $OPENVPN_SUBNET_IP $OPENVPN_SUBNET_MASK \\n\
|
||||||
ifconfig-pool-persist ipp.txt \\n\
|
ifconfig-pool-persist ipp.txt \\n\
|
||||||
duplicate-cn \\n\
|
duplicate-cn \\n\
|
||||||
keepalive 10 120 \\n\
|
keepalive 10 120 \\n\
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
# This scripts copied from Amnezia client to Docker container to /opt/amnezia and launched every time container starts
|
# This scripts copied from Amnezia client to Docker container to /opt/amnezia and launched every time container starts
|
||||||
|
|
||||||
echo "Container startup"
|
echo "Container startup"
|
||||||
|
ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up
|
||||||
|
|
||||||
if [ ! -c /dev/net/tun ]; then mkdir -p /dev/net; mknod /dev/net/tun c 10 200; fi
|
if [ ! -c /dev/net/tun ]; then mkdir -p /dev/net; mknod /dev/net/tun c 10 200; fi
|
||||||
|
|
||||||
|
|
@ -12,10 +13,10 @@ iptables -A FORWARD -i tun0 -j ACCEPT
|
||||||
iptables -A OUTPUT -o tun0 -j ACCEPT
|
iptables -A OUTPUT -o tun0 -j ACCEPT
|
||||||
|
|
||||||
# Allow forwarding traffic only from the VPN.
|
# Allow forwarding traffic only from the VPN.
|
||||||
iptables -A FORWARD -i tun0 -o eth0 -s $VPN_SUBNET_IP/$VPN_SUBNET_MASK_VAL -j ACCEPT
|
iptables -A FORWARD -i tun0 -o eth0 -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -j ACCEPT
|
||||||
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
|
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||||
|
|
||||||
iptables -t nat -A POSTROUTING -s $VPN_SUBNET_IP/$VPN_SUBNET_MASK_VAL -o eth0 -j MASQUERADE
|
iptables -t nat -A POSTROUTING -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -o eth0 -j MASQUERADE
|
||||||
|
|
||||||
# kill daemons in case of restart
|
# kill daemons in case of restart
|
||||||
killall -KILL openvpn
|
killall -KILL openvpn
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ ca /opt/amnezia/openvpn/ca.crt \\n\
|
||||||
cert /opt/amnezia/openvpn/AmneziaReq.crt \\n\
|
cert /opt/amnezia/openvpn/AmneziaReq.crt \\n\
|
||||||
key /opt/amnezia/openvpn/AmneziaReq.key \\n\
|
key /opt/amnezia/openvpn/AmneziaReq.key \\n\
|
||||||
dh /opt/amnezia/openvpn/dh.pem \\n\
|
dh /opt/amnezia/openvpn/dh.pem \\n\
|
||||||
server $VPN_SUBNET_IP $VPN_SUBNET_MASK \\n\
|
server $OPENVPN_SUBNET_IP $OPENVPN_SUBNET_MASK \\n\
|
||||||
ifconfig-pool-persist ipp.txt \\n\
|
ifconfig-pool-persist ipp.txt \\n\
|
||||||
duplicate-cn \\n\
|
duplicate-cn \\n\
|
||||||
keepalive 10 120 \\n\
|
keepalive 10 120 \\n\
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
# This scripts copied from Amnezia client to Docker container to /opt/amnezia and launched every time container starts
|
# This scripts copied from Amnezia client to Docker container to /opt/amnezia and launched every time container starts
|
||||||
|
|
||||||
echo "Container startup"
|
echo "Container startup"
|
||||||
|
ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up
|
||||||
|
|
||||||
if [ ! -c /dev/net/tun ]; then mkdir -p /dev/net; mknod /dev/net/tun c 10 200; fi
|
if [ ! -c /dev/net/tun ]; then mkdir -p /dev/net; mknod /dev/net/tun c 10 200; fi
|
||||||
|
|
||||||
|
|
@ -12,10 +13,10 @@ iptables -A FORWARD -i tun0 -j ACCEPT
|
||||||
iptables -A OUTPUT -o tun0 -j ACCEPT
|
iptables -A OUTPUT -o tun0 -j ACCEPT
|
||||||
|
|
||||||
# Allow forwarding traffic only from the VPN.
|
# Allow forwarding traffic only from the VPN.
|
||||||
iptables -A FORWARD -i tun0 -o eth0 -s $VPN_SUBNET_IP/$VPN_SUBNET_MASK_VAL -j ACCEPT
|
iptables -A FORWARD -i tun0 -o eth0 -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -j ACCEPT
|
||||||
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
|
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||||
|
|
||||||
iptables -t nat -A POSTROUTING -s $VPN_SUBNET_IP/$VPN_SUBNET_MASK_VAL -o eth0 -j MASQUERADE
|
iptables -t nat -A POSTROUTING -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -o eth0 -j MASQUERADE
|
||||||
|
|
||||||
# kill daemons in case of restart
|
# kill daemons in case of restart
|
||||||
killall -KILL openvpn
|
killall -KILL openvpn
|
||||||
|
|
|
||||||
47
client/server_scripts/wireguard/Dockerfile
Normal file
47
client/server_scripts/wireguard/Dockerfile
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
#FROM alpine:latest
|
||||||
|
FROM itsthenetwork/alpine-tcpdump:latest
|
||||||
|
|
||||||
|
LABEL maintainer="AmneziaVPN"
|
||||||
|
|
||||||
|
#Install required packages
|
||||||
|
RUN apk add --no-cache curl wireguard-tools dumb-init
|
||||||
|
RUN apk --update upgrade --no-cache
|
||||||
|
|
||||||
|
RUN mkdir -p /opt/amnezia
|
||||||
|
RUN echo -e "#!/bin/bash\ntail -f /dev/null" > /opt/amnezia/start.sh
|
||||||
|
RUN chmod a+x /opt/amnezia/start.sh
|
||||||
|
|
||||||
|
# Tune network
|
||||||
|
RUN echo -e " \n\
|
||||||
|
fs.file-max = 51200 \n\
|
||||||
|
\n\
|
||||||
|
net.core.rmem_max = 67108864 \n\
|
||||||
|
net.core.wmem_max = 67108864 \n\
|
||||||
|
net.core.netdev_max_backlog = 250000 \n\
|
||||||
|
net.core.somaxconn = 4096 \n\
|
||||||
|
\n\
|
||||||
|
net.ipv4.tcp_syncookies = 1 \n\
|
||||||
|
net.ipv4.tcp_tw_reuse = 1 \n\
|
||||||
|
net.ipv4.tcp_tw_recycle = 0 \n\
|
||||||
|
net.ipv4.tcp_fin_timeout = 30 \n\
|
||||||
|
net.ipv4.tcp_keepalive_time = 1200 \n\
|
||||||
|
net.ipv4.ip_local_port_range = 10000 65000 \n\
|
||||||
|
net.ipv4.tcp_max_syn_backlog = 8192 \n\
|
||||||
|
net.ipv4.tcp_max_tw_buckets = 5000 \n\
|
||||||
|
net.ipv4.tcp_fastopen = 3 \n\
|
||||||
|
net.ipv4.tcp_mem = 25600 51200 102400 \n\
|
||||||
|
net.ipv4.tcp_rmem = 4096 87380 67108864 \n\
|
||||||
|
net.ipv4.tcp_wmem = 4096 65536 67108864 \n\
|
||||||
|
net.ipv4.tcp_mtu_probing = 1 \n\
|
||||||
|
net.ipv4.tcp_congestion_control = hybla \n\
|
||||||
|
# for low-latency network, use cubic instead \n\
|
||||||
|
# net.ipv4.tcp_congestion_control = cubic \n\
|
||||||
|
" | sed -e 's/^\s\+//g' | tee -a /etc/sysctl.conf && \
|
||||||
|
mkdir -p /etc/security && \
|
||||||
|
echo -e " \n\
|
||||||
|
* soft nofile 51200 \n\
|
||||||
|
* hard nofile 51200 \n\
|
||||||
|
" | sed -e 's/^\s\+//g' | tee -a /etc/security/limits.conf
|
||||||
|
|
||||||
|
ENTRYPOINT [ "dumb-init", "/opt/amnezia/start.sh" ]
|
||||||
|
CMD [ "" ]
|
||||||
13
client/server_scripts/wireguard/configure_container.sh
Normal file
13
client/server_scripts/wireguard/configure_container.sh
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Wireguard config
|
||||||
|
sudo docker exec -i $CONTAINER_NAME bash -c '\
|
||||||
|
mkdir -p /opt/amnezia/wireguard; \
|
||||||
|
cd /opt/amnezia/wireguard || exit 1; \
|
||||||
|
WIREGUARD_SERVER_PRIVATE_KEY=$(wg genkey) && echo $WIREGUARD_SERVER_PRIVATE_KEY > /opt/amnezia/wireguard/wireguard_server_private_key.key; \
|
||||||
|
WIREGUARD_SERVER_PUBLIC_KEY=$(echo $WIREGUARD_SERVER_PRIVATE_KEY | wg pubkey) && echo $WIREGUARD_SERVER_PUBLIC_KEY > /opt/amnezia/wireguard/wireguard_server_public_key.key; \
|
||||||
|
WIREGUARD_PSK=$(wg genpsk) && echo $WIREGUARD_PSK > /opt/amnezia/wireguard/wireguard_psk.key; \
|
||||||
|
echo -e "\
|
||||||
|
[Interface]\\n\
|
||||||
|
PrivateKey = $WIREGUARD_SERVER_PRIVATE_KEY \\n\
|
||||||
|
Address = $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR \\n\
|
||||||
|
ListenPort = $WIREGUARD_SERVER_PORT \\n\
|
||||||
|
" >/opt/amnezia/wireguard/wg0.conf'
|
||||||
15
client/server_scripts/wireguard/run_container.sh
Normal file
15
client/server_scripts/wireguard/run_container.sh
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# Run container
|
||||||
|
sudo docker run -d \
|
||||||
|
--restart always \
|
||||||
|
--privileged \
|
||||||
|
--cap-add=NET_ADMIN \
|
||||||
|
--cap-add=SYS_MODULE \
|
||||||
|
-p $WIREGUARD_SERVER_PORT:$WIREGUARD_SERVER_PORT/udp \
|
||||||
|
-v /lib/modules:/lib/modules \
|
||||||
|
--sysctl="net.ipv4.conf.all.src_valid_mark=1" \
|
||||||
|
--name $CONTAINER_NAME \
|
||||||
|
$CONTAINER_NAME
|
||||||
|
|
||||||
|
# Prevent to route packets outside of the container in case if server behind of the NAT
|
||||||
|
#sudo docker exec -i $CONTAINER_NAME sh -c "ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up"
|
||||||
|
|
||||||
25
client/server_scripts/wireguard/start.sh
Normal file
25
client/server_scripts/wireguard/start.sh
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This scripts copied from Amnezia client to Docker container to /opt/amnezia and launched every time container starts
|
||||||
|
|
||||||
|
echo "Container startup"
|
||||||
|
#ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up
|
||||||
|
|
||||||
|
# kill daemons in case of restart
|
||||||
|
wg-quick down /opt/amnezia/wireguard/wg0.conf
|
||||||
|
|
||||||
|
# start daemons if configured
|
||||||
|
if [ -f /opt/amnezia/wireguard/wg0.conf ]; then (wg-quick up /opt/amnezia/wireguard/wg0.conf); fi
|
||||||
|
|
||||||
|
# Allow traffic on the TUN interface.
|
||||||
|
iptables -A INPUT -i wg0 -j ACCEPT
|
||||||
|
iptables -A FORWARD -i wg0 -j ACCEPT
|
||||||
|
iptables -A OUTPUT -o wg0 -j ACCEPT
|
||||||
|
|
||||||
|
# Allow forwarding traffic only from the VPN.
|
||||||
|
iptables -A FORWARD -i wg0 -o eth0 -s $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_MASK_CIDR -j ACCEPT
|
||||||
|
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||||
|
|
||||||
|
iptables -t nat -A POSTROUTING -s $WIREGUARD_SUBNET_IP/$OPENVPN_SUBNET_CIDR -o eth0 -j MASQUERADE
|
||||||
|
|
||||||
|
tail -f /dev/null
|
||||||
11
client/server_scripts/wireguard/template.conf
Normal file
11
client/server_scripts/wireguard/template.conf
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
[Interface]
|
||||||
|
Address = 10.8.1.2/32
|
||||||
|
DNS = 1.1.1.1, 1.0.0.1
|
||||||
|
PrivateKey = $WIREGUARD_CLIENT_PRIVATE_KEY
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = $WIREGUARD_SERVER_PUBLIC_KEY
|
||||||
|
PresharedKey = $WIREGUARD_PSK
|
||||||
|
AllowedIPs = 0.0.0.0/0, ::/0
|
||||||
|
Endpoint = $SERVER_IP_ADDRESS:$WIREGUARD_SERVER_PORT
|
||||||
|
PersistentKeepalive = 25
|
||||||
|
|
@ -78,17 +78,6 @@ public:
|
||||||
|
|
||||||
RouteMode routeMode() const { return static_cast<RouteMode>(m_settings.value("Conf/routeMode", 0).toInt()); }
|
RouteMode routeMode() const { return static_cast<RouteMode>(m_settings.value("Conf/routeMode", 0).toInt()); }
|
||||||
void setRouteMode(RouteMode mode) { m_settings.setValue("Conf/routeMode", mode); }
|
void setRouteMode(RouteMode mode) { m_settings.setValue("Conf/routeMode", mode); }
|
||||||
// bool customRouting() const { return m_settings.value("Conf/customRouting", false).toBool(); }
|
|
||||||
// void setCustomRouting(bool customRouting) { m_settings.setValue("Conf/customRouting", customRouting); }
|
|
||||||
|
|
||||||
// // list of sites to pass blocking added by user
|
|
||||||
// QStringList customSites() { return m_settings.value("Conf/customSites").toStringList(); }
|
|
||||||
// void setCustomSites(const QStringList &customSites) { m_settings.setValue("Conf/customSites", customSites); }
|
|
||||||
|
|
||||||
// // list of ips to pass blocking generated from customSites
|
|
||||||
// QStringList customIps() { return m_settings.value("Conf/customIps").toStringList(); }
|
|
||||||
// void setCustomIps(const QStringList &customIps) { m_settings.setValue("Conf/customIps", customIps); }
|
|
||||||
|
|
||||||
|
|
||||||
QVariantMap vpnSites(RouteMode mode) const { return m_settings.value("Conf/" + routeModeString(mode)).toMap(); }
|
QVariantMap vpnSites(RouteMode mode) const { return m_settings.value("Conf/" + routeModeString(mode)).toMap(); }
|
||||||
void setVpnSites(RouteMode mode, const QVariantMap &sites) { m_settings.setValue("Conf/"+ routeModeString(mode), sites); m_settings.sync(); }
|
void setVpnSites(RouteMode mode, const QVariantMap &sites) { m_settings.setValue("Conf/"+ routeModeString(mode), sites); m_settings.sync(); }
|
||||||
|
|
@ -100,16 +89,6 @@ public:
|
||||||
void removeVpnSites(RouteMode mode, const QStringList &sites);
|
void removeVpnSites(RouteMode mode, const QStringList &sites);
|
||||||
|
|
||||||
|
|
||||||
// QVariantMap vpnForwardSites() const { return m_settings.value("Conf/vpnForwardSites").toMap(); }
|
|
||||||
// void setVpnForwardSites(const QVariantMap &sites) { m_settings.setValue("Conf/vpnForwardSites", sites); }
|
|
||||||
// void addVpnForwardSite(const QString &site, const QString &ip);
|
|
||||||
// QStringList getVpnForwardIps() const;
|
|
||||||
|
|
||||||
// QVariantMap vpnExceptSites() const { return m_settings.value("Conf/vpnExceptSites").toMap(); }
|
|
||||||
// void setVpnExceptSites(const QVariantMap &sites) { m_settings.setValue("Conf/vpnExceptSites", sites); }
|
|
||||||
// void addVpnExceptSite(const QString &site, const QString &ip);
|
|
||||||
// QStringList getVpnExceptIps() const;
|
|
||||||
|
|
||||||
QString primaryDns() const;
|
QString primaryDns() const;
|
||||||
QString secondaryDns() const;
|
QString secondaryDns() const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,11 @@
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "configurators/cloak_configurator.h"
|
||||||
#include "configurators/vpn_configurator.h"
|
#include "configurators/vpn_configurator.h"
|
||||||
#include "configurators/openvpn_configurator.h"
|
#include "configurators/openvpn_configurator.h"
|
||||||
#include "configurators/shadowsocks_configurator.h"
|
#include "configurators/shadowsocks_configurator.h"
|
||||||
#include "configurators/cloak_configurator.h"
|
#include "configurators/ssh_configurator.h"
|
||||||
|
|
||||||
#include "core/servercontroller.h"
|
#include "core/servercontroller.h"
|
||||||
#include "core/server_defs.h"
|
#include "core/server_defs.h"
|
||||||
|
|
@ -113,7 +113,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
qInfo().noquote() << QString("Started %1 version %2").arg(APPLICATION_NAME).arg(APP_VERSION);
|
qInfo().noquote() << QString("Started %1 version %2").arg(APPLICATION_NAME).arg(APP_VERSION);
|
||||||
qInfo().noquote() << QString("%1 (%2)").arg(QSysInfo::prettyProductName()).arg(QSysInfo::currentCpuArchitecture());
|
qInfo().noquote() << QString("%1 (%2)").arg(QSysInfo::prettyProductName()).arg(QSysInfo::currentCpuArchitecture());
|
||||||
|
|
||||||
Utils::initializePath(Utils::configPath());
|
|
||||||
|
|
||||||
m_vpnConnection = new VpnConnection(this);
|
m_vpnConnection = new VpnConnection(this);
|
||||||
connect(m_vpnConnection, SIGNAL(bytesChanged(quint64, quint64)), this, SLOT(onBytesChanged(quint64, quint64)));
|
connect(m_vpnConnection, SIGNAL(bytesChanged(quint64, quint64)), this, SLOT(onBytesChanged(quint64, quint64)));
|
||||||
|
|
@ -129,8 +128,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug().noquote() << QString("Default config: %1").arg(Utils::defaultVpnConfigFileName());
|
|
||||||
|
|
||||||
m_ipAddressValidator.setRegExp(Utils::ipAddressRegExp());
|
m_ipAddressValidator.setRegExp(Utils::ipAddressRegExp());
|
||||||
m_ipAddressPortValidator.setRegExp(Utils::ipAddressPortRegExp());
|
m_ipAddressPortValidator.setRegExp(Utils::ipAddressPortRegExp());
|
||||||
m_ipNetwok24Validator.setRegExp(Utils::ipNetwork24RegExp());
|
m_ipNetwok24Validator.setRegExp(Utils::ipNetwork24RegExp());
|
||||||
|
|
@ -378,6 +375,9 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
|
||||||
selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex);
|
selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex);
|
||||||
goToPage(Page::ServerVpnProtocols);
|
goToPage(Page::ServerVpnProtocols);
|
||||||
break;
|
break;
|
||||||
|
case Qt::Key_T:
|
||||||
|
SshConfigurator::openSshTerminal(m_settings.serverCredentials(m_settings.defaultServerIndex()));
|
||||||
|
break;
|
||||||
case Qt::Key_Escape:
|
case Qt::Key_Escape:
|
||||||
if (currentPage() == Page::Vpn) break;
|
if (currentPage() == Page::Vpn) break;
|
||||||
if (currentPage() == Page::ServerConfiguring) break;
|
if (currentPage() == Page::ServerConfiguring) break;
|
||||||
|
|
@ -470,7 +470,7 @@ void MainWindow::onPushButtonNewServerConnect(bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.contains("OPENSSH") && key.contains("BEGIN") && key.contains("PRIVATE KEY")) {
|
if (key.contains("OPENSSH") && key.contains("BEGIN") && key.contains("PRIVATE KEY")) {
|
||||||
key = OpenVpnConfigurator::convertOpenSShKey(key);
|
key = SshConfigurator::convertOpenSShKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
serverCredentials.password = key;
|
serverCredentials.password = key;
|
||||||
|
|
@ -1272,18 +1272,20 @@ void MainWindow::setupProtocolsPageConnections()
|
||||||
{
|
{
|
||||||
QJsonObject openvpnConfig;
|
QJsonObject openvpnConfig;
|
||||||
|
|
||||||
// default buttons
|
// all containers
|
||||||
QList<DockerContainer> containers {
|
QList<DockerContainer> containers {
|
||||||
DockerContainer::OpenVpn,
|
DockerContainer::OpenVpn,
|
||||||
DockerContainer::OpenVpnOverShadowSocks,
|
DockerContainer::OpenVpnOverShadowSocks,
|
||||||
DockerContainer::OpenVpnOverCloak
|
DockerContainer::OpenVpnOverCloak,
|
||||||
|
DockerContainer::WireGuard
|
||||||
};
|
};
|
||||||
|
|
||||||
// default buttons
|
// default buttons
|
||||||
QList<QPushButton *> defaultButtons {
|
QList<QPushButton *> defaultButtons {
|
||||||
ui->pushButton_proto_openvpn_cont_default,
|
ui->pushButton_proto_openvpn_cont_default,
|
||||||
ui->pushButton_proto_ss_openvpn_cont_default,
|
ui->pushButton_proto_ss_openvpn_cont_default,
|
||||||
ui->pushButton_proto_cloak_openvpn_cont_default
|
ui->pushButton_proto_cloak_openvpn_cont_default,
|
||||||
|
ui->pushButton_proto_wireguard_cont_default
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < containers.size(); ++i) {
|
for (int i = 0; i < containers.size(); ++i) {
|
||||||
|
|
@ -1297,7 +1299,8 @@ void MainWindow::setupProtocolsPageConnections()
|
||||||
QList<QPushButton *> installButtons {
|
QList<QPushButton *> installButtons {
|
||||||
ui->pushButton_proto_openvpn_cont_install,
|
ui->pushButton_proto_openvpn_cont_install,
|
||||||
ui->pushButton_proto_ss_openvpn_cont_install,
|
ui->pushButton_proto_ss_openvpn_cont_install,
|
||||||
ui->pushButton_proto_cloak_openvpn_cont_install
|
ui->pushButton_proto_cloak_openvpn_cont_install,
|
||||||
|
ui->pushButton_proto_wireguard_cont_install
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < containers.size(); ++i) {
|
for (int i = 0; i < containers.size(); ++i) {
|
||||||
|
|
@ -1338,7 +1341,8 @@ void MainWindow::setupProtocolsPageConnections()
|
||||||
QList<QPushButton *> shareButtons {
|
QList<QPushButton *> shareButtons {
|
||||||
ui->pushButton_proto_openvpn_cont_share,
|
ui->pushButton_proto_openvpn_cont_share,
|
||||||
ui->pushButton_proto_ss_openvpn_cont_share,
|
ui->pushButton_proto_ss_openvpn_cont_share,
|
||||||
ui->pushButton_proto_cloak_openvpn_cont_share
|
ui->pushButton_proto_cloak_openvpn_cont_share,
|
||||||
|
ui->pushButton_proto_wireguard_cont_share
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < containers.size(); ++i) {
|
for (int i = 0; i < containers.size(); ++i) {
|
||||||
|
|
@ -1827,6 +1831,10 @@ void MainWindow::onPushButtonAddCustomSitesClicked()
|
||||||
m_vpnConnection->addRoutes(QStringList() << ip);
|
m_vpnConnection->addRoutes(QStringList() << ip);
|
||||||
m_vpnConnection->flushDns();
|
m_vpnConnection->flushDns();
|
||||||
}
|
}
|
||||||
|
else if (Utils::ipAddressWithSubnetRegExp().exactMatch(newSite)) {
|
||||||
|
m_vpnConnection->addRoutes(QStringList() << newSite);
|
||||||
|
m_vpnConnection->flushDns();
|
||||||
|
}
|
||||||
|
|
||||||
updateSitesPage();
|
updateSitesPage();
|
||||||
};
|
};
|
||||||
|
|
@ -1961,33 +1969,58 @@ void MainWindow::updateProtocolsPage()
|
||||||
ui->progressBar_protocols_container_reinstall->hide();
|
ui->progressBar_protocols_container_reinstall->hide();
|
||||||
|
|
||||||
auto containers = m_settings.containers(selectedServerIndex);
|
auto containers = m_settings.containers(selectedServerIndex);
|
||||||
|
DockerContainer defaultContainer = m_settings.defaultContainer(selectedServerIndex);
|
||||||
bool haveAuthData = m_settings.haveAuthData(selectedServerIndex);
|
bool haveAuthData = m_settings.haveAuthData(selectedServerIndex);
|
||||||
|
|
||||||
DockerContainer defaultContainer = m_settings.defaultContainer(selectedServerIndex);
|
// all containers
|
||||||
ui->pushButton_proto_cloak_openvpn_cont_default->setChecked(defaultContainer == DockerContainer::OpenVpnOverCloak);
|
QList<DockerContainer> allContainers {
|
||||||
ui->pushButton_proto_ss_openvpn_cont_default->setChecked(defaultContainer == DockerContainer::OpenVpnOverShadowSocks);
|
DockerContainer::OpenVpn,
|
||||||
ui->pushButton_proto_openvpn_cont_default->setChecked(defaultContainer == DockerContainer::OpenVpn);
|
DockerContainer::OpenVpnOverShadowSocks,
|
||||||
|
DockerContainer::OpenVpnOverCloak,
|
||||||
|
DockerContainer::WireGuard
|
||||||
|
};
|
||||||
|
|
||||||
ui->pushButton_proto_cloak_openvpn_cont_default->setVisible(haveAuthData && containers.contains(DockerContainer::OpenVpnOverCloak));
|
// install buttons
|
||||||
ui->pushButton_proto_ss_openvpn_cont_default->setVisible(haveAuthData && containers.contains(DockerContainer::OpenVpnOverShadowSocks));
|
QList<QPushButton *> installButtons {
|
||||||
ui->pushButton_proto_openvpn_cont_default->setVisible(haveAuthData && containers.contains(DockerContainer::OpenVpn));
|
ui->pushButton_proto_openvpn_cont_install,
|
||||||
|
ui->pushButton_proto_ss_openvpn_cont_install,
|
||||||
|
ui->pushButton_proto_cloak_openvpn_cont_install,
|
||||||
|
ui->pushButton_proto_wireguard_cont_install
|
||||||
|
};
|
||||||
|
|
||||||
ui->pushButton_proto_cloak_openvpn_cont_share->setVisible(haveAuthData && containers.contains(DockerContainer::OpenVpnOverCloak));
|
// default buttons
|
||||||
ui->pushButton_proto_ss_openvpn_cont_share->setVisible(haveAuthData && containers.contains(DockerContainer::OpenVpnOverShadowSocks));
|
QList<QPushButton *> defaultButtons {
|
||||||
ui->pushButton_proto_openvpn_cont_share->setVisible(haveAuthData && containers.contains(DockerContainer::OpenVpn));
|
ui->pushButton_proto_openvpn_cont_default,
|
||||||
|
ui->pushButton_proto_ss_openvpn_cont_default,
|
||||||
|
ui->pushButton_proto_cloak_openvpn_cont_default,
|
||||||
|
ui->pushButton_proto_wireguard_cont_default
|
||||||
|
};
|
||||||
|
|
||||||
ui->pushButton_proto_cloak_openvpn_cont_install->setChecked(containers.contains(DockerContainer::OpenVpnOverCloak));
|
// share buttons
|
||||||
ui->pushButton_proto_ss_openvpn_cont_install->setChecked(containers.contains(DockerContainer::OpenVpnOverShadowSocks));
|
QList<QPushButton *> shareButtons {
|
||||||
ui->pushButton_proto_openvpn_cont_install->setChecked(containers.contains(DockerContainer::OpenVpn));
|
ui->pushButton_proto_openvpn_cont_share,
|
||||||
|
ui->pushButton_proto_ss_openvpn_cont_share,
|
||||||
|
ui->pushButton_proto_cloak_openvpn_cont_share,
|
||||||
|
ui->pushButton_proto_wireguard_cont_share
|
||||||
|
};
|
||||||
|
|
||||||
ui->pushButton_proto_cloak_openvpn_cont_install->setEnabled(haveAuthData);
|
// frames
|
||||||
ui->pushButton_proto_ss_openvpn_cont_install->setEnabled(haveAuthData);
|
QList<QFrame *> frames {
|
||||||
ui->pushButton_proto_openvpn_cont_install->setEnabled(haveAuthData);
|
ui->frame_openvpn_settings,
|
||||||
|
ui->frame_openvpn_ss_settings,
|
||||||
|
ui->frame_openvpn_ss_cloak_settings,
|
||||||
|
ui->frame_wireguard_settings
|
||||||
|
};
|
||||||
|
|
||||||
ui->frame_openvpn_ss_cloak_settings->setVisible(containers.contains(DockerContainer::OpenVpnOverCloak));
|
for (int i = 0; i < allContainers.size(); ++i) {
|
||||||
ui->frame_openvpn_ss_settings->setVisible(containers.contains(DockerContainer::OpenVpnOverShadowSocks));
|
defaultButtons.at(i)->setChecked(defaultContainer == allContainers.at(i));
|
||||||
ui->frame_openvpn_settings->setVisible(containers.contains(DockerContainer::OpenVpn));
|
defaultButtons.at(i)->setVisible(haveAuthData && containers.contains(allContainers.at(i)));
|
||||||
|
shareButtons.at(i)->setVisible(haveAuthData && containers.contains(allContainers.at(i)));
|
||||||
|
installButtons.at(i)->setChecked(containers.contains(allContainers.at(i)));
|
||||||
|
installButtons.at(i)->setEnabled(haveAuthData);
|
||||||
|
frames.at(i)->setVisible(containers.contains(allContainers.at(i)));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateOpenVpnPage(const QJsonObject &openvpnConfig, DockerContainer container, bool haveAuthData)
|
void MainWindow::updateOpenVpnPage(const QJsonObject &openvpnConfig, DockerContainer container, bool haveAuthData)
|
||||||
|
|
@ -2000,7 +2033,7 @@ void MainWindow::updateOpenVpnPage(const QJsonObject &openvpnConfig, DockerConta
|
||||||
ui->radioButton_proto_openvpn_tcp->setEnabled(true);
|
ui->radioButton_proto_openvpn_tcp->setEnabled(true);
|
||||||
|
|
||||||
ui->lineEdit_proto_openvpn_subnet->setText(openvpnConfig.value(config_key::subnet_address).
|
ui->lineEdit_proto_openvpn_subnet->setText(openvpnConfig.value(config_key::subnet_address).
|
||||||
toString(protocols::vpnDefaultSubnetAddress));
|
toString(protocols::openvpn::defaultSubnetAddress));
|
||||||
|
|
||||||
QString trasnsport = openvpnConfig.value(config_key::transport_proto).
|
QString trasnsport = openvpnConfig.value(config_key::transport_proto).
|
||||||
toString(protocols::openvpn::defaultTransportProto);
|
toString(protocols::openvpn::defaultTransportProto);
|
||||||
|
|
|
||||||
|
|
@ -274,7 +274,7 @@ QPushButton:hover {
|
||||||
<string notr="true"/>
|
<string notr="true"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>13</number>
|
<number>8</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page_start">
|
<widget class="QWidget" name="page_start">
|
||||||
<widget class="QLabel" name="label_25">
|
<widget class="QLabel" name="label_25">
|
||||||
|
|
@ -2578,6 +2578,127 @@ border: none;
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="frame_new_server_settings_parent_wireguard">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>100</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMinAndMaxSize</enum>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget_10" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBox_new_server_wireguard">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>WireGuard</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_new_server_settings_wireguard">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>PointingHandCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="frame_new_server_settings_wireguard">
|
||||||
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_73">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>130</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>130</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Port</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_new_server_wireguard_port">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>185</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>185</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_new_server_2">
|
<spacer name="verticalSpacer_new_server_2">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|
@ -5346,6 +5467,161 @@ QPushButton:!checked {
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="frame_wireguard">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>100</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_17">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMinAndMaxSize</enum>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_74">
|
||||||
|
<property name="text">
|
||||||
|
<string>WireGuard container</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_proto_wireguard_cont_default">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>PointingHandCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QPushButton {
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/images/check.png);
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
QPushButton:checked {
|
||||||
|
image: url(:/images/check.png);
|
||||||
|
}
|
||||||
|
QPushButton:!checked {
|
||||||
|
image: url(:/images/uncheck.png);
|
||||||
|
}
|
||||||
|
</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_proto_wireguard_cont_share">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>PointingHandCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background: transparent;
|
||||||
|
image: url(:/images/share.png);
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_proto_wireguard_cont_install">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>36</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>PointingHandCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QPushButton {
|
||||||
|
background: transparent;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
QPushButton:checked {
|
||||||
|
image: url(:/images/connect_button_connected.png);
|
||||||
|
}
|
||||||
|
QPushButton:!checked {
|
||||||
|
image: url(:/images/connect_button_disconnected.png);
|
||||||
|
}
|
||||||
|
</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="frame_wireguard_settings">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_18">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_proto_wireguard_cont_wireguard_config">
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>PointingHandCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>WireGuard settings</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,6 @@ QString Utils::getRandomString(int len)
|
||||||
return randomString;
|
return randomString;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Utils::defaultVpnConfigFileName()
|
|
||||||
{
|
|
||||||
return configPath() + QString("/%1.ovpn").arg(APPLICATION_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Utils::systemLogPath()
|
QString Utils::systemLogPath()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
|
@ -54,11 +49,6 @@ bool Utils::initializePath(const QString& path)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Utils::configPath()
|
|
||||||
{
|
|
||||||
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/config";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Utils::createEmptyFile(const QString& path)
|
bool Utils::createEmptyFile(const QString& path)
|
||||||
{
|
{
|
||||||
QFile f(path);
|
QFile f(path);
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,6 @@ class Utils {
|
||||||
public:
|
public:
|
||||||
static QString getRandomString(int len);
|
static QString getRandomString(int len);
|
||||||
|
|
||||||
static QString configPath();
|
|
||||||
static QString defaultVpnConfigFileName();
|
|
||||||
static QString executable(const QString& baseName, bool absPath);
|
static QString executable(const QString& baseName, bool absPath);
|
||||||
static QString systemLogPath();
|
static QString systemLogPath();
|
||||||
static bool createEmptyFile(const QString& path);
|
static bool createEmptyFile(const QString& path);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@
|
||||||
#include <configurators/openvpn_configurator.h>
|
#include <configurators/openvpn_configurator.h>
|
||||||
#include <configurators/cloak_configurator.h>
|
#include <configurators/cloak_configurator.h>
|
||||||
#include <configurators/shadowsocks_configurator.h>
|
#include <configurators/shadowsocks_configurator.h>
|
||||||
|
#include <configurators/wireguard_configurator.h>
|
||||||
#include <core/servercontroller.h>
|
#include <core/servercontroller.h>
|
||||||
|
#include <protocols/wireguardprotocol.h>
|
||||||
|
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
#include "core/ipcclient.h"
|
#include "core/ipcclient.h"
|
||||||
|
|
@ -43,7 +45,7 @@ void VpnConnection::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
||||||
if (state == VpnProtocol::Connected){
|
if (state == VpnProtocol::Connected){
|
||||||
IpcClient::Interface()->flushDns();
|
IpcClient::Interface()->flushDns();
|
||||||
|
|
||||||
if (m_settings.routeMode() == Settings::VpnOnlyForwardSites) {
|
if (m_settings.routeMode() != Settings::VpnAllSites) {
|
||||||
IpcClient::Interface()->routeDeleteList(m_vpnProtocol->vpnGateway(), QStringList() << "0.0.0.0");
|
IpcClient::Interface()->routeDeleteList(m_vpnProtocol->vpnGateway(), QStringList() << "0.0.0.0");
|
||||||
//qDebug() << "VpnConnection::onConnectionStateChanged :: adding custom routes, count:" << forwardIps.size();
|
//qDebug() << "VpnConnection::onConnectionStateChanged :: adding custom routes, count:" << forwardIps.size();
|
||||||
}
|
}
|
||||||
|
|
@ -55,6 +57,10 @@ void VpnConnection::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
||||||
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), m_settings.getVpnIps(Settings::VpnOnlyForwardSites));
|
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), m_settings.getVpnIps(Settings::VpnOnlyForwardSites));
|
||||||
}
|
}
|
||||||
else if (m_settings.routeMode() == Settings::VpnAllExceptSites) {
|
else if (m_settings.routeMode() == Settings::VpnAllExceptSites) {
|
||||||
|
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << "0.0.0.0/1");
|
||||||
|
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << "128.0.0.0/1");
|
||||||
|
|
||||||
|
IpcClient::Interface()->routeAddList(m_vpnProtocol->routeGateway(), QStringList() << remoteAddress());
|
||||||
IpcClient::Interface()->routeAddList(m_vpnProtocol->routeGateway(), m_settings.getVpnIps(Settings::VpnAllExceptSites));
|
IpcClient::Interface()->routeAddList(m_vpnProtocol->routeGateway(), m_settings.getVpnIps(Settings::VpnAllExceptSites));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,6 +77,11 @@ void VpnConnection::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
||||||
emit connectionStateChanged(state);
|
emit connectionStateChanged(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QString &VpnConnection::remoteAddress() const
|
||||||
|
{
|
||||||
|
return m_remoteAddress;
|
||||||
|
}
|
||||||
|
|
||||||
QSharedPointer<VpnProtocol> VpnConnection::vpnProtocol() const
|
QSharedPointer<VpnProtocol> VpnConnection::vpnProtocol() const
|
||||||
{
|
{
|
||||||
return m_vpnProtocol;
|
return m_vpnProtocol;
|
||||||
|
|
@ -159,6 +170,10 @@ QString VpnConnection::createVpnConfigurationForProto(int serverIndex,
|
||||||
configData = ShadowSocksConfigurator::genShadowSocksConfig(credentials,
|
configData = ShadowSocksConfigurator::genShadowSocksConfig(credentials,
|
||||||
container, containerConfig, &e);
|
container, containerConfig, &e);
|
||||||
}
|
}
|
||||||
|
else if (proto == Protocol::WireGuard) {
|
||||||
|
configData = WireguardConfigurator::genWireguardConfig(credentials,
|
||||||
|
container, containerConfig, &e);
|
||||||
|
}
|
||||||
|
|
||||||
if (errorCode && e) {
|
if (errorCode && e) {
|
||||||
*errorCode = e;
|
*errorCode = e;
|
||||||
|
|
@ -197,7 +212,7 @@ ErrorCode VpnConnection::createVpnConfiguration(int serverIndex,
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
QFile file(Utils::defaultVpnConfigFileName());
|
QFile file(OpenVpnProtocol::defaultConfigFileName());
|
||||||
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)){
|
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)){
|
||||||
QTextStream stream(&file);
|
QTextStream stream(&file);
|
||||||
stream << openVpnConfigData << endl;
|
stream << openVpnConfigData << endl;
|
||||||
|
|
@ -226,6 +241,13 @@ ErrorCode VpnConnection::createVpnConfiguration(int serverIndex,
|
||||||
m_vpnConfiguration.insert(config::key_cloak_config_data, cloakConfigData);
|
m_vpnConfiguration.insert(config::key_cloak_config_data, cloakConfigData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (container == DockerContainer::WireGuard) {
|
||||||
|
QString wgConfigData = createVpnConfigurationForProto(
|
||||||
|
serverIndex, credentials, container, containerConfig, Protocol::WireGuard, &errorCode);
|
||||||
|
|
||||||
|
m_vpnConfiguration.insert(config::key_wireguard_config_data, wgConfigData);
|
||||||
|
}
|
||||||
|
|
||||||
//qDebug().noquote() << "VPN config" << QJsonDocument(m_vpnConfiguration).toJson();
|
//qDebug().noquote() << "VPN config" << QJsonDocument(m_vpnConfiguration).toJson();
|
||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
}
|
}
|
||||||
|
|
@ -233,11 +255,15 @@ ErrorCode VpnConnection::createVpnConfiguration(int serverIndex,
|
||||||
ErrorCode VpnConnection::connectToVpn(int serverIndex,
|
ErrorCode VpnConnection::connectToVpn(int serverIndex,
|
||||||
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig)
|
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig)
|
||||||
{
|
{
|
||||||
qDebug() << "СonnectToVpn, Route mode is" << m_settings.routeMode();
|
qDebug() << QString("СonnectToVpn, Server index is %1, container is %2, route mode is")
|
||||||
|
.arg(serverIndex).arg(containerToString(container)) << m_settings.routeMode();
|
||||||
|
m_remoteAddress = credentials.hostName;
|
||||||
|
|
||||||
emit connectionStateChanged(VpnProtocol::Connecting);
|
emit connectionStateChanged(VpnProtocol::Connecting);
|
||||||
|
|
||||||
|
if (credentials.isValid()) {
|
||||||
ServerController::setupServerFirewall(credentials);
|
ServerController::setupServerFirewall(credentials);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_vpnProtocol) {
|
if (m_vpnProtocol) {
|
||||||
disconnect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
|
disconnect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
|
||||||
|
|
@ -287,6 +313,15 @@ ErrorCode VpnConnection::connectToVpn(int serverIndex,
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (container == DockerContainer::WireGuard) {
|
||||||
|
ErrorCode e = createVpnConfiguration(serverIndex, credentials, DockerContainer::WireGuard, containerConfig);
|
||||||
|
if (e) {
|
||||||
|
emit connectionStateChanged(VpnProtocol::Error);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_vpnProtocol.reset(new WireguardProtocol(m_vpnConfiguration));
|
||||||
|
}
|
||||||
|
|
||||||
connect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
|
connect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
|
||||||
connect(m_vpnProtocol.data(), SIGNAL(connectionStateChanged(VpnProtocol::ConnectionState)), this, SLOT(onConnectionStateChanged(VpnProtocol::ConnectionState)));
|
connect(m_vpnProtocol.data(), SIGNAL(connectionStateChanged(VpnProtocol::ConnectionState)), this, SLOT(onConnectionStateChanged(VpnProtocol::ConnectionState)));
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,8 @@ public:
|
||||||
void deleteRoutes(const QStringList &ips);
|
void deleteRoutes(const QStringList &ips);
|
||||||
void flushDns();
|
void flushDns();
|
||||||
|
|
||||||
|
const QString &remoteAddress() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||||
void connectionStateChanged(VpnProtocol::ConnectionState state);
|
void connectionStateChanged(VpnProtocol::ConnectionState state);
|
||||||
|
|
@ -66,6 +68,7 @@ private:
|
||||||
Settings m_settings;
|
Settings m_settings;
|
||||||
QJsonObject m_vpnConfiguration;
|
QJsonObject m_vpnConfiguration;
|
||||||
QJsonObject m_routeMode;
|
QJsonObject m_routeMode;
|
||||||
|
QString m_remoteAddress;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,14 @@ class IpcProcessInterface
|
||||||
SLOT( setProgram(const QString &program) );
|
SLOT( setProgram(const QString &program) );
|
||||||
SLOT( setWorkingDirectory(const QString &dir) );
|
SLOT( setWorkingDirectory(const QString &dir) );
|
||||||
|
|
||||||
|
SLOT( QByteArray readAll() );
|
||||||
SLOT( QByteArray readAllStandardError() );
|
SLOT( QByteArray readAllStandardError() );
|
||||||
SLOT( QByteArray readAllStandardOutput() );
|
SLOT( QByteArray readAllStandardOutput() );
|
||||||
|
|
||||||
|
|
||||||
SIGNAL( errorOccurred(QProcess::ProcessError error) );
|
SIGNAL( errorOccurred(QProcess::ProcessError error) );
|
||||||
SIGNAL( finished(int exitCode, QProcess::ExitStatus exitStatus) );
|
SIGNAL( finished(int exitCode, QProcess::ExitStatus exitStatus) );
|
||||||
|
SIGNAL( readyRead() );
|
||||||
SIGNAL( readyReadStandardError() );
|
SIGNAL( readyReadStandardError() );
|
||||||
SIGNAL( readyReadStandardOutput() );
|
SIGNAL( readyReadStandardOutput() );
|
||||||
SIGNAL( started() );
|
SIGNAL( started() );
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ IpcServerProcess::IpcServerProcess(QObject *parent) :
|
||||||
{
|
{
|
||||||
connect(m_process.data(), &QProcess::errorOccurred, this, &IpcServerProcess::errorOccurred);
|
connect(m_process.data(), &QProcess::errorOccurred, this, &IpcServerProcess::errorOccurred);
|
||||||
connect(m_process.data(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &IpcServerProcess::finished);
|
connect(m_process.data(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &IpcServerProcess::finished);
|
||||||
|
connect(m_process.data(), &QProcess::readyRead, this, &IpcServerProcess::readyRead);
|
||||||
connect(m_process.data(), &QProcess::readyReadStandardError, this, &IpcServerProcess::readyReadStandardError);
|
connect(m_process.data(), &QProcess::readyReadStandardError, this, &IpcServerProcess::readyReadStandardError);
|
||||||
connect(m_process.data(), &QProcess::readyReadStandardOutput, this, &IpcServerProcess::readyReadStandardOutput);
|
connect(m_process.data(), &QProcess::readyReadStandardOutput, this, &IpcServerProcess::readyReadStandardOutput);
|
||||||
connect(m_process.data(), &QProcess::started, this, &IpcServerProcess::started);
|
connect(m_process.data(), &QProcess::started, this, &IpcServerProcess::started);
|
||||||
|
|
@ -88,6 +89,11 @@ void IpcServerProcess::setWorkingDirectory(const QString &dir)
|
||||||
m_process->setWorkingDirectory(dir);
|
m_process->setWorkingDirectory(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray IpcServerProcess::readAll()
|
||||||
|
{
|
||||||
|
return m_process->readAll();
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray IpcServerProcess::readAllStandardError()
|
QByteArray IpcServerProcess::readAllStandardError()
|
||||||
{
|
{
|
||||||
return m_process->readAllStandardError();
|
return m_process->readAllStandardError();
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ public:
|
||||||
void setProgram(const QString &program) override;
|
void setProgram(const QString &program) override;
|
||||||
void setWorkingDirectory(const QString &dir) override;
|
void setWorkingDirectory(const QString &dir) override;
|
||||||
|
|
||||||
|
QByteArray readAll() override;
|
||||||
QByteArray readAllStandardError() override;
|
QByteArray readAllStandardError() override;
|
||||||
QByteArray readAllStandardOutput() override;
|
QByteArray readAllStandardOutput() override;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue