mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-23 02:00:20 +07:00
feat: awg 2 support (#1836)
* Add updated awg container * add missing files * Hide uninstalled AwgLegacy container * Fix resources file * Add role for allowed for installation containers * Add native config sharing for new Awg container * Fix not opening awg settings * Remove AwgLegacy from wizard manual installation page * Fix AmneziaWG settings * chore: update link to submodule * refactor: remove j1-j3 and itime * chore: return s3 s4 fields to ui * fix: awg2 native config compatability * chore: update packet size validation * feat: add awg2 support in self-hosted containers * fix: delete parameters from server config * feat: add H-parameters validation as a strings * chore: update link to submodule * chore: add containers type for awg 1.5 and awg 2 * chore: fixed s3/s4 visibility for awg 1 --------- Co-authored-by: aiamnezia <ai@amnezia.org>
This commit is contained in:
@@ -166,9 +166,10 @@ namespace
|
||||
qDebug() << "missing containers field";
|
||||
return ErrorCode::ApiConfigEmptyError;
|
||||
}
|
||||
auto container = containers.at(0).toObject();
|
||||
QString containerName = ContainerProps::containerTypeToString(DockerContainer::Awg);
|
||||
auto serverProtocolConfig = container.value(containerName).toObject();
|
||||
auto containerObject = containers.at(0).toObject();
|
||||
auto containerType = ContainerProps::containerFromString(containerObject.value(config_key::container).toString());
|
||||
QString containerName = ContainerProps::containerTypeToString(containerType);
|
||||
auto serverProtocolConfig = containerObject.value(containerName).toObject();
|
||||
auto clientProtocolConfig =
|
||||
QJsonDocument::fromJson(serverProtocolConfig.value(config_key::last_config).toString().toUtf8()).object();
|
||||
|
||||
@@ -191,15 +192,11 @@ namespace
|
||||
serverProtocolConfig[config_key::specialJunk3] = clientProtocolConfig.value(config_key::specialJunk3);
|
||||
serverProtocolConfig[config_key::specialJunk4] = clientProtocolConfig.value(config_key::specialJunk4);
|
||||
serverProtocolConfig[config_key::specialJunk5] = clientProtocolConfig.value(config_key::specialJunk5);
|
||||
serverProtocolConfig[config_key::controlledJunk1] = clientProtocolConfig.value(config_key::controlledJunk1);
|
||||
serverProtocolConfig[config_key::controlledJunk2] = clientProtocolConfig.value(config_key::controlledJunk2);
|
||||
serverProtocolConfig[config_key::controlledJunk3] = clientProtocolConfig.value(config_key::controlledJunk3);
|
||||
serverProtocolConfig[config_key::specialHandshakeTimeout] = clientProtocolConfig.value(config_key::specialHandshakeTimeout);
|
||||
|
||||
//
|
||||
|
||||
container[containerName] = serverProtocolConfig;
|
||||
containers.replace(0, container);
|
||||
containerObject[containerName] = serverProtocolConfig;
|
||||
containers.replace(0, containerObject);
|
||||
newServerConfig[config_key::containers] = containers;
|
||||
configStr = QString(QJsonDocument(newServerConfig).toJson());
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
|
||||
void ExportController::generateAwgConfig(const QString &clientName)
|
||||
{
|
||||
QJsonObject nativeConfig;
|
||||
ErrorCode errorCode = generateNativeConfig(DockerContainer::Awg, clientName, Proto::Awg, nativeConfig);
|
||||
ErrorCode errorCode = generateNativeConfig(DockerContainer::Awg2, clientName, Proto::Awg, nativeConfig);
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorCode);
|
||||
return;
|
||||
|
||||
@@ -272,7 +272,7 @@ void ImportController::processNativeWireGuardConfig()
|
||||
auto containers = m_config.value(config_key::containers).toArray();
|
||||
if (!containers.isEmpty()) {
|
||||
auto container = containers.at(0).toObject();
|
||||
auto serverProtocolConfig = container.value(ContainerProps::containerTypeToString(DockerContainer::WireGuard)).toObject();
|
||||
auto serverProtocolConfig = container.value(ContainerProps::containerTypeToProtocolString(DockerContainer::WireGuard)).toObject();
|
||||
auto clientProtocolConfig = QJsonDocument::fromJson(serverProtocolConfig.value(config_key::last_config).toString().toUtf8()).object();
|
||||
|
||||
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(4, 7));
|
||||
@@ -288,18 +288,8 @@ void ImportController::processNativeWireGuardConfig()
|
||||
clientProtocolConfig[config_key::underloadPacketMagicHeader] = "3";
|
||||
clientProtocolConfig[config_key::transportPacketMagicHeader] = "4";
|
||||
|
||||
// clientProtocolConfig[config_key::cookieReplyPacketJunkSize] = "0";
|
||||
// clientProtocolConfig[config_key::transportPacketJunkSize] = "0";
|
||||
|
||||
// clientProtocolConfig[config_key::specialJunk1] = "";
|
||||
// clientProtocolConfig[config_key::specialJunk2] = "";
|
||||
// clientProtocolConfig[config_key::specialJunk3] = "";
|
||||
// clientProtocolConfig[config_key::specialJunk4] = "";
|
||||
// clientProtocolConfig[config_key::specialJunk5] = "";
|
||||
// clientProtocolConfig[config_key::controlledJunk1] = "";
|
||||
// clientProtocolConfig[config_key::controlledJunk2] = "";
|
||||
// clientProtocolConfig[config_key::controlledJunk3] = "";
|
||||
// clientProtocolConfig[config_key::specialHandshakeTimeout] = "0";
|
||||
clientProtocolConfig[config_key::cookieReplyPacketJunkSize] = "0";
|
||||
clientProtocolConfig[config_key::transportPacketJunkSize] = "0";
|
||||
|
||||
clientProtocolConfig[config_key::isObfuscationEnabled] = true;
|
||||
|
||||
@@ -465,11 +455,10 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
||||
config_key::responsePacketMagicHeader, config_key::underloadPacketMagicHeader,
|
||||
config_key::transportPacketMagicHeader };
|
||||
|
||||
const QStringList optionalJunkFields = { // config_key::cookieReplyPacketJunkSize,
|
||||
// config_key::transportPacketJunkSize,
|
||||
const QStringList optionalJunkFields = { config_key::cookieReplyPacketJunkSize,
|
||||
config_key::transportPacketJunkSize,
|
||||
config_key::specialJunk1, config_key::specialJunk2, config_key::specialJunk3,
|
||||
config_key::specialJunk4, config_key::specialJunk5, config_key::controlledJunk1,
|
||||
config_key::controlledJunk2, config_key::controlledJunk3, config_key::specialHandshakeTimeout
|
||||
config_key::specialJunk4, config_key::specialJunk5
|
||||
};
|
||||
|
||||
bool hasAllRequiredFields = std::all_of(requiredJunkFields.begin(), requiredJunkFields.end(),
|
||||
@@ -485,14 +474,30 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
||||
}
|
||||
}
|
||||
|
||||
protocolName = "awg";
|
||||
bool hasCookieReplyPacketJunkSize = !configMap.value(config_key::cookieReplyPacketJunkSize).isEmpty();
|
||||
bool hasTransportPacketJunkSize = !configMap.value(config_key::transportPacketJunkSize).isEmpty();
|
||||
bool hasSpecialJunk = !configMap.value(config_key::specialJunk1).isEmpty() ||
|
||||
!configMap.value(config_key::specialJunk2).isEmpty() ||
|
||||
!configMap.value(config_key::specialJunk3).isEmpty() ||
|
||||
!configMap.value(config_key::specialJunk4).isEmpty() ||
|
||||
!configMap.value(config_key::specialJunk5).isEmpty();
|
||||
|
||||
if (hasCookieReplyPacketJunkSize && hasTransportPacketJunkSize) {
|
||||
protocolName = "awg2";
|
||||
} else if (hasSpecialJunk && !hasCookieReplyPacketJunkSize && !hasTransportPacketJunkSize) {
|
||||
protocolName = "awg1.5";
|
||||
} else {
|
||||
protocolName = "awg";
|
||||
}
|
||||
m_configType = ConfigTypes::Awg;
|
||||
}
|
||||
|
||||
if (!configMap.value("MTU").isEmpty()) {
|
||||
lastConfig[config_key::mtu] = configMap.value("MTU");
|
||||
} else {
|
||||
lastConfig[config_key::mtu] = protocolName == "awg" ? protocols::awg::defaultMtu : protocols::wireguard::defaultMtu;
|
||||
lastConfig[config_key::mtu] = (protocolName == "awg" || protocolName == "awg2" || protocolName == "awg1.5")
|
||||
? protocols::awg::defaultMtu
|
||||
: protocols::wireguard::defaultMtu;
|
||||
}
|
||||
|
||||
QJsonObject wireguardConfig;
|
||||
@@ -733,8 +738,8 @@ void ImportController::processAmneziaConfig(QJsonObject &config)
|
||||
for (auto i = 0; i < containers.size(); i++) {
|
||||
auto container = containers.at(i).toObject();
|
||||
auto dockerContainer = ContainerProps::containerFromString(container.value(config_key::container).toString());
|
||||
if (dockerContainer == DockerContainer::Awg || dockerContainer == DockerContainer::WireGuard) {
|
||||
auto containerConfig = container.value(ContainerProps::containerTypeToString(dockerContainer)).toObject();
|
||||
if (ContainerProps::isAwgContainer(dockerContainer) || dockerContainer == DockerContainer::WireGuard) {
|
||||
auto containerConfig = container.value(ContainerProps::containerTypeToProtocolString(dockerContainer)).toObject();
|
||||
auto protocolConfig = containerConfig.value(config_key::last_config).toString();
|
||||
if (protocolConfig.isEmpty()) {
|
||||
return;
|
||||
@@ -742,11 +747,11 @@ void ImportController::processAmneziaConfig(QJsonObject &config)
|
||||
|
||||
QJsonObject jsonConfig = QJsonDocument::fromJson(protocolConfig.toUtf8()).object();
|
||||
jsonConfig[config_key::mtu] =
|
||||
dockerContainer == DockerContainer::Awg ? protocols::awg::defaultMtu : protocols::wireguard::defaultMtu;
|
||||
ContainerProps::isAwgContainer(dockerContainer) ? protocols::awg::defaultMtu : protocols::wireguard::defaultMtu;
|
||||
|
||||
containerConfig[config_key::last_config] = QString(QJsonDocument(jsonConfig).toJson());
|
||||
|
||||
container[ContainerProps::containerTypeToString(dockerContainer)] = containerConfig;
|
||||
container[ContainerProps::containerTypeToProtocolString(dockerContainer)] = containerConfig;
|
||||
containers.replace(i, container);
|
||||
config.insert(config_key::containers, containers);
|
||||
}
|
||||
|
||||
Executable → Regular
+35
-45
@@ -72,15 +72,15 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
||||
containerConfig.insert(config_key::port, QString::number(port));
|
||||
containerConfig.insert(config_key::transport_proto, ProtocolProps::transportProtoToString(transportProto, protocol));
|
||||
|
||||
if (container == DockerContainer::Awg) {
|
||||
if (container == DockerContainer::Awg2) {
|
||||
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(4, 7));
|
||||
QString junkPacketMinSize = QString::number(10);
|
||||
QString junkPacketMaxSize = QString::number(50);
|
||||
|
||||
int s1 = QRandomGenerator::global()->bounded(15, 150);
|
||||
int s2 = QRandomGenerator::global()->bounded(15, 150);
|
||||
// int s3 = QRandomGenerator::global()->bounded(15, 150);
|
||||
// int s4 = QRandomGenerator::global()->bounded(15, 150);
|
||||
int s3 = QRandomGenerator::global()->bounded(0, 64);
|
||||
int s4 = QRandomGenerator::global()->bounded(0, 32);
|
||||
|
||||
// Ensure all values are unique and don't create equal packet sizes
|
||||
QSet<int> usedValues;
|
||||
@@ -91,24 +91,21 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
||||
}
|
||||
usedValues.insert(s2);
|
||||
|
||||
// while (usedValues.contains(s3)
|
||||
// || s1 + AwgConstant::messageInitiationSize == s3 + AwgConstant::messageCookieReplySize
|
||||
// || s2 + AwgConstant::messageResponseSize == s3 + AwgConstant::messageCookieReplySize) {
|
||||
// s3 = QRandomGenerator::global()->bounded(15, 150);
|
||||
// }
|
||||
// usedValues.insert(s3);
|
||||
while (usedValues.contains(s3)
|
||||
|| s1 + AwgConstant::messageInitiationSize == s3 + AwgConstant::messageCookieReplySize
|
||||
|| s2 + AwgConstant::messageResponseSize == s3 + AwgConstant::messageCookieReplySize) {
|
||||
s3 = QRandomGenerator::global()->bounded(0, 64);
|
||||
}
|
||||
usedValues.insert(s3);
|
||||
|
||||
// while (usedValues.contains(s4)
|
||||
// || s1 + AwgConstant::messageInitiationSize == s4 + AwgConstant::messageTransportSize
|
||||
// || s2 + AwgConstant::messageResponseSize == s4 + AwgConstant::messageTransportSize
|
||||
// || s3 + AwgConstant::messageCookieReplySize == s4 + AwgConstant::messageTransportSize) {
|
||||
// s4 = QRandomGenerator::global()->bounded(15, 150);
|
||||
// }
|
||||
while (usedValues.contains(s4)) {
|
||||
s4 = QRandomGenerator::global()->bounded(0, 32);
|
||||
}
|
||||
|
||||
QString initPacketJunkSize = QString::number(s1);
|
||||
QString responsePacketJunkSize = QString::number(s2);
|
||||
// QString cookieReplyPacketJunkSize = QString::number(s3);
|
||||
// QString transportPacketJunkSize = QString::number(s4);
|
||||
QString cookieReplyPacketJunkSize = QString::number(s3);
|
||||
QString transportPacketJunkSize = QString::number(s4);
|
||||
|
||||
QSet<QString> headersValue;
|
||||
while (headersValue.size() != 4) {
|
||||
@@ -133,19 +130,14 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
||||
containerConfig[config_key::underloadPacketMagicHeader] = underloadPacketMagicHeader;
|
||||
containerConfig[config_key::transportPacketMagicHeader] = transportPacketMagicHeader;
|
||||
|
||||
// TODO:
|
||||
// containerConfig[config_key::cookieReplyPacketJunkSize] = cookieReplyPacketJunkSize;
|
||||
// containerConfig[config_key::transportPacketJunkSize] = transportPacketJunkSize;
|
||||
containerConfig[config_key::cookieReplyPacketJunkSize] = cookieReplyPacketJunkSize;
|
||||
containerConfig[config_key::transportPacketJunkSize] = transportPacketJunkSize;
|
||||
|
||||
// containerConfig[config_key::specialJunk1] = specialJunk1;
|
||||
// containerConfig[config_key::specialJunk2] = specialJunk2;
|
||||
// containerConfig[config_key::specialJunk3] = specialJunk3;
|
||||
// containerConfig[config_key::specialJunk4] = specialJunk4;
|
||||
// containerConfig[config_key::specialJunk5] = specialJunk5;
|
||||
// containerConfig[config_key::controlledJunk1] = controlledJunk1;
|
||||
// containerConfig[config_key::controlledJunk2] = controlledJunk2;
|
||||
// containerConfig[config_key::controlledJunk3] = controlledJunk3;
|
||||
// containerConfig[config_key::specialHandshakeTimeout] = specialHandshakeTimeout;
|
||||
containerConfig[config_key::specialJunk1] = "";
|
||||
containerConfig[config_key::specialJunk2] = "";
|
||||
containerConfig[config_key::specialJunk3] = "";
|
||||
containerConfig[config_key::specialJunk4] = "";
|
||||
containerConfig[config_key::specialJunk5] = "";
|
||||
|
||||
} else if (container == DockerContainer::Sftp) {
|
||||
containerConfig.insert(config_key::userName, protocols::sftp::defaultUserName);
|
||||
@@ -420,8 +412,12 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
||||
containerConfig.insert(config_key::transport_proto, transportProto);
|
||||
|
||||
if (protocol == Proto::Awg) {
|
||||
QString configPath = amnezia::protocols::awg::serverConfigPath;
|
||||
if (container == DockerContainer::Awg) {
|
||||
configPath = amnezia::protocols::awg::serverLegacyConfigPath;
|
||||
}
|
||||
QString serverConfig = serverController->getTextFileFromContainer(container, credentials,
|
||||
protocols::awg::serverConfigPath, errorCode);
|
||||
configPath, errorCode);
|
||||
|
||||
QMap<QString, QString> serverConfigMap;
|
||||
auto serverConfigLines = serverConfig.split("\n");
|
||||
@@ -450,18 +446,12 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
||||
containerConfig[config_key::transportPacketMagicHeader] =
|
||||
serverConfigMap.value(config_key::transportPacketMagicHeader);
|
||||
|
||||
// containerConfig[config_key::cookieReplyPacketJunkSize] = serverConfigMap.value(config_key::cookieReplyPacketJunkSize);
|
||||
// containerConfig[config_key::transportPacketJunkSize] = serverConfigMap.value(config_key::transportPacketJunkSize);
|
||||
|
||||
// containerConfig[config_key::specialJunk1] = serverConfigMap.value(config_key::specialJunk1);
|
||||
// containerConfig[config_key::specialJunk2] = serverConfigMap.value(config_key::specialJunk2);
|
||||
// containerConfig[config_key::specialJunk3] = serverConfigMap.value(config_key::specialJunk3);
|
||||
// containerConfig[config_key::specialJunk4] = serverConfigMap.value(config_key::specialJunk4);
|
||||
// containerConfig[config_key::specialJunk5] = serverConfigMap.value(config_key::specialJunk5);
|
||||
// containerConfig[config_key::controlledJunk1] = serverConfigMap.value(config_key::controlledJunk1);
|
||||
// containerConfig[config_key::controlledJunk2] = serverConfigMap.value(config_key::controlledJunk2);
|
||||
// containerConfig[config_key::controlledJunk3] = serverConfigMap.value(config_key::controlledJunk3);
|
||||
// containerConfig[config_key::specialHandshakeTimeout] = serverConfigMap.value(config_key::specialHandshakeTimeout);
|
||||
if (container == DockerContainer::Awg2) {
|
||||
containerConfig[config_key::cookieReplyPacketJunkSize] =
|
||||
serverConfigMap.value(config_key::cookieReplyPacketJunkSize);
|
||||
containerConfig[config_key::transportPacketJunkSize] =
|
||||
serverConfigMap.value(config_key::transportPacketJunkSize);
|
||||
}
|
||||
|
||||
} else if (protocol == Proto::WireGuard) {
|
||||
QString serverConfig = serverController->getTextFileFromContainer(container, credentials,
|
||||
@@ -1068,9 +1058,9 @@ bool InstallController::isUpdateDockerContainerRequired(const DockerContainer co
|
||||
const QJsonObject &oldProtoConfig = oldConfig.value(ProtocolProps::protoToString(mainProto)).toObject();
|
||||
const QJsonObject &newProtoConfig = newConfig.value(ProtocolProps::protoToString(mainProto)).toObject();
|
||||
|
||||
if (container == DockerContainer::Awg) {
|
||||
const AwgConfig oldConfig(oldProtoConfig);
|
||||
const AwgConfig newConfig(newProtoConfig);
|
||||
if (container == DockerContainer::Awg2) {
|
||||
const AwgConfig oldConfig(oldProtoConfig, container);
|
||||
const AwgConfig newConfig(newProtoConfig, container);
|
||||
|
||||
if (oldConfig.hasEqualServerSettings(newConfig)) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user