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:
vkamn
2025-12-11 15:18:36 +08:00
committed by GitHub
parent ac77b4ee75
commit 40950b92ee
48 changed files with 586 additions and 501 deletions

View File

@@ -122,19 +122,15 @@ open class Wireguard : Protocol() {
configData.optStringOrNull("S2")?.let { setS2(it.toInt()) }
configData.optStringOrNull("S3")?.let { setS3(it.toInt()) }
configData.optStringOrNull("S4")?.let { setS4(it.toInt()) }
configData.optStringOrNull("H1")?.let { setH1(it.toLong()) }
configData.optStringOrNull("H2")?.let { setH2(it.toLong()) }
configData.optStringOrNull("H3")?.let { setH3(it.toLong()) }
configData.optStringOrNull("H4")?.let { setH4(it.toLong()) }
configData.optStringOrNull("H1")?.trim()?.let { if (it.isNotEmpty()) setH1(it) }
configData.optStringOrNull("H2")?.trim()?.let { if (it.isNotEmpty()) setH2(it) }
configData.optStringOrNull("H3")?.trim()?.let { if (it.isNotEmpty()) setH3(it) }
configData.optStringOrNull("H4")?.trim()?.let { if (it.isNotEmpty()) setH4(it) }
configData.optStringOrNull("I1")?.let { setI1(it) }
configData.optStringOrNull("I2")?.let { setI2(it) }
configData.optStringOrNull("I3")?.let { setI3(it) }
configData.optStringOrNull("I4")?.let { setI4(it) }
configData.optStringOrNull("I5")?.let { setI5(it) }
configData.optStringOrNull("J1")?.let { setJ1(it) }
configData.optStringOrNull("J2")?.let { setJ2(it) }
configData.optStringOrNull("J3")?.let { setJ3(it) }
configData.optStringOrNull("Itime")?.let { setItime(it.toInt()) }
}
private fun start(config: WireguardConfig, vpnBuilder: Builder, protect: (Int) -> Boolean) {

View File

@@ -22,19 +22,15 @@ open class WireguardConfig protected constructor(
val s2: Int?,
val s3: Int?,
val s4: Int?,
val h1: Long?,
val h2: Long?,
val h3: Long?,
val h4: Long?,
val h1: String?,
val h2: String?,
val h3: String?,
val h4: String?,
var i1: String?,
var i2: String?,
var i3: String?,
var i4: String?,
var i5: String?,
var j1: String?,
var j2: String?,
var j3: String?,
var itime: Int?
) : ProtocolConfig(protocolConfigBuilder) {
protected constructor(builder: Builder) : this(
@@ -61,10 +57,6 @@ open class WireguardConfig protected constructor(
builder.i3,
builder.i4,
builder.i5,
builder.j1,
builder.j2,
builder.j3,
builder.itime
)
fun toWgUserspaceString(): String = with(StringBuilder()) {
@@ -94,10 +86,6 @@ open class WireguardConfig protected constructor(
i3?.let { appendLine("i3=$it") }
i4?.let { appendLine("i4=$it") }
i5?.let { appendLine("i5=$it") }
j1?.let { appendLine("j1=$it") }
j2?.let { appendLine("j2=$it") }
j3?.let { appendLine("j3=$it") }
itime?.let { appendLine("itime=$it") }
}
}
@@ -152,19 +140,15 @@ open class WireguardConfig protected constructor(
internal var s2: Int? = null
internal var s3: Int? = null
internal var s4: Int? = null
internal var h1: Long? = null
internal var h2: Long? = null
internal var h3: Long? = null
internal var h4: Long? = null
internal var h1: String? = null
internal var h2: String? = null
internal var h3: String? = null
internal var h4: String? = null
internal var i1: String? = null
internal var i2: String? = null
internal var i3: String? = null
internal var i4: String? = null
internal var i5: String? = null
internal var j1: String? = null
internal var j2: String? = null
internal var j3: String? = null
internal var itime: Int? = null
fun setEndpoint(endpoint: InetEndpoint) = apply { this.endpoint = endpoint }
@@ -185,19 +169,15 @@ open class WireguardConfig protected constructor(
fun setS2(s2: Int) = apply { this.s2 = s2 }
fun setS3(s3: Int) = apply { this.s3 = s3 }
fun setS4(s4: Int) = apply { this.s4 = s4 }
fun setH1(h1: Long) = apply { this.h1 = h1 }
fun setH2(h2: Long) = apply { this.h2 = h2 }
fun setH3(h3: Long) = apply { this.h3 = h3 }
fun setH4(h4: Long) = apply { this.h4 = h4 }
fun setH1(h1: String) = apply { this.h1 = h1 }
fun setH2(h2: String) = apply { this.h2 = h2 }
fun setH3(h3: String) = apply { this.h3 = h3 }
fun setH4(h4: String) = apply { this.h4 = h4 }
fun setI1(i1: String) = apply { this.i1 = i1 }
fun setI2(i2: String) = apply { this.i2 = i2 }
fun setI3(i3: String) = apply { this.i3 = i3 }
fun setI4(i4: String) = apply { this.i4 = i4 }
fun setI5(i5: String) = apply { this.i5 = i5 }
fun setJ1(j1: String) = apply { this.j1 = j1 }
fun setJ2(j2: String) = apply { this.j2 = j2 }
fun setJ3(j3: String) = apply { this.j3 = j3 }
fun setItime(itime: Int) = apply { this.itime = itime }
override fun build(): WireguardConfig = configBuild().run { WireguardConfig(this@Builder) }
}

View File

@@ -41,18 +41,16 @@ QString AwgConfigurator::createConfig(const ServerCredentials &credentials, Dock
jsonConfig[config_key::underloadPacketMagicHeader] = configMap.value(config_key::underloadPacketMagicHeader);
jsonConfig[config_key::transportPacketMagicHeader] = configMap.value(config_key::transportPacketMagicHeader);
// jsonConfig[config_key::cookieReplyPacketJunkSize] = configMap.value(config_key::cookieReplyPacketJunkSize);
// jsonConfig[config_key::transportPacketJunkSize] = configMap.value(config_key::transportPacketJunkSize);
if (container == DockerContainer::Awg2) {
jsonConfig[config_key::cookieReplyPacketJunkSize] = configMap.value(config_key::cookieReplyPacketJunkSize);
jsonConfig[config_key::transportPacketJunkSize] = configMap.value(config_key::transportPacketJunkSize);
}
// jsonConfig[config_key::specialJunk1] = configMap.value(amnezia::config_key::specialJunk1);
// jsonConfig[config_key::specialJunk2] = configMap.value(amnezia::config_key::specialJunk2);
// jsonConfig[config_key::specialJunk3] = configMap.value(amnezia::config_key::specialJunk3);
// jsonConfig[config_key::specialJunk4] = configMap.value(amnezia::config_key::specialJunk4);
// jsonConfig[config_key::specialJunk5] = configMap.value(amnezia::config_key::specialJunk5);
// jsonConfig[config_key::controlledJunk1] = configMap.value(amnezia::config_key::controlledJunk1);
// jsonConfig[config_key::controlledJunk2] = configMap.value(amnezia::config_key::controlledJunk2);
// jsonConfig[config_key::controlledJunk3] = configMap.value(amnezia::config_key::controlledJunk3);
// jsonConfig[config_key::specialHandshakeTimeout] = configMap.value(amnezia::config_key::specialHandshakeTimeout);
jsonConfig[config_key::specialJunk1] = configMap.value(amnezia::config_key::specialJunk1);
jsonConfig[config_key::specialJunk2] = configMap.value(amnezia::config_key::specialJunk2);
jsonConfig[config_key::specialJunk3] = configMap.value(amnezia::config_key::specialJunk3);
jsonConfig[config_key::specialJunk4] = configMap.value(amnezia::config_key::specialJunk4);
jsonConfig[config_key::specialJunk5] = configMap.value(amnezia::config_key::specialJunk5);
jsonConfig[config_key::mtu] =
containerConfig.value(ProtocolProps::protoToString(Proto::Awg)).toObject().value(config_key::mtu).toString(protocols::awg::defaultMtu);

View File

@@ -103,7 +103,11 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
return connData;
}
QString getIpsScript = QString("cat %1 | grep AllowedIPs").arg(m_serverConfigPath);
QString configPath = m_serverConfigPath;
if (container == DockerContainer::Awg) {
configPath = amnezia::protocols::awg::serverLegacyConfigPath;
}
QString getIpsScript = QString("cat %1 | grep AllowedIPs").arg(configPath);
QString stdOut;
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
stdOut += data + "\n";
@@ -161,15 +165,18 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
"AllowedIPs = %3/32\n\n")
.arg(connData.clientPubKey, connData.pskKey, connData.clientIP);
errorCode = m_serverController->uploadTextFileToContainer(container, credentials, configPart, m_serverConfigPath,
errorCode = m_serverController->uploadTextFileToContainer(container, credentials, configPart, configPath,
libssh::ScpOverwriteMode::ScpAppendToExisting);
if (errorCode != ErrorCode::NoError) {
return connData;
}
QString script = QString("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip %1)'")
.arg(m_serverConfigPath);
bool isAwg = (container == DockerContainer::Awg2);
QString bin = isAwg ? QStringLiteral("awg") : QStringLiteral("wg");
QString iface = isAwg ? QStringLiteral("awg0") : QStringLiteral("wg0");
QString script = QString(
"sudo docker exec -i $CONTAINER_NAME bash -c '%1 syncconf %2 <(%1-quick strip %3)'").arg(bin, iface, configPath);
errorCode = m_serverController->runScript(
credentials,

View File

@@ -28,6 +28,12 @@ QString ContainerProps::containerToString(amnezia::DockerContainer c)
return "none";
if (c == DockerContainer::Cloak)
return "amnezia-openvpn-cloak";
if (c == DockerContainer::Awg)
return "amnezia-awg";
if (c == DockerContainer::Awg1_5)
return "amnezia-awg1.5";
if (c == DockerContainer::Awg2)
return "amnezia-awg2";
QMetaEnum metaEnum = QMetaEnum::fromType<DockerContainer>();
QString containerKey = metaEnum.valueToKey(static_cast<int>(c));
@@ -41,6 +47,12 @@ QString ContainerProps::containerTypeToString(amnezia::DockerContainer c)
return "none";
if (c == DockerContainer::Ipsec)
return "ikev2";
if (c == DockerContainer::Awg)
return "awg";
if (c == DockerContainer::Awg1_5)
return "awg1.5";
if (c == DockerContainer::Awg2)
return "awg2";
QMetaEnum metaEnum = QMetaEnum::fromType<DockerContainer>();
QString containerKey = metaEnum.valueToKey(static_cast<int>(c));
@@ -71,6 +83,9 @@ QVector<amnezia::Proto> ContainerProps::protocolsForContainer(amnezia::DockerCon
case DockerContainer::Socks5Proxy: return { Proto::Socks5Proxy };
case DockerContainer::Awg: return { Proto::Awg };
case DockerContainer::Awg1_5: return { Proto::Awg };
case DockerContainer::Awg2: return { Proto::Awg };
default: return { defaultProtocol(container) };
}
}
@@ -93,6 +108,8 @@ QMap<DockerContainer, QString> ContainerProps::containerHumanNames()
{ DockerContainer::ShadowSocks, "OpenVPN over SS" },
{ DockerContainer::Cloak, "OpenVPN over Cloak" },
{ DockerContainer::WireGuard, "WireGuard" },
{ DockerContainer::Awg2, "AmneziaWG 2" },
{ DockerContainer::Awg1_5, "AmneziaWG 1.5" },
{ DockerContainer::Awg, "AmneziaWG" },
{ DockerContainer::Xray, "XRay" },
{ DockerContainer::Ipsec, QObject::tr("IPsec") },
@@ -117,6 +134,9 @@ QMap<DockerContainer, QString> ContainerProps::containerDescriptions()
{ DockerContainer::WireGuard,
QObject::tr("WireGuard - popular VPN protocol with high performance, high speed and low power "
"consumption.") },
{ DockerContainer::Awg2,
QObject::tr("AmneziaWG is a special protocol from Amnezia based on WireGuard. "
"It provides high connection speed and ensures stable operation even in the most challenging network conditions.") },
{ DockerContainer::Awg,
QObject::tr("AmneziaWG is a special protocol from Amnezia based on WireGuard. "
"It provides high connection speed and ensures stable operation even in the most challenging network conditions.") },
@@ -182,7 +202,7 @@ QMap<DockerContainer, QString> ContainerProps::containerDetailedDescriptions()
"* Minimal configuration required\n"
"* Easily detected by DPI systems (susceptible to blocking)\n"
"* Operates over UDP protocol") },
{ DockerContainer::Awg,
{ DockerContainer::Awg2,
QObject::tr("AmneziaWG is a modern VPN protocol based on WireGuard, "
"combining simplified architecture with high performance across all devices. "
"It addresses WireGuard's main vulnerability (easy detection by DPI systems) through advanced obfuscation techniques, "
@@ -194,6 +214,17 @@ QMap<DockerContainer, QString> ContainerProps::containerDetailedDescriptions()
"* Minimal settings required\n"
"* Undetectable by traffic analysis systems (DPI)\n"
"* Operates over UDP protocol") },
{ DockerContainer::Awg,
QObject::tr("AmneziaWG is an older version of the AmneziaWG protocol based on WireGuard."
"It addresses WireGuard's main vulnerability (easy detection by DPI systems) through advanced obfuscation techniques, "
"making VPN traffic indistinguishable from regular internet traffic.\n"
"\nAmneziaWG is an excellent choice for those seeking a fast, stealthy VPN connection.\n"
"\nFeatures:\n"
"* Available on all AmneziaVPN platforms\n"
"* Low battery consumption on mobile devices\n"
"* Minimal settings required\n"
"* Undetectable by traffic analysis systems (DPI)\n"
"* Operates over UDP protocol") },
{ DockerContainer::Xray,
QObject::tr("REALITY is an innovative protocol developed by the creators of XRay, designed specifically to combat high levels of internet censorship. "
"REALITY identifies censorship systems during the TLS handshake, "
@@ -242,6 +273,8 @@ Proto ContainerProps::defaultProtocol(DockerContainer c)
case DockerContainer::Cloak: return Proto::Cloak;
case DockerContainer::ShadowSocks: return Proto::ShadowSocks;
case DockerContainer::WireGuard: return Proto::WireGuard;
case DockerContainer::Awg2: return Proto::Awg;
case DockerContainer::Awg1_5: return Proto::Awg;
case DockerContainer::Awg: return Proto::Awg;
case DockerContainer::Xray: return Proto::Xray;
case DockerContainer::Ipsec: return Proto::Ikev2;
@@ -255,6 +288,15 @@ Proto ContainerProps::defaultProtocol(DockerContainer c)
}
}
QString ContainerProps::containerTypeToProtocolString(DockerContainer c)
{
if (c == DockerContainer::None)
return "none";
Proto p = defaultProtocol(c);
return ProtocolProps::protoToString(p);
}
bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
{
#ifdef Q_OS_WINDOWS
@@ -265,6 +307,8 @@ bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
switch (c) {
case DockerContainer::WireGuard: return true;
case DockerContainer::OpenVpn: return true;
case DockerContainer::Awg2: return true;
case DockerContainer::Awg1_5: return true;
case DockerContainer::Awg: return true;
case DockerContainer::Xray: return true;
case DockerContainer::Cloak: return true;
@@ -278,7 +322,8 @@ bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
// macOS build using Network Extension hide OpenVPN-based containers
switch (c) {
case DockerContainer::WireGuard: return true;
case DockerContainer::Awg: return true;
case DockerContainer::Awg2: return true;
case DockerContainer::Awg1_5: return true;
case DockerContainer::Xray: return true;
case DockerContainer::SSXray: return true;
case DockerContainer::OpenVpn:
@@ -300,6 +345,8 @@ bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
case DockerContainer::WireGuard: return true;
case DockerContainer::OpenVpn: return true;
case DockerContainer::ShadowSocks: return false;
case DockerContainer::Awg2: return true;
case DockerContainer::Awg1_5: return true;
case DockerContainer::Awg: return true;
case DockerContainer::Cloak: return true;
case DockerContainer::Xray: return true;
@@ -329,7 +376,7 @@ QStringList ContainerProps::fixedPortsForContainer(DockerContainer c)
bool ContainerProps::isEasySetupContainer(DockerContainer container)
{
switch (container) {
case DockerContainer::Awg: return true;
case DockerContainer::Awg2: return true;
default: return false;
}
}
@@ -337,7 +384,7 @@ bool ContainerProps::isEasySetupContainer(DockerContainer container)
QString ContainerProps::easySetupHeader(DockerContainer container)
{
switch (container) {
case DockerContainer::Awg: return tr("Automatic");
case DockerContainer::Awg2: return tr("Automatic");
default: return "";
}
}
@@ -345,7 +392,7 @@ QString ContainerProps::easySetupHeader(DockerContainer container)
QString ContainerProps::easySetupDescription(DockerContainer container)
{
switch (container) {
case DockerContainer::Awg: return tr("AmneziaWG protocol will be installed. "
case DockerContainer::Awg2: return tr("AmneziaWG protocol will be installed. "
"It provides high connection speed and ensures stable operation even in the most challenging network conditions.");
default: return "";
}
@@ -354,7 +401,7 @@ QString ContainerProps::easySetupDescription(DockerContainer container)
int ContainerProps::easySetupOrder(DockerContainer container)
{
switch (container) {
case DockerContainer::Awg: return 1;
case DockerContainer::Awg2: return 1;
default: return 0;
}
}
@@ -370,6 +417,11 @@ bool ContainerProps::isShareable(DockerContainer container)
}
}
bool ContainerProps::isAwgContainer(DockerContainer container)
{
return container == DockerContainer::Awg2 || container == DockerContainer::Awg || container == DockerContainer::Awg1_5;
}
QJsonObject ContainerProps::getProtocolConfigFromContainer(const Proto protocol, const QJsonObject &containerConfig)
{
QString protocolConfigString = containerConfig.value(ProtocolProps::protoToString(protocol))
@@ -387,7 +439,7 @@ int ContainerProps::installPageOrder(DockerContainer container)
case DockerContainer::Cloak: return 5;
case DockerContainer::ShadowSocks: return 6;
case DockerContainer::WireGuard: return 2;
case DockerContainer::Awg: return 1;
case DockerContainer::Awg2: return 1;
case DockerContainer::Xray: return 3;
case DockerContainer::Ipsec: return 7;
case DockerContainer::SSXray: return 8;

View File

@@ -16,6 +16,8 @@ namespace amnezia
Q_NAMESPACE
enum DockerContainer {
None = 0,
Awg2,
Awg1_5,
Awg,
WireGuard,
OpenVpn,
@@ -45,6 +47,7 @@ namespace amnezia
Q_INVOKABLE static amnezia::DockerContainer containerFromString(const QString &container);
Q_INVOKABLE static QString containerToString(amnezia::DockerContainer container);
Q_INVOKABLE static QString containerTypeToString(amnezia::DockerContainer c);
Q_INVOKABLE static QString containerTypeToProtocolString(amnezia::DockerContainer c);
Q_INVOKABLE static QList<amnezia::DockerContainer> allContainers();
@@ -71,6 +74,8 @@ namespace amnezia
static bool isShareable(amnezia::DockerContainer container);
static bool isAwgContainer(amnezia::DockerContainer container);
static QJsonObject getProtocolConfigFromContainer(const amnezia::Proto protocol, const QJsonObject &containerConfig);
static int installPageOrder(amnezia::DockerContainer container);

View File

@@ -345,7 +345,7 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
return true;
}
if (container == DockerContainer::Awg) {
if (ContainerProps::isAwgContainer(container)) {
if ((oldProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress)
!= newProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress))
|| (oldProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort)
@@ -367,11 +367,11 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
|| (oldProtoConfig.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader)
!= newProtoConfig.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader))
|| (oldProtoConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader))
!= newProtoConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader))
// || (oldProtoConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize)
// != newProtoConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize))
// || (oldProtoConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize)
// != newProtoConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize))
!= newProtoConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader)
|| (oldProtoConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize)
!= newProtoConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize))
|| (oldProtoConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize)
!= newProtoConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize)))
return true;
}
@@ -648,6 +648,11 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
vars.append({ { "$COOKIE_REPLY_PACKET_JUNK_SIZE", amneziaWireguarConfig.value(config_key::cookieReplyPacketJunkSize).toString() } });
vars.append({ { "$TRANSPORT_PACKET_JUNK_SIZE", amneziaWireguarConfig.value(config_key::transportPacketJunkSize).toString() } });
vars.append({ { "$SPECIAL_JUNK_1", amneziaWireguarConfig.value(config_key::specialJunk1).toString() } });
vars.append({ { "$SPECIAL_JUNK_2", amneziaWireguarConfig.value(config_key::specialJunk2).toString() } });
vars.append({ { "$SPECIAL_JUNK_3", amneziaWireguarConfig.value(config_key::specialJunk3).toString() } });
vars.append({ { "$SPECIAL_JUNK_4", amneziaWireguarConfig.value(config_key::specialJunk4).toString() } });
vars.append({ { "$SPECIAL_JUNK_5", amneziaWireguarConfig.value(config_key::specialJunk5).toString() } });
// Socks5 proxy vars
vars.append({ { "$SOCKS5_PROXY_PORT", socks5ProxyConfig.value(config_key::port).toString(protocols::socks5Proxy::defaultPort) } });
@@ -657,7 +662,8 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
vars.append({ { "$SOCKS5_USER", socks5user } });
vars.append({ { "$SOCKS5_AUTH_TYPE", socks5user.isEmpty() ? "none" : "strong" } });
QString serverIp = (container != DockerContainer::Awg && container != DockerContainer::WireGuard && container != DockerContainer::Xray)
QString serverIp = (!ContainerProps::isAwgContainer(container) &&
container != DockerContainer::WireGuard && container != DockerContainer::Xray)
? NetworkUtilities::getIPAddress(credentials.hostName)
: credentials.hostName;
if (!serverIp.isEmpty()) {

View File

@@ -99,11 +99,12 @@ QJsonObject VpnConfigurationsController::createVpnConfiguration(const QPair<QStr
protocolConfigString = configurator->processConfigWithLocalSettings(dns, isApiConfig, protocolConfigString);
QJsonObject vpnConfigData = QJsonDocument::fromJson(protocolConfigString.toUtf8()).object();
if (container == DockerContainer::Awg || container == DockerContainer::WireGuard) {
if (ContainerProps::isAwgContainer(container) || container == DockerContainer::WireGuard) {
// add mtu for old configs
if (vpnConfigData[config_key::mtu].toString().isEmpty()) {
vpnConfigData[config_key::mtu] =
container == DockerContainer::Awg ? protocols::awg::defaultMtu : protocols::wireguard::defaultMtu;
ContainerProps::isAwgContainer(container) ? protocols::awg::defaultMtu :
protocols::wireguard::defaultMtu;
}
}

View File

@@ -11,7 +11,8 @@ QString amnezia::scriptFolder(amnezia::DockerContainer container)
case DockerContainer::Cloak: return QLatin1String("openvpn_cloak");
case DockerContainer::ShadowSocks: return QLatin1String("openvpn_shadowsocks");
case DockerContainer::WireGuard: return QLatin1String("wireguard");
case DockerContainer::Awg: return QLatin1String("awg");
case DockerContainer::Awg2: return QLatin1String("awg");
case DockerContainer::Awg: return QLatin1String("awg_legacy");
case DockerContainer::Ipsec: return QLatin1String("ipsec");
case DockerContainer::Xray: return QLatin1String("xray");

View File

@@ -440,18 +440,6 @@ bool Daemon::parseConfig(const QJsonObject& obj, InterfaceConfig& config) {
if (!obj.value("I5").isNull()) {
config.m_specialJunk["I5"] = obj.value("I5").toString();
}
if (!obj.value("J1").isNull()) {
config.m_controlledJunk["J1"] = obj.value("J1").toString();
}
if (!obj.value("J2").isNull()) {
config.m_controlledJunk["J2"] = obj.value("J2").toString();
}
if (!obj.value("J3").isNull()) {
config.m_controlledJunk["J3"] = obj.value("J3").toString();
}
if (!obj.value("Itime").isNull()) {
config.m_specialHandshakeTimeout = obj.value("Itime").toString();
}
return true;
}

View File

@@ -152,12 +152,6 @@ QString InterfaceConfig::toWgConf(const QMap<QString, QString>& extra) const {
for (const QString& key : m_specialJunk.keys()) {
out << key << " = " << m_specialJunk[key] << "\n";
}
for (const QString& key : m_controlledJunk.keys()) {
out << key << " = " << m_controlledJunk[key] << "\n";
}
if (!m_specialHandshakeTimeout.isNull()) {
out << "Itime = " << m_specialHandshakeTimeout << "\n";
}
// If any extra config was provided, append it now.
for (const QString& key : extra.keys()) {

View File

@@ -57,8 +57,6 @@ class InterfaceConfig {
QString m_underloadPacketMagicHeader;
QString m_transportPacketMagicHeader;
QMap<QString, QString> m_specialJunk;
QMap<QString, QString> m_controlledJunk;
QString m_specialHandshakeTimeout;
QJsonObject toJson() const;
QString toWgConf(

View File

@@ -260,50 +260,38 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) {
json.insert(amnezia::config_key::specialJunk3, wgConfig.value(amnezia::config_key::specialJunk3));
json.insert(amnezia::config_key::specialJunk4, wgConfig.value(amnezia::config_key::specialJunk4));
json.insert(amnezia::config_key::specialJunk5, wgConfig.value(amnezia::config_key::specialJunk5));
json.insert(amnezia::config_key::controlledJunk1, wgConfig.value(amnezia::config_key::controlledJunk1));
json.insert(amnezia::config_key::controlledJunk2, wgConfig.value(amnezia::config_key::controlledJunk2));
json.insert(amnezia::config_key::controlledJunk3, wgConfig.value(amnezia::config_key::controlledJunk3));
json.insert(amnezia::config_key::specialHandshakeTimeout, wgConfig.value(amnezia::config_key::specialHandshakeTimeout));
} else if (!wgConfig.value(amnezia::config_key::junkPacketCount).isUndefined()
&& !wgConfig.value(amnezia::config_key::junkPacketMinSize).isUndefined()
&& !wgConfig.value(amnezia::config_key::junkPacketMaxSize).isUndefined()
&& !wgConfig.value(amnezia::config_key::initPacketJunkSize).isUndefined()
&& !wgConfig.value(amnezia::config_key::responsePacketJunkSize).isUndefined()
// && !wgConfig.value(amnezia::config_key::cookieReplyPacketJunkSize).isUndefined()
// && !wgConfig.value(amnezia::config_key::transportPacketJunkSize).isUndefined()
&& !wgConfig.value(amnezia::config_key::cookieReplyPacketJunkSize).isUndefined()
&& !wgConfig.value(amnezia::config_key::transportPacketJunkSize).isUndefined()
&& !wgConfig.value(amnezia::config_key::initPacketMagicHeader).isUndefined()
&& !wgConfig.value(amnezia::config_key::responsePacketMagicHeader).isUndefined()
&& !wgConfig.value(amnezia::config_key::underloadPacketMagicHeader).isUndefined()
&& !wgConfig.value(amnezia::config_key::transportPacketMagicHeader).isUndefined()
/* && !wgConfig.value(amnezia::config_key::specialJunk1).isUndefined()
&& !wgConfig.value(amnezia::config_key::specialJunk1).isUndefined()
&& !wgConfig.value(amnezia::config_key::specialJunk2).isUndefined()
&& !wgConfig.value(amnezia::config_key::specialJunk3).isUndefined()
&& !wgConfig.value(amnezia::config_key::specialJunk4).isUndefined()
&& !wgConfig.value(amnezia::config_key::specialJunk5).isUndefined()
&& !wgConfig.value(amnezia::config_key::controlledJunk1).isUndefined()
&& !wgConfig.value(amnezia::config_key::controlledJunk2).isUndefined()
&& !wgConfig.value(amnezia::config_key::controlledJunk3).isUndefined()
&& !wgConfig.value(amnezia::config_key::specialHandshakeTimeout).isUndefined()*/) {
&& !wgConfig.value(amnezia::config_key::specialJunk5).isUndefined()) {
json.insert(amnezia::config_key::junkPacketCount, wgConfig.value(amnezia::config_key::junkPacketCount));
json.insert(amnezia::config_key::junkPacketMinSize, wgConfig.value(amnezia::config_key::junkPacketMinSize));
json.insert(amnezia::config_key::junkPacketMaxSize, wgConfig.value(amnezia::config_key::junkPacketMaxSize));
json.insert(amnezia::config_key::initPacketJunkSize, wgConfig.value(amnezia::config_key::initPacketJunkSize));
json.insert(amnezia::config_key::responsePacketJunkSize, wgConfig.value(amnezia::config_key::responsePacketJunkSize));
// json.insert(amnezia::config_key::cookieReplyPacketJunkSize, wgConfig.value(amnezia::config_key::cookieReplyPacketJunkSize));
// json.insert(amnezia::config_key::transportPacketJunkSize, wgConfig.value(amnezia::config_key::transportPacketJunkSize));
json.insert(amnezia::config_key::cookieReplyPacketJunkSize, wgConfig.value(amnezia::config_key::cookieReplyPacketJunkSize));
json.insert(amnezia::config_key::transportPacketJunkSize, wgConfig.value(amnezia::config_key::transportPacketJunkSize));
json.insert(amnezia::config_key::initPacketMagicHeader, wgConfig.value(amnezia::config_key::initPacketMagicHeader));
json.insert(amnezia::config_key::responsePacketMagicHeader, wgConfig.value(amnezia::config_key::responsePacketMagicHeader));
json.insert(amnezia::config_key::underloadPacketMagicHeader, wgConfig.value(amnezia::config_key::underloadPacketMagicHeader));
json.insert(amnezia::config_key::transportPacketMagicHeader, wgConfig.value(amnezia::config_key::transportPacketMagicHeader));
// json.insert(amnezia::config_key::specialJunk1, wgConfig.value(amnezia::config_key::specialJunk1));
// json.insert(amnezia::config_key::specialJunk2, wgConfig.value(amnezia::config_key::specialJunk2));
// json.insert(amnezia::config_key::specialJunk3, wgConfig.value(amnezia::config_key::specialJunk3));
// json.insert(amnezia::config_key::specialJunk4, wgConfig.value(amnezia::config_key::specialJunk4));
// json.insert(amnezia::config_key::specialJunk5, wgConfig.value(amnezia::config_key::specialJunk5));
// json.insert(amnezia::config_key::controlledJunk1, wgConfig.value(amnezia::config_key::controlledJunk1));
// json.insert(amnezia::config_key::controlledJunk2, wgConfig.value(amnezia::config_key::controlledJunk2));
// json.insert(amnezia::config_key::controlledJunk3, wgConfig.value(amnezia::config_key::controlledJunk3));
// json.insert(amnezia::config_key::specialHandshakeTimeout, wgConfig.value(amnezia::config_key::specialHandshakeTimeout));
json.insert(amnezia::config_key::specialJunk1, wgConfig.value(amnezia::config_key::specialJunk1));
json.insert(amnezia::config_key::specialJunk2, wgConfig.value(amnezia::config_key::specialJunk2));
json.insert(amnezia::config_key::specialJunk3, wgConfig.value(amnezia::config_key::specialJunk3));
json.insert(amnezia::config_key::specialJunk4, wgConfig.value(amnezia::config_key::specialJunk4));
json.insert(amnezia::config_key::specialJunk5, wgConfig.value(amnezia::config_key::specialJunk5));
}
write(json);

View File

@@ -6,8 +6,6 @@ struct WGConfig: Decodable {
let junkPacketCount, junkPacketMinSize, junkPacketMaxSize: String?
let initPacketJunkSize, responsePacketJunkSize, cookieReplyPacketJunkSize, transportPacketJunkSize: String?
let specialJunk1, specialJunk2, specialJunk3, specialJunk4, specialJunk5: String?
let controlledJunk1, controlledJunk2, controlledJunk3: String?
let specialHandshakeTimeout: String?
let dns1: String
let dns2: String
let mtu: String
@@ -28,8 +26,6 @@ struct WGConfig: Decodable {
case junkPacketCount = "Jc", junkPacketMinSize = "Jmin", junkPacketMaxSize = "Jmax"
case initPacketJunkSize = "S1", responsePacketJunkSize = "S2", cookieReplyPacketJunkSize = "S3", transportPacketJunkSize = "S4"
case specialJunk1 = "I1", specialJunk2 = "I2", specialJunk3 = "I3", specialJunk4 = "I4", specialJunk5 = "I5"
case controlledJunk1 = "J1", controlledJunk2 = "J2", controlledJunk3 = "J3"
case specialHandshakeTimeout = "Itime"
case dns1
case dns2
case mtu
@@ -85,18 +81,6 @@ struct WGConfig: Decodable {
if let i5 = specialJunk5, !i5.isEmpty {
settingsLines.append("I5 = \(i5)")
}
if let j1 = controlledJunk1, !j1.isEmpty {
settingsLines.append("J1 = \(j1)")
}
if let j2 = controlledJunk2, !j2.isEmpty {
settingsLines.append("J2 = \(j2)")
}
if let j3 = controlledJunk3, !j3.isEmpty {
settingsLines.append("J3 = \(j3)")
}
if let itime = specialHandshakeTimeout, !itime.isEmpty {
settingsLines.append("Itime = \(itime)")
}
return settingsLines.joined(separator: "\n")
}

View File

@@ -670,10 +670,6 @@ bool IosController::setupAwg()
wgConfig.insert(config_key::specialJunk3, config[config_key::specialJunk3]);
wgConfig.insert(config_key::specialJunk4, config[config_key::specialJunk4]);
wgConfig.insert(config_key::specialJunk5, config[config_key::specialJunk5]);
wgConfig.insert(config_key::controlledJunk1, config[config_key::controlledJunk1]);
wgConfig.insert(config_key::controlledJunk2, config[config_key::controlledJunk2]);
wgConfig.insert(config_key::controlledJunk3, config[config_key::controlledJunk3]);
wgConfig.insert(config_key::specialHandshakeTimeout, config[config_key::specialHandshakeTimeout]);
QJsonDocument wgConfigDoc(wgConfig);
QString wgConfigDocStr(wgConfigDoc.toJson(QJsonDocument::Compact));

View File

@@ -143,12 +143,6 @@ bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) {
for (const QString& key : config.m_specialJunk.keys()) {
out << key.toLower() << "=" << config.m_specialJunk.value(key) << "\n";
}
for (const QString& key : config.m_controlledJunk.keys()) {
out << key.toLower() << "=" << config.m_controlledJunk.value(key) << "\n";
}
if (!config.m_specialHandshakeTimeout.isEmpty()) {
out << "itime=" << config.m_specialHandshakeTimeout << "\n";
}
int err = uapiErrno(uapiCommand(message));
if (err != 0) {

View File

@@ -141,12 +141,6 @@ bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) {
for (const QString& key : config.m_specialJunk.keys()) {
out << key.toLower() << "=" << config.m_specialJunk.value(key) << "\n";
}
for (const QString& key : config.m_controlledJunk.keys()) {
out << key.toLower() << "=" << config.m_controlledJunk.value(key) << "\n";
}
if (!config.m_specialHandshakeTimeout.isEmpty()) {
out << "itime=" << config.m_specialHandshakeTimeout << "\n";
}
int err = uapiErrno(uapiCommand(message));
if (err != 0) {

View File

@@ -83,10 +83,6 @@ namespace amnezia
constexpr char specialJunk3[] = "I3";
constexpr char specialJunk4[] = "I4";
constexpr char specialJunk5[] = "I5";
constexpr char controlledJunk1[] = "J1";
constexpr char controlledJunk2[] = "J2";
constexpr char controlledJunk3[] = "J3";
constexpr char specialHandshakeTimeout[] = "Itime";
constexpr char openvpn[] = "openvpn";
constexpr char wireguard[] = "wireguard";
@@ -218,7 +214,8 @@ namespace amnezia
constexpr char defaultMtu[] = "1376";
#endif
constexpr char serverConfigPath[] = "/opt/amnezia/awg/wg0.conf";
constexpr char serverConfigPath[] = "/opt/amnezia/awg/awg0.conf";
constexpr char serverLegacyConfigPath[] = "/opt/amnezia/awg/wg0.conf";
constexpr char serverPublicKeyPath[] = "/opt/amnezia/awg/wireguard_server_public_key.key";
constexpr char serverPskKeyPath[] = "/opt/amnezia/awg/wireguard_psk.key";
@@ -239,10 +236,6 @@ namespace amnezia
constexpr char defaultSpecialJunk3[] = "";
constexpr char defaultSpecialJunk4[] = "";
constexpr char defaultSpecialJunk5[] = "";
constexpr char defaultControlledJunk1[] = "";
constexpr char defaultControlledJunk2[] = "";
constexpr char defaultControlledJunk3[] = "";
constexpr char defaultSpecialHandshakeTimeout[] = "";
}
namespace socks5Proxy

View File

@@ -119,6 +119,7 @@ VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject &
case DockerContainer::Cloak: return new OpenVpnOverCloakProtocol(configuration);
case DockerContainer::ShadowSocks: return new ShadowSocksVpnProtocol(configuration);
case DockerContainer::WireGuard: return new WireguardProtocol(configuration);
case DockerContainer::Awg2: return new WireguardProtocol(configuration);
case DockerContainer::Awg: return new WireguardProtocol(configuration);
case DockerContainer::Xray: return new XrayProtocol(configuration);
case DockerContainer::SSXray: return new XrayProtocol(configuration);

View File

@@ -68,6 +68,11 @@
<file>server_scripts/awg/run_container.sh</file>
<file>server_scripts/awg/start.sh</file>
<file>server_scripts/awg/template.conf</file>
<file>server_scripts/awg_legacy/configure_container.sh</file>
<file>server_scripts/awg_legacy/Dockerfile</file>
<file>server_scripts/awg_legacy/run_container.sh</file>
<file>server_scripts/awg_legacy/start.sh</file>
<file>server_scripts/awg_legacy/template.conf</file>
<file>server_scripts/build_container.sh</file>
<file>server_scripts/check_connection.sh</file>
<file>server_scripts/check_server_is_busy.sh</file>

View File

@@ -1,4 +1,4 @@
FROM amneziavpn/amnezia-wg:latest
FROM amneziavpn/amneziawg-go:latest
LABEL maintainer="AmneziaVPN"

View File

@@ -1,15 +1,15 @@
mkdir -p /opt/amnezia/awg
cd /opt/amnezia/awg
WIREGUARD_SERVER_PRIVATE_KEY=$(wg genkey)
WIREGUARD_SERVER_PRIVATE_KEY=$(awg genkey)
echo $WIREGUARD_SERVER_PRIVATE_KEY > /opt/amnezia/awg/wireguard_server_private_key.key
WIREGUARD_SERVER_PUBLIC_KEY=$(echo $WIREGUARD_SERVER_PRIVATE_KEY | wg pubkey)
WIREGUARD_SERVER_PUBLIC_KEY=$(echo $WIREGUARD_SERVER_PRIVATE_KEY | awg pubkey)
echo $WIREGUARD_SERVER_PUBLIC_KEY > /opt/amnezia/awg/wireguard_server_public_key.key
WIREGUARD_PSK=$(wg genpsk)
WIREGUARD_PSK=$(awg genpsk)
echo $WIREGUARD_PSK > /opt/amnezia/awg/wireguard_psk.key
cat > /opt/amnezia/awg/wg0.conf <<EOF
cat > /opt/amnezia/awg/awg0.conf <<EOF
[Interface]
PrivateKey = $WIREGUARD_SERVER_PRIVATE_KEY
Address = $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR
@@ -19,6 +19,8 @@ Jmin = $JUNK_PACKET_MIN_SIZE
Jmax = $JUNK_PACKET_MAX_SIZE
S1 = $INIT_PACKET_JUNK_SIZE
S2 = $RESPONSE_PACKET_JUNK_SIZE
S3 = $COOKIE_REPLY_PACKET_JUNK_SIZE
S4 = $TRANSPORT_PACKET_JUNK_SIZE
H1 = $INIT_PACKET_MAGIC_HEADER
H2 = $RESPONSE_PACKET_MAGIC_HEADER
H3 = $UNDERLOAD_PACKET_MAGIC_HEADER

View File

@@ -6,19 +6,19 @@ echo "Container startup"
#ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up
# kill daemons in case of restart
wg-quick down /opt/amnezia/awg/wg0.conf
awg-quick down /opt/amnezia/awg/awg0.conf
# start daemons if configured
if [ -f /opt/amnezia/awg/wg0.conf ]; then (wg-quick up /opt/amnezia/awg/wg0.conf); fi
if [ -f /opt/amnezia/awg/awg0.conf ]; then (awg-quick up /opt/amnezia/awg/awg0.conf); fi
# Allow traffic on the TUN interface.
iptables -A INPUT -i wg0 -j ACCEPT
iptables -A FORWARD -i wg0 -j ACCEPT
iptables -A OUTPUT -o wg0 -j ACCEPT
iptables -A INPUT -i awg0 -j ACCEPT
iptables -A FORWARD -i awg0 -j ACCEPT
iptables -A OUTPUT -o awg0 -j ACCEPT
# Allow forwarding traffic only from the VPN.
iptables -A FORWARD -i wg0 -o eth0 -s $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT
iptables -A FORWARD -i wg0 -o eth1 -s $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT
iptables -A FORWARD -i awg0 -o eth0 -s $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT
iptables -A FORWARD -i awg0 -o eth1 -s $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

View File

@@ -7,10 +7,17 @@ Jmin = $JUNK_PACKET_MIN_SIZE
Jmax = $JUNK_PACKET_MAX_SIZE
S1 = $INIT_PACKET_JUNK_SIZE
S2 = $RESPONSE_PACKET_JUNK_SIZE
S3 = $COOKIE_REPLY_PACKET_JUNK_SIZE
S4 = $TRANSPORT_PACKET_JUNK_SIZE
H1 = $INIT_PACKET_MAGIC_HEADER
H2 = $RESPONSE_PACKET_MAGIC_HEADER
H3 = $UNDERLOAD_PACKET_MAGIC_HEADER
H4 = $TRANSPORT_PACKET_MAGIC_HEADER
I1 = $SPECIAL_JUNK_1
I2 = $SPECIAL_JUNK_2
I3 = $SPECIAL_JUNK_3
I4 = $SPECIAL_JUNK_4
I5 = $SPECIAL_JUNK_5
[Peer]
PublicKey = $WIREGUARD_SERVER_PUBLIC_KEY

View File

@@ -0,0 +1,46 @@
FROM amneziavpn/amnezia-wg:latest
LABEL maintainer="AmneziaVPN"
#Install required packages
RUN apk add --no-cache bash curl dumb-init
RUN apk --update upgrade --no-cache
RUN mkdir -p /opt/amnezia
RUN echo -e "#!/bin/bash\ntail -f /dev/null" > /opt/amnezia/start.sh
RUN chmod a+x /opt/amnezia/start.sh
# Tune network
RUN echo -e " \n\
fs.file-max = 51200 \n\
\n\
net.core.rmem_max = 67108864 \n\
net.core.wmem_max = 67108864 \n\
net.core.netdev_max_backlog = 250000 \n\
net.core.somaxconn = 4096 \n\
\n\
net.ipv4.tcp_syncookies = 1 \n\
net.ipv4.tcp_tw_reuse = 1 \n\
net.ipv4.tcp_tw_recycle = 0 \n\
net.ipv4.tcp_fin_timeout = 30 \n\
net.ipv4.tcp_keepalive_time = 1200 \n\
net.ipv4.ip_local_port_range = 10000 65000 \n\
net.ipv4.tcp_max_syn_backlog = 8192 \n\
net.ipv4.tcp_max_tw_buckets = 5000 \n\
net.ipv4.tcp_fastopen = 3 \n\
net.ipv4.tcp_mem = 25600 51200 102400 \n\
net.ipv4.tcp_rmem = 4096 87380 67108864 \n\
net.ipv4.tcp_wmem = 4096 65536 67108864 \n\
net.ipv4.tcp_mtu_probing = 1 \n\
net.ipv4.tcp_congestion_control = hybla \n\
# for low-latency network, use cubic instead \n\
# net.ipv4.tcp_congestion_control = cubic \n\
" | sed -e 's/^\s\+//g' | tee -a /etc/sysctl.conf && \
mkdir -p /etc/security && \
echo -e " \n\
* soft nofile 51200 \n\
* hard nofile 51200 \n\
" | sed -e 's/^\s\+//g' | tee -a /etc/security/limits.conf
ENTRYPOINT [ "dumb-init", "/opt/amnezia/start.sh" ]
CMD [ "" ]

View File

@@ -0,0 +1,26 @@
mkdir -p /opt/amnezia/awg
cd /opt/amnezia/awg
WIREGUARD_SERVER_PRIVATE_KEY=$(wg genkey)
echo $WIREGUARD_SERVER_PRIVATE_KEY > /opt/amnezia/awg/wireguard_server_private_key.key
WIREGUARD_SERVER_PUBLIC_KEY=$(echo $WIREGUARD_SERVER_PRIVATE_KEY | wg pubkey)
echo $WIREGUARD_SERVER_PUBLIC_KEY > /opt/amnezia/awg/wireguard_server_public_key.key
WIREGUARD_PSK=$(wg genpsk)
echo $WIREGUARD_PSK > /opt/amnezia/awg/wireguard_psk.key
cat > /opt/amnezia/awg/wg0.conf <<EOF
[Interface]
PrivateKey = $WIREGUARD_SERVER_PRIVATE_KEY
Address = $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR
ListenPort = $AWG_SERVER_PORT
Jc = $JUNK_PACKET_COUNT
Jmin = $JUNK_PACKET_MIN_SIZE
Jmax = $JUNK_PACKET_MAX_SIZE
S1 = $INIT_PACKET_JUNK_SIZE
S2 = $RESPONSE_PACKET_JUNK_SIZE
H1 = $INIT_PACKET_MAGIC_HEADER
H2 = $RESPONSE_PACKET_MAGIC_HEADER
H3 = $UNDERLOAD_PACKET_MAGIC_HEADER
H4 = $TRANSPORT_PACKET_MAGIC_HEADER
EOF

View File

@@ -0,0 +1,18 @@
# Run container
sudo docker run -d \
--log-driver none \
--restart always \
--privileged \
--cap-add=NET_ADMIN \
--cap-add=SYS_MODULE \
-p $AWG_SERVER_PORT:$AWG_SERVER_PORT/udp \
-v /lib/modules:/lib/modules \
--sysctl="net.ipv4.conf.all.src_valid_mark=1" \
--name $CONTAINER_NAME \
$CONTAINER_NAME
sudo docker network connect amnezia-dns-net $CONTAINER_NAME
# Prevent to route packets outside of the container in case if server behind of the NAT
#sudo docker exec -i $CONTAINER_NAME sh -c "ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up"

View File

@@ -0,0 +1,28 @@
#!/bin/bash
# This scripts copied from Amnezia client to Docker container to /opt/amnezia and launched every time container starts
echo "Container startup"
#ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up
# kill daemons in case of restart
wg-quick down /opt/amnezia/awg/wg0.conf
# start daemons if configured
if [ -f /opt/amnezia/awg/wg0.conf ]; then (wg-quick up /opt/amnezia/awg/wg0.conf); fi
# Allow traffic on the TUN interface.
iptables -A INPUT -i wg0 -j ACCEPT
iptables -A FORWARD -i wg0 -j ACCEPT
iptables -A OUTPUT -o wg0 -j ACCEPT
# Allow forwarding traffic only from the VPN.
iptables -A FORWARD -i wg0 -o eth0 -s $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT
iptables -A FORWARD -i wg0 -o eth1 -s $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -s $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -o eth1 -j MASQUERADE
tail -f /dev/null

View File

@@ -0,0 +1,20 @@
[Interface]
Address = $WIREGUARD_CLIENT_IP/32
DNS = $PRIMARY_DNS, $SECONDARY_DNS
PrivateKey = $WIREGUARD_CLIENT_PRIVATE_KEY
Jc = $JUNK_PACKET_COUNT
Jmin = $JUNK_PACKET_MIN_SIZE
Jmax = $JUNK_PACKET_MAX_SIZE
S1 = $INIT_PACKET_JUNK_SIZE
S2 = $RESPONSE_PACKET_JUNK_SIZE
H1 = $INIT_PACKET_MAGIC_HEADER
H2 = $RESPONSE_PACKET_MAGIC_HEADER
H3 = $UNDERLOAD_PACKET_MAGIC_HEADER
H4 = $TRANSPORT_PACKET_MAGIC_HEADER
[Peer]
PublicKey = $WIREGUARD_SERVER_PUBLIC_KEY
PresharedKey = $WIREGUARD_PSK
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = $SERVER_IP_ADDRESS:$AWG_SERVER_PORT
PersistentKeepalive = 25

View File

@@ -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());
}

View File

@@ -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;

View File

@@ -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);
}

80
client/ui/controllers/installController.cpp Executable file → Normal file
View File

@@ -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;

View File

@@ -104,7 +104,7 @@ ErrorCode ClientManagementModel::updateModel(const DockerContainer container, co
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
error = getOpenVpnClients(container, credentials, serverController, count);
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
} else if (container == DockerContainer::WireGuard || ContainerProps::isAwgContainer(container)) {
error = getWireGuardClients(container, credentials, serverController, count);
} else if (container == DockerContainer::Xray) {
error = getXrayClients(container, credentials, serverController, count);
@@ -209,8 +209,15 @@ ErrorCode ClientManagementModel::getWireGuardClients(const DockerContainer conta
{
ErrorCode error = ErrorCode::NoError;
const QString wireGuardConfigFile = QString("opt/amnezia/%1/wg0.conf").arg(container == DockerContainer::WireGuard ? "wireguard" : "awg");
const QString wireguardConfigString = serverController->getTextFileFromContainer(container, credentials, wireGuardConfigFile, error);
QString configPath;
if (container == DockerContainer::Awg) {
configPath = QString::fromLatin1(amnezia::protocols::awg::serverLegacyConfigPath);
} else if (container == DockerContainer::Awg2) {
configPath = QString::fromLatin1(amnezia::protocols::awg::serverConfigPath);
} else {
configPath = QString::fromLatin1(amnezia::protocols::wireguard::serverConfigPath);
}
const QString wireguardConfigString = serverController->getTextFileFromContainer(container, credentials, configPath, error);
if (error != ErrorCode::NoError) {
logger.error() << "Failed to get the wg conf file from the server";
return error;
@@ -307,7 +314,7 @@ ErrorCode ClientManagementModel::getXrayClients(const DockerContainer container,
ErrorCode ClientManagementModel::wgShow(const DockerContainer container, const ServerCredentials &credentials,
const QSharedPointer<ServerController> &serverController, std::vector<WgShowData> &data)
{
if (container != DockerContainer::WireGuard && container != DockerContainer::Awg) {
if (container != DockerContainer::WireGuard && !ContainerProps::isAwgContainer(container)) {
return ErrorCode::NoError;
}
@@ -318,7 +325,11 @@ ErrorCode ClientManagementModel::wgShow(const DockerContainer container, const S
return ErrorCode::NoError;
};
const QString command = QString("sudo docker exec -i $CONTAINER_NAME bash -c '%1'").arg("wg show all");
QString showBin = (container == DockerContainer::Awg2)
? QStringLiteral("awg")
: QStringLiteral("wg");
const QString command = QString("sudo docker exec -i $CONTAINER_NAME bash -c '%1 show all'")
.arg(showBin);
QString script = serverController->replaceVars(command, serverController->genVarsForScript(credentials, container));
error = serverController->runScript(credentials, script, cbReadStdOut);
@@ -397,6 +408,7 @@ ErrorCode ClientManagementModel::appendClient(const DockerContainer container, c
break;
case DockerContainer::OpenVpn:
case DockerContainer::WireGuard:
case DockerContainer::Awg2:
case DockerContainer::Awg:
case DockerContainer::Xray:
protocol = ContainerProps::defaultProtocol(container);
@@ -547,6 +559,7 @@ ErrorCode ClientManagementModel::revokeClient(const int row, const DockerContain
break;
}
case DockerContainer::WireGuard:
case DockerContainer::Awg2:
case DockerContainer::Awg: {
errorCode = revokeWireGuard(row, container, credentials, serverController);
break;
@@ -606,6 +619,7 @@ ErrorCode ClientManagementModel::revokeClient(const QJsonObject &containerConfig
}
case DockerContainer::OpenVpn:
case DockerContainer::WireGuard:
case DockerContainer::Awg2:
case DockerContainer::Awg:
case DockerContainer::Xray: {
protocol = ContainerProps::defaultProtocol(container);
@@ -679,7 +693,8 @@ ErrorCode ClientManagementModel::revokeClient(const QJsonObject &containerConfig
break;
}
case DockerContainer::WireGuard:
case DockerContainer::Awg: {
case DockerContainer::Awg:
case DockerContainer::Awg2: {
errorCode = revokeWireGuard(row, container, credentials, serverController);
break;
}
@@ -738,9 +753,15 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
{
ErrorCode error = ErrorCode::NoError;
const QString wireGuardConfigFile =
QString("/opt/amnezia/%1/wg0.conf").arg(container == DockerContainer::WireGuard ? "wireguard" : "awg");
const QString wireguardConfigString = serverController->getTextFileFromContainer(container, credentials, wireGuardConfigFile, error);
QString configPath;
if (container == DockerContainer::Awg) {
configPath = QString::fromLatin1(amnezia::protocols::awg::serverLegacyConfigPath);
} else if (container == DockerContainer::Awg2) {
configPath = QString::fromLatin1(amnezia::protocols::awg::serverConfigPath);
} else {
configPath = QString::fromLatin1(amnezia::protocols::wireguard::serverConfigPath);
}
const QString wireguardConfigString = serverController->getTextFileFromContainer(container, credentials, configPath, error);
if (error != ErrorCode::NoError) {
logger.error() << "Failed to get the wg conf file from the server";
return error;
@@ -758,7 +779,7 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
}
QString newWireGuardConfig = configSections.join("[");
newWireGuardConfig.insert(0, "[");
error = serverController->uploadTextFileToContainer(container, credentials, newWireGuardConfig, wireGuardConfigFile);
error = serverController->uploadTextFileToContainer(container, credentials, newWireGuardConfig, configPath);
if (error != ErrorCode::NoError) {
logger.error() << "Failed to upload the wg conf file to the server";
return error;
@@ -782,12 +803,18 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
return error;
}
const QString script = "sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip %1)'";
bool isAwg = (container == DockerContainer::Awg2);
QString command = isAwg ? QStringLiteral("awg") : QStringLiteral("wg");
QString iface = isAwg ? QStringLiteral("awg0") : QStringLiteral("wg0");
QString script = QString(
"sudo docker exec -i $CONTAINER_NAME bash -c '%1 syncconf %2 <(%1-quick strip %3)'"
).arg(command, iface, configPath);
error = serverController->runScript(
credentials,
serverController->replaceVars(script.arg(wireGuardConfigFile), serverController->genVarsForScript(credentials, container)));
credentials,
serverController->replaceVars(script, serverController->genVarsForScript(credentials, container))
);
if (error != ErrorCode::NoError) {
logger.error() << "Failed to execute the command 'wg syncconf' on the server";
logger.error() << QString("Failed to execute command '%1 syncconf %2' on the server").arg(command, iface);
return error;
}
@@ -915,4 +942,4 @@ QHash<int, QByteArray> ClientManagementModel::roleNames() const
roles[DataSentRole] = "dataSent";
roles[AllowedIpsRole] = "allowedIps";
return roles;
}
}

View File

@@ -31,12 +31,17 @@ QVariant ContainersModel::data(const QModelIndex &index, int role) const
}
return m_containers.value(container);
}
case IsThirdPartyConfigRole: {
QString protocolKey = ContainerProps::containerTypeToProtocolString(container);
return m_containers.value(container).value(protocolKey).toObject().value(config_key::isThirdPartyConfig).toBool();
}
case ServiceTypeRole: return ContainerProps::containerService(container);
case DockerContainerRole: return container;
case IsEasySetupContainerRole: return ContainerProps::isEasySetupContainer(container);
case EasySetupHeaderRole: return ContainerProps::easySetupHeader(container);
case EasySetupDescriptionRole: return ContainerProps::easySetupDescription(container);
case EasySetupOrderRole: return ContainerProps::easySetupOrder(container);
case IsInstallationAllowedRole: return ContainersModel::isInstallationAllowed(container);
case IsInstalledRole: return m_containers.contains(container);
case IsCurrentlyProcessedRole: return container == static_cast<DockerContainer>(m_processedContainerIndex);
case IsSupportedRole: return ContainerProps::isSupportedByCurrentPlatform(container);
@@ -114,6 +119,11 @@ bool ContainersModel::hasInstalledProtocols()
return false;
}
bool ContainersModel::isInstallationAllowed(DockerContainer container)
{
return container != DockerContainer::Awg && container != DockerContainer::Awg1_5;
}
QHash<int, QByteArray> ContainersModel::roleNames() const
{
QHash<int, QByteArray> roles;
@@ -123,6 +133,7 @@ QHash<int, QByteArray> ContainersModel::roleNames() const
roles[ServiceTypeRole] = "serviceType";
roles[DockerContainerRole] = "dockerContainer";
roles[ConfigRole] = "config";
roles[IsThirdPartyConfigRole] = "isThirdPartyConfig";
roles[IsEasySetupContainerRole] = "isEasySetupContainer";
roles[EasySetupHeaderRole] = "easySetupHeader";
@@ -133,7 +144,7 @@ QHash<int, QByteArray> ContainersModel::roleNames() const
roles[IsCurrentlyProcessedRole] = "isCurrentlyProcessed";
roles[IsSupportedRole] = "isSupported";
roles[IsShareableRole] = "isShareable";
roles[IsInstallationAllowedRole] = "isInstallationAllowed";
roles[InstallPageOrderRole] = "installPageOrder";
return roles;
}

View File

@@ -20,6 +20,7 @@ public:
DetailedDescriptionRole,
ServiceTypeRole,
ConfigRole,
IsThirdPartyConfigRole,
DockerContainerRole,
IsEasySetupContainerRole,
@@ -27,6 +28,7 @@ public:
EasySetupDescriptionRole,
EasySetupOrderRole,
IsInstallationAllowedRole,
IsInstalledRole,
IsCurrentlyProcessedRole,
IsDefaultRole,
@@ -57,6 +59,8 @@ public slots:
bool hasInstalledServices();
bool hasInstalledProtocols();
static bool isInstallationAllowed(DockerContainer container);
protected:
QHash<int, QByteArray> roleNames() const override;

View File

@@ -33,12 +33,6 @@ bool AwgConfigModel::setData(const QModelIndex &index, const QVariant &value, in
case Roles::ClientSpecialJunk3Role: m_clientProtocolConfig.insert(config_key::specialJunk3, value.toString()); break;
case Roles::ClientSpecialJunk4Role: m_clientProtocolConfig.insert(config_key::specialJunk4, value.toString()); break;
case Roles::ClientSpecialJunk5Role: m_clientProtocolConfig.insert(config_key::specialJunk5, value.toString()); break;
case Roles::ClientControlledJunk1Role: m_clientProtocolConfig.insert(config_key::controlledJunk1, value.toString()); break;
case Roles::ClientControlledJunk2Role: m_clientProtocolConfig.insert(config_key::controlledJunk2, value.toString()); break;
case Roles::ClientControlledJunk3Role: m_clientProtocolConfig.insert(config_key::controlledJunk3, value.toString()); break;
case Roles::ClientSpecialHandshakeTimeoutRole:
m_clientProtocolConfig.insert(config_key::specialHandshakeTimeout, value.toString());
break;
case Roles::ServerJunkPacketCountRole: m_serverProtocolConfig.insert(config_key::junkPacketCount, value.toString()); break;
case Roles::ServerJunkPacketMinSizeRole: m_serverProtocolConfig.insert(config_key::junkPacketMinSize, value.toString()); break;
case Roles::ServerJunkPacketMaxSizeRole: m_serverProtocolConfig.insert(config_key::junkPacketMaxSize, value.toString()); break;
@@ -46,12 +40,12 @@ bool AwgConfigModel::setData(const QModelIndex &index, const QVariant &value, in
case Roles::ServerResponsePacketJunkSizeRole:
m_serverProtocolConfig.insert(config_key::responsePacketJunkSize, value.toString());
break;
// case Roles::ServerCookieReplyPacketJunkSizeRole:
// m_serverProtocolConfig.insert(config_key::cookieReplyPacketJunkSize, value.toString());
// break;
// case Roles::ServerTransportPacketJunkSizeRole:
// m_serverProtocolConfig.insert(config_key::transportPacketJunkSize, value.toString());
// break;
case Roles::ServerCookieReplyPacketJunkSizeRole:
m_serverProtocolConfig.insert(config_key::cookieReplyPacketJunkSize, value.toString());
break;
case Roles::ServerTransportPacketJunkSizeRole:
m_serverProtocolConfig.insert(config_key::transportPacketJunkSize, value.toString());
break;
case Roles::ServerInitPacketMagicHeaderRole: m_serverProtocolConfig.insert(config_key::initPacketMagicHeader, value.toString()); break;
case Roles::ServerResponsePacketMagicHeaderRole:
m_serverProtocolConfig.insert(config_key::responsePacketMagicHeader, value.toString());
@@ -87,22 +81,20 @@ QVariant AwgConfigModel::data(const QModelIndex &index, int role) const
case Roles::ClientSpecialJunk3Role: return m_clientProtocolConfig.value(config_key::specialJunk3);
case Roles::ClientSpecialJunk4Role: return m_clientProtocolConfig.value(config_key::specialJunk4);
case Roles::ClientSpecialJunk5Role: return m_clientProtocolConfig.value(config_key::specialJunk5);
case Roles::ClientControlledJunk1Role: return m_clientProtocolConfig.value(config_key::controlledJunk1);
case Roles::ClientControlledJunk2Role: return m_clientProtocolConfig.value(config_key::controlledJunk2);
case Roles::ClientControlledJunk3Role: return m_clientProtocolConfig.value(config_key::controlledJunk3);
case Roles::ClientSpecialHandshakeTimeoutRole: return m_clientProtocolConfig.value(config_key::specialHandshakeTimeout);
case Roles::ServerJunkPacketCountRole: return m_serverProtocolConfig.value(config_key::junkPacketCount);
case Roles::ServerJunkPacketMinSizeRole: return m_serverProtocolConfig.value(config_key::junkPacketMinSize);
case Roles::ServerJunkPacketMaxSizeRole: return m_serverProtocolConfig.value(config_key::junkPacketMaxSize);
case Roles::ServerInitPacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::initPacketJunkSize);
case Roles::ServerResponsePacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::responsePacketJunkSize);
// case Roles::ServerCookieReplyPacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::cookieReplyPacketJunkSize);
// case Roles::ServerTransportPacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::transportPacketJunkSize);
case Roles::ServerCookieReplyPacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::cookieReplyPacketJunkSize);
case Roles::ServerTransportPacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::transportPacketJunkSize);
case Roles::ServerInitPacketMagicHeaderRole: return m_serverProtocolConfig.value(config_key::initPacketMagicHeader);
case Roles::ServerResponsePacketMagicHeaderRole: return m_serverProtocolConfig.value(config_key::responsePacketMagicHeader);
case Roles::ServerUnderloadPacketMagicHeaderRole: return m_serverProtocolConfig.value(config_key::underloadPacketMagicHeader);
case Roles::ServerTransportPacketMagicHeaderRole: return m_serverProtocolConfig.value(config_key::transportPacketMagicHeader);
case Roles::IsAwg2Role: return m_container == DockerContainer::Awg2;
}
return QVariant();
@@ -134,10 +126,10 @@ void AwgConfigModel::updateModel(const QJsonObject &config)
serverProtocolConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize);
m_serverProtocolConfig[config_key::responsePacketJunkSize] =
serverProtocolConfig.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize);
// m_serverProtocolConfig[config_key::cookieReplyPacketJunkSize] =
// serverProtocolConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize);
// m_serverProtocolConfig[config_key::transportPacketJunkSize] =
// serverProtocolConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize);
m_serverProtocolConfig[config_key::cookieReplyPacketJunkSize] =
serverProtocolConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize);
m_serverProtocolConfig[config_key::transportPacketJunkSize] =
serverProtocolConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize);
m_serverProtocolConfig[config_key::initPacketMagicHeader] =
serverProtocolConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader);
m_serverProtocolConfig[config_key::responsePacketMagicHeader] =
@@ -166,21 +158,13 @@ void AwgConfigModel::updateModel(const QJsonObject &config)
clientProtocolConfig.value(config_key::specialJunk4).toString(protocols::awg::defaultSpecialJunk4);
m_clientProtocolConfig[config_key::specialJunk5] =
clientProtocolConfig.value(config_key::specialJunk5).toString(protocols::awg::defaultSpecialJunk5);
m_clientProtocolConfig[config_key::controlledJunk1] =
clientProtocolConfig.value(config_key::controlledJunk1).toString(protocols::awg::defaultControlledJunk1);
m_clientProtocolConfig[config_key::controlledJunk2] =
clientProtocolConfig.value(config_key::controlledJunk2).toString(protocols::awg::defaultControlledJunk2);
m_clientProtocolConfig[config_key::controlledJunk3] =
clientProtocolConfig.value(config_key::controlledJunk3).toString(protocols::awg::defaultControlledJunk3);
m_clientProtocolConfig[config_key::specialHandshakeTimeout] =
clientProtocolConfig.value(config_key::specialHandshakeTimeout).toString(protocols::awg::defaultSpecialHandshakeTimeout);
endResetModel();
}
QJsonObject AwgConfigModel::getConfig()
{
const AwgConfig oldConfig(m_fullConfig.value(config_key::awg).toObject());
const AwgConfig newConfig(m_serverProtocolConfig);
const AwgConfig oldConfig(m_fullConfig.value(config_key::awg).toObject(), m_container);
const AwgConfig newConfig(m_serverProtocolConfig, m_container);
if (!oldConfig.hasEqualServerSettings(newConfig)) {
m_serverProtocolConfig.remove(config_key::last_config);
@@ -196,10 +180,6 @@ QJsonObject AwgConfigModel::getConfig()
jsonConfig[config_key::specialJunk3] = m_clientProtocolConfig[config_key::specialJunk3].toString().trimmed();
jsonConfig[config_key::specialJunk4] = m_clientProtocolConfig[config_key::specialJunk4].toString().trimmed();
jsonConfig[config_key::specialJunk5] = m_clientProtocolConfig[config_key::specialJunk5].toString().trimmed();
jsonConfig[config_key::controlledJunk1] = m_clientProtocolConfig[config_key::controlledJunk1].toString().trimmed();
jsonConfig[config_key::controlledJunk2] = m_clientProtocolConfig[config_key::controlledJunk2].toString().trimmed();
jsonConfig[config_key::controlledJunk3] = m_clientProtocolConfig[config_key::controlledJunk3].toString().trimmed();
jsonConfig[config_key::specialHandshakeTimeout] = m_clientProtocolConfig[config_key::specialHandshakeTimeout];
m_serverProtocolConfig[config_key::last_config] = QString(QJsonDocument(jsonConfig).toJson());
}
@@ -213,26 +193,21 @@ bool AwgConfigModel::isHeadersEqual(const QString &h1, const QString &h2, const
return (h1 == h2) || (h1 == h3) || (h1 == h4) || (h2 == h3) || (h2 == h4) || (h3 == h4);
}
bool AwgConfigModel::isPacketSizeEqual(const int s1, const int s2)
bool AwgConfigModel::isPacketSizeEqual(const int s1, const int s2, const int s3, const int s4)
{
return (AwgConstant::messageInitiationSize + s1 == AwgConstant::messageResponseSize + s2);
int initSize = AwgConstant::messageInitiationSize + s1;
int responseSize = AwgConstant::messageResponseSize + s2;
int cookieSize = AwgConstant::messageCookieReplySize + s3;
int transportSize = AwgConstant::messageTransportSize + s4;
return (initSize == responseSize || initSize == cookieSize || initSize == transportSize || responseSize == cookieSize
|| responseSize == transportSize || cookieSize == transportSize);
}
// bool AwgConfigModel::isPacketSizeEqual(const int s1, const int s2, const int s3, const int s4)
// {
// int initSize = AwgConstant::messageInitiationSize + s1;
// int responseSize = AwgConstant::messageResponseSize + s2;
// int cookieSize = AwgConstant::messageCookieReplySize + s3;
// int transportSize = AwgConstant::messageTransportSize + s4;
// return (initSize == responseSize || initSize == cookieSize || initSize == transportSize || responseSize == cookieSize
// || responseSize == transportSize || cookieSize == transportSize);
// }
bool AwgConfigModel::isServerSettingsEqual()
{
const AwgConfig oldConfig(m_fullConfig.value(config_key::awg).toObject());
const AwgConfig newConfig(m_serverProtocolConfig);
const AwgConfig oldConfig(m_fullConfig.value(config_key::awg).toObject(), m_container);
const AwgConfig newConfig(m_serverProtocolConfig, m_container);
return oldConfig.hasEqualServerSettings(newConfig);
}
@@ -253,10 +228,6 @@ QHash<int, QByteArray> AwgConfigModel::roleNames() const
roles[ClientSpecialJunk3Role] = "clientSpecialJunk3";
roles[ClientSpecialJunk4Role] = "clientSpecialJunk4";
roles[ClientSpecialJunk5Role] = "clientSpecialJunk5";
roles[ClientControlledJunk1Role] = "clientControlledJunk1";
roles[ClientControlledJunk2Role] = "clientControlledJunk2";
roles[ClientControlledJunk3Role] = "clientControlledJunk3";
roles[ClientSpecialHandshakeTimeoutRole] = "clientSpecialHandshakeTimeout";
roles[ServerJunkPacketCountRole] = "serverJunkPacketCount";
roles[ServerJunkPacketMinSizeRole] = "serverJunkPacketMinSize";
@@ -271,11 +242,15 @@ QHash<int, QByteArray> AwgConfigModel::roleNames() const
roles[ServerUnderloadPacketMagicHeaderRole] = "serverUnderloadPacketMagicHeader";
roles[ServerTransportPacketMagicHeaderRole] = "serverTransportPacketMagicHeader";
roles[IsAwg2Role] = "isAwg2";
return roles;
}
AwgConfig::AwgConfig(const QJsonObject &serverProtocolConfig)
AwgConfig::AwgConfig(const QJsonObject &serverProtocolConfig, const DockerContainer containerType)
{
m_containerType = containerType;
auto lastConfig = serverProtocolConfig.value(config_key::last_config).toString();
QJsonObject clientProtocolConfig = QJsonDocument::fromJson(lastConfig.toUtf8()).object();
clientMtu = clientProtocolConfig[config_key::mtu].toString(protocols::awg::defaultMtu);
@@ -287,11 +262,6 @@ AwgConfig::AwgConfig(const QJsonObject &serverProtocolConfig)
clientSpecialJunk3 = clientProtocolConfig.value(config_key::specialJunk3).toString(protocols::awg::defaultSpecialJunk3);
clientSpecialJunk4 = clientProtocolConfig.value(config_key::specialJunk4).toString(protocols::awg::defaultSpecialJunk4);
clientSpecialJunk5 = clientProtocolConfig.value(config_key::specialJunk5).toString(protocols::awg::defaultSpecialJunk5);
clientControlledJunk1 = clientProtocolConfig.value(config_key::controlledJunk1).toString(protocols::awg::defaultControlledJunk1);
clientControlledJunk2 = clientProtocolConfig.value(config_key::controlledJunk2).toString(protocols::awg::defaultControlledJunk2);
clientControlledJunk3 = clientProtocolConfig.value(config_key::controlledJunk3).toString(protocols::awg::defaultControlledJunk3);
clientSpecialHandshakeTimeout =
clientProtocolConfig.value(config_key::specialHandshakeTimeout).toString(protocols::awg::defaultSpecialHandshakeTimeout);
subnetAddress = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
port = serverProtocolConfig.value(config_key::port).toString(protocols::awg::defaultPort);
@@ -301,10 +271,14 @@ AwgConfig::AwgConfig(const QJsonObject &serverProtocolConfig)
serverInitPacketJunkSize = serverProtocolConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize);
serverResponsePacketJunkSize =
serverProtocolConfig.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize);
// serverCookieReplyPacketJunkSize =
// serverProtocolConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize);
// serverTransportPacketJunkSize =
// serverProtocolConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize);
if (m_containerType == DockerContainer::Awg2) {
serverCookieReplyPacketJunkSize =
serverProtocolConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize);
serverTransportPacketJunkSize =
serverProtocolConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize);
}
serverInitPacketMagicHeader =
serverProtocolConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader);
serverResponsePacketMagicHeader =
@@ -320,14 +294,20 @@ bool AwgConfig::hasEqualServerSettings(const AwgConfig &other) const
if (subnetAddress != other.subnetAddress || port != other.port || serverJunkPacketCount != other.serverJunkPacketCount
|| serverJunkPacketMinSize != other.serverJunkPacketMinSize || serverJunkPacketMaxSize != other.serverJunkPacketMaxSize
|| serverInitPacketJunkSize != other.serverInitPacketJunkSize || serverResponsePacketJunkSize != other.serverResponsePacketJunkSize
// || serverCookieReplyPacketJunkSize != other.serverCookieReplyPacketJunkSize
// || serverTransportPacketJunkSize != other.serverTransportPacketJunkSize
|| serverInitPacketMagicHeader != other.serverInitPacketMagicHeader
|| serverResponsePacketMagicHeader != other.serverResponsePacketMagicHeader
|| serverUnderloadPacketMagicHeader != other.serverUnderloadPacketMagicHeader
|| serverTransportPacketMagicHeader != other.serverTransportPacketMagicHeader) {
return false;
}
if (m_containerType == DockerContainer::Awg2) {
if (serverCookieReplyPacketJunkSize != other.serverCookieReplyPacketJunkSize
|| serverTransportPacketJunkSize != other.serverTransportPacketJunkSize) {
return false;
}
}
return true;
}
@@ -337,9 +317,7 @@ bool AwgConfig::hasEqualClientSettings(const AwgConfig &other) const
|| clientJunkPacketMinSize != other.clientJunkPacketMinSize || clientJunkPacketMaxSize != other.clientJunkPacketMaxSize
|| clientSpecialJunk1 != other.clientSpecialJunk1 || clientSpecialJunk2 != other.clientSpecialJunk2
|| clientSpecialJunk3 != other.clientSpecialJunk3 || clientSpecialJunk4 != other.clientSpecialJunk4
|| clientSpecialJunk5 != other.clientSpecialJunk5 || clientControlledJunk1 != other.clientControlledJunk1
|| clientControlledJunk2 != other.clientControlledJunk2 || clientControlledJunk3 != other.clientControlledJunk3
|| clientSpecialHandshakeTimeout != other.clientSpecialHandshakeTimeout) {
|| clientSpecialJunk5 != other.clientSpecialJunk5) {
return false;
}
return true;

View File

@@ -16,7 +16,7 @@ namespace AwgConstant
struct AwgConfig
{
AwgConfig(const QJsonObject &jsonConfig);
AwgConfig(const QJsonObject &jsonConfig, const DockerContainer containerType);
QString subnetAddress;
QString port;
@@ -30,10 +30,6 @@ struct AwgConfig
QString clientSpecialJunk3;
QString clientSpecialJunk4;
QString clientSpecialJunk5;
QString clientControlledJunk1;
QString clientControlledJunk2;
QString clientControlledJunk3;
QString clientSpecialHandshakeTimeout;
QString serverJunkPacketCount;
QString serverJunkPacketMinSize;
@@ -49,6 +45,9 @@ struct AwgConfig
bool hasEqualServerSettings(const AwgConfig &other) const;
bool hasEqualClientSettings(const AwgConfig &other) const;
private:
DockerContainer m_containerType;
};
class AwgConfigModel : public QAbstractListModel
@@ -69,10 +68,6 @@ public:
ClientSpecialJunk3Role,
ClientSpecialJunk4Role,
ClientSpecialJunk5Role,
ClientControlledJunk1Role,
ClientControlledJunk2Role,
ClientControlledJunk3Role,
ClientSpecialHandshakeTimeoutRole,
ServerJunkPacketCountRole,
ServerJunkPacketMinSizeRole,
@@ -86,6 +81,8 @@ public:
ServerResponsePacketMagicHeaderRole,
ServerUnderloadPacketMagicHeaderRole,
ServerTransportPacketMagicHeaderRole,
IsAwg2Role
};
explicit AwgConfigModel(QObject *parent = nullptr);
@@ -100,7 +97,7 @@ public slots:
QJsonObject getConfig();
bool isHeadersEqual(const QString &h1, const QString &h2, const QString &h3, const QString &h4);
bool isPacketSizeEqual(const int s1, const int s2/*, const int s3, const int s4*/);
bool isPacketSizeEqual(const int s1, const int s2, const int s3, const int s4);
bool isServerSettingsEqual();

View File

@@ -42,7 +42,7 @@ QVariant ProtocolsModel::data(const QModelIndex &index, int role) const
return static_cast<int>(clientProtocolPage(ProtocolProps::protoFromString(m_content.keys().at(index.row()))));
case ProtocolIndexRole: return ProtocolProps::protoFromString(m_content.keys().at(index.row()));
case RawConfigRole: {
auto protocolConfig = m_content.value(ContainerProps::containerTypeToString(m_container)).toObject();
auto protocolConfig = m_content.value(ContainerProps::containerTypeToProtocolString(m_container)).toObject();
auto lastConfigJsonDoc =
QJsonDocument::fromJson(protocolConfig.value(config_key::last_config).toString().toUtf8());
auto lastConfigJson = lastConfigJsonDoc.object();
@@ -55,7 +55,8 @@ QVariant ProtocolsModel::data(const QModelIndex &index, int role) const
return rawConfig;
}
case IsClientProtocolExistsRole: {
auto protocolConfig = m_content.value(ContainerProps::containerTypeToString(m_container)).toObject();
QString protocolKey = ContainerProps::containerTypeToProtocolString(m_container);
auto protocolConfig = m_content.value(protocolKey).toObject();
auto lastConfigJsonDoc =
QJsonDocument::fromJson(protocolConfig.value(config_key::last_config).toString().toUtf8());
auto lastConfigJson = lastConfigJsonDoc.object();

View File

@@ -753,8 +753,8 @@ bool ServersModel::isDefaultServerDefaultContainerHasSplitTunneling()
if (container.value(config_key::container).toString() != ContainerProps::containerToString(defaultContainer)) {
continue;
}
if (defaultContainer == DockerContainer::Awg || defaultContainer == DockerContainer::WireGuard) {
QJsonObject serverProtocolConfig = container.value(ContainerProps::containerTypeToString(defaultContainer)).toObject();
if (ContainerProps::isAwgContainer(defaultContainer) || defaultContainer == DockerContainer::WireGuard) {
QJsonObject serverProtocolConfig = container.value(ContainerProps::containerTypeToProtocolString(defaultContainer)).toObject();
QString clientProtocolConfigString = serverProtocolConfig.value(config_key::last_config).toString();
QJsonObject clientProtocolConfig = QJsonDocument::fromJson(clientProtocolConfigString.toUtf8()).object();
return (clientProtocolConfigString.contains("AllowedIPs") && !clientProtocolConfigString.contains("AllowedIPs = 0.0.0.0/0, ::/0"))
@@ -762,7 +762,7 @@ bool ServersModel::isDefaultServerDefaultContainerHasSplitTunneling()
&& !clientProtocolConfig.value(config_key::allowed_ips).toArray().contains("0.0.0.0/0"));
} else if (defaultContainer == DockerContainer::Cloak || defaultContainer == DockerContainer::OpenVpn
|| defaultContainer == DockerContainer::ShadowSocks) {
auto serverProtocolConfig = container.value(ContainerProps::containerTypeToString(DockerContainer::OpenVpn)).toObject();
auto serverProtocolConfig = container.value(ContainerProps::containerTypeToProtocolString(DockerContainer::OpenVpn)).toObject();
QString clientProtocolConfigString = serverProtocolConfig.value(config_key::last_config).toString();
return !clientProtocolConfigString.isEmpty() && !clientProtocolConfigString.contains("redirect-gateway");
}

View File

@@ -33,12 +33,10 @@ ListViewType {
var containerIndex = root.model.mapToSource(index)
ContainersModel.setProcessedContainerIndex(containerIndex)
if (serviceType !== ProtocolEnum.Other) {
if (config[ContainerProps.containerTypeToString(containerIndex)]["isThirdPartyConfig"]) {
ProtocolsModel.updateModel(config)
PageController.goToPage(PageEnum.PageProtocolRaw)
return
}
if (serviceType !== ProtocolEnum.Other && isThirdPartyConfig) {
ProtocolsModel.updateModel(config)
PageController.goToPage(PageEnum.PageProtocolRaw)
return
}
switch (containerIndex) {

View File

@@ -31,8 +31,19 @@ Item {
value: true
}
ValueFilter {
id: installationAllowedFilter
roleName: "isInstallationAllowed"
value: true
}
AnyOf {
id: showProtocolFilter
filters: [ installedFilter, installationAllowedFilter ]
}
function getWriteAccessProtocolsListFilters() {
return [vpnTypeFilter]
return [ vpnTypeFilter, showProtocolFilter ]
}
function getReadAccessProtocolsListFilters() {
return [vpnTypeFilter, installedFilter]

View File

@@ -281,100 +281,6 @@ PageType {
}
}
AwgTextField {
id: controlledJunk1TextField
Layout.leftMargin: 16
Layout.rightMargin: 16
headerText: qsTr("J1 - First controlled junk packet")
textField.text: clientControlledJunk1
textField.validator: null
checkEmptyText: false
textField.onEditingFinished: {
if (textField.text !== clientControlledJunk1) {
clientControlledJunk1 = textField.text
}
}
textField.onActiveFocusChanged: {
if (textField.activeFocus) {
smartScroll.scrollToItem(controlledJunk1TextField)
}
}
}
AwgTextField {
id: controlledJunk2TextField
Layout.leftMargin: 16
Layout.rightMargin: 16
headerText: qsTr("J2 - Second controlled junk packet")
textField.text: clientControlledJunk2
textField.validator: null
checkEmptyText: false
textField.onEditingFinished: {
if (textField.text !== clientControlledJunk2) {
clientControlledJunk2 = textField.text
}
}
textField.onActiveFocusChanged: {
if (textField.activeFocus) {
smartScroll.scrollToItem(controlledJunk2TextField)
}
}
}
AwgTextField {
id: controlledJunk3TextField
Layout.leftMargin: 16
Layout.rightMargin: 16
headerText: qsTr("J3 - Third controlled junk packet")
textField.text: clientControlledJunk3
textField.validator: null
checkEmptyText: false
textField.onEditingFinished: {
if (textField.text !== clientControlledJunk3) {
clientControlledJunk3 = textField.text
}
}
textField.onActiveFocusChanged: {
if (textField.activeFocus) {
smartScroll.scrollToItem(controlledJunk3TextField)
}
}
}
AwgTextField {
id: iTimeTextField
Layout.leftMargin: 16
Layout.rightMargin: 16
headerText: qsTr("Itime - Special handshake timeout")
textField.text: clientSpecialHandshakeTimeout
checkEmptyText: false
textField.onEditingFinished: {
if (textField.text !== clientSpecialHandshakeTimeout) {
clientSpecialHandshakeTimeout = textField.text
}
}
textField.onActiveFocusChanged: {
if (textField.activeFocus) {
smartScroll.scrollToItem(iTimeTextField)
}
}
}
Header2TextType {
Layout.fillWidth: true
@@ -421,29 +327,29 @@ PageType {
textField.text: serverResponsePacketJunkSize
}
// AwgTextField {
// id: cookieReplyPacketJunkSizeTextField
AwgTextField {
id: cookieReplyPacketJunkSizeTextField
// Layout.leftMargin: 16
// Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.rightMargin: 16
// enabled: false
enabled: false
// headerText: "S3 - Cookie Reply packet junk size"
// textField.text: serverCookieReplyPacketJunkSize
// }
headerText: "S3 - Cookie Reply packet junk size"
textField.text: serverCookieReplyPacketJunkSize
}
// AwgTextField {
// id: transportPacketJunkSizeTextField
AwgTextField {
id: transportPacketJunkSizeTextField
// Layout.leftMargin: 16
// Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.rightMargin: 16
// enabled: false
enabled: false
// headerText: "S4 - Transport packet junk size"
// textField.text: serverTransportPacketJunkSize
// }
headerText: "S4 - Transport packet junk size"
textField.text: serverTransportPacketJunkSize
}
AwgTextField {
id: initPacketMagicHeaderTextField

View File

@@ -234,37 +234,53 @@ PageType {
}
}
// AwgTextField {
// id: cookieReplyPacketJunkSizeTextField
AwgTextField {
id: cookieReplyPacketJunkSizeTextField
// Layout.leftMargin: 16
// Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.rightMargin: 16
// headerText: qsTr("S3 - Cookie reply packet junk size")
// textField.text: serverCookieReplyPacketJunkSize
visible: isAwg2
// textField.onEditingFinished: {
// if (textField.text !== serverCookieReplyPacketJunkSize) {
// serverCookieReplyPacketJunkSize = textField.text
// }
// }
// }
headerText: qsTr("S3 - Cookie reply packet junk size")
textField.text: serverCookieReplyPacketJunkSize
// AwgTextField {
// id: transportPacketJunkSizeTextField
textField.onEditingFinished: {
if (textField.text !== serverCookieReplyPacketJunkSize) {
serverCookieReplyPacketJunkSize = textField.text
}
}
// Layout.leftMargin: 16
// Layout.rightMargin: 16
textField.onActiveFocusChanged: {
if (textField.activeFocus) {
smartScroll.scrollToItem(cookieReplyPacketJunkSizeTextField)
}
}
}
// headerText: qsTr("S4 - Transport packet junk size")
// textField.text: serverTransportPacketJunkSize
AwgTextField {
id: transportPacketJunkSizeTextField
// textField.onEditingFinished: {
// if (textField.text !== serverTransportPacketJunkSize) {
// serverTransportPacketJunkSize = textField.text
// }
// }
// }
Layout.leftMargin: 16
Layout.rightMargin: 16
visible: isAwg2
headerText: qsTr("S4 - Transport packet junk size")
textField.text: serverTransportPacketJunkSize
textField.onEditingFinished: {
if (textField.text !== serverTransportPacketJunkSize) {
serverTransportPacketJunkSize = textField.text
}
}
textField.onActiveFocusChanged: {
if (textField.activeFocus) {
smartScroll.scrollToItem(transportPacketJunkSizeTextField)
}
}
}
AwgTextField {
id: initPacketMagicHeaderTextField
@@ -274,6 +290,9 @@ PageType {
headerText: qsTr("H1 - Init packet magic header")
textField.text: serverInitPacketMagicHeader
textField.validator: RegularExpressionValidator {
regularExpression: /^(\d+)(-\d+)?$/
}
textField.onEditingFinished: {
if (textField.text !== serverInitPacketMagicHeader) {
@@ -296,6 +315,9 @@ PageType {
headerText: qsTr("H2 - Response packet magic header")
textField.text: serverResponsePacketMagicHeader
textField.validator: RegularExpressionValidator {
regularExpression: /^(\d+)(-\d+)?$/
}
textField.onEditingFinished: {
if (textField.text !== serverResponsePacketMagicHeader) {
@@ -318,6 +340,9 @@ PageType {
headerText: qsTr("H3 - Underload packet magic header")
textField.text: serverUnderloadPacketMagicHeader
textField.validator: RegularExpressionValidator {
regularExpression: /^(\d+)(-\d+)?$/
}
textField.onEditingFinished: {
if (textField.text !== serverUnderloadPacketMagicHeader) {
@@ -340,6 +365,9 @@ PageType {
headerText: qsTr("H4 - Transport packet magic header")
textField.text: serverTransportPacketMagicHeader
textField.validator: RegularExpressionValidator {
regularExpression: /^(\d+)(-\d+)?$/
}
textField.onEditingFinished: {
if (textField.text !== serverTransportPacketMagicHeader) {
@@ -368,8 +396,8 @@ PageType {
responsePacketMagicHeaderTextField.errorText === "" &&
initPacketMagicHeaderTextField.errorText === "" &&
responsePacketJunkSizeTextField.errorText === "" &&
// cookieReplyHeaderJunkTextField.errorText === "" &&
// transportHeaderJunkTextField.errorText === "" &&
cookieReplyPacketJunkSizeTextField.errorText === "" &&
transportPacketJunkSizeTextField.errorText === "" &&
initPacketJunkSizeTextField.errorText === "" &&
junkPacketMaxSizeTextField.errorText === "" &&
junkPacketMinSizeTextField.errorText === "" &&
@@ -396,17 +424,12 @@ PageType {
}
if (AwgConfigModel.isPacketSizeEqual(parseInt(initPacketJunkSizeTextField.textField.text),
parseInt(responsePacketJunkSizeTextField.textField.text))) {
PageController.showErrorMessage(qsTr("The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92)"))
parseInt(responsePacketJunkSizeTextField.textField.text),
parseInt(cookieReplyPacketJunkSizeTextField.textField.text),
parseInt(transportPacketJunkSizeTextField.textField.text))) {
PageController.showErrorMessage(qsTr("The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) + S3 + cookie reply size (64) + S4 + transport packet size (32)"))
return
}
// if (AwgConfigModel.isPacketSizeEqual(parseInt(initPacketJunkSizeTextField.textField.text),
// parseInt(responsePacketJunkSizeTextField.textField.text),
// parseInt(cookieReplyPacketJunkSizeTextField.textField.text),
// parseInt(transportPacketJunkSizeTextField.textField.text))) {
// PageController.showErrorMessage(qsTr("The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) + S3 + cookie reply size (64) + S4 + transport packet size (32)"))
// return
// }
}
var headerText = qsTr("Save settings?")

View File

@@ -26,6 +26,10 @@ PageType {
ValueFilter {
roleName: "isSupported"
value: true
},
ValueFilter {
roleName: "isInstallationAllowed"
value: true
}
]
sorters: RoleSorter {

View File

@@ -459,6 +459,10 @@ PageType {
root.connectionTypesModel.push(wireGuardConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-awg")) {
root.connectionTypesModel.push(awgConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-awg2")) {
root.connectionTypesModel.push(awgConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-awg1.5")) {
root.connectionTypesModel.push(awgConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-shadowsocks")) {
root.connectionTypesModel.push(openVpnConnectionFormat)
root.connectionTypesModel.push(shadowSocksConnectionFormat)

View File

@@ -74,7 +74,8 @@ void VpnConnection::onConnectionStateChanged(Vpn::ConnectionState state)
IpcClient::Interface()->resetIpStack();
IpcClient::Interface()->flushDns();
if (container != DockerContainer::Awg && container != DockerContainer::WireGuard) {
if (!ContainerProps::isAwgContainer(container) &&
container != DockerContainer::WireGuard) {
QString dns1 = m_vpnConfiguration.value(config_key::dns1).toString();
QString dns2 = m_vpnConfiguration.value(config_key::dns2).toString();