mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-22 02:01:08 +07:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 44018ec94c | |||
| 89577651d6 | |||
| 3b2d3a0b34 | |||
| fe3228ed74 | |||
| 917942be94 | |||
| 6a3875ec7f | |||
| e121ca9b53 | |||
| c23c8e8462 | |||
| 36fae9152f | |||
| 2b0ba2aff9 | |||
| 68830021d6 | |||
| 6a903792ab | |||
| d2d9c33837 | |||
| 7d51cb7d58 | |||
| 7df3600a62 | |||
| 634ca6cbe8 | |||
| 8032e55d7c | |||
| dc2a1467c7 | |||
| 67c36f5b30 |
@@ -235,6 +235,7 @@ if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/openvpnovercloakprotocol.h
|
${CMAKE_CURRENT_LIST_DIR}/protocols/openvpnovercloakprotocol.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/shadowsocksvpnprotocol.h
|
${CMAKE_CURRENT_LIST_DIR}/protocols/shadowsocksvpnprotocol.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/wireguardprotocol.h
|
${CMAKE_CURRENT_LIST_DIR}/protocols/wireguardprotocol.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/protocols/v2rayprotocol.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES ${SOURCES}
|
set(SOURCES ${SOURCES}
|
||||||
@@ -245,6 +246,7 @@ if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/openvpnovercloakprotocol.cpp
|
${CMAKE_CURRENT_LIST_DIR}/protocols/openvpnovercloakprotocol.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/shadowsocksvpnprotocol.cpp
|
${CMAKE_CURRENT_LIST_DIR}/protocols/shadowsocksvpnprotocol.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/wireguardprotocol.cpp
|
${CMAKE_CURRENT_LIST_DIR}/protocols/wireguardprotocol.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/protocols/v2rayprotocol.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -558,7 +560,7 @@ if(WIN32)
|
|||||||
set(DEPLOY_ARTIFACT_PATH "windows/x32")
|
set(DEPLOY_ARTIFACT_PATH "windows/x32")
|
||||||
endif()
|
endif()
|
||||||
elseif(LINUX)
|
elseif(LINUX)
|
||||||
set(DEPLOY_ARTIFACT_PATH "linux/client")
|
set(DEPLOY_ARTIFACT_PATH "linux/client/bin")
|
||||||
elseif(APPLE AND NOT IOS)
|
elseif(APPLE AND NOT IOS)
|
||||||
set(DEPLOY_ARTIFACT_PATH "macos")
|
set(DEPLOY_ARTIFACT_PATH "macos")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -7,24 +7,24 @@
|
|||||||
#include "core/servercontroller.h"
|
#include "core/servercontroller.h"
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
|
|
||||||
CloakConfigurator::CloakConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
CloakConfigurator::CloakConfigurator(std::shared_ptr<Settings> settings,
|
||||||
ConfiguratorBase(settings, parent)
|
QObject *parent): ConfiguratorBase(settings, parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CloakConfigurator::genCloakConfig(const ServerCredentials &credentials,
|
QString CloakConfigurator::genCloakConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
|
|
||||||
|
|
||||||
QString cloakPublicKey = serverController.getTextFileFromContainer(container, credentials,
|
QString cloakPublicKey = serverController.getTextFileFromContainer(container, credentials,
|
||||||
amnezia::protocols::cloak::ckPublicKeyPath, &e);
|
amnezia::protocols::cloak::ckPublicKeyPath, &e);
|
||||||
cloakPublicKey.replace("\n", "");
|
cloakPublicKey.replace("\n", "");
|
||||||
|
|
||||||
QString cloakBypassUid = serverController.getTextFileFromContainer(container, credentials,
|
QString cloakBypassUid = serverController.getTextFileFromContainer(container, credentials,
|
||||||
amnezia::protocols::cloak::ckBypassUidKeyPath, &e);
|
amnezia::protocols::cloak::ckBypassUidKeyPath, &e);
|
||||||
cloakBypassUid.replace("\n", "");
|
cloakBypassUid.replace("\n", "");
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public:
|
|||||||
CloakConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
CloakConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
QString genCloakConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString genCloakConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CLOAK_CONFIGURATOR_H
|
#endif // CLOAK_CONFIGURATOR_H
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#include "configurator_base.h"
|
#include "configurator_base.h"
|
||||||
|
|
||||||
ConfiguratorBase::ConfiguratorBase(std::shared_ptr<Settings> settings, QObject *parent)
|
ConfiguratorBase::ConfiguratorBase(std::shared_ptr<Settings> settings,
|
||||||
: QObject{parent},
|
QObject *parent): QObject{parent}, m_settings(settings)
|
||||||
m_settings(settings)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "ikev2_configurator.h"
|
#include "ikev2_configurator.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
@@ -15,14 +16,13 @@
|
|||||||
#include "core/servercontroller.h"
|
#include "core/servercontroller.h"
|
||||||
|
|
||||||
|
|
||||||
Ikev2Configurator::Ikev2Configurator(std::shared_ptr<Settings> settings, QObject *parent):
|
Ikev2Configurator::Ikev2Configurator(std::shared_ptr<Settings> settings,
|
||||||
ConfiguratorBase(settings, parent)
|
QObject *parent): ConfiguratorBase(settings, parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials,
|
Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials,
|
||||||
DockerContainer container, ErrorCode *errorCode)
|
DockerContainer container, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
Ikev2Configurator::ConnectionData connData;
|
Ikev2Configurator::ConnectionData connData;
|
||||||
connData.host = credentials.hostName;
|
connData.host = credentials.hostName;
|
||||||
@@ -33,21 +33,18 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
|
|||||||
QString certFileName = "/opt/amnezia/ikev2/clients/" + connData.clientId + ".p12";
|
QString certFileName = "/opt/amnezia/ikev2/clients/" + connData.clientId + ".p12";
|
||||||
|
|
||||||
QString scriptCreateCert = QString("certutil -z <(head -c 1024 /dev/urandom) "\
|
QString scriptCreateCert = QString("certutil -z <(head -c 1024 /dev/urandom) "\
|
||||||
"-S -c \"IKEv2 VPN CA\" -n \"%1\" "\
|
"-S -c \"IKEv2 VPN CA\" -n \"%1\" "\
|
||||||
"-s \"O=IKEv2 VPN,CN=%1\" "\
|
"-s \"O=IKEv2 VPN,CN=%1\" "\
|
||||||
"-k rsa -g 3072 -v 120 "\
|
"-k rsa -g 3072 -v 120 "\
|
||||||
"-d sql:/etc/ipsec.d -t \",,\" "\
|
"-d sql:/etc/ipsec.d -t \",,\" "\
|
||||||
"--keyUsage digitalSignature,keyEncipherment "\
|
"--keyUsage digitalSignature,keyEncipherment "\
|
||||||
"--extKeyUsage serverAuth,clientAuth -8 \"%1\"")
|
"--extKeyUsage serverAuth,clientAuth -8 \"%1\"").arg(connData.clientId);
|
||||||
.arg(connData.clientId);
|
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
ErrorCode e = serverController.runContainerScript(credentials, container, scriptCreateCert);
|
ErrorCode e = serverController.runContainerScript(credentials, container, scriptCreateCert);
|
||||||
|
|
||||||
QString scriptExportCert = QString("pk12util -W \"%1\" -d sql:/etc/ipsec.d -n \"%2\" -o \"%3\"")
|
QString scriptExportCert = QString("pk12util -W \"%1\" -d sql:/etc/ipsec.d -n \"%2\" -o \"%3\"")
|
||||||
.arg(connData.password)
|
.arg(connData.password, connData.clientId, certFileName);
|
||||||
.arg(connData.clientId)
|
|
||||||
.arg(certFileName);
|
|
||||||
e = serverController.runContainerScript(credentials, container, scriptExportCert);
|
e = serverController.runContainerScript(credentials, container, scriptExportCert);
|
||||||
|
|
||||||
connData.clientCert = serverController.getTextFileFromContainer(container, credentials, certFileName, &e);
|
connData.clientCert = serverController.getTextFileFromContainer(container, credentials, certFileName, &e);
|
||||||
@@ -59,8 +56,8 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
|
|||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Ikev2Configurator::genIkev2Config(const ServerCredentials &credentials,
|
QString Ikev2Configurator::genIkev2Config(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
Q_UNUSED(containerConfig)
|
Q_UNUSED(containerConfig)
|
||||||
|
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
QString genIkev2Config(const ServerCredentials &credentials, DockerContainer container,
|
QString genIkev2Config(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
QString genIkev2Config(const ConnectionData &connData);
|
QString genIkev2Config(const ConnectionData &connData);
|
||||||
QString genMobileConfig(const ConnectionData &connData);
|
QString genMobileConfig(const ConnectionData &connData);
|
||||||
QString genStrongSwanConfig(const ConnectionData &connData);
|
QString genStrongSwanConfig(const ConnectionData &connData);
|
||||||
|
|
||||||
ConnectionData prepareIkev2Config(const ServerCredentials &credentials,
|
ConnectionData prepareIkev2Config(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, ErrorCode *errorCode = nullptr);
|
ErrorCode *errorCode = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // IKEV2_CONFIGURATOR_H
|
#endif // IKEV2_CONFIGURATOR_H
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "openvpn_configurator.h"
|
#include "openvpn_configurator.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
@@ -19,14 +20,13 @@
|
|||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
|
|
||||||
OpenVpnConfigurator::OpenVpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
OpenVpnConfigurator::OpenVpnConfigurator(std::shared_ptr<Settings> settings,
|
||||||
ConfiguratorBase(settings, parent)
|
QObject *parent): ConfiguratorBase(settings, parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const ServerCredentials &credentials,
|
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const ServerCredentials &credentials,
|
||||||
DockerContainer container, ErrorCode *errorCode)
|
DockerContainer container, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
OpenVpnConfigurator::ConnectionData connData = OpenVpnConfigurator::createCertRequest();
|
OpenVpnConfigurator::ConnectionData connData = OpenVpnConfigurator::createCertRequest();
|
||||||
connData.host = credentials.hostName;
|
connData.host = credentials.hostName;
|
||||||
@@ -36,9 +36,7 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
|
|||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString reqFileName = QString("%1/%2.req").
|
QString reqFileName = QString("%1/%2.req").arg(amnezia::protocols::openvpn::clientsDirPath, connData.clientId);
|
||||||
arg(amnezia::protocols::openvpn::clientsDirPath).
|
|
||||||
arg(connData.clientId);
|
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
ErrorCode e = serverController.uploadTextFileToContainer(container, credentials, connData.request, reqFileName);
|
ErrorCode e = serverController.uploadTextFileToContainer(container, credentials, connData.request, reqFileName);
|
||||||
@@ -53,9 +51,11 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
|
|||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
connData.caCert = serverController.getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::caCertPath, &e);
|
connData.caCert = serverController.getTextFileFromContainer(container, credentials,
|
||||||
|
amnezia::protocols::openvpn::caCertPath, &e);
|
||||||
connData.clientCert = serverController.getTextFileFromContainer(container, credentials,
|
connData.clientCert = serverController.getTextFileFromContainer(container, credentials,
|
||||||
QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath).arg(connData.clientId), &e);
|
QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath, connData.clientId),
|
||||||
|
&e);
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
if (errorCode) *errorCode = e;
|
if (errorCode) *errorCode = e;
|
||||||
@@ -71,12 +71,12 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
|
|||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentials,
|
QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
QString config = serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::openvpn_template, container),
|
QString config = serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::openvpn_template, container),
|
||||||
serverController.genVarsForScript(credentials, container, containerConfig));
|
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
ConnectionData connData = prepareOpenVpnConfig(credentials, container, errorCode);
|
ConnectionData connData = prepareOpenVpnConfig(credentials, container, errorCode);
|
||||||
if (errorCode && *errorCode) {
|
if (errorCode && *errorCode) {
|
||||||
@@ -89,8 +89,7 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia
|
|||||||
|
|
||||||
if (config.contains("$OPENVPN_TA_KEY")) {
|
if (config.contains("$OPENVPN_TA_KEY")) {
|
||||||
config.replace("$OPENVPN_TA_KEY", connData.taKey);
|
config.replace("$OPENVPN_TA_KEY", connData.taKey);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
config.replace("<tls-auth>", "");
|
config.replace("<tls-auth>", "");
|
||||||
config.replace("</tls-auth>", "");
|
config.replace("</tls-auth>", "");
|
||||||
}
|
}
|
||||||
@@ -112,8 +111,7 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(QString jsonConfig)
|
|||||||
|
|
||||||
if (m_settings->routeMode() != Settings::VpnAllSites) {
|
if (m_settings->routeMode() != Settings::VpnAllSites) {
|
||||||
config.replace("redirect-gateway def1 bypass-dhcp", "");
|
config.replace("redirect-gateway def1 bypass-dhcp", "");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if(!config.contains("redirect-gateway def1 bypass-dhcp")) {
|
if(!config.contains("redirect-gateway def1 bypass-dhcp")) {
|
||||||
config.append("redirect-gateway def1 bypass-dhcp\n");
|
config.append("redirect-gateway def1 bypass-dhcp\n");
|
||||||
}
|
}
|
||||||
@@ -151,23 +149,22 @@ QString OpenVpnConfigurator::processConfigWithExportSettings(QString jsonConfig)
|
|||||||
return QJsonDocument(json).toJson();
|
return QJsonDocument(json).toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode OpenVpnConfigurator::signCert(DockerContainer container,
|
ErrorCode OpenVpnConfigurator::signCert(DockerContainer container, const ServerCredentials &credentials, QString clientId)
|
||||||
const ServerCredentials &credentials, QString clientId)
|
|
||||||
{
|
{
|
||||||
QString script_import = QString("sudo docker exec -i %1 bash -c \"cd /opt/amnezia/openvpn && "
|
QString script_import = QString("sudo docker exec -i %1 bash -c \"cd /opt/amnezia/openvpn && "
|
||||||
"easyrsa import-req %2/%3.req %3\"")
|
"easyrsa import-req %2/%3.req %3\"")
|
||||||
.arg(ContainerProps::containerToString(container))
|
.arg(ContainerProps::containerToString(container),
|
||||||
.arg(amnezia::protocols::openvpn::clientsDirPath)
|
amnezia::protocols::openvpn::clientsDirPath,
|
||||||
.arg(clientId);
|
clientId);
|
||||||
|
|
||||||
QString script_sign = QString("sudo docker exec -i %1 bash -c \"export EASYRSA_BATCH=1; cd /opt/amnezia/openvpn && "
|
QString script_sign = QString("sudo docker exec -i %1 bash -c \"export EASYRSA_BATCH=1; cd /opt/amnezia/openvpn && "
|
||||||
"easyrsa sign-req client %2\"")
|
"easyrsa sign-req client %2\"")
|
||||||
.arg(ContainerProps::containerToString(container))
|
.arg(ContainerProps::containerToString(container), clientId);
|
||||||
.arg(clientId);
|
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
QStringList scriptList {script_import, script_sign};
|
QStringList scriptList {script_import, script_sign};
|
||||||
QString script = serverController.replaceVars(scriptList.join("\n"), serverController.genVarsForScript(credentials, container));
|
QString script = serverController.replaceVars(scriptList.join("\n"),
|
||||||
|
serverController.genVarsForScript(credentials, container));
|
||||||
|
|
||||||
return serverController.runScript(credentials, script);
|
return serverController.runScript(credentials, script);
|
||||||
}
|
}
|
||||||
@@ -177,8 +174,8 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
|||||||
ConnectionData connData;
|
ConnectionData connData;
|
||||||
connData.clientId = Utils::getRandomString(32);
|
connData.clientId = Utils::getRandomString(32);
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int nVersion = 1;
|
int nVersion = 1;
|
||||||
|
|
||||||
QByteArray clientIdUtf8 = connData.clientId.toUtf8();
|
QByteArray clientIdUtf8 = connData.clientId.toUtf8();
|
||||||
|
|
||||||
@@ -211,7 +208,7 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
|||||||
|
|
||||||
// 4. set public key of x509 req
|
// 4. set public key of x509 req
|
||||||
ret = X509_REQ_set_pubkey(x509_req, pKey);
|
ret = X509_REQ_set_pubkey(x509_req, pKey);
|
||||||
if (ret != 1){
|
if (ret != 1) {
|
||||||
qWarning() << "Could not set pubkey!";
|
qWarning() << "Could not set pubkey!";
|
||||||
X509_REQ_free(x509_req);
|
X509_REQ_free(x509_req);
|
||||||
EVP_PKEY_free(pKey);
|
EVP_PKEY_free(pKey);
|
||||||
@@ -220,7 +217,7 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
|||||||
|
|
||||||
// 5. set sign key of x509 req
|
// 5. set sign key of x509 req
|
||||||
ret = X509_REQ_sign(x509_req, pKey, EVP_sha256()); // return x509_req->signature->length
|
ret = X509_REQ_sign(x509_req, pKey, EVP_sha256()); // return x509_req->signature->length
|
||||||
if (ret <= 0){
|
if (ret <= 0) {
|
||||||
qWarning() << "Could not sign request!";
|
qWarning() << "Could not sign request!";
|
||||||
X509_REQ_free(x509_req);
|
X509_REQ_free(x509_req);
|
||||||
EVP_PKEY_free(pKey);
|
EVP_PKEY_free(pKey);
|
||||||
@@ -230,8 +227,7 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
|||||||
// save private key
|
// save private key
|
||||||
BIO * bp_private = BIO_new(BIO_s_mem());
|
BIO * bp_private = BIO_new(BIO_s_mem());
|
||||||
q_check_ptr(bp_private);
|
q_check_ptr(bp_private);
|
||||||
if (PEM_write_bio_PrivateKey(bp_private, pKey, nullptr, nullptr, 0, nullptr, nullptr) != 1)
|
if (PEM_write_bio_PrivateKey(bp_private, pKey, nullptr, nullptr, 0, nullptr, nullptr) != 1) {
|
||||||
{
|
|
||||||
qFatal("PEM_write_bio_PrivateKey");
|
qFatal("PEM_write_bio_PrivateKey");
|
||||||
EVP_PKEY_free(pKey);
|
EVP_PKEY_free(pKey);
|
||||||
BIO_free_all(bp_private);
|
BIO_free_all(bp_private);
|
||||||
|
|||||||
@@ -24,20 +24,18 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
QString genOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString genOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
QString processConfigWithLocalSettings(QString jsonConfig);
|
QString processConfigWithLocalSettings(QString jsonConfig);
|
||||||
QString processConfigWithExportSettings(QString jsonConfig);
|
QString processConfigWithExportSettings(QString jsonConfig);
|
||||||
|
|
||||||
ErrorCode signCert(DockerContainer container,
|
ErrorCode signCert(DockerContainer container, const ServerCredentials &credentials, QString clientId);
|
||||||
const ServerCredentials &credentials, QString clientId);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConnectionData createCertRequest();
|
ConnectionData createCertRequest();
|
||||||
|
|
||||||
ConnectionData prepareOpenVpnConfig(const ServerCredentials &credentials,
|
ConnectionData prepareOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, ErrorCode *errorCode = nullptr);
|
ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // OPENVPN_CONFIGURATOR_H
|
#endif // OPENVPN_CONFIGURATOR_H
|
||||||
|
|||||||
@@ -5,16 +5,16 @@
|
|||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
|
#include "core/scripts_registry.h"
|
||||||
#include "core/servercontroller.h"
|
#include "core/servercontroller.h"
|
||||||
|
|
||||||
ShadowSocksConfigurator::ShadowSocksConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
ShadowSocksConfigurator::ShadowSocksConfigurator(std::shared_ptr<Settings> settings,
|
||||||
ConfiguratorBase(settings, parent)
|
QObject *parent): ConfiguratorBase(settings, parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ShadowSocksConfigurator::genShadowSocksConfig(const ServerCredentials &credentials,
|
QString ShadowSocksConfigurator::genShadowSocksConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
@@ -28,18 +28,12 @@ QString ShadowSocksConfigurator::genShadowSocksConfig(const ServerCredentials &c
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject config;
|
QString ssClientConfig = serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::shadowsocks_client_template, container),
|
||||||
config.insert("server", credentials.hostName);
|
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
config.insert("server_port", "$SHADOWSOCKS_SERVER_PORT");
|
|
||||||
config.insert("local_port", "$SHADOWSOCKS_LOCAL_PORT");
|
|
||||||
config.insert("password", ssKey);
|
|
||||||
config.insert("timeout", 60);
|
|
||||||
config.insert("method", "$SHADOWSOCKS_CIPHER");
|
|
||||||
|
|
||||||
|
ssClientConfig.replace("$SHADOWSOCKS_PASSWORD", ssKey);
|
||||||
QString textCfg = serverController.replaceVars(QJsonDocument(config).toJson(),
|
ssClientConfig = serverController.replaceVars(ssClientConfig, serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
serverController.genVarsForScript(credentials, container, containerConfig));
|
|
||||||
|
|
||||||
//qDebug().noquote() << textCfg;
|
//qDebug().noquote() << textCfg;
|
||||||
return textCfg;
|
return ssClientConfig;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public:
|
|||||||
ShadowSocksConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
ShadowSocksConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
QString genShadowSocksConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString genShadowSocksConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHADOWSOCKS_CONFIGURATOR_H
|
#endif // SHADOWSOCKS_CONFIGURATOR_H
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "ssh_configurator.h"
|
#include "ssh_configurator.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
@@ -14,11 +15,9 @@
|
|||||||
#include "core/server_defs.h"
|
#include "core/server_defs.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
|
SshConfigurator::SshConfigurator(std::shared_ptr<Settings> settings,
|
||||||
SshConfigurator::SshConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
QObject *parent): ConfiguratorBase(settings, parent)
|
||||||
ConfiguratorBase(settings, parent)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SshConfigurator::convertOpenSShKey(const QString &key)
|
QString SshConfigurator::convertOpenSShKey(const QString &key)
|
||||||
@@ -73,10 +72,8 @@ void SshConfigurator::openSshTerminal(const ServerCredentials &credentials)
|
|||||||
// todo: connect by key
|
// todo: connect by key
|
||||||
// p->setNativeArguments(QString("%1@%2")
|
// p->setNativeArguments(QString("%1@%2")
|
||||||
// .arg(credentials.userName).arg(credentials.hostName).arg(credentials.password));
|
// .arg(credentials.userName).arg(credentials.hostName).arg(credentials.password));
|
||||||
}
|
} else {
|
||||||
else {
|
p->setNativeArguments(QString("%1@%2 -pw %3").arg(credentials.userName).arg(credentials.hostName, credentials.password));
|
||||||
p->setNativeArguments(QString("%1@%2 -pw %3")
|
|
||||||
.arg(credentials.userName).arg(credentials.hostName).arg(credentials.password));
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
p->setProgram("/bin/bash");
|
p->setProgram("/bin/bash");
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ public:
|
|||||||
QProcessEnvironment prepareEnv();
|
QProcessEnvironment prepareEnv();
|
||||||
QString convertOpenSShKey(const QString &key);
|
QString convertOpenSShKey(const QString &key);
|
||||||
void openSshTerminal(const ServerCredentials &credentials);
|
void openSshTerminal(const ServerCredentials &credentials);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SSH_CONFIGURATOR_H
|
#endif // SSH_CONFIGURATOR_H
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#include "v2ray_configurator.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QPair>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
|
#include "core/servercontroller.h"
|
||||||
|
#include "core/scripts_registry.h"
|
||||||
|
#include "containers/containers_defs.h"
|
||||||
|
|
||||||
|
V2RayConfigurator::V2RayConfigurator(std::shared_ptr<Settings> settings,
|
||||||
|
QObject *parent) : ConfiguratorBase(settings, parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString V2RayConfigurator::genV2RayConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||||
|
{
|
||||||
|
ErrorCode e = ErrorCode::NoError;
|
||||||
|
|
||||||
|
ServerController serverController(m_settings);
|
||||||
|
QString v2RayVmessClientUuid = serverController.getTextFileFromContainer(container, credentials,
|
||||||
|
amnezia::protocols::v2ray::v2rayKeyPath, &e);
|
||||||
|
if (v2RayVmessClientUuid.isEmpty()) {
|
||||||
|
if (errorCode) *errorCode = ErrorCode::V2RayKeyMissing;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
v2RayVmessClientUuid.replace("\n", "");
|
||||||
|
|
||||||
|
if (e) {
|
||||||
|
if (errorCode) *errorCode = e;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString v2RayClientConfig = serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::v2ray_client_template, container),
|
||||||
|
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
|
v2RayClientConfig.replace("$V2RAY_VMESS_CLIENT_UUID", v2RayVmessClientUuid);
|
||||||
|
v2RayClientConfig = serverController.replaceVars(v2RayClientConfig,
|
||||||
|
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
|
return v2RayClientConfig;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef V2RAYCONFIGURATOR_H
|
||||||
|
#define V2RAYCONFIGURATOR_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "configurator_base.h"
|
||||||
|
|
||||||
|
using namespace amnezia;
|
||||||
|
|
||||||
|
class V2RayConfigurator : ConfiguratorBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
V2RayConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QString genV2RayConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // V2RAYCONFIGURATOR_H
|
||||||
|
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "wireguard_configurator.h"
|
#include "wireguard_configurator.h"
|
||||||
#include "ikev2_configurator.h"
|
#include "ikev2_configurator.h"
|
||||||
#include "ssh_configurator.h"
|
#include "ssh_configurator.h"
|
||||||
|
#include "v2ray_configurator.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
@@ -14,8 +15,8 @@
|
|||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
VpnConfigurator::VpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
VpnConfigurator::VpnConfigurator(std::shared_ptr<Settings> settings,
|
||||||
ConfiguratorBase(settings, parent)
|
QObject *parent) : ConfiguratorBase(settings, parent)
|
||||||
{
|
{
|
||||||
openVpnConfigurator = std::shared_ptr<OpenVpnConfigurator>(new OpenVpnConfigurator(settings, this));
|
openVpnConfigurator = std::shared_ptr<OpenVpnConfigurator>(new OpenVpnConfigurator(settings, this));
|
||||||
shadowSocksConfigurator = std::shared_ptr<ShadowSocksConfigurator>(new ShadowSocksConfigurator(settings, this));
|
shadowSocksConfigurator = std::shared_ptr<ShadowSocksConfigurator>(new ShadowSocksConfigurator(settings, this));
|
||||||
@@ -25,25 +26,22 @@ VpnConfigurator::VpnConfigurator(std::shared_ptr<Settings> settings, QObject *pa
|
|||||||
sshConfigurator = std::shared_ptr<SshConfigurator>(new SshConfigurator(settings, this));
|
sshConfigurator = std::shared_ptr<SshConfigurator>(new SshConfigurator(settings, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials,
|
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
switch (proto) {
|
switch (proto) {
|
||||||
case Proto::OpenVpn:
|
case Proto::OpenVpn:
|
||||||
return openVpnConfigurator->genOpenVpnConfig(credentials, container, containerConfig, errorCode);
|
return openVpnConfigurator->genOpenVpnConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
case Proto::ShadowSocks:
|
case Proto::ShadowSocks:
|
||||||
return shadowSocksConfigurator->genShadowSocksConfig(credentials, container, containerConfig, errorCode);
|
return shadowSocksConfigurator->genShadowSocksConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
case Proto::Cloak:
|
case Proto::Cloak:
|
||||||
return cloakConfigurator->genCloakConfig(credentials, container, containerConfig, errorCode);
|
return cloakConfigurator->genCloakConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
case Proto::WireGuard:
|
case Proto::WireGuard:
|
||||||
return wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig, errorCode);
|
return wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
case Proto::Ikev2:
|
case Proto::Ikev2:
|
||||||
return ikev2Configurator->genIkev2Config(credentials, container, containerConfig, errorCode);
|
return ikev2Configurator->genIkev2Config(credentials, container, containerConfig, errorCode);
|
||||||
|
case Proto::V2Ray:
|
||||||
|
return v2RayConfigurator->genV2RayConfig(credentials, container, containerConfig, errorCode);
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -62,8 +60,7 @@ QPair<QString, QString> VpnConfigurator::getDnsForConfig(int serverIndex)
|
|||||||
if (dns.first.isEmpty() || !Utils::checkIPv4Format(dns.first)) {
|
if (dns.first.isEmpty() || !Utils::checkIPv4Format(dns.first)) {
|
||||||
if (useAmneziaDns && m_settings->containers(serverIndex).contains(DockerContainer::Dns)) {
|
if (useAmneziaDns && m_settings->containers(serverIndex).contains(DockerContainer::Dns)) {
|
||||||
dns.first = protocols::dns::amneziaDnsIp;
|
dns.first = protocols::dns::amneziaDnsIp;
|
||||||
}
|
} else dns.first = m_settings->primaryDns();
|
||||||
else dns.first = m_settings->primaryDns();
|
|
||||||
}
|
}
|
||||||
if (dns.second.isEmpty() || !Utils::checkIPv4Format(dns.second)) {
|
if (dns.second.isEmpty() || !Utils::checkIPv4Format(dns.second)) {
|
||||||
dns.second = m_settings->secondaryDns();
|
dns.second = m_settings->secondaryDns();
|
||||||
@@ -73,8 +70,7 @@ QPair<QString, QString> VpnConfigurator::getDnsForConfig(int serverIndex)
|
|||||||
return dns;
|
return dns;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString &VpnConfigurator::processConfigWithDnsSettings(int serverIndex, DockerContainer container,
|
QString &VpnConfigurator::processConfigWithDnsSettings(int serverIndex, DockerContainer container, Proto proto, QString &config)
|
||||||
Proto proto, QString &config)
|
|
||||||
{
|
{
|
||||||
auto dns = getDnsForConfig(serverIndex);
|
auto dns = getDnsForConfig(serverIndex);
|
||||||
|
|
||||||
@@ -84,8 +80,7 @@ QString &VpnConfigurator::processConfigWithDnsSettings(int serverIndex, DockerCo
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString &VpnConfigurator::processConfigWithLocalSettings(int serverIndex, DockerContainer container,
|
QString &VpnConfigurator::processConfigWithLocalSettings(int serverIndex, DockerContainer container, Proto proto, QString &config)
|
||||||
Proto proto, QString &config)
|
|
||||||
{
|
{
|
||||||
processConfigWithDnsSettings(serverIndex, container, proto, config);
|
processConfigWithDnsSettings(serverIndex, container, proto, config);
|
||||||
|
|
||||||
@@ -95,8 +90,7 @@ QString &VpnConfigurator::processConfigWithLocalSettings(int serverIndex, Docker
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString &VpnConfigurator::processConfigWithExportSettings(int serverIndex, DockerContainer container,
|
QString &VpnConfigurator::processConfigWithExportSettings(int serverIndex, DockerContainer container, Proto proto, QString &config)
|
||||||
Proto proto, QString &config)
|
|
||||||
{
|
{
|
||||||
processConfigWithDnsSettings(serverIndex, container, proto, config);
|
processConfigWithDnsSettings(serverIndex, container, proto, config);
|
||||||
|
|
||||||
@@ -107,7 +101,7 @@ QString &VpnConfigurator::processConfigWithExportSettings(int serverIndex, Docke
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VpnConfigurator::updateContainerConfigAfterInstallation(DockerContainer container, QJsonObject &containerConfig,
|
void VpnConfigurator::updateContainerConfigAfterInstallation(DockerContainer container, QJsonObject &containerConfig,
|
||||||
const QString &stdOut)
|
const QString &stdOut)
|
||||||
{
|
{
|
||||||
Proto mainProto = ContainerProps::defaultProtocol(container);
|
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class CloakConfigurator;
|
|||||||
class WireguardConfigurator;
|
class WireguardConfigurator;
|
||||||
class Ikev2Configurator;
|
class Ikev2Configurator;
|
||||||
class SshConfigurator;
|
class SshConfigurator;
|
||||||
|
class V2RayConfigurator;
|
||||||
|
|
||||||
// Retrieve connection settings from server
|
// Retrieve connection settings from server
|
||||||
class VpnConfigurator : ConfiguratorBase
|
class VpnConfigurator : ConfiguratorBase
|
||||||
@@ -22,7 +23,7 @@ public:
|
|||||||
VpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
VpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
QString genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
QPair<QString, QString> getDnsForConfig(int serverIndex);
|
QPair<QString, QString> getDnsForConfig(int serverIndex);
|
||||||
QString &processConfigWithDnsSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
|
QString &processConfigWithDnsSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
|
||||||
@@ -31,8 +32,7 @@ public:
|
|||||||
QString &processConfigWithExportSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
|
QString &processConfigWithExportSettings(int serverIndex, DockerContainer container, Proto proto, QString &config);
|
||||||
|
|
||||||
// workaround for containers which is not support normal configaration
|
// workaround for containers which is not support normal configaration
|
||||||
void updateContainerConfigAfterInstallation(DockerContainer container,
|
void updateContainerConfigAfterInstallation(DockerContainer container, QJsonObject &containerConfig, const QString &stdOut);
|
||||||
QJsonObject &containerConfig, const QString &stdOut);
|
|
||||||
|
|
||||||
std::shared_ptr<OpenVpnConfigurator> openVpnConfigurator;
|
std::shared_ptr<OpenVpnConfigurator> openVpnConfigurator;
|
||||||
std::shared_ptr<ShadowSocksConfigurator> shadowSocksConfigurator;
|
std::shared_ptr<ShadowSocksConfigurator> shadowSocksConfigurator;
|
||||||
@@ -40,6 +40,7 @@ public:
|
|||||||
std::shared_ptr<WireguardConfigurator> wireguardConfigurator;
|
std::shared_ptr<WireguardConfigurator> wireguardConfigurator;
|
||||||
std::shared_ptr<Ikev2Configurator> ikev2Configurator;
|
std::shared_ptr<Ikev2Configurator> ikev2Configurator;
|
||||||
std::shared_ptr<SshConfigurator> sshConfigurator;
|
std::shared_ptr<SshConfigurator> sshConfigurator;
|
||||||
|
std::shared_ptr<V2RayConfigurator> v2RayConfigurator;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VPN_CONFIGURATOR_H
|
#endif // VPN_CONFIGURATOR_H
|
||||||
|
|||||||
@@ -7,13 +7,11 @@
|
|||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
|
||||||
|
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include <openssl/rsa.h>
|
#include <openssl/rsa.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
|
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
#include "core/server_defs.h"
|
#include "core/server_defs.h"
|
||||||
#include "core/scripts_registry.h"
|
#include "core/scripts_registry.h"
|
||||||
@@ -21,10 +19,9 @@
|
|||||||
#include "core/servercontroller.h"
|
#include "core/servercontroller.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings,
|
||||||
ConfiguratorBase(settings, parent)
|
QObject *parent): ConfiguratorBase(settings, parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
|
WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
|
||||||
@@ -59,7 +56,9 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
|
|||||||
}
|
}
|
||||||
|
|
||||||
WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardConfig(const ServerCredentials &credentials,
|
WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardConfig(const ServerCredentials &credentials,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
DockerContainer container,
|
||||||
|
const QJsonObject &containerConfig,
|
||||||
|
ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
|
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
|
||||||
connData.host = credentials.hostName;
|
connData.host = credentials.hostName;
|
||||||
@@ -95,8 +94,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||||||
// Calc next IP address
|
// Calc next IP address
|
||||||
if (ips.isEmpty()) {
|
if (ips.isEmpty()) {
|
||||||
nextIpNumber = "2";
|
nextIpNumber = "2";
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
int next = ips.last().split(".").last().toInt() + 1;
|
int next = ips.last().split(".").last().toInt() + 1;
|
||||||
if (next > 254) {
|
if (next > 254) {
|
||||||
if (errorCode) *errorCode = ErrorCode::AddressPoolError;
|
if (errorCode) *errorCode = ErrorCode::AddressPoolError;
|
||||||
@@ -120,14 +118,16 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get keys
|
// Get keys
|
||||||
connData.serverPubKey = serverController.getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPublicKeyPath, &e);
|
connData.serverPubKey = serverController.getTextFileFromContainer(container, credentials,
|
||||||
|
amnezia::protocols::wireguard::serverPublicKeyPath, &e);
|
||||||
connData.serverPubKey.replace("\n", "");
|
connData.serverPubKey.replace("\n", "");
|
||||||
if (e) {
|
if (e) {
|
||||||
if (errorCode) *errorCode = e;
|
if (errorCode) *errorCode = e;
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
connData.pskKey = serverController.getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPskKeyPath, &e);
|
connData.pskKey = serverController.getTextFileFromContainer(container, credentials,
|
||||||
|
amnezia::protocols::wireguard::serverPskKeyPath, &e);
|
||||||
connData.pskKey.replace("\n", "");
|
connData.pskKey.replace("\n", "");
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
@@ -136,32 +136,29 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add client to config
|
// Add client to config
|
||||||
QString configPart = QString(
|
QString configPart = QString("[Peer]\n"
|
||||||
"[Peer]\n"
|
"PublicKey = %1\n"
|
||||||
"PublicKey = %1\n"
|
"PresharedKey = %2\n"
|
||||||
"PresharedKey = %2\n"
|
"AllowedIPs = %3/32\n\n").arg(connData.clientPubKey, connData.pskKey, connData.clientIP);
|
||||||
"AllowedIPs = %3/32\n\n").
|
|
||||||
arg(connData.clientPubKey).
|
|
||||||
arg(connData.pskKey).
|
|
||||||
arg(connData.clientIP);
|
|
||||||
|
|
||||||
e = serverController.uploadTextFileToContainer(container, credentials, configPart,
|
e = serverController.uploadTextFileToContainer(container, credentials, configPart,
|
||||||
protocols::wireguard::serverConfigPath, libssh::SftpOverwriteMode::SftpAppendToExisting);
|
protocols::wireguard::serverConfigPath,
|
||||||
|
libssh::SftpOverwriteMode::SftpAppendToExisting);
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
if (errorCode) *errorCode = e;
|
if (errorCode) *errorCode = e;
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString script = "sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip /opt/amnezia/wireguard/wg0.conf)'";
|
||||||
e = serverController.runScript(credentials,
|
e = serverController.runScript(credentials,
|
||||||
serverController.replaceVars("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip /opt/amnezia/wireguard/wg0.conf)'",
|
serverController.replaceVars(script, serverController.genVarsForScript(credentials, container)));
|
||||||
serverController.genVarsForScript(credentials, container)));
|
|
||||||
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials,
|
QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
QString config = serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::wireguard_template, container),
|
QString config = serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::wireguard_template, container),
|
||||||
|
|||||||
@@ -23,15 +23,14 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
QString genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
QString processConfigWithLocalSettings(QString config);
|
QString processConfigWithLocalSettings(QString config);
|
||||||
QString processConfigWithExportSettings(QString config);
|
QString processConfigWithExportSettings(QString config);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConnectionData prepareWireguardConfig(const ServerCredentials &credentials,
|
ConnectionData prepareWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
ConnectionData genClientKeys();
|
ConnectionData genClientKeys();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ QVector<amnezia::Proto> ContainerProps::protocolsForContainer(amnezia::DockerCon
|
|||||||
case DockerContainer::Ipsec:
|
case DockerContainer::Ipsec:
|
||||||
return { Proto::Ikev2 /*, Protocol::L2tp */};
|
return { Proto::Ikev2 /*, Protocol::L2tp */};
|
||||||
|
|
||||||
|
case DockerContainer::V2Ray:
|
||||||
|
return { Proto::OpenVpn, Proto::V2Ray };
|
||||||
|
|
||||||
case DockerContainer::Dns:
|
case DockerContainer::Dns:
|
||||||
return { };
|
return { };
|
||||||
|
|
||||||
@@ -86,6 +89,7 @@ QMap<DockerContainer, QString> ContainerProps::containerHumanNames()
|
|||||||
{DockerContainer::Cloak, "OpenVpn over Cloak"},
|
{DockerContainer::Cloak, "OpenVpn over Cloak"},
|
||||||
{DockerContainer::WireGuard, "WireGuard"},
|
{DockerContainer::WireGuard, "WireGuard"},
|
||||||
{DockerContainer::Ipsec, QObject::tr("IPsec")},
|
{DockerContainer::Ipsec, QObject::tr("IPsec")},
|
||||||
|
{DockerContainer::V2Ray, "V2Ray"},
|
||||||
|
|
||||||
{DockerContainer::TorWebSite, QObject::tr("Web site in Tor network")},
|
{DockerContainer::TorWebSite, QObject::tr("Web site in Tor network")},
|
||||||
{DockerContainer::Dns, QObject::tr("DNS Service")},
|
{DockerContainer::Dns, QObject::tr("DNS Service")},
|
||||||
@@ -103,6 +107,7 @@ QMap<DockerContainer, QString> ContainerProps::containerDescriptions()
|
|||||||
"configured with traffic masking by Cloak plugin")},
|
"configured with traffic masking by Cloak plugin")},
|
||||||
{DockerContainer::WireGuard, QObject::tr("WireGuard container")},
|
{DockerContainer::WireGuard, QObject::tr("WireGuard container")},
|
||||||
{DockerContainer::Ipsec, QObject::tr("IPsec container")},
|
{DockerContainer::Ipsec, QObject::tr("IPsec container")},
|
||||||
|
{DockerContainer::V2Ray, QObject::tr("V2Ray container")},
|
||||||
|
|
||||||
{DockerContainer::TorWebSite, QObject::tr("Web site in Tor network")},
|
{DockerContainer::TorWebSite, QObject::tr("Web site in Tor network")},
|
||||||
{DockerContainer::Dns, QObject::tr("DNS Service")},
|
{DockerContainer::Dns, QObject::tr("DNS Service")},
|
||||||
@@ -120,6 +125,8 @@ amnezia::ServiceType ContainerProps::containerService(DockerContainer c)
|
|||||||
case DockerContainer::ShadowSocks : return ServiceType::Vpn;
|
case DockerContainer::ShadowSocks : return ServiceType::Vpn;
|
||||||
case DockerContainer::WireGuard : return ServiceType::Vpn;
|
case DockerContainer::WireGuard : return ServiceType::Vpn;
|
||||||
case DockerContainer::Ipsec : return ServiceType::Vpn;
|
case DockerContainer::Ipsec : return ServiceType::Vpn;
|
||||||
|
case DockerContainer::V2Ray : return ServiceType::Vpn;
|
||||||
|
|
||||||
case DockerContainer::TorWebSite : return ServiceType::Other;
|
case DockerContainer::TorWebSite : return ServiceType::Other;
|
||||||
case DockerContainer::Dns : return ServiceType::Other;
|
case DockerContainer::Dns : return ServiceType::Other;
|
||||||
//case DockerContainer::FileShare : return ServiceType::Other;
|
//case DockerContainer::FileShare : return ServiceType::Other;
|
||||||
@@ -137,6 +144,7 @@ Proto ContainerProps::defaultProtocol(DockerContainer c)
|
|||||||
case DockerContainer::ShadowSocks : return Proto::ShadowSocks;
|
case DockerContainer::ShadowSocks : return Proto::ShadowSocks;
|
||||||
case DockerContainer::WireGuard : return Proto::WireGuard;
|
case DockerContainer::WireGuard : return Proto::WireGuard;
|
||||||
case DockerContainer::Ipsec : return Proto::Ikev2;
|
case DockerContainer::Ipsec : return Proto::Ikev2;
|
||||||
|
case DockerContainer::V2Ray : return Proto::V2Ray;
|
||||||
|
|
||||||
case DockerContainer::TorWebSite : return Proto::TorWebSite;
|
case DockerContainer::TorWebSite : return Proto::TorWebSite;
|
||||||
case DockerContainer::Dns : return Proto::Dns;
|
case DockerContainer::Dns : return Proto::Dns;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ enum DockerContainer {
|
|||||||
Cloak,
|
Cloak,
|
||||||
WireGuard,
|
WireGuard,
|
||||||
Ipsec,
|
Ipsec,
|
||||||
|
V2Ray,
|
||||||
|
|
||||||
//non-vpn
|
//non-vpn
|
||||||
TorWebSite,
|
TorWebSite,
|
||||||
|
|||||||
+4
-1
@@ -55,6 +55,7 @@ enum ErrorCode
|
|||||||
ShadowSocksExecutableMissing,
|
ShadowSocksExecutableMissing,
|
||||||
CloakExecutableMissing,
|
CloakExecutableMissing,
|
||||||
AmneziaServiceConnectionFailed,
|
AmneziaServiceConnectionFailed,
|
||||||
|
V2RayExecutableMissing,
|
||||||
ExecutableMissing,
|
ExecutableMissing,
|
||||||
|
|
||||||
// VPN errors
|
// VPN errors
|
||||||
@@ -67,7 +68,9 @@ enum ErrorCode
|
|||||||
OpenSslFailed,
|
OpenSslFailed,
|
||||||
OpenVpnExecutableCrashed,
|
OpenVpnExecutableCrashed,
|
||||||
ShadowSocksExecutableCrashed,
|
ShadowSocksExecutableCrashed,
|
||||||
CloakExecutableCrashed
|
CloakExecutableCrashed,
|
||||||
|
V2RayExecutableCrashed,
|
||||||
|
V2RayKeyMissing
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace amnezia
|
} // namespace amnezia
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ QString errorString(ErrorCode code){
|
|||||||
case (AmneziaServiceConnectionFailed): return QObject::tr("Amnezia helper service error");
|
case (AmneziaServiceConnectionFailed): return QObject::tr("Amnezia helper service error");
|
||||||
case (OpenSslFailed): return QObject::tr("OpenSSL failed");
|
case (OpenSslFailed): return QObject::tr("OpenSSL failed");
|
||||||
|
|
||||||
|
// V2Ray errors
|
||||||
|
case (V2RayExecutableMissing): return QObject::tr("V2Ray (v2ray) executable missing");
|
||||||
|
case (V2RayKeyMissing): return QObject::tr("V2Ray key missing");
|
||||||
|
|
||||||
// VPN errors
|
// VPN errors
|
||||||
case (OpenVpnAdaptersInUseError): return QObject::tr("Can't connect: another VPN connection is active");
|
case (OpenVpnAdaptersInUseError): return QObject::tr("Can't connect: another VPN connection is active");
|
||||||
case (OpenVpnTapAdapterError): return QObject::tr("Can't setup OpenVPN TAP network adapter");
|
case (OpenVpnTapAdapterError): return QObject::tr("Can't setup OpenVPN TAP network adapter");
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ QString amnezia::scriptFolder(amnezia::DockerContainer container)
|
|||||||
case DockerContainer::ShadowSocks: return QLatin1String("openvpn_shadowsocks");
|
case DockerContainer::ShadowSocks: return QLatin1String("openvpn_shadowsocks");
|
||||||
case DockerContainer::WireGuard: return QLatin1String("wireguard");
|
case DockerContainer::WireGuard: return QLatin1String("wireguard");
|
||||||
case DockerContainer::Ipsec: return QLatin1String("ipsec");
|
case DockerContainer::Ipsec: return QLatin1String("ipsec");
|
||||||
|
case DockerContainer::V2Ray: return QLatin1String("openvpn_v2ray_vmess");
|
||||||
|
|
||||||
case DockerContainer::TorWebSite: return QLatin1String("website_tor");
|
case DockerContainer::TorWebSite: return QLatin1String("website_tor");
|
||||||
case DockerContainer::Dns: return QLatin1String("dns");
|
case DockerContainer::Dns: return QLatin1String("dns");
|
||||||
@@ -44,6 +45,8 @@ QString amnezia::scriptName(ProtocolScriptType type)
|
|||||||
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");
|
case ProtocolScriptType::wireguard_template: return QLatin1String("template.conf");
|
||||||
|
case ProtocolScriptType::v2ray_client_template: return QLatin1String("template_v2ray_client.json");
|
||||||
|
case ProtocolScriptType::shadowsocks_client_template: return QLatin1String("template_ss_client.json");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ enum ProtocolScriptType {
|
|||||||
configure_container,
|
configure_container,
|
||||||
container_startup,
|
container_startup,
|
||||||
openvpn_template,
|
openvpn_template,
|
||||||
wireguard_template
|
wireguard_template,
|
||||||
|
v2ray_client_template,
|
||||||
|
shadowsocks_client_template
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -516,6 +516,7 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
|||||||
const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Proto::ShadowSocks)).toObject();
|
const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Proto::ShadowSocks)).toObject();
|
||||||
const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Proto::WireGuard)).toObject();
|
const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Proto::WireGuard)).toObject();
|
||||||
const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Proto::Sftp)).toObject();
|
const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Proto::Sftp)).toObject();
|
||||||
|
const QJsonObject &v2RayConfig = config.value(ProtocolProps::protoToString(Proto::V2Ray)).toObject();
|
||||||
//
|
//
|
||||||
|
|
||||||
Vars vars;
|
Vars vars;
|
||||||
@@ -567,6 +568,10 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
|||||||
|
|
||||||
vars.append({{"$WIREGUARD_SERVER_PORT", wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) }});
|
vars.append({{"$WIREGUARD_SERVER_PORT", wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) }});
|
||||||
|
|
||||||
|
// V2Ray vars
|
||||||
|
vars.append({{"$V2RAY_VMESS_PORT", v2RayConfig.value(config_key::port).toString(protocols::v2ray::defaultServerPort) }});
|
||||||
|
vars.append({{"$V2RAY_SOCKS_LOCAL_PORT", v2RayConfig.value(config_key::local_port).toString(protocols::v2ray::defaultLocalPort) }});
|
||||||
|
|
||||||
// IPsec vars
|
// IPsec vars
|
||||||
vars.append({{"$IPSEC_VPN_L2TP_NET", "192.168.42.0/24"}});
|
vars.append({{"$IPSEC_VPN_L2TP_NET", "192.168.42.0/24"}});
|
||||||
vars.append({{"$IPSEC_VPN_L2TP_POOL", "192.168.42.10-192.168.42.250"}});
|
vars.append({{"$IPSEC_VPN_L2TP_POOL", "192.168.42.10-192.168.42.250"}});
|
||||||
|
|||||||
@@ -52,26 +52,25 @@ ErrorCode OpenVpnOverCloakProtocol::start()
|
|||||||
args << "-u";
|
args << "-u";
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug().noquote() << "OpenVpnOverCloakProtocol::start()"
|
qDebug().noquote() << "OpenVpnOverCloakProtocol::start()" << cloakExecPath() << args.join(" ");
|
||||||
<< cloakExecPath() << args.join(" ");
|
|
||||||
|
|
||||||
m_ckProcess.setProcessChannelMode(QProcess::MergedChannels);
|
m_ckProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
|
||||||
m_ckProcess.setProgram(cloakExecPath());
|
m_ckProcess.setProgram(cloakExecPath());
|
||||||
m_ckProcess.setArguments(args);
|
m_ckProcess.setArguments(args);
|
||||||
|
|
||||||
connect(&m_ckProcess, &QProcess::readyReadStandardOutput, this, [this](){
|
connect(&m_ckProcess, &QProcess::readyReadStandardOutput, this, [this]() {
|
||||||
qDebug().noquote() << "ck-client:" << m_ckProcess.readAllStandardOutput();
|
qDebug().noquote() << "ck-client:" << m_ckProcess.readAllStandardOutput();
|
||||||
});
|
});
|
||||||
|
|
||||||
m_errorHandlerConnection = connect(&m_ckProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus){
|
m_errorHandlerConnection = connect(&m_ckProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||||
qDebug().noquote() << "OpenVpnOverCloakProtocol finished, exitCode, exiStatus" << exitCode << exitStatus;
|
qDebug().noquote() << "OpenVpnOverCloakProtocol finished, exitCode, exiStatus" << exitCode << exitStatus;
|
||||||
setConnectionState(VpnProtocol::Disconnected);
|
setConnectionState(VpnProtocol::Disconnected);
|
||||||
if (exitStatus != QProcess::NormalExit){
|
if (exitStatus != QProcess::NormalExit) {
|
||||||
emit protocolError(amnezia::ErrorCode::CloakExecutableCrashed);
|
emit protocolError(amnezia::ErrorCode::CloakExecutableCrashed);
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
if (exitCode !=0 ){
|
if (exitCode !=0 ) {
|
||||||
emit protocolError(amnezia::ErrorCode::InternalError);
|
emit protocolError(amnezia::ErrorCode::InternalError);
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
@@ -84,8 +83,9 @@ ErrorCode OpenVpnOverCloakProtocol::start()
|
|||||||
setConnectionState(VpnConnectionState::Connecting);
|
setConnectionState(VpnConnectionState::Connecting);
|
||||||
|
|
||||||
return OpenVpnProtocol::start();
|
return OpenVpnProtocol::start();
|
||||||
|
} else {
|
||||||
|
return ErrorCode::CloakExecutableMissing;
|
||||||
}
|
}
|
||||||
else return ErrorCode::CloakExecutableMissing;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ QMap<amnezia::Proto, QString> ProtocolProps::protocolHumanNames()
|
|||||||
{Proto::WireGuard, "WireGuard"},
|
{Proto::WireGuard, "WireGuard"},
|
||||||
{Proto::Ikev2, "IKEv2"},
|
{Proto::Ikev2, "IKEv2"},
|
||||||
{Proto::L2tp, "L2TP"},
|
{Proto::L2tp, "L2TP"},
|
||||||
|
{Proto::V2Ray, "V2Ray"},
|
||||||
|
|
||||||
{Proto::TorWebSite, "Web site in Tor network"},
|
{Proto::TorWebSite, "Web site in Tor network"},
|
||||||
{Proto::Dns, "DNS Service"},
|
{Proto::Dns, "DNS Service"},
|
||||||
@@ -96,10 +97,12 @@ amnezia::ServiceType ProtocolProps::protocolService(Proto p)
|
|||||||
case Proto::Cloak : return ServiceType::Vpn;
|
case Proto::Cloak : return ServiceType::Vpn;
|
||||||
case Proto::ShadowSocks : return ServiceType::Vpn;
|
case Proto::ShadowSocks : return ServiceType::Vpn;
|
||||||
case Proto::WireGuard : return ServiceType::Vpn;
|
case Proto::WireGuard : return ServiceType::Vpn;
|
||||||
case Proto::TorWebSite : return ServiceType::Other;
|
case Proto::V2Ray : return ServiceType::Vpn;
|
||||||
|
|
||||||
|
case Proto::TorWebSite : return ServiceType::Other;
|
||||||
case Proto::Dns : return ServiceType::Other;
|
case Proto::Dns : return ServiceType::Other;
|
||||||
case Proto::FileShare : return ServiceType::Other;
|
case Proto::FileShare : return ServiceType::Other;
|
||||||
default: return ServiceType::Other;
|
default: return ServiceType::Other;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,12 +116,13 @@ int ProtocolProps::defaultPort(Proto p)
|
|||||||
case Proto::WireGuard : return 51820;
|
case Proto::WireGuard : return 51820;
|
||||||
case Proto::Ikev2 : return -1;
|
case Proto::Ikev2 : return -1;
|
||||||
case Proto::L2tp : return -1;
|
case Proto::L2tp : return -1;
|
||||||
|
case Proto::V2Ray : return 10086;
|
||||||
|
|
||||||
case Proto::TorWebSite : return -1;
|
case Proto::TorWebSite : return -1;
|
||||||
case Proto::Dns : return 53;
|
case Proto::Dns : return 53;
|
||||||
case Proto::FileShare : return 139;
|
case Proto::FileShare : return 139;
|
||||||
case Proto::Sftp : return 222;
|
case Proto::Sftp : return 222;
|
||||||
default: return -1;
|
default: return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,12 +136,13 @@ bool ProtocolProps::defaultPortChangeable(Proto p)
|
|||||||
case Proto::WireGuard : return true;
|
case Proto::WireGuard : return true;
|
||||||
case Proto::Ikev2 : return false;
|
case Proto::Ikev2 : return false;
|
||||||
case Proto::L2tp : return false;
|
case Proto::L2tp : return false;
|
||||||
|
case Proto::V2Ray : return true;
|
||||||
|
|
||||||
|
|
||||||
case Proto::TorWebSite : return true;
|
case Proto::TorWebSite : return true;
|
||||||
case Proto::Dns : return false;
|
case Proto::Dns : return false;
|
||||||
case Proto::FileShare : return false;
|
case Proto::FileShare : return false;
|
||||||
default: return -1;
|
default: return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +156,7 @@ TransportProto ProtocolProps::defaultTransportProto(Proto p)
|
|||||||
case Proto::WireGuard : return TransportProto::Udp;
|
case Proto::WireGuard : return TransportProto::Udp;
|
||||||
case Proto::Ikev2 : return TransportProto::Udp;
|
case Proto::Ikev2 : return TransportProto::Udp;
|
||||||
case Proto::L2tp : return TransportProto::Udp;
|
case Proto::L2tp : return TransportProto::Udp;
|
||||||
|
case Proto::V2Ray : return TransportProto::Tcp;
|
||||||
// non-vpn
|
// non-vpn
|
||||||
case Proto::TorWebSite : return TransportProto::Tcp;
|
case Proto::TorWebSite : return TransportProto::Tcp;
|
||||||
case Proto::Dns : return TransportProto::Udp;
|
case Proto::Dns : return TransportProto::Udp;
|
||||||
@@ -169,12 +175,13 @@ bool ProtocolProps::defaultTransportProtoChangeable(Proto p)
|
|||||||
case Proto::WireGuard : return false;
|
case Proto::WireGuard : return false;
|
||||||
case Proto::Ikev2 : return false;
|
case Proto::Ikev2 : return false;
|
||||||
case Proto::L2tp : return false;
|
case Proto::L2tp : return false;
|
||||||
|
case Proto::V2Ray : return false;
|
||||||
// non-vpn
|
// non-vpn
|
||||||
case Proto::TorWebSite : return false;
|
case Proto::TorWebSite : return false;
|
||||||
case Proto::Dns : return false;
|
case Proto::Dns : return false;
|
||||||
case Proto::FileShare : return false;
|
case Proto::FileShare : return false;
|
||||||
case Proto::Sftp : return false;
|
case Proto::Sftp : return false;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,12 @@ constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key";
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace v2ray {
|
||||||
|
constexpr char v2rayKeyPath[] = "/opt/amnezia/v2ray/v2ray.key";
|
||||||
|
constexpr char defaultLocalPort[] = "1080";
|
||||||
|
constexpr char defaultServerPort[] = "10086";
|
||||||
|
}
|
||||||
|
|
||||||
namespace sftp {
|
namespace sftp {
|
||||||
constexpr char defaultUserName[] = "sftp_user";
|
constexpr char defaultUserName[] = "sftp_user";
|
||||||
|
|
||||||
@@ -148,6 +154,7 @@ enum Proto {
|
|||||||
WireGuard,
|
WireGuard,
|
||||||
Ikev2,
|
Ikev2,
|
||||||
L2tp,
|
L2tp,
|
||||||
|
V2Ray,
|
||||||
|
|
||||||
// non-vpn
|
// non-vpn
|
||||||
TorWebSite,
|
TorWebSite,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
|
||||||
ShadowSocksVpnProtocol::ShadowSocksVpnProtocol(const QJsonObject &configuration, QObject *parent):
|
ShadowSocksVpnProtocol::ShadowSocksVpnProtocol(const QJsonObject &configuration, QObject *parent):
|
||||||
OpenVpnProtocol(configuration, parent)
|
OpenVpnProtocol(configuration, parent)
|
||||||
{
|
{
|
||||||
readShadowSocksConfiguration(configuration);
|
readShadowSocksConfiguration(configuration);
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,6 @@ ErrorCode ShadowSocksVpnProtocol::start()
|
|||||||
return lastError();
|
return lastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef Q_OS_IOS
|
#ifndef Q_OS_IOS
|
||||||
if (Utils::processIsRunning(Utils::executable("ss-local", false))) {
|
if (Utils::processIsRunning(Utils::executable("ss-local", false))) {
|
||||||
Utils::killProcessByName(Utils::executable("ss-local", false));
|
Utils::killProcessByName(Utils::executable("ss-local", false));
|
||||||
@@ -48,30 +47,28 @@ ErrorCode ShadowSocksVpnProtocol::start()
|
|||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
QStringList args = QStringList() << "-c" << m_shadowSocksCfgFile.fileName();
|
QStringList args = QStringList() << "-c" << m_shadowSocksCfgFile.fileName();
|
||||||
#else
|
#else
|
||||||
QStringList args = QStringList() << "-c" << m_shadowSocksCfgFile.fileName()
|
QStringList args = QStringList() << "-c" << m_shadowSocksCfgFile.fileName() << "--no-delay";
|
||||||
<< "--no-delay";
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
qDebug().noquote() << "ShadowSocksVpnProtocol::start()"
|
qDebug().noquote() << "ShadowSocksVpnProtocol::start()" << shadowSocksExecPath() << args.join(" ");
|
||||||
<< shadowSocksExecPath() << args.join(" ");
|
|
||||||
|
|
||||||
m_ssProcess.setProcessChannelMode(QProcess::MergedChannels);
|
m_ssProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
|
||||||
m_ssProcess.setProgram(shadowSocksExecPath());
|
m_ssProcess.setProgram(shadowSocksExecPath());
|
||||||
m_ssProcess.setArguments(args);
|
m_ssProcess.setArguments(args);
|
||||||
|
|
||||||
connect(&m_ssProcess, &QProcess::readyReadStandardOutput, this, [this](){
|
connect(&m_ssProcess, &QProcess::readyReadStandardOutput, this, [this]() {
|
||||||
qDebug().noquote() << "ss-local:" << m_ssProcess.readAllStandardOutput();
|
qDebug().noquote() << "ss-local:" << m_ssProcess.readAllStandardOutput();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(&m_ssProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus){
|
connect(&m_ssProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||||
qDebug().noquote() << "ShadowSocksVpnProtocol finished, exitCode, exiStatus" << exitCode << exitStatus;
|
qDebug().noquote() << "ShadowSocksVpnProtocol finished, exitCode, exiStatus" << exitCode << exitStatus;
|
||||||
setConnectionState(VpnProtocol::Disconnected);
|
setConnectionState(VpnProtocol::Disconnected);
|
||||||
if (exitStatus != QProcess::NormalExit){
|
if (exitStatus != QProcess::NormalExit) {
|
||||||
emit protocolError(amnezia::ErrorCode::ShadowSocksExecutableCrashed);
|
emit protocolError(amnezia::ErrorCode::ShadowSocksExecutableCrashed);
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
if (exitCode !=0 ){
|
if (exitCode !=0 ) {
|
||||||
emit protocolError(amnezia::ErrorCode::InternalError);
|
emit protocolError(amnezia::ErrorCode::InternalError);
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
@@ -84,8 +81,9 @@ ErrorCode ShadowSocksVpnProtocol::start()
|
|||||||
setConnectionState(VpnConnectionState::Connecting);
|
setConnectionState(VpnConnectionState::Connecting);
|
||||||
|
|
||||||
return OpenVpnProtocol::start();
|
return OpenVpnProtocol::start();
|
||||||
|
} else {
|
||||||
|
return ErrorCode::ShadowSocksExecutableMissing;
|
||||||
}
|
}
|
||||||
else return ErrorCode::ShadowSocksExecutableMissing;
|
|
||||||
#else
|
#else
|
||||||
return ErrorCode::NotImplementedError;
|
return ErrorCode::NotImplementedError;
|
||||||
#endif
|
#endif
|
||||||
@@ -116,17 +114,5 @@ QString ShadowSocksVpnProtocol::shadowSocksExecPath()
|
|||||||
|
|
||||||
void ShadowSocksVpnProtocol::readShadowSocksConfiguration(const QJsonObject &configuration)
|
void ShadowSocksVpnProtocol::readShadowSocksConfiguration(const QJsonObject &configuration)
|
||||||
{
|
{
|
||||||
QJsonObject shadowSocksConfig = configuration.value(ProtocolProps::key_proto_config_data(Proto::ShadowSocks)).toObject();
|
m_shadowSocksConfig = configuration.value(ProtocolProps::key_proto_config_data(Proto::ShadowSocks)).toObject();
|
||||||
bool isLocalPortConvertOk = false;
|
|
||||||
bool isServerPortConvertOk = false;
|
|
||||||
int localPort = shadowSocksConfig.value("local_port").toString().toInt(&isLocalPortConvertOk);
|
|
||||||
int serverPort = shadowSocksConfig.value("server_port").toString().toInt(&isServerPortConvertOk);
|
|
||||||
if (!isLocalPortConvertOk) {
|
|
||||||
qDebug() << "Error when converting local_port field in ShadowSocks config";
|
|
||||||
} else if (!isServerPortConvertOk) {
|
|
||||||
qDebug() << "Error when converting server_port field in ShadowSocks config";
|
|
||||||
}
|
|
||||||
shadowSocksConfig["local_port"] = localPort;
|
|
||||||
shadowSocksConfig["server_port"] = serverPort;
|
|
||||||
m_shadowSocksConfig = shadowSocksConfig;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#ifndef SHADOWSOCKSVPNPROTOCOL_H
|
#ifndef SHADOWSOCKSVPNPROTOCOL_H
|
||||||
#define SHADOWSOCKSVPNPROTOCOL_H
|
#define SHADOWSOCKSVPNPROTOCOL_H
|
||||||
|
|
||||||
#include "openvpnprotocol.h"
|
|
||||||
#include "QProcess"
|
#include "QProcess"
|
||||||
#include "containers/containers_defs.h"
|
|
||||||
|
#include "openvpnprotocol.h"
|
||||||
|
|
||||||
class ShadowSocksVpnProtocol : public OpenVpnProtocol
|
class ShadowSocksVpnProtocol : public OpenVpnProtocol
|
||||||
{
|
{
|
||||||
@@ -14,20 +14,18 @@ public:
|
|||||||
ErrorCode start() override;
|
ErrorCode start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
protected:
|
|
||||||
void readShadowSocksConfiguration(const QJsonObject &configuration);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QJsonObject m_shadowSocksConfig;
|
QJsonObject m_shadowSocksConfig;
|
||||||
|
|
||||||
private:
|
void readShadowSocksConfiguration(const QJsonObject &configuration);
|
||||||
static QString shadowSocksExecPath();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifndef Q_OS_IOS
|
#ifndef Q_OS_IOS
|
||||||
QProcess m_ssProcess;
|
QProcess m_ssProcess;
|
||||||
#endif
|
#endif
|
||||||
QTemporaryFile m_shadowSocksCfgFile;
|
QTemporaryFile m_shadowSocksCfgFile;
|
||||||
|
|
||||||
|
static QString shadowSocksExecPath();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHADOWSOCKSVPNPROTOCOL_H
|
#endif // SHADOWSOCKSVPNPROTOCOL_H
|
||||||
|
|||||||
@@ -0,0 +1,108 @@
|
|||||||
|
#include "v2rayprotocol.h"
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
|
V2RayProtocol::V2RayProtocol(const QJsonObject &configuration, QObject *parent) : OpenVpnProtocol(configuration, parent)
|
||||||
|
{
|
||||||
|
writeV2RayConfiguration(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
V2RayProtocol::~V2RayProtocol()
|
||||||
|
{
|
||||||
|
qDebug() << "V2RayProtocol::~V2RayProtocol";
|
||||||
|
V2RayProtocol::stop();
|
||||||
|
QThread::msleep(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode V2RayProtocol::start()
|
||||||
|
{
|
||||||
|
#ifndef Q_OS_IOS
|
||||||
|
if (!QFileInfo::exists(v2RayExecPath())) {
|
||||||
|
setLastError(ErrorCode::V2RayExecutableMissing);
|
||||||
|
return lastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Utils::processIsRunning(Utils::executable("v2ray", false))) {
|
||||||
|
Utils::killProcessByName(Utils::executable("v2ray", false));
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList args = QStringList() << "-c" << m_v2RayConfigFile.fileName();
|
||||||
|
|
||||||
|
qDebug().noquote() << "V2RayProtocol::start()" << v2RayExecPath() << args.join(" ");
|
||||||
|
|
||||||
|
m_v2RayProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
|
||||||
|
m_v2RayProcess.setProgram(v2RayExecPath());
|
||||||
|
m_v2RayProcess.setArguments(args);
|
||||||
|
|
||||||
|
connect(&m_v2RayProcess, &QProcess::readyReadStandardOutput, this, [this]() {
|
||||||
|
qDebug().noquote() << "V2Ray:" << m_v2RayProcess.readAllStandardOutput();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(&m_v2RayProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||||
|
qDebug().noquote() << "V2RayProtocol finished, exitCode, exiStatus" << exitCode << exitStatus;
|
||||||
|
setConnectionState(VpnProtocol::Disconnected);
|
||||||
|
if (exitStatus != QProcess::NormalExit) {
|
||||||
|
emit protocolError(amnezia::ErrorCode::V2RayExecutableCrashed);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
if (exitCode != 0 ) {
|
||||||
|
emit protocolError(amnezia::ErrorCode::InternalError);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_v2RayProcess.start();
|
||||||
|
m_v2RayProcess.waitForStarted();
|
||||||
|
|
||||||
|
if (m_v2RayProcess.state() == QProcess::ProcessState::Running) {
|
||||||
|
setConnectionState(VpnConnectionState::Connecting);
|
||||||
|
|
||||||
|
return OpenVpnProtocol::start();
|
||||||
|
} else {
|
||||||
|
return ErrorCode::V2RayExecutableMissing;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return ErrorCode::NotImplementedError;
|
||||||
|
#endif
|
||||||
|
return ErrorCode::NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
void V2RayProtocol::stop()
|
||||||
|
{
|
||||||
|
OpenVpnProtocol::stop();
|
||||||
|
|
||||||
|
qDebug() << "V2RayProtocol::stop()";
|
||||||
|
#ifndef Q_OS_IOS
|
||||||
|
m_v2RayProcess.terminate();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
Utils::signalCtrl(m_v2RayProcess.processId(), CTRL_C_EVENT);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void V2RayProtocol::writeV2RayConfiguration(const QJsonObject &configuration)
|
||||||
|
{
|
||||||
|
m_v2RayConfig = configuration.value(ProtocolProps::key_proto_config_data(Proto::V2Ray)).toObject();
|
||||||
|
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
m_v2RayConfigFile.setAutoRemove(false);
|
||||||
|
#endif
|
||||||
|
m_v2RayConfigFile.open();
|
||||||
|
m_v2RayConfigFile.write(QJsonDocument(m_v2RayConfig).toJson());
|
||||||
|
m_v2RayConfigFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString V2RayProtocol::v2RayExecPath() const
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
return Utils::executable(QString("v2ray/v2ray"), true);
|
||||||
|
#else
|
||||||
|
return Utils::executable(QString("v2ray"), true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#ifndef V2RAYPROTOCOL_H
|
||||||
|
#define V2RAYPROTOCOL_H
|
||||||
|
|
||||||
|
#include "QProcess"
|
||||||
|
#include "QTemporaryFile"
|
||||||
|
|
||||||
|
#include "openvpnprotocol.h"
|
||||||
|
|
||||||
|
class V2RayProtocol : public OpenVpnProtocol
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
V2RayProtocol(const QJsonObject& configuration, QObject* parent = nullptr);
|
||||||
|
virtual ~V2RayProtocol() override;
|
||||||
|
|
||||||
|
ErrorCode start() override;
|
||||||
|
void stop() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QJsonObject m_v2RayConfig;
|
||||||
|
QTemporaryFile m_v2RayConfigFile;
|
||||||
|
#ifndef Q_OS_IOS
|
||||||
|
QProcess m_v2RayProcess;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void writeV2RayConfiguration(const QJsonObject &configuration);
|
||||||
|
|
||||||
|
const QString v2RayExecPath() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // V2RAYPROTOCOL_H
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "shadowsocksvpnprotocol.h"
|
#include "shadowsocksvpnprotocol.h"
|
||||||
#include "openvpnovercloakprotocol.h"
|
#include "openvpnovercloakprotocol.h"
|
||||||
#include "wireguardprotocol.h"
|
#include "wireguardprotocol.h"
|
||||||
|
#include "v2rayprotocol.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
@@ -114,6 +115,7 @@ VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject&
|
|||||||
case DockerContainer::Cloak: return new OpenVpnOverCloakProtocol(configuration);
|
case DockerContainer::Cloak: return new OpenVpnOverCloakProtocol(configuration);
|
||||||
case DockerContainer::ShadowSocks: return new ShadowSocksVpnProtocol(configuration);
|
case DockerContainer::ShadowSocks: return new ShadowSocksVpnProtocol(configuration);
|
||||||
case DockerContainer::WireGuard: return new WireguardProtocol(configuration);
|
case DockerContainer::WireGuard: return new WireguardProtocol(configuration);
|
||||||
|
case DockerContainer::V2Ray: return new V2RayProtocol(configuration);
|
||||||
#endif
|
#endif
|
||||||
default: return nullptr;
|
default: return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,5 +166,13 @@
|
|||||||
<file>ui/qml/Pages/PageAdvancedServerSettings.qml</file>
|
<file>ui/qml/Pages/PageAdvancedServerSettings.qml</file>
|
||||||
<file>ui/qml/Controls/PopupWarning.qml</file>
|
<file>ui/qml/Controls/PopupWarning.qml</file>
|
||||||
<file>ui/qml/Controls/PopupWithTextField.qml</file>
|
<file>ui/qml/Controls/PopupWithTextField.qml</file>
|
||||||
|
<file>ui/qml/Pages/Protocols/PageProtoV2Ray.qml</file>
|
||||||
|
<file>server_scripts/openvpn_v2ray_vmess/configure_container.sh</file>
|
||||||
|
<file>server_scripts/openvpn_v2ray_vmess/Dockerfile</file>
|
||||||
|
<file>server_scripts/openvpn_v2ray_vmess/run_container.sh</file>
|
||||||
|
<file>server_scripts/openvpn_v2ray_vmess/start.sh</file>
|
||||||
|
<file>server_scripts/openvpn_v2ray_vmess/template.ovpn</file>
|
||||||
|
<file>server_scripts/openvpn_v2ray_vmess/template_v2ray_client.json</file>
|
||||||
|
<file>server_scripts/openvpn_shadowsocks/template_ss_client.json</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
sudo docker build -t $CONTAINER_NAME $DOCKERFILE_FOLDER --build-arg SERVER_ARCH=$(uname -m)
|
sudo docker build --network host -t $CONTAINER_NAME $DOCKERFILE_FOLDER --build-arg SERVER_ARCH=$(uname -m)
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"local_port": $SHADOWSOCKS_LOCAL_PORT,
|
||||||
|
"method": "$SHADOWSOCKS_CIPHER",
|
||||||
|
"password": "$SHADOWSOCKS_PASSWORD",
|
||||||
|
"server": "$REMOTE_HOST",
|
||||||
|
"server_port": $SHADOWSOCKS_SERVER_PORT,
|
||||||
|
"timeout": 60
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
FROM alpine:3.15
|
||||||
|
|
||||||
|
LABEL maintainer="AmneziaVPN"
|
||||||
|
|
||||||
|
#Install required packages
|
||||||
|
RUN apk add --no-cache curl openvpn easy-rsa bash netcat-openbsd dumb-init rng-tools
|
||||||
|
RUN apk --update upgrade --no-cache
|
||||||
|
|
||||||
|
ENV EASYRSA_BATCH 1
|
||||||
|
ENV PATH="/usr/share/easy-rsa:${PATH}"
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
RUN apk add --no-cache v2ray
|
||||||
|
|
||||||
|
# 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 [ "" ]
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
cat > /opt/amnezia/openvpn/server.conf <<EOF
|
||||||
|
port $OPENVPN_PORT
|
||||||
|
proto $OPENVPN_TRANSPORT_PROTO
|
||||||
|
dev tun
|
||||||
|
ca /opt/amnezia/openvpn/ca.crt
|
||||||
|
cert /opt/amnezia/openvpn/AmneziaReq.crt
|
||||||
|
key /opt/amnezia/openvpn/AmneziaReq.key
|
||||||
|
dh /opt/amnezia/openvpn/dh.pem
|
||||||
|
server $OPENVPN_SUBNET_IP $OPENVPN_SUBNET_MASK
|
||||||
|
ifconfig-pool-persist ipp.txt
|
||||||
|
duplicate-cn
|
||||||
|
keepalive 10 120
|
||||||
|
$OPENVPN_NCP_DISABLE
|
||||||
|
cipher $OPENVPN_CIPHER
|
||||||
|
data-ciphers $OPENVPN_CIPHER
|
||||||
|
auth $OPENVPN_HASH
|
||||||
|
user nobody
|
||||||
|
group nobody
|
||||||
|
persist-key
|
||||||
|
persist-tun
|
||||||
|
status openvpn-status.log
|
||||||
|
verb 1
|
||||||
|
tls-server
|
||||||
|
tls-version-min 1.2
|
||||||
|
$OPENVPN_TLS_AUTH
|
||||||
|
$OPENVPN_ADDITIONAL_SERVER_CONFIG
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# V2RAY_VMESS_PORT port for v2ray listening, for example 10086.
|
||||||
|
# V2RAY_VMESS_CLIENT_UUID client's id and secret as UUID.
|
||||||
|
# UUID is 32 hexadecimal digits /([0-9a-f]-?){32}/ (128 bit value).
|
||||||
|
|
||||||
|
mkdir -p /opt/amnezia/v2ray
|
||||||
|
cd /opt/amnezia/v2ray
|
||||||
|
V2RAY_VMESS_CLIENT_UUID=$(cat /proc/sys/kernel/random/uuid)
|
||||||
|
echo $V2RAY_VMESS_CLIENT_UUID > /opt/amnezia/v2ray/v2ray.key
|
||||||
|
|
||||||
|
cat > /opt/amnezia/v2ray/v2ray-server.json <<EOF
|
||||||
|
{
|
||||||
|
"log": {
|
||||||
|
"loglevel": "None"
|
||||||
|
},
|
||||||
|
"inbounds": [
|
||||||
|
{
|
||||||
|
"port": $V2RAY_VMESS_PORT,
|
||||||
|
"protocol": "vmess",
|
||||||
|
"settings": {
|
||||||
|
"clients": [
|
||||||
|
{
|
||||||
|
"id": "$V2RAY_VMESS_CLIENT_UUID",
|
||||||
|
"level": 1,
|
||||||
|
"alterId": 64
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outbounds": [
|
||||||
|
{
|
||||||
|
"protocol": "freedom",
|
||||||
|
"settings": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"policy": {
|
||||||
|
"levels": {
|
||||||
|
"0": {"uplinkOnly": 0}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Run container
|
||||||
|
sudo docker run -d \
|
||||||
|
--log-driver none \
|
||||||
|
--restart always \
|
||||||
|
--cap-add=NET_ADMIN \
|
||||||
|
-p $V2RAY_VMESS_PORT:$V2RAY_VMESS_PORT/tcp \
|
||||||
|
--name $CONTAINER_NAME $CONTAINER_NAME
|
||||||
|
|
||||||
|
sudo docker network connect amnezia-dns-net $CONTAINER_NAME
|
||||||
|
|
||||||
|
# Create tun device if not exist
|
||||||
|
sudo docker exec -i $CONTAINER_NAME bash -c 'mkdir -p /dev/net; if [ ! -c /dev/net/tun ]; then mknod /dev/net/tun c 10 200; fi'
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
|
||||||
|
# OpenVPN config
|
||||||
|
sudo docker exec -i $CONTAINER_NAME bash -c 'mkdir -p /opt/amnezia/openvpn/clients; \
|
||||||
|
cd /opt/amnezia/openvpn && easyrsa init-pki; \
|
||||||
|
cd /opt/amnezia/openvpn && easyrsa gen-dh; \
|
||||||
|
cd /opt/amnezia/openvpn && cp pki/dh.pem /opt/amnezia/openvpn && easyrsa build-ca nopass << EOF yes EOF && easyrsa gen-req AmneziaReq nopass << EOF2 yes EOF2;\
|
||||||
|
cd /opt/amnezia/openvpn && easyrsa sign-req server AmneziaReq << EOF3 yes EOF3;\
|
||||||
|
cd /opt/amnezia/openvpn && openvpn --genkey --secret ta.key << EOF4;\
|
||||||
|
cd /opt/amnezia/openvpn && cp pki/ca.crt pki/issued/AmneziaReq.crt pki/private/AmneziaReq.key /opt/amnezia/openvpn'
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#!/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
|
||||||
|
|
||||||
|
if [ ! -c /dev/net/tun ]; then mkdir -p /dev/net; mknod /dev/net/tun c 10 200; fi
|
||||||
|
|
||||||
|
# Allow traffic on the TUN interface.
|
||||||
|
iptables -A INPUT -i tun0 -j ACCEPT
|
||||||
|
iptables -A FORWARD -i tun0 -j ACCEPT
|
||||||
|
iptables -A OUTPUT -o tun0 -j ACCEPT
|
||||||
|
|
||||||
|
# Allow forwarding traffic only from the VPN.
|
||||||
|
iptables -A FORWARD -i tun0 -o eth0 -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -j ACCEPT
|
||||||
|
iptables -A FORWARD -i tun0 -o eth1 -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -j ACCEPT
|
||||||
|
|
||||||
|
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||||
|
|
||||||
|
iptables -t nat -A POSTROUTING -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -o eth0 -j MASQUERADE
|
||||||
|
iptables -t nat -A POSTROUTING -s $OPENVPN_SUBNET_IP/$OPENVPN_SUBNET_CIDR -o eth1 -j MASQUERADE
|
||||||
|
|
||||||
|
# kill daemons in case of restart
|
||||||
|
killall -KILL openvpn
|
||||||
|
|
||||||
|
# start daemons if configured
|
||||||
|
if [ -f /opt/amnezia/openvpn/ca.crt ]; then (openvpn --config /opt/amnezia/openvpn/server.conf --daemon); fi
|
||||||
|
if [ -f /opt/amnezia/v2ray/v2ray-server.json ]; then (v2ray -config /opt/amnezia/v2ray/v2ray-server.json &); fi
|
||||||
|
|
||||||
|
tail -f /dev/null
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
client
|
||||||
|
dev tun
|
||||||
|
proto $OPENVPN_TRANSPORT_PROTO
|
||||||
|
resolv-retry infinite
|
||||||
|
nobind
|
||||||
|
persist-key
|
||||||
|
persist-tun
|
||||||
|
$OPENVPN_NCP_DISABLE
|
||||||
|
cipher $OPENVPN_CIPHER
|
||||||
|
auth $OPENVPN_HASH
|
||||||
|
verb 3
|
||||||
|
tls-client
|
||||||
|
tls-version-min 1.2
|
||||||
|
key-direction 1
|
||||||
|
remote-cert-tls server
|
||||||
|
redirect-gateway def1 bypass-dhcp
|
||||||
|
|
||||||
|
dhcp-option DNS $PRIMARY_DNS
|
||||||
|
dhcp-option DNS $SECONDARY_DNS
|
||||||
|
block-outside-dns
|
||||||
|
|
||||||
|
socks-proxy 127.0.0.1 $V2RAY_SOCKS_LOCAL_PORT
|
||||||
|
route $REMOTE_HOST 255.255.255.255 net_gateway
|
||||||
|
remote 127.0.0.1 $OPENVPN_PORT
|
||||||
|
|
||||||
|
$OPENVPN_ADDITIONAL_CLIENT_CONFIG
|
||||||
|
|
||||||
|
<ca>
|
||||||
|
$OPENVPN_CA_CERT
|
||||||
|
</ca>
|
||||||
|
<cert>
|
||||||
|
$OPENVPN_CLIENT_CERT
|
||||||
|
</cert>
|
||||||
|
<key>
|
||||||
|
$OPENVPN_PRIV_KEY
|
||||||
|
</key>
|
||||||
|
<tls-auth>
|
||||||
|
$OPENVPN_TA_KEY
|
||||||
|
</tls-auth>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"inbounds": [
|
||||||
|
{
|
||||||
|
"listen": "127.0.0.1",
|
||||||
|
"port": $V2RAY_SOCKS_LOCAL_PORT,
|
||||||
|
"protocol": "socks",
|
||||||
|
"settings": {
|
||||||
|
"auth": "noauth",
|
||||||
|
"udp": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outbounds": [
|
||||||
|
{
|
||||||
|
"protocol": "vmess",
|
||||||
|
"settings": {
|
||||||
|
"vnext": [
|
||||||
|
{
|
||||||
|
"address": "$REMOTE_HOST",
|
||||||
|
"port": $V2RAY_VMESS_PORT,
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"id": "$V2RAY_VMESS_CLIENT_UUID"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -55,6 +55,7 @@ public:
|
|||||||
friend class ShadowSocksLogic;
|
friend class ShadowSocksLogic;
|
||||||
friend class CloakLogic;
|
friend class CloakLogic;
|
||||||
friend class UiLogic;
|
friend class UiLogic;
|
||||||
|
friend class V2RayLogic;
|
||||||
|
|
||||||
void onUpdatePage() override;
|
void onUpdatePage() override;
|
||||||
ErrorCode doInstallAction(const std::function<ErrorCode()> &action);
|
ErrorCode doInstallAction(const std::function<ErrorCode()> &action);
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ void OpenVpnLogic::onPushButtonSaveClicked()
|
|||||||
auto installAction = [this, containerConfig, &newContainerConfig]() {
|
auto installAction = [this, containerConfig, &newContainerConfig]() {
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
return serverController.updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
|
return serverController.updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
|
||||||
uiLogic()->m_selectedDockerContainer, containerConfig, newContainerConfig);
|
uiLogic()->m_selectedDockerContainer, containerConfig, newContainerConfig);
|
||||||
};
|
};
|
||||||
|
|
||||||
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction, pageFunc, progressBarFunc,
|
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction, pageFunc, progressBarFunc,
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ QJsonObject ShadowSocksLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
|
|||||||
void ShadowSocksLogic::onPushButtonSaveClicked()
|
void ShadowSocksLogic::onPushButtonSaveClicked()
|
||||||
{
|
{
|
||||||
QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, Proto::ShadowSocks);
|
QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, Proto::ShadowSocks);
|
||||||
|
protocolConfig = getProtocolConfigFromPage(protocolConfig);
|
||||||
|
|
||||||
QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer);
|
QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer);
|
||||||
QJsonObject newContainerConfig = containerConfig;
|
QJsonObject newContainerConfig = containerConfig;
|
||||||
@@ -108,7 +109,7 @@ void ShadowSocksLogic::onPushButtonSaveClicked()
|
|||||||
auto installAction = [this, containerConfig, &newContainerConfig]() {
|
auto installAction = [this, containerConfig, &newContainerConfig]() {
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
return serverController.updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
|
return serverController.updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
|
||||||
uiLogic()->m_selectedDockerContainer, containerConfig, newContainerConfig);
|
uiLogic()->m_selectedDockerContainer, containerConfig, newContainerConfig);
|
||||||
};
|
};
|
||||||
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction, pageFunc, progressBarFunc,
|
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction, pageFunc, progressBarFunc,
|
||||||
saveButtonFunc, waitInfoFunc,
|
saveButtonFunc, waitInfoFunc,
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
#include "V2RayLogic.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "core/servercontroller.h"
|
||||||
|
#include "ui/pages_logic/ServerConfiguringProgressLogic.h"
|
||||||
|
#include "ui/uilogic.h"
|
||||||
|
|
||||||
|
using namespace amnezia;
|
||||||
|
using namespace PageEnumNS;
|
||||||
|
|
||||||
|
V2RayLogic::V2RayLogic(UiLogic *logic, QObject *parent):
|
||||||
|
PageProtocolLogicBase(logic, parent),
|
||||||
|
m_lineEditServerPortText{},
|
||||||
|
m_pushButtonSaveVisible{false},
|
||||||
|
m_progressBarResetVisible{false},
|
||||||
|
m_lineEditServerPortEnabled{false},
|
||||||
|
m_labelInfoVisible{true},
|
||||||
|
m_labelInfoText{},
|
||||||
|
m_progressBarResetValue{0},
|
||||||
|
m_progressBarResetMaximium{100},
|
||||||
|
m_lineEditLocalPortEnabled{false},
|
||||||
|
m_lineEditLocalPortText{}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void V2RayLogic::updateProtocolPage(const QJsonObject &v2RayConfig, DockerContainer container, bool haveAuthData)
|
||||||
|
{
|
||||||
|
set_pageEnabled(haveAuthData);
|
||||||
|
set_pushButtonSaveVisible(haveAuthData);
|
||||||
|
set_progressBarResetVisible(haveAuthData);
|
||||||
|
|
||||||
|
set_lineEditServerPortText(v2RayConfig.value(config_key::port).toString(protocols::v2ray::defaultServerPort));
|
||||||
|
set_lineEditServerPortEnabled(container == DockerContainer::V2Ray);
|
||||||
|
|
||||||
|
set_lineEditLocalPortText(v2RayConfig.value(config_key::local_port).toString(protocols::v2ray::defaultLocalPort));
|
||||||
|
set_lineEditLocalPortEnabled(container == DockerContainer::V2Ray);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject V2RayLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
|
||||||
|
{
|
||||||
|
oldConfig.insert(config_key::port, lineEditServerPortText());
|
||||||
|
oldConfig.insert(config_key::local_port, lineEditLocalPortText());
|
||||||
|
return oldConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
void V2RayLogic::onPushButtonSaveClicked()
|
||||||
|
{
|
||||||
|
QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, Proto::V2Ray);
|
||||||
|
protocolConfig = getProtocolConfigFromPage(protocolConfig);
|
||||||
|
|
||||||
|
QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer);
|
||||||
|
QJsonObject newContainerConfig = containerConfig;
|
||||||
|
newContainerConfig.insert(ProtocolProps::protoToString(Proto::V2Ray), protocolConfig);
|
||||||
|
ServerConfiguringProgressLogic::PageFunc pageFunc;
|
||||||
|
pageFunc.setEnabledFunc = [this] (bool enabled) -> void {
|
||||||
|
set_pageEnabled(enabled);
|
||||||
|
};
|
||||||
|
ServerConfiguringProgressLogic::ButtonFunc saveButtonFunc;
|
||||||
|
saveButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
|
||||||
|
set_pushButtonSaveVisible(visible);
|
||||||
|
};
|
||||||
|
ServerConfiguringProgressLogic::LabelFunc waitInfoFunc;
|
||||||
|
waitInfoFunc.setVisibleFunc = [this] (bool visible) -> void {
|
||||||
|
set_labelInfoVisible(visible);
|
||||||
|
};
|
||||||
|
waitInfoFunc.setTextFunc = [this] (const QString& text) -> void {
|
||||||
|
set_labelInfoText(text);
|
||||||
|
};
|
||||||
|
ServerConfiguringProgressLogic::ProgressFunc progressBarFunc;
|
||||||
|
progressBarFunc.setVisibleFunc = [this] (bool visible) -> void {
|
||||||
|
set_progressBarResetVisible(visible);
|
||||||
|
};
|
||||||
|
progressBarFunc.setValueFunc = [this] (int value) -> void {
|
||||||
|
set_progressBarResetValue(value);
|
||||||
|
};
|
||||||
|
progressBarFunc.getValueFunc = [this] (void) -> int {
|
||||||
|
return progressBarResetValue();
|
||||||
|
};
|
||||||
|
progressBarFunc.getMaximiumFunc = [this] (void) -> int {
|
||||||
|
return progressBarResetMaximium();
|
||||||
|
};
|
||||||
|
progressBarFunc.setTextVisibleFunc = [this] (bool visible) -> void {
|
||||||
|
set_progressBarTextVisible(visible);
|
||||||
|
};
|
||||||
|
progressBarFunc.setTextFunc = [this] (const QString& text) -> void {
|
||||||
|
set_progressBarText(text);
|
||||||
|
};
|
||||||
|
|
||||||
|
ServerConfiguringProgressLogic::LabelFunc busyInfoFuncy;
|
||||||
|
busyInfoFuncy.setTextFunc = [this] (const QString& text) -> void {
|
||||||
|
set_labelServerBusyText(text);
|
||||||
|
};
|
||||||
|
busyInfoFuncy.setVisibleFunc = [this] (bool visible) -> void {
|
||||||
|
set_labelServerBusyVisible(visible);
|
||||||
|
};
|
||||||
|
|
||||||
|
ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc;
|
||||||
|
cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
|
||||||
|
set_pushButtonCancelVisible(visible);
|
||||||
|
};
|
||||||
|
|
||||||
|
progressBarFunc.setTextVisibleFunc(true);
|
||||||
|
progressBarFunc.setTextFunc(QString("Configuring..."));
|
||||||
|
|
||||||
|
auto installAction = [this, containerConfig, &newContainerConfig]() {
|
||||||
|
ServerController serverController(m_settings);
|
||||||
|
return serverController.updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
|
||||||
|
uiLogic()->m_selectedDockerContainer, containerConfig, newContainerConfig);
|
||||||
|
};
|
||||||
|
|
||||||
|
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction, pageFunc, progressBarFunc,
|
||||||
|
saveButtonFunc, waitInfoFunc,
|
||||||
|
busyInfoFuncy, cancelButtonFunc);
|
||||||
|
|
||||||
|
if (!e) {
|
||||||
|
m_settings->setContainerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, newContainerConfig);
|
||||||
|
m_settings->clearLastConnectionConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer);
|
||||||
|
}
|
||||||
|
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->m_selectedServerIndex << uiLogic()->m_selectedDockerContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void V2RayLogic::onPushButtonCancelClicked()
|
||||||
|
{
|
||||||
|
emit uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->cancelDoInstallAction(true);
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef V2RAYLOGIC_H
|
||||||
|
#define V2RAYLOGIC_H
|
||||||
|
|
||||||
|
#include "PageProtocolLogicBase.h"
|
||||||
|
|
||||||
|
class UiLogic;
|
||||||
|
|
||||||
|
class V2RayLogic : public PageProtocolLogicBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
AUTO_PROPERTY(bool, lineEditServerPortEnabled)
|
||||||
|
AUTO_PROPERTY(QString, lineEditServerPortText)
|
||||||
|
|
||||||
|
AUTO_PROPERTY(bool, lineEditLocalPortEnabled)
|
||||||
|
AUTO_PROPERTY(QString, lineEditLocalPortText)
|
||||||
|
|
||||||
|
AUTO_PROPERTY(bool, labelInfoVisible)
|
||||||
|
AUTO_PROPERTY(QString, labelInfoText)
|
||||||
|
|
||||||
|
AUTO_PROPERTY(int, progressBarResetValue)
|
||||||
|
AUTO_PROPERTY(int, progressBarResetMaximium)
|
||||||
|
AUTO_PROPERTY(bool, progressBarResetVisible)
|
||||||
|
AUTO_PROPERTY(bool, progressBarTextVisible)
|
||||||
|
AUTO_PROPERTY(QString, progressBarText)
|
||||||
|
|
||||||
|
AUTO_PROPERTY(bool, labelServerBusyVisible)
|
||||||
|
AUTO_PROPERTY(QString, labelServerBusyText)
|
||||||
|
|
||||||
|
AUTO_PROPERTY(bool, pushButtonSaveVisible)
|
||||||
|
AUTO_PROPERTY(bool, pushButtonCancelVisible)
|
||||||
|
|
||||||
|
public:
|
||||||
|
Q_INVOKABLE void onPushButtonSaveClicked();
|
||||||
|
Q_INVOKABLE void onPushButtonCancelClicked();
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit V2RayLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
||||||
|
~V2RayLogic() = default;
|
||||||
|
|
||||||
|
void updateProtocolPage(const QJsonObject &v2rayConfig, DockerContainer container, bool haveAuthData) override;
|
||||||
|
QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
UiLogic *m_uiLogic;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // V2RAYLOGIC_H
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import ProtocolEnum 1.0
|
||||||
|
import "../"
|
||||||
|
import "../../Controls"
|
||||||
|
import "../../Config"
|
||||||
|
|
||||||
|
PageProtocolBase {
|
||||||
|
id: root
|
||||||
|
protocol: ProtocolEnum.V2Ray
|
||||||
|
logic: UiLogic.protocolLogic(protocol)
|
||||||
|
|
||||||
|
BackButton {
|
||||||
|
id: back
|
||||||
|
enabled: !logic.pushButtonCancelVisible
|
||||||
|
}
|
||||||
|
|
||||||
|
Caption {
|
||||||
|
id: caption
|
||||||
|
text: qsTr("V2Ray Settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
enabled: logic.pageEnabled
|
||||||
|
anchors.top: caption.bottom
|
||||||
|
anchors.left: root.left
|
||||||
|
anchors.right: root.right
|
||||||
|
anchors.bottom: pb_save.top
|
||||||
|
anchors.margins: 20
|
||||||
|
anchors.topMargin: 10
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
LabelType {
|
||||||
|
Layout.preferredWidth: 0.3 * root.width - 10
|
||||||
|
height: 31
|
||||||
|
text: qsTr("Port")
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 31
|
||||||
|
text: logic.lineEditServerPortText
|
||||||
|
onEditingFinished: {
|
||||||
|
logic.lineEditServerPortText = text
|
||||||
|
}
|
||||||
|
enabled: logic.lineEditServerPortEnabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
LabelType {
|
||||||
|
Layout.preferredWidth: 0.3 * root.width - 10
|
||||||
|
height: 31
|
||||||
|
text: qsTr("Local port")
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 31
|
||||||
|
text: logic.lineEditLocalPortText
|
||||||
|
onEditingFinished: {
|
||||||
|
logic.lineEditLocalPortText = text
|
||||||
|
}
|
||||||
|
enabled: logic.lineEditLocalPortEnabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelType {
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
Layout.maximumWidth: parent.width
|
||||||
|
Layout.fillWidth: true
|
||||||
|
visible: logic.labelServerBusyVisible
|
||||||
|
text: logic.labelServerBusyText
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelType {
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
Layout.maximumWidth: parent.width
|
||||||
|
Layout.fillWidth: true
|
||||||
|
visible: logic.labelInfoVisible
|
||||||
|
text: logic.labelInfoText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgressBar {
|
||||||
|
id: progressBar_reset
|
||||||
|
anchors.fill: pb_save
|
||||||
|
from: 0
|
||||||
|
to: logic.progressBarResetMaximium
|
||||||
|
value: logic.progressBarResetValue
|
||||||
|
visible: logic.progressBarResetVisible
|
||||||
|
background: Rectangle {
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: parent.height
|
||||||
|
color: "#100A44"
|
||||||
|
radius: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Item {
|
||||||
|
implicitWidth: parent.width
|
||||||
|
implicitHeight: parent.height
|
||||||
|
Rectangle {
|
||||||
|
width: progressBar_reset.visualPosition * parent.width
|
||||||
|
height: parent.height
|
||||||
|
radius: 4
|
||||||
|
color: Qt.rgba(255, 255, 255, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LabelType {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: logic.progressBarText
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
font.family: "Lato"
|
||||||
|
font.styleName: "normal"
|
||||||
|
font.pixelSize: 16
|
||||||
|
color: "#D4D4D4"
|
||||||
|
visible: logic.progressBarTextVisible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BlueButtonType {
|
||||||
|
id: pb_save
|
||||||
|
enabled: logic.pageEnabled
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.bottom: root.bottom
|
||||||
|
anchors.bottomMargin: 20
|
||||||
|
width: root.width - 60
|
||||||
|
height: 40
|
||||||
|
text: qsTr("Save and restart VPN")
|
||||||
|
visible: logic.pushButtonSaveVisible
|
||||||
|
onClicked: {
|
||||||
|
logic.onPushButtonSaveClicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BlueButtonType {
|
||||||
|
anchors.fill: pb_save
|
||||||
|
text: qsTr("Cancel")
|
||||||
|
visible: logic.pushButtonCancelVisible
|
||||||
|
enabled: logic.pushButtonCancelVisible
|
||||||
|
onClicked: {
|
||||||
|
logic.onPushButtonCancelClicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,6 +72,7 @@
|
|||||||
#include "pages_logic/protocols/ShadowSocksLogic.h"
|
#include "pages_logic/protocols/ShadowSocksLogic.h"
|
||||||
#include "pages_logic/protocols/OtherProtocolsLogic.h"
|
#include "pages_logic/protocols/OtherProtocolsLogic.h"
|
||||||
#include "pages_logic/protocols/WireGuardLogic.h"
|
#include "pages_logic/protocols/WireGuardLogic.h"
|
||||||
|
#include "pages_logic/protocols/V2RayLogic.h"
|
||||||
|
|
||||||
using namespace amnezia;
|
using namespace amnezia;
|
||||||
using namespace PageEnumNS;
|
using namespace PageEnumNS;
|
||||||
@@ -93,6 +94,7 @@ UiLogic::UiLogic(std::shared_ptr<Settings> settings, std::shared_ptr<VpnConfigur
|
|||||||
m_protocolLogicMap.insert(Proto::ShadowSocks, new ShadowSocksLogic(this));
|
m_protocolLogicMap.insert(Proto::ShadowSocks, new ShadowSocksLogic(this));
|
||||||
m_protocolLogicMap.insert(Proto::Cloak, new CloakLogic(this));
|
m_protocolLogicMap.insert(Proto::Cloak, new CloakLogic(this));
|
||||||
m_protocolLogicMap.insert(Proto::WireGuard, new WireGuardLogic(this));
|
m_protocolLogicMap.insert(Proto::WireGuard, new WireGuardLogic(this));
|
||||||
|
m_protocolLogicMap.insert(Proto::V2Ray, new V2RayLogic(this));
|
||||||
|
|
||||||
m_protocolLogicMap.insert(Proto::Dns, new OtherProtocolsLogic(this));
|
m_protocolLogicMap.insert(Proto::Dns, new OtherProtocolsLogic(this));
|
||||||
m_protocolLogicMap.insert(Proto::Sftp, new OtherProtocolsLogic(this));
|
m_protocolLogicMap.insert(Proto::Sftp, new OtherProtocolsLogic(this));
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ class PageProtocolLogicBase;
|
|||||||
class OpenVpnLogic;
|
class OpenVpnLogic;
|
||||||
class ShadowSocksLogic;
|
class ShadowSocksLogic;
|
||||||
class CloakLogic;
|
class CloakLogic;
|
||||||
|
class V2RayLogic;
|
||||||
|
|
||||||
class OtherProtocolsLogic;
|
class OtherProtocolsLogic;
|
||||||
|
|
||||||
@@ -94,6 +95,7 @@ public:
|
|||||||
friend class OpenVpnLogic;
|
friend class OpenVpnLogic;
|
||||||
friend class ShadowSocksLogic;
|
friend class ShadowSocksLogic;
|
||||||
friend class CloakLogic;
|
friend class CloakLogic;
|
||||||
|
friend class V2RayLogic;
|
||||||
|
|
||||||
friend class OtherProtocolsLogic;
|
friend class OtherProtocolsLogic;
|
||||||
|
|
||||||
|
|||||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user