added implementation of V2RayConfigurator and V2RayProtocol classes
This commit is contained in:
parent
8032e55d7c
commit
7d51cb7d58
24 changed files with 369 additions and 20 deletions
|
|
@ -1,13 +1,70 @@
|
||||||
#include "v2ray_configurator.h"
|
#include "v2ray_configurator.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QPair>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
|
#include "core/servercontroller.h"
|
||||||
|
#include "containers/containers_defs.h"
|
||||||
|
|
||||||
V2RayConfigurator::V2RayConfigurator(std::shared_ptr<Settings> settings, std::shared_ptr<ServerController> serverController,
|
V2RayConfigurator::V2RayConfigurator(std::shared_ptr<Settings> settings, std::shared_ptr<ServerController> serverController,
|
||||||
QObject *parent) : ConfiguratorBase(settings, serverController, parent)
|
QObject *parent) : ConfiguratorBase(settings, serverController, parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString V2RayConfigurator::genCloakConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString V2RayConfigurator::genV2RayConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
|
ErrorCode e = ErrorCode::NoError;
|
||||||
|
|
||||||
|
QString v2rayVmessClientUuid = m_serverController->getTextFileFromContainer(container, credentials,
|
||||||
|
amnezia::protocols::v2ray::v2rayKeyPath, &e);
|
||||||
|
v2rayVmessClientUuid.replace("\n", "");
|
||||||
|
|
||||||
|
if (e) {
|
||||||
|
if (errorCode) *errorCode = e;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject config;
|
||||||
|
|
||||||
|
QJsonObject inboundsSocks;
|
||||||
|
inboundsSocks.insert("protocol", "socks");
|
||||||
|
inboundsSocks.insert("listen", "127.0.0.1");
|
||||||
|
inboundsSocks.insert("port", 1080); //todo
|
||||||
|
QJsonObject socksSettings;
|
||||||
|
socksSettings.insert("auth", "noauth");
|
||||||
|
socksSettings.insert("udp", true);
|
||||||
|
inboundsSocks.insert("settings", socksSettings);
|
||||||
|
|
||||||
|
QJsonArray inbounds;
|
||||||
|
inbounds.push_back(inboundsSocks);
|
||||||
|
config.insert("inbounds", inbounds);
|
||||||
|
|
||||||
|
|
||||||
|
QJsonObject outboundsVmess;
|
||||||
|
outboundsVmess.insert("protocol", "vmess");
|
||||||
|
QJsonObject vmessSettings;
|
||||||
|
QJsonObject vnext;
|
||||||
|
vnext.insert("address", credentials.hostName);
|
||||||
|
vnext.insert("port", 10086); //todo
|
||||||
|
QJsonObject users;
|
||||||
|
users.insert("id", v2rayVmessClientUuid);
|
||||||
|
vnext.insert("users", QJsonArray({users}));
|
||||||
|
vmessSettings.insert("vnext", QJsonArray({vnext}));
|
||||||
|
outboundsVmess.insert("settings", vmessSettings);
|
||||||
|
|
||||||
|
QJsonArray outbounds;
|
||||||
|
outbounds.push_back(outboundsVmess);
|
||||||
|
config.insert("outbounds", outbounds);
|
||||||
|
|
||||||
|
|
||||||
|
QString textCfg = m_serverController->replaceVars(QJsonDocument(config).toJson(),
|
||||||
|
m_serverController->genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
|
// qDebug().noquote() << textCfg;
|
||||||
|
return textCfg;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ public:
|
||||||
V2RayConfigurator(std::shared_ptr<Settings> settings,
|
V2RayConfigurator(std::shared_ptr<Settings> settings,
|
||||||
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
|
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
|
||||||
|
|
||||||
QString genCloakConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString genV2RayConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -24,6 +25,7 @@ VpnConfigurator::VpnConfigurator(std::shared_ptr<Settings> settings,
|
||||||
wireguardConfigurator = std::shared_ptr<WireguardConfigurator>(new WireguardConfigurator(settings, serverController, this));
|
wireguardConfigurator = std::shared_ptr<WireguardConfigurator>(new WireguardConfigurator(settings, serverController, this));
|
||||||
ikev2Configurator = std::shared_ptr<Ikev2Configurator>(new Ikev2Configurator(settings, serverController, this));
|
ikev2Configurator = std::shared_ptr<Ikev2Configurator>(new Ikev2Configurator(settings, serverController, this));
|
||||||
sshConfigurator = std::shared_ptr<SshConfigurator>(new SshConfigurator(settings, serverController, this));
|
sshConfigurator = std::shared_ptr<SshConfigurator>(new SshConfigurator(settings, serverController, this));
|
||||||
|
v2RayConfigurator = std::shared_ptr<V2RayConfigurator>(new V2RayConfigurator(settings, serverController, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials,
|
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials,
|
||||||
|
|
@ -45,6 +47,9 @@ QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentia
|
||||||
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 "";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -43,6 +44,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
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ QVector<amnezia::Proto> ContainerProps::protocolsForContainer(amnezia::DockerCon
|
||||||
return { Proto::Ikev2 /*, Protocol::L2tp */};
|
return { Proto::Ikev2 /*, Protocol::L2tp */};
|
||||||
|
|
||||||
case DockerContainer::V2Ray:
|
case DockerContainer::V2Ray:
|
||||||
return { Proto::V2Ray };
|
return { Proto::OpenVpn, Proto::V2Ray };
|
||||||
|
|
||||||
case DockerContainer::Dns:
|
case DockerContainer::Dns:
|
||||||
return { };
|
return { };
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ enum ErrorCode
|
||||||
ShadowSocksExecutableMissing,
|
ShadowSocksExecutableMissing,
|
||||||
CloakExecutableMissing,
|
CloakExecutableMissing,
|
||||||
AmneziaServiceConnectionFailed,
|
AmneziaServiceConnectionFailed,
|
||||||
|
V2RayExecutableMissing,
|
||||||
ExecutableMissing,
|
ExecutableMissing,
|
||||||
|
|
||||||
// VPN errors
|
// VPN errors
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ QString errorString(ErrorCode code){
|
||||||
case (ShadowSocksExecutableMissing): return QObject::tr("ShadowSocks (ss-local) executable missing");
|
case (ShadowSocksExecutableMissing): return QObject::tr("ShadowSocks (ss-local) executable missing");
|
||||||
case (CloakExecutableMissing): return QObject::tr("Cloak (ck-client) executable missing");
|
case (CloakExecutableMissing): return QObject::tr("Cloak (ck-client) executable missing");
|
||||||
case (AmneziaServiceConnectionFailed): return QObject::tr("Amnezia helper service error");
|
case (AmneziaServiceConnectionFailed): return QObject::tr("Amnezia helper service error");
|
||||||
|
case (V2RayExecutableMissing): return QObject::tr("V2Ray (v2ray) executable missing");
|
||||||
case (OpenSslFailed): return QObject::tr("OpenSSL failed");
|
case (OpenSslFailed): return QObject::tr("OpenSSL failed");
|
||||||
|
|
||||||
// VPN errors
|
// VPN errors
|
||||||
|
|
|
||||||
|
|
@ -667,6 +667,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;
|
||||||
|
|
@ -718,6 +719,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_SERVER_PORT", v2RayConfig.value(config_key::port).toString(protocols::v2ray::defaultLocalPort) }});
|
||||||
|
vars.append({{"$V2RAY_LOCAL_PORT", v2RayConfig.value(config_key::local_port).toString(protocols::v2ray::defaultServerPort) }});
|
||||||
|
|
||||||
// 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"}});
|
||||||
|
|
|
||||||
|
|
@ -49,9 +49,9 @@ void ManagementServer::onNewConnection()
|
||||||
m_socket = QPointer<QTcpSocket>(m_tcpServer->nextPendingConnection());
|
m_socket = QPointer<QTcpSocket>(m_tcpServer->nextPendingConnection());
|
||||||
if (m_tcpServer) m_tcpServer->close();
|
if (m_tcpServer) m_tcpServer->close();
|
||||||
|
|
||||||
QObject::connect(m_socket.data(), SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
|
QObject::connect(m_socket.data(), &QTcpSocket::disconnected, this, &ManagementServer::onSocketDisconnected);
|
||||||
QObject::connect(m_socket.data(), SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onSocketError(QAbstractSocket::SocketError)));
|
QObject::connect(m_socket.data(), &QTcpSocket::errorOccurred, this, &ManagementServer::onSocketError);
|
||||||
QObject::connect(m_socket.data(), SIGNAL(readyRead()), this, SLOT(onReadyRead()));
|
QObject::connect(m_socket.data(), &QTcpSocket::readyRead, this, &ManagementServer::onReadyRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManagementServer::onSocketError(QAbstractSocket::SocketError socketError)
|
void ManagementServer::onSocketError(QAbstractSocket::SocketError socketError)
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ 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 -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;
|
||||||
|
|
|
||||||
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,104 @@
|
||||||
#include "v2rayprotocol.h"
|
#include "v2rayprotocol.h"
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
V2RayProtocol::V2RayProtocol(const QJsonObject &configuration, QObject *parent) : VpnProtocol(configuration, parent)
|
V2RayProtocol::V2RayProtocol(const QJsonObject &configuration, QObject *parent) : OpenVpnProtocol(configuration, parent)
|
||||||
{
|
{
|
||||||
writeV2RayConfiguration(configuration);
|
writeV2RayConfiguration(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
V2RayProtocol::~V2RayProtocol()
|
V2RayProtocol::~V2RayProtocol()
|
||||||
{
|
{
|
||||||
|
qDebug() << "V2RayProtocol::~V2RayProtocol";
|
||||||
|
V2RayProtocol::stop();
|
||||||
|
QThread::msleep(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode V2RayProtocol::start()
|
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() << "ShadowSocksVpnProtocol::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::ShadowSocksExecutableCrashed); //todo
|
||||||
|
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::ShadowSocksExecutableMissing;
|
||||||
|
#else
|
||||||
|
return ErrorCode::NotImplementedError;
|
||||||
|
#endif
|
||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
void V2RayProtocol::stop()
|
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)
|
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
|
const QString V2RayProtocol::v2RayExecPath() const
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
return Utils::executable(QString("v2ray/v2ray"), true);
|
return Utils::executable(QString("v2ray/v2ray"), true);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
#ifndef V2RAYPROTOCOL_H
|
#ifndef V2RAYPROTOCOL_H
|
||||||
#define V2RAYPROTOCOL_H
|
#define V2RAYPROTOCOL_H
|
||||||
|
|
||||||
#include "vpnprotocol.h"
|
#include "QProcess"
|
||||||
|
#include "QTemporaryFile"
|
||||||
|
|
||||||
class V2RayProtocol : public VpnProtocol
|
#include "openvpnprotocol.h"
|
||||||
|
|
||||||
|
class V2RayProtocol : public OpenVpnProtocol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
V2RayProtocol(const QJsonObject& configuration, QObject* parent = nullptr);
|
V2RayProtocol(const QJsonObject& configuration, QObject* parent = nullptr);
|
||||||
|
|
@ -13,10 +16,15 @@ public:
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QJsonObject m_shadowSocksConfig;
|
QJsonObject m_v2RayConfig;
|
||||||
|
QTemporaryFile m_v2RayConfigFile;
|
||||||
|
#ifndef Q_OS_IOS
|
||||||
|
QProcess m_v2RayProcess;
|
||||||
|
#endif
|
||||||
|
|
||||||
void writeV2RayConfiguration(const QJsonObject &configuration);
|
void writeV2RayConfiguration(const QJsonObject &configuration);
|
||||||
|
|
||||||
const QString v2rayExecPath() const;
|
const QString v2RayExecPath() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // V2RAYPROTOCOL_H
|
#endif // V2RAYPROTOCOL_H
|
||||||
|
|
|
||||||
|
|
@ -164,5 +164,11 @@
|
||||||
<file>images/svg/settings_suggest_black_24dp.svg</file>
|
<file>images/svg/settings_suggest_black_24dp.svg</file>
|
||||||
<file>server_scripts/website_tor/Dockerfile</file>
|
<file>server_scripts/website_tor/Dockerfile</file>
|
||||||
<file>ui/qml/Controls/PopupWithQuestion.qml</file>
|
<file>ui/qml/Controls/PopupWithQuestion.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>
|
||||||
</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)
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,15 @@ $OPENVPN_TLS_AUTH
|
||||||
$OPENVPN_ADDITIONAL_SERVER_CONFIG
|
$OPENVPN_ADDITIONAL_SERVER_CONFIG
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# V2RAY_VMESS_PORT port for v2ray listening, for example 10086.
|
# V2RAY_SERVER_PORT port for v2ray listening, for example 10086.
|
||||||
# V2RAY_VMESS_CLIENT_UUID client's id and secret as UUID.
|
# V2RAY_VMESS_CLIENT_UUID client's id and secret as UUID.
|
||||||
# UUID is 32 hexadecimal digits /([0-9a-f]-?){32}/ (128 bit value).
|
# UUID is 32 hexadecimal digits /([0-9a-f]-?){32}/ (128 bit value).
|
||||||
|
|
||||||
mkdir -p /opt/amnezia/v2ray
|
mkdir -p /opt/amnezia/v2ray
|
||||||
|
cd /opt/amnezia/v2ray
|
||||||
|
V2RAY_VMESS_CLIENT_UUID="b831381d-6324-4d53-ad4f-8cda48b30811" # $(openssl rand -base64 32 | tr "=" "A" | tr "+" "A" | tr "/" "A")
|
||||||
|
echo $V2RAY_VMESS_CLIENT_UUID > /opt/amnezia/v2ray/v2ray.key
|
||||||
|
|
||||||
cat < /opt/amnezia/v2ray/v2ray-server.json <<EOF
|
cat < /opt/amnezia/v2ray/v2ray-server.json <<EOF
|
||||||
{
|
{
|
||||||
"log": {
|
"log": {
|
||||||
|
|
@ -38,7 +42,7 @@ cat < /opt/amnezia/v2ray/v2ray-server.json <<EOF
|
||||||
},
|
},
|
||||||
"inbounds": [
|
"inbounds": [
|
||||||
{
|
{
|
||||||
"port": $V2RAY_VMESS_PORT,
|
"port": $V2RAY_SERVER_PORT,
|
||||||
"protocol": "vmess",
|
"protocol": "vmess",
|
||||||
"settings": {
|
"settings": {
|
||||||
"clients": [
|
"clients": [
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ sudo docker run -d \
|
||||||
--log-driver none \
|
--log-driver none \
|
||||||
--restart always \
|
--restart always \
|
||||||
--cap-add=NET_ADMIN \
|
--cap-add=NET_ADMIN \
|
||||||
-p $V2RAY_VMESS_PORT:$V2RAY_VMESS_PORT/tcp \
|
-p $V2RAY_SERVER_PORT:$V2RAY_SERVER_PORT/tcp \
|
||||||
--name $CONTAINER_NAME $CONTAINER_NAME
|
--name $CONTAINER_NAME $CONTAINER_NAME
|
||||||
|
|
||||||
sudo docker network connect amnezia-dns-net $CONTAINER_NAME
|
sudo docker network connect amnezia-dns-net $CONTAINER_NAME
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
127
client/ui/pages_logic/protocols/V2RayLogic.cpp
Normal file
127
client/ui/pages_logic/protocols/V2RayLogic.cpp
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
#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_comboBoxCipherText{"chacha20-poly1305"},
|
||||||
|
m_lineEditPortText{},
|
||||||
|
m_pushButtonSaveVisible{false},
|
||||||
|
m_progressBarResetVisible{false},
|
||||||
|
m_lineEditPortEnabled{false},
|
||||||
|
m_labelInfoVisible{true},
|
||||||
|
m_labelInfoText{},
|
||||||
|
m_progressBarResetValue{0},
|
||||||
|
m_progressBarResetMaximium{100}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void V2RayLogic::updateProtocolPage(const QJsonObject &ssConfig, DockerContainer container, bool haveAuthData)
|
||||||
|
{
|
||||||
|
set_pageEnabled(haveAuthData);
|
||||||
|
set_pushButtonSaveVisible(haveAuthData);
|
||||||
|
set_progressBarResetVisible(haveAuthData);
|
||||||
|
|
||||||
|
set_comboBoxCipherText(ssConfig.value(config_key::cipher).
|
||||||
|
toString(protocols::shadowsocks::defaultCipher));
|
||||||
|
|
||||||
|
set_lineEditPortText(ssConfig.value(config_key::port).
|
||||||
|
toString(protocols::shadowsocks::defaultPort));
|
||||||
|
|
||||||
|
set_lineEditPortEnabled(container == DockerContainer::ShadowSocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject V2RayLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
|
||||||
|
{
|
||||||
|
oldConfig.insert(config_key::cipher, comboBoxCipherText());
|
||||||
|
oldConfig.insert(config_key::port, lineEditPortText());
|
||||||
|
|
||||||
|
return oldConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
void V2RayLogic::onPushButtonSaveClicked()
|
||||||
|
{
|
||||||
|
QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::ShadowSocks);
|
||||||
|
|
||||||
|
QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
||||||
|
QJsonObject newContainerConfig = containerConfig;
|
||||||
|
newContainerConfig.insert(ProtocolProps::protoToString(Proto::ShadowSocks), 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..."));
|
||||||
|
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction([this, containerConfig, &newContainerConfig](){
|
||||||
|
return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex),
|
||||||
|
uiLogic()->selectedDockerContainer,
|
||||||
|
containerConfig,
|
||||||
|
newContainerConfig);
|
||||||
|
},
|
||||||
|
pageFunc, progressBarFunc,
|
||||||
|
saveButtonFunc, waitInfoFunc,
|
||||||
|
busyInfoFuncy, cancelButtonFunc);
|
||||||
|
|
||||||
|
if (!e) {
|
||||||
|
m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
|
||||||
|
m_settings->clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
||||||
|
}
|
||||||
|
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void V2RayLogic::onPushButtonCancelClicked()
|
||||||
|
{
|
||||||
|
emit uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->cancelDoInstallAction(true);
|
||||||
|
}
|
||||||
46
client/ui/pages_logic/protocols/V2RayLogic.h
Normal file
46
client/ui/pages_logic/protocols/V2RayLogic.h
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef V2RAYLOGIC_H
|
||||||
|
#define V2RAYLOGIC_H
|
||||||
|
|
||||||
|
#include "PageProtocolLogicBase.h"
|
||||||
|
|
||||||
|
class UiLogic;
|
||||||
|
|
||||||
|
class V2RayLogic : public PageProtocolLogicBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
AUTO_PROPERTY(QString, comboBoxCipherText)
|
||||||
|
AUTO_PROPERTY(QString, lineEditPortText)
|
||||||
|
AUTO_PROPERTY(bool, pushButtonSaveVisible)
|
||||||
|
AUTO_PROPERTY(bool, progressBarResetVisible)
|
||||||
|
AUTO_PROPERTY(bool, lineEditPortEnabled)
|
||||||
|
AUTO_PROPERTY(bool, labelInfoVisible)
|
||||||
|
AUTO_PROPERTY(QString, labelInfoText)
|
||||||
|
AUTO_PROPERTY(int, progressBarResetValue)
|
||||||
|
AUTO_PROPERTY(int, progressBarResetMaximium)
|
||||||
|
AUTO_PROPERTY(bool, progressBarTextVisible)
|
||||||
|
AUTO_PROPERTY(QString, progressBarText)
|
||||||
|
|
||||||
|
AUTO_PROPERTY(bool, labelServerBusyVisible)
|
||||||
|
AUTO_PROPERTY(QString, labelServerBusyText)
|
||||||
|
|
||||||
|
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 &ssConfig, DockerContainer container, bool haveAuthData) override;
|
||||||
|
QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
UiLogic *m_uiLogic;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // V2RAYLOGIC_H
|
||||||
5
client/ui/qml/Pages/Protocols/PageProtoV2Ray.qml
Normal file
5
client/ui/qml/Pages/Protocols/PageProtoV2Ray.qml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Item {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -73,6 +73,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;
|
||||||
|
|
@ -96,6 +97,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));
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ class PageProtocolLogicBase;
|
||||||
class OpenVpnLogic;
|
class OpenVpnLogic;
|
||||||
class ShadowSocksLogic;
|
class ShadowSocksLogic;
|
||||||
class CloakLogic;
|
class CloakLogic;
|
||||||
|
class V2RayLogic;
|
||||||
|
|
||||||
class OtherProtocolsLogic;
|
class OtherProtocolsLogic;
|
||||||
|
|
||||||
|
|
@ -92,6 +93,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;
|
||||||
|
|
||||||
|
|
|
||||||
BIN
deploy/data/windows/x64/v2ray/v2ctl.exe
Normal file
BIN
deploy/data/windows/x64/v2ray/v2ctl.exe
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue