Compare commits

...

11 Commits

Author SHA1 Message Date
aiamnezia bb576450b2 Fix AmneziaWG settings 2025-07-28 15:36:49 +04:00
aiamnezia b01e9864cf Merge branch 'dev' into feature/add-new-awg-docker-image 2025-07-25 18:00:33 +04:00
aiamnezia 6b756f87b8 Remove AwgLegacy from wizard manual installation page 2025-07-25 17:12:35 +04:00
aiamnezia 5163d0edc4 Fix not opening awg settings 2025-07-25 16:58:10 +04:00
aiamnezia 8d830e726c Add native config sharing for new Awg container 2025-07-18 17:06:07 +04:00
aiamnezia f6441b8b80 Add role for allowed for installation containers 2025-07-13 20:11:45 +04:00
aiamnezia bd30191060 Merge branch 'dev' into feature/add-new-awg-docker-image 2025-07-11 18:14:18 +04:00
aiamnezia 321ceb225c Fix resources file 2025-07-11 18:13:55 +04:00
aiamnezia 7fba1a50de Hide uninstalled AwgLegacy container 2025-07-11 17:26:49 +04:00
aiamnezia 151dac2316 add missing files 2025-07-11 07:49:00 +04:00
aiamnezia c40506f2f2 Add updated awg container 2025-07-11 07:10:58 +04:00
30 changed files with 315 additions and 57 deletions
@@ -103,7 +103,11 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
return connData; return connData;
} }
QString getIpsScript = QString("cat %1 | grep AllowedIPs").arg(m_serverConfigPath); QString configPath = m_serverConfigPath;
if (container == DockerContainer::AwgLegacy) {
configPath = amnezia::protocols::awg::serverLegacyConfigPath;
}
QString getIpsScript = QString("cat %1 | grep AllowedIPs").arg(configPath);
QString stdOut; QString stdOut;
auto cbReadStdOut = [&](const QString &data, libssh::Client &) { auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
stdOut += data + "\n"; stdOut += data + "\n";
@@ -161,15 +165,18 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
"AllowedIPs = %3/32\n\n") "AllowedIPs = %3/32\n\n")
.arg(connData.clientPubKey, connData.pskKey, connData.clientIP); .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); libssh::ScpOverwriteMode::ScpAppendToExisting);
if (errorCode != ErrorCode::NoError) { if (errorCode != ErrorCode::NoError) {
return connData; return connData;
} }
QString script = QString("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip %1)'") bool isAwg = (container == DockerContainer::Awg);
.arg(m_serverConfigPath); 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( errorCode = m_serverController->runScript(
credentials, credentials,
+37
View File
@@ -28,6 +28,10 @@ QString ContainerProps::containerToString(amnezia::DockerContainer c)
return "none"; return "none";
if (c == DockerContainer::Cloak) if (c == DockerContainer::Cloak)
return "amnezia-openvpn-cloak"; return "amnezia-openvpn-cloak";
if (c == DockerContainer::AwgLegacy)
return "amnezia-awg";
if (c == DockerContainer::Awg)
return "amnezia-awg-go";
QMetaEnum metaEnum = QMetaEnum::fromType<DockerContainer>(); QMetaEnum metaEnum = QMetaEnum::fromType<DockerContainer>();
QString containerKey = metaEnum.valueToKey(static_cast<int>(c)); QString containerKey = metaEnum.valueToKey(static_cast<int>(c));
@@ -41,6 +45,10 @@ QString ContainerProps::containerTypeToString(amnezia::DockerContainer c)
return "none"; return "none";
if (c == DockerContainer::Ipsec) if (c == DockerContainer::Ipsec)
return "ikev2"; return "ikev2";
if (c == DockerContainer::AwgLegacy)
return "awg";
if (c == DockerContainer::Awg)
return "awg-go";
QMetaEnum metaEnum = QMetaEnum::fromType<DockerContainer>(); QMetaEnum metaEnum = QMetaEnum::fromType<DockerContainer>();
QString containerKey = metaEnum.valueToKey(static_cast<int>(c)); QString containerKey = metaEnum.valueToKey(static_cast<int>(c));
@@ -71,6 +79,8 @@ QVector<amnezia::Proto> ContainerProps::protocolsForContainer(amnezia::DockerCon
case DockerContainer::Socks5Proxy: return { Proto::Socks5Proxy }; case DockerContainer::Socks5Proxy: return { Proto::Socks5Proxy };
case DockerContainer::AwgLegacy: return { Proto::Awg };
default: return { defaultProtocol(container) }; default: return { defaultProtocol(container) };
} }
} }
@@ -94,6 +104,7 @@ QMap<DockerContainer, QString> ContainerProps::containerHumanNames()
{ DockerContainer::Cloak, "OpenVPN over Cloak" }, { DockerContainer::Cloak, "OpenVPN over Cloak" },
{ DockerContainer::WireGuard, "WireGuard" }, { DockerContainer::WireGuard, "WireGuard" },
{ DockerContainer::Awg, "AmneziaWG" }, { DockerContainer::Awg, "AmneziaWG" },
{ DockerContainer::AwgLegacy, "AmneziaWG Legacy" },
{ DockerContainer::Xray, "XRay" }, { DockerContainer::Xray, "XRay" },
{ DockerContainer::Ipsec, QObject::tr("IPsec") }, { DockerContainer::Ipsec, QObject::tr("IPsec") },
{ DockerContainer::SSXray, "Shadowsocks"}, { DockerContainer::SSXray, "Shadowsocks"},
@@ -120,6 +131,9 @@ QMap<DockerContainer, QString> ContainerProps::containerDescriptions()
{ DockerContainer::Awg, { DockerContainer::Awg,
QObject::tr("AmneziaWG is a special protocol from Amnezia based on WireGuard. " 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.") }, "It provides high connection speed and ensures stable operation even in the most challenging network conditions.") },
{ DockerContainer::AwgLegacy,
QObject::tr("AmneziaWG Legacy is an old version of AmneziaWG protocol from Amnezia based on WireGuard. "
"It provides high connection speed and ensures stable operation even in the most challenging network conditions.") },
{ DockerContainer::Xray, { DockerContainer::Xray,
QObject::tr("XRay with REALITY masks VPN traffic as web traffic and protects against active probing. " QObject::tr("XRay with REALITY masks VPN traffic as web traffic and protects against active probing. "
"It is highly resistant to detection and offers high speed.") }, "It is highly resistant to detection and offers high speed.") },
@@ -194,6 +208,17 @@ QMap<DockerContainer, QString> ContainerProps::containerDetailedDescriptions()
"* Minimal settings required\n" "* Minimal settings required\n"
"* Undetectable by traffic analysis systems (DPI)\n" "* Undetectable by traffic analysis systems (DPI)\n"
"* Operates over UDP protocol") }, "* Operates over UDP protocol") },
{ DockerContainer::AwgLegacy,
QObject::tr("AmneziaWG Legacy 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, { DockerContainer::Xray,
QObject::tr("REALITY is an innovative protocol developed by the creators of XRay, designed specifically to combat high levels of internet censorship. " 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, " "REALITY identifies censorship systems during the TLS handshake, "
@@ -243,6 +268,7 @@ Proto ContainerProps::defaultProtocol(DockerContainer c)
case DockerContainer::ShadowSocks: return Proto::ShadowSocks; case DockerContainer::ShadowSocks: return Proto::ShadowSocks;
case DockerContainer::WireGuard: return Proto::WireGuard; case DockerContainer::WireGuard: return Proto::WireGuard;
case DockerContainer::Awg: return Proto::Awg; case DockerContainer::Awg: return Proto::Awg;
case DockerContainer::AwgLegacy: return Proto::Awg;
case DockerContainer::Xray: return Proto::Xray; case DockerContainer::Xray: return Proto::Xray;
case DockerContainer::Ipsec: return Proto::Ikev2; case DockerContainer::Ipsec: return Proto::Ikev2;
case DockerContainer::SSXray: return Proto::SSXray; case DockerContainer::SSXray: return Proto::SSXray;
@@ -255,6 +281,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) bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
{ {
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
@@ -265,6 +300,7 @@ bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
case DockerContainer::WireGuard: return true; case DockerContainer::WireGuard: return true;
case DockerContainer::OpenVpn: return true; case DockerContainer::OpenVpn: return true;
case DockerContainer::Awg: return true; case DockerContainer::Awg: return true;
case DockerContainer::AwgLegacy: return true;
case DockerContainer::Xray: return true; case DockerContainer::Xray: return true;
case DockerContainer::Cloak: return true; case DockerContainer::Cloak: return true;
case DockerContainer::SSXray: return true; case DockerContainer::SSXray: return true;
@@ -284,6 +320,7 @@ bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
case DockerContainer::OpenVpn: return true; case DockerContainer::OpenVpn: return true;
case DockerContainer::ShadowSocks: return false; case DockerContainer::ShadowSocks: return false;
case DockerContainer::Awg: return true; case DockerContainer::Awg: return true;
case DockerContainer::AwgLegacy: return true;
case DockerContainer::Cloak: return true; case DockerContainer::Cloak: return true;
case DockerContainer::Xray: return true; case DockerContainer::Xray: return true;
case DockerContainer::SSXray: return true; case DockerContainer::SSXray: return true;
+2
View File
@@ -17,6 +17,7 @@ namespace amnezia
enum DockerContainer { enum DockerContainer {
None = 0, None = 0,
Awg, Awg,
AwgLegacy,
WireGuard, WireGuard,
OpenVpn, OpenVpn,
Cloak, Cloak,
@@ -45,6 +46,7 @@ namespace amnezia
Q_INVOKABLE static amnezia::DockerContainer containerFromString(const QString &container); Q_INVOKABLE static amnezia::DockerContainer containerFromString(const QString &container);
Q_INVOKABLE static QString containerToString(amnezia::DockerContainer container); Q_INVOKABLE static QString containerToString(amnezia::DockerContainer container);
Q_INVOKABLE static QString containerTypeToString(amnezia::DockerContainer c); Q_INVOKABLE static QString containerTypeToString(amnezia::DockerContainer c);
Q_INVOKABLE static QString containerTypeToProtocolString(amnezia::DockerContainer c);
Q_INVOKABLE static QList<amnezia::DockerContainer> allContainers(); Q_INVOKABLE static QList<amnezia::DockerContainer> allContainers();
+4 -3
View File
@@ -345,7 +345,7 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
return true; return true;
} }
if (container == DockerContainer::Awg) { if (container == DockerContainer::Awg || container == DockerContainer::AwgLegacy) {
if ((oldProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) if ((oldProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress)
!= newProtoConfig.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) || (oldProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort)
@@ -657,7 +657,8 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
vars.append({ { "$SOCKS5_USER", socks5user } }); vars.append({ { "$SOCKS5_USER", socks5user } });
vars.append({ { "$SOCKS5_AUTH_TYPE", socks5user.isEmpty() ? "none" : "strong" } }); vars.append({ { "$SOCKS5_AUTH_TYPE", socks5user.isEmpty() ? "none" : "strong" } });
QString serverIp = (container != DockerContainer::Awg && container != DockerContainer::WireGuard && container != DockerContainer::Xray) QString serverIp = (container != DockerContainer::Awg && container != DockerContainer::AwgLegacy &&
container != DockerContainer::WireGuard && container != DockerContainer::Xray)
? NetworkUtilities::getIPAddress(credentials.hostName) ? NetworkUtilities::getIPAddress(credentials.hostName)
: credentials.hostName; : credentials.hostName;
if (!serverIp.isEmpty()) { if (!serverIp.isEmpty()) {
@@ -866,4 +867,4 @@ ErrorCode ServerController::getDecryptedPrivateKey(const ServerCredentials &cred
{ {
auto error = m_sshClient.getDecryptedPrivateKey(credentials, decryptedPrivateKey, callback); auto error = m_sshClient.getDecryptedPrivateKey(credentials, decryptedPrivateKey, callback);
return error; return error;
} }
@@ -99,11 +99,12 @@ QJsonObject VpnConfigurationsController::createVpnConfiguration(const QPair<QStr
protocolConfigString = configurator->processConfigWithLocalSettings(dns, isApiConfig, protocolConfigString); protocolConfigString = configurator->processConfigWithLocalSettings(dns, isApiConfig, protocolConfigString);
QJsonObject vpnConfigData = QJsonDocument::fromJson(protocolConfigString.toUtf8()).object(); QJsonObject vpnConfigData = QJsonDocument::fromJson(protocolConfigString.toUtf8()).object();
if (container == DockerContainer::Awg || container == DockerContainer::WireGuard) { if (container == DockerContainer::Awg || container == DockerContainer::AwgLegacy || container == DockerContainer::WireGuard) {
// add mtu for old configs // add mtu for old configs
if (vpnConfigData[config_key::mtu].toString().isEmpty()) { if (vpnConfigData[config_key::mtu].toString().isEmpty()) {
vpnConfigData[config_key::mtu] = vpnConfigData[config_key::mtu] =
container == DockerContainer::Awg ? protocols::awg::defaultMtu : protocols::wireguard::defaultMtu; (container == DockerContainer::Awg || container == DockerContainer::AwgLegacy) ? protocols::awg::defaultMtu :
protocols::wireguard::defaultMtu;
} }
} }
+1
View File
@@ -12,6 +12,7 @@ QString amnezia::scriptFolder(amnezia::DockerContainer container)
case DockerContainer::ShadowSocks: return QLatin1String("openvpn_shadowsocks"); case DockerContainer::ShadowSocks: return QLatin1String("openvpn_shadowsocks");
case DockerContainer::WireGuard: return QLatin1String("wireguard"); case DockerContainer::WireGuard: return QLatin1String("wireguard");
case DockerContainer::Awg: return QLatin1String("awg"); case DockerContainer::Awg: return QLatin1String("awg");
case DockerContainer::AwgLegacy: return QLatin1String("awg_legacy");
case DockerContainer::Ipsec: return QLatin1String("ipsec"); case DockerContainer::Ipsec: return QLatin1String("ipsec");
case DockerContainer::Xray: return QLatin1String("xray"); case DockerContainer::Xray: return QLatin1String("xray");
+2 -1
View File
@@ -218,7 +218,8 @@ namespace amnezia
constexpr char defaultMtu[] = "1376"; constexpr char defaultMtu[] = "1376";
#endif #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 serverPublicKeyPath[] = "/opt/amnezia/awg/wireguard_server_public_key.key";
constexpr char serverPskKeyPath[] = "/opt/amnezia/awg/wireguard_psk.key"; constexpr char serverPskKeyPath[] = "/opt/amnezia/awg/wireguard_psk.key";
+1
View File
@@ -115,6 +115,7 @@ VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject &
case DockerContainer::ShadowSocks: return new ShadowSocksVpnProtocol(configuration); case DockerContainer::ShadowSocks: return new ShadowSocksVpnProtocol(configuration);
case DockerContainer::WireGuard: return new WireguardProtocol(configuration); case DockerContainer::WireGuard: return new WireguardProtocol(configuration);
case DockerContainer::Awg: return new WireguardProtocol(configuration); case DockerContainer::Awg: return new WireguardProtocol(configuration);
case DockerContainer::AwgLegacy: return new WireguardProtocol(configuration);
case DockerContainer::Xray: return new XrayProtocol(configuration); case DockerContainer::Xray: return new XrayProtocol(configuration);
case DockerContainer::SSXray: return new XrayProtocol(configuration); case DockerContainer::SSXray: return new XrayProtocol(configuration);
#endif #endif
+5
View File
@@ -64,6 +64,11 @@
<file>server_scripts/awg/run_container.sh</file> <file>server_scripts/awg/run_container.sh</file>
<file>server_scripts/awg/start.sh</file> <file>server_scripts/awg/start.sh</file>
<file>server_scripts/awg/template.conf</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/build_container.sh</file>
<file>server_scripts/check_connection.sh</file> <file>server_scripts/check_connection.sh</file>
<file>server_scripts/check_server_is_busy.sh</file> <file>server_scripts/check_server_is_busy.sh</file>
+1 -1
View File
@@ -1,4 +1,4 @@
FROM amneziavpn/amnezia-wg:latest FROM amneziavpn/amneziawg-go:latest
LABEL maintainer="AmneziaVPN" LABEL maintainer="AmneziaVPN"
@@ -1,15 +1,15 @@
mkdir -p /opt/amnezia/awg mkdir -p /opt/amnezia/awg
cd /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 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 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 echo $WIREGUARD_PSK > /opt/amnezia/awg/wireguard_psk.key
cat > /opt/amnezia/awg/wg0.conf <<EOF cat > /opt/amnezia/awg/awg0.conf <<EOF
[Interface] [Interface]
PrivateKey = $WIREGUARD_SERVER_PRIVATE_KEY PrivateKey = $WIREGUARD_SERVER_PRIVATE_KEY
Address = $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR Address = $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR
+7 -7
View File
@@ -6,19 +6,19 @@ echo "Container startup"
#ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up #ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up
# kill daemons in case of restart # 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 # 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. # Allow traffic on the TUN interface.
iptables -A INPUT -i wg0 -j ACCEPT iptables -A INPUT -i awg0 -j ACCEPT
iptables -A FORWARD -i wg0 -j ACCEPT iptables -A FORWARD -i awg0 -j ACCEPT
iptables -A OUTPUT -o wg0 -j ACCEPT iptables -A OUTPUT -o awg0 -j ACCEPT
# Allow forwarding traffic only from the VPN. # 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 awg0 -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 eth1 -s $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
@@ -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 [ "" ]
@@ -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
@@ -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"
+28
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
@@ -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
@@ -158,7 +158,7 @@ namespace
return ErrorCode::ApiConfigEmptyError; return ErrorCode::ApiConfigEmptyError;
} }
auto container = containers.at(0).toObject(); auto container = containers.at(0).toObject();
QString containerName = ContainerProps::containerTypeToString(DockerContainer::Awg); QString containerName = ContainerProps::containerTypeToProtocolString(DockerContainer::Awg);
auto serverProtocolConfig = container.value(containerName).toObject(); auto serverProtocolConfig = container.value(containerName).toObject();
auto clientProtocolConfig = auto clientProtocolConfig =
QJsonDocument::fromJson(serverProtocolConfig.value(config_key::last_config).toString().toUtf8()).object(); QJsonDocument::fromJson(serverProtocolConfig.value(config_key::last_config).toString().toUtf8()).object();
+5 -5
View File
@@ -271,7 +271,7 @@ void ImportController::processNativeWireGuardConfig()
auto containers = m_config.value(config_key::containers).toArray(); auto containers = m_config.value(config_key::containers).toArray();
if (!containers.isEmpty()) { if (!containers.isEmpty()) {
auto container = containers.at(0).toObject(); 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(); auto clientProtocolConfig = QJsonDocument::fromJson(serverProtocolConfig.value(config_key::last_config).toString().toUtf8()).object();
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(2, 5)); QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(2, 5));
@@ -727,8 +727,8 @@ void ImportController::processAmneziaConfig(QJsonObject &config)
for (auto i = 0; i < containers.size(); i++) { for (auto i = 0; i < containers.size(); i++) {
auto container = containers.at(i).toObject(); auto container = containers.at(i).toObject();
auto dockerContainer = ContainerProps::containerFromString(container.value(config_key::container).toString()); auto dockerContainer = ContainerProps::containerFromString(container.value(config_key::container).toString());
if (dockerContainer == DockerContainer::Awg || dockerContainer == DockerContainer::WireGuard) { if (dockerContainer == DockerContainer::Awg || dockerContainer == DockerContainer::AwgLegacy || dockerContainer == DockerContainer::WireGuard) {
auto containerConfig = container.value(ContainerProps::containerTypeToString(dockerContainer)).toObject(); auto containerConfig = container.value(ContainerProps::containerTypeToProtocolString(dockerContainer)).toObject();
auto protocolConfig = containerConfig.value(config_key::last_config).toString(); auto protocolConfig = containerConfig.value(config_key::last_config).toString();
if (protocolConfig.isEmpty()) { if (protocolConfig.isEmpty()) {
return; return;
@@ -736,11 +736,11 @@ void ImportController::processAmneziaConfig(QJsonObject &config)
QJsonObject jsonConfig = QJsonDocument::fromJson(protocolConfig.toUtf8()).object(); QJsonObject jsonConfig = QJsonDocument::fromJson(protocolConfig.toUtf8()).object();
jsonConfig[config_key::mtu] = jsonConfig[config_key::mtu] =
dockerContainer == DockerContainer::Awg ? protocols::awg::defaultMtu : protocols::wireguard::defaultMtu; (dockerContainer == DockerContainer::Awg || dockerContainer == DockerContainer::AwgLegacy) ? protocols::awg::defaultMtu : protocols::wireguard::defaultMtu;
containerConfig[config_key::last_config] = QString(QJsonDocument(jsonConfig).toJson()); containerConfig[config_key::last_config] = QString(QJsonDocument(jsonConfig).toJson());
container[ContainerProps::containerTypeToString(dockerContainer)] = containerConfig; container[ContainerProps::containerTypeToProtocolString(dockerContainer)] = containerConfig;
containers.replace(i, container); containers.replace(i, container);
config.insert(config_key::containers, containers); config.insert(config_key::containers, containers);
} }
+5 -1
View File
@@ -410,8 +410,12 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
containerConfig.insert(config_key::transport_proto, transportProto); containerConfig.insert(config_key::transport_proto, transportProto);
if (protocol == Proto::Awg) { if (protocol == Proto::Awg) {
QString configPath = amnezia::protocols::awg::serverConfigPath;
if (container == DockerContainer::AwgLegacy) {
configPath = amnezia::protocols::awg::serverLegacyConfigPath;
}
QString serverConfig = serverController->getTextFileFromContainer(container, credentials, QString serverConfig = serverController->getTextFileFromContainer(container, credentials,
protocols::awg::serverConfigPath, errorCode); configPath, errorCode);
QMap<QString, QString> serverConfigMap; QMap<QString, QString> serverConfigMap;
auto serverConfigLines = serverConfig.split("\n"); auto serverConfigLines = serverConfig.split("\n");
+41 -14
View File
@@ -104,7 +104,7 @@ ErrorCode ClientManagementModel::updateModel(const DockerContainer container, co
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) { if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
error = getOpenVpnClients(container, credentials, serverController, count); error = getOpenVpnClients(container, credentials, serverController, count);
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) { } else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg || container == DockerContainer::AwgLegacy) {
error = getWireGuardClients(container, credentials, serverController, count); error = getWireGuardClients(container, credentials, serverController, count);
} else if (container == DockerContainer::Xray) { } else if (container == DockerContainer::Xray) {
error = getXrayClients(container, credentials, serverController, count); error = getXrayClients(container, credentials, serverController, count);
@@ -209,8 +209,15 @@ ErrorCode ClientManagementModel::getWireGuardClients(const DockerContainer conta
{ {
ErrorCode error = ErrorCode::NoError; ErrorCode error = ErrorCode::NoError;
const QString wireGuardConfigFile = QString("opt/amnezia/%1/wg0.conf").arg(container == DockerContainer::WireGuard ? "wireguard" : "awg"); QString configPath;
const QString wireguardConfigString = serverController->getTextFileFromContainer(container, credentials, wireGuardConfigFile, error); if (container == DockerContainer::AwgLegacy) {
configPath = QString::fromLatin1(amnezia::protocols::awg::serverLegacyConfigPath);
} else if (container == DockerContainer::Awg) {
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) { if (error != ErrorCode::NoError) {
logger.error() << "Failed to get the wg conf file from the server"; logger.error() << "Failed to get the wg conf file from the server";
return error; return error;
@@ -307,7 +314,7 @@ ErrorCode ClientManagementModel::getXrayClients(const DockerContainer container,
ErrorCode ClientManagementModel::wgShow(const DockerContainer container, const ServerCredentials &credentials, ErrorCode ClientManagementModel::wgShow(const DockerContainer container, const ServerCredentials &credentials,
const QSharedPointer<ServerController> &serverController, std::vector<WgShowData> &data) const QSharedPointer<ServerController> &serverController, std::vector<WgShowData> &data)
{ {
if (container != DockerContainer::WireGuard && container != DockerContainer::Awg) { if (container != DockerContainer::WireGuard && container != DockerContainer::Awg && container != DockerContainer::AwgLegacy) {
return ErrorCode::NoError; return ErrorCode::NoError;
} }
@@ -318,7 +325,11 @@ ErrorCode ClientManagementModel::wgShow(const DockerContainer container, const S
return ErrorCode::NoError; return ErrorCode::NoError;
}; };
const QString command = QString("sudo docker exec -i $CONTAINER_NAME bash -c '%1'").arg("wg show all"); QString showBin = (container == DockerContainer::Awg)
? 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)); QString script = serverController->replaceVars(command, serverController->genVarsForScript(credentials, container));
error = serverController->runScript(credentials, script, cbReadStdOut); error = serverController->runScript(credentials, script, cbReadStdOut);
@@ -398,6 +409,7 @@ ErrorCode ClientManagementModel::appendClient(const DockerContainer container, c
case DockerContainer::OpenVpn: case DockerContainer::OpenVpn:
case DockerContainer::WireGuard: case DockerContainer::WireGuard:
case DockerContainer::Awg: case DockerContainer::Awg:
case DockerContainer::AwgLegacy:
case DockerContainer::Xray: case DockerContainer::Xray:
protocol = ContainerProps::defaultProtocol(container); protocol = ContainerProps::defaultProtocol(container);
break; break;
@@ -545,7 +557,8 @@ ErrorCode ClientManagementModel::revokeClient(const int row, const DockerContain
break; break;
} }
case DockerContainer::WireGuard: case DockerContainer::WireGuard:
case DockerContainer::Awg: { case DockerContainer::Awg:
case DockerContainer::AwgLegacy: {
errorCode = revokeWireGuard(row, container, credentials, serverController); errorCode = revokeWireGuard(row, container, credentials, serverController);
break; break;
} }
@@ -605,6 +618,7 @@ ErrorCode ClientManagementModel::revokeClient(const QJsonObject &containerConfig
case DockerContainer::OpenVpn: case DockerContainer::OpenVpn:
case DockerContainer::WireGuard: case DockerContainer::WireGuard:
case DockerContainer::Awg: case DockerContainer::Awg:
case DockerContainer::AwgLegacy:
case DockerContainer::Xray: { case DockerContainer::Xray: {
protocol = ContainerProps::defaultProtocol(container); protocol = ContainerProps::defaultProtocol(container);
break; break;
@@ -677,6 +691,7 @@ ErrorCode ClientManagementModel::revokeClient(const QJsonObject &containerConfig
break; break;
} }
case DockerContainer::WireGuard: case DockerContainer::WireGuard:
case DockerContainer::AwgLegacy:
case DockerContainer::Awg: { case DockerContainer::Awg: {
errorCode = revokeWireGuard(row, container, credentials, serverController); errorCode = revokeWireGuard(row, container, credentials, serverController);
break; break;
@@ -736,9 +751,15 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
{ {
ErrorCode error = ErrorCode::NoError; ErrorCode error = ErrorCode::NoError;
const QString wireGuardConfigFile = QString configPath;
QString("/opt/amnezia/%1/wg0.conf").arg(container == DockerContainer::WireGuard ? "wireguard" : "awg"); if (container == DockerContainer::AwgLegacy) {
const QString wireguardConfigString = serverController->getTextFileFromContainer(container, credentials, wireGuardConfigFile, error); configPath = QString::fromLatin1(amnezia::protocols::awg::serverLegacyConfigPath);
} else if (container == DockerContainer::Awg) {
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) { if (error != ErrorCode::NoError) {
logger.error() << "Failed to get the wg conf file from the server"; logger.error() << "Failed to get the wg conf file from the server";
return error; return error;
@@ -756,7 +777,7 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
} }
QString newWireGuardConfig = configSections.join("["); QString newWireGuardConfig = configSections.join("[");
newWireGuardConfig.insert(0, "["); newWireGuardConfig.insert(0, "[");
error = serverController->uploadTextFileToContainer(container, credentials, newWireGuardConfig, wireGuardConfigFile); error = serverController->uploadTextFileToContainer(container, credentials, newWireGuardConfig, configPath);
if (error != ErrorCode::NoError) { if (error != ErrorCode::NoError) {
logger.error() << "Failed to upload the wg conf file to the server"; logger.error() << "Failed to upload the wg conf file to the server";
return error; return error;
@@ -780,12 +801,18 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
return error; return error;
} }
const QString script = "sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip %1)'"; bool isAwg = (container == DockerContainer::Awg);
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( error = serverController->runScript(
credentials, credentials,
serverController->replaceVars(script.arg(wireGuardConfigFile), serverController->genVarsForScript(credentials, container))); serverController->replaceVars(script, serverController->genVarsForScript(credentials, container))
);
if (error != ErrorCode::NoError) { 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; return error;
} }
+12 -1
View File
@@ -31,12 +31,17 @@ QVariant ContainersModel::data(const QModelIndex &index, int role) const
} }
return m_containers.value(container); 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 ServiceTypeRole: return ContainerProps::containerService(container);
case DockerContainerRole: return container; case DockerContainerRole: return container;
case IsEasySetupContainerRole: return ContainerProps::isEasySetupContainer(container); case IsEasySetupContainerRole: return ContainerProps::isEasySetupContainer(container);
case EasySetupHeaderRole: return ContainerProps::easySetupHeader(container); case EasySetupHeaderRole: return ContainerProps::easySetupHeader(container);
case EasySetupDescriptionRole: return ContainerProps::easySetupDescription(container); case EasySetupDescriptionRole: return ContainerProps::easySetupDescription(container);
case EasySetupOrderRole: return ContainerProps::easySetupOrder(container); case EasySetupOrderRole: return ContainerProps::easySetupOrder(container);
case IsInstallationAllowedRole: return ContainersModel::isInstallationAllowed(container);
case IsInstalledRole: return m_containers.contains(container); case IsInstalledRole: return m_containers.contains(container);
case IsCurrentlyProcessedRole: return container == static_cast<DockerContainer>(m_processedContainerIndex); case IsCurrentlyProcessedRole: return container == static_cast<DockerContainer>(m_processedContainerIndex);
case IsSupportedRole: return ContainerProps::isSupportedByCurrentPlatform(container); case IsSupportedRole: return ContainerProps::isSupportedByCurrentPlatform(container);
@@ -114,6 +119,11 @@ bool ContainersModel::hasInstalledProtocols()
return false; return false;
} }
bool ContainersModel::isInstallationAllowed(DockerContainer container)
{
return container != DockerContainer::AwgLegacy;
}
QHash<int, QByteArray> ContainersModel::roleNames() const QHash<int, QByteArray> ContainersModel::roleNames() const
{ {
QHash<int, QByteArray> roles; QHash<int, QByteArray> roles;
@@ -123,6 +133,7 @@ QHash<int, QByteArray> ContainersModel::roleNames() const
roles[ServiceTypeRole] = "serviceType"; roles[ServiceTypeRole] = "serviceType";
roles[DockerContainerRole] = "dockerContainer"; roles[DockerContainerRole] = "dockerContainer";
roles[ConfigRole] = "config"; roles[ConfigRole] = "config";
roles[IsThirdPartyConfigRole] = "isThirdPartyConfig";
roles[IsEasySetupContainerRole] = "isEasySetupContainer"; roles[IsEasySetupContainerRole] = "isEasySetupContainer";
roles[EasySetupHeaderRole] = "easySetupHeader"; roles[EasySetupHeaderRole] = "easySetupHeader";
@@ -133,7 +144,7 @@ QHash<int, QByteArray> ContainersModel::roleNames() const
roles[IsCurrentlyProcessedRole] = "isCurrentlyProcessed"; roles[IsCurrentlyProcessedRole] = "isCurrentlyProcessed";
roles[IsSupportedRole] = "isSupported"; roles[IsSupportedRole] = "isSupported";
roles[IsShareableRole] = "isShareable"; roles[IsShareableRole] = "isShareable";
roles[IsInstallationAllowedRole] = "isInstallationAllowed";
roles[InstallPageOrderRole] = "installPageOrder"; roles[InstallPageOrderRole] = "installPageOrder";
return roles; return roles;
} }
+4
View File
@@ -20,6 +20,7 @@ public:
DetailedDescriptionRole, DetailedDescriptionRole,
ServiceTypeRole, ServiceTypeRole,
ConfigRole, ConfigRole,
IsThirdPartyConfigRole,
DockerContainerRole, DockerContainerRole,
IsEasySetupContainerRole, IsEasySetupContainerRole,
@@ -27,6 +28,7 @@ public:
EasySetupDescriptionRole, EasySetupDescriptionRole,
EasySetupOrderRole, EasySetupOrderRole,
IsInstallationAllowedRole,
IsInstalledRole, IsInstalledRole,
IsCurrentlyProcessedRole, IsCurrentlyProcessedRole,
IsDefaultRole, IsDefaultRole,
@@ -57,6 +59,8 @@ public slots:
bool hasInstalledServices(); bool hasInstalledServices();
bool hasInstalledProtocols(); bool hasInstalledProtocols();
static bool isInstallationAllowed(DockerContainer container);
protected: protected:
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
+3 -2
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())))); 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 ProtocolIndexRole: return ProtocolProps::protoFromString(m_content.keys().at(index.row()));
case RawConfigRole: { case RawConfigRole: {
auto protocolConfig = m_content.value(ContainerProps::containerTypeToString(m_container)).toObject(); auto protocolConfig = m_content.value(ContainerProps::containerTypeToProtocolString(m_container)).toObject();
auto lastConfigJsonDoc = auto lastConfigJsonDoc =
QJsonDocument::fromJson(protocolConfig.value(config_key::last_config).toString().toUtf8()); QJsonDocument::fromJson(protocolConfig.value(config_key::last_config).toString().toUtf8());
auto lastConfigJson = lastConfigJsonDoc.object(); auto lastConfigJson = lastConfigJsonDoc.object();
@@ -55,7 +55,8 @@ QVariant ProtocolsModel::data(const QModelIndex &index, int role) const
return rawConfig; return rawConfig;
} }
case IsClientProtocolExistsRole: { 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 = auto lastConfigJsonDoc =
QJsonDocument::fromJson(protocolConfig.value(config_key::last_config).toString().toUtf8()); QJsonDocument::fromJson(protocolConfig.value(config_key::last_config).toString().toUtf8());
auto lastConfigJson = lastConfigJsonDoc.object(); auto lastConfigJson = lastConfigJsonDoc.object();
+3 -3
View File
@@ -733,8 +733,8 @@ bool ServersModel::isDefaultServerDefaultContainerHasSplitTunneling()
if (container.value(config_key::container).toString() != ContainerProps::containerToString(defaultContainer)) { if (container.value(config_key::container).toString() != ContainerProps::containerToString(defaultContainer)) {
continue; continue;
} }
if (defaultContainer == DockerContainer::Awg || defaultContainer == DockerContainer::WireGuard) { if (defaultContainer == DockerContainer::Awg || defaultContainer == DockerContainer::AwgLegacy || defaultContainer == DockerContainer::WireGuard) {
QJsonObject serverProtocolConfig = container.value(ContainerProps::containerTypeToString(defaultContainer)).toObject(); QJsonObject serverProtocolConfig = container.value(ContainerProps::containerTypeToProtocolString(defaultContainer)).toObject();
QString clientProtocolConfigString = serverProtocolConfig.value(config_key::last_config).toString(); QString clientProtocolConfigString = serverProtocolConfig.value(config_key::last_config).toString();
QJsonObject clientProtocolConfig = QJsonDocument::fromJson(clientProtocolConfigString.toUtf8()).object(); QJsonObject clientProtocolConfig = QJsonDocument::fromJson(clientProtocolConfigString.toUtf8()).object();
return (clientProtocolConfigString.contains("AllowedIPs") && !clientProtocolConfigString.contains("AllowedIPs = 0.0.0.0/0, ::/0")) return (clientProtocolConfigString.contains("AllowedIPs") && !clientProtocolConfigString.contains("AllowedIPs = 0.0.0.0/0, ::/0"))
@@ -742,7 +742,7 @@ bool ServersModel::isDefaultServerDefaultContainerHasSplitTunneling()
&& !clientProtocolConfig.value(config_key::allowed_ips).toArray().contains("0.0.0.0/0")); && !clientProtocolConfig.value(config_key::allowed_ips).toArray().contains("0.0.0.0/0"));
} else if (defaultContainer == DockerContainer::Cloak || defaultContainer == DockerContainer::OpenVpn } else if (defaultContainer == DockerContainer::Cloak || defaultContainer == DockerContainer::OpenVpn
|| defaultContainer == DockerContainer::ShadowSocks) { || 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(); QString clientProtocolConfigString = serverProtocolConfig.value(config_key::last_config).toString();
return !clientProtocolConfigString.isEmpty() && !clientProtocolConfigString.contains("redirect-gateway"); return !clientProtocolConfigString.isEmpty() && !clientProtocolConfigString.contains("redirect-gateway");
} }
@@ -46,12 +46,10 @@ ListView {
var containerIndex = root.model.mapToSource(index) var containerIndex = root.model.mapToSource(index)
ContainersModel.setProcessedContainerIndex(containerIndex) ContainersModel.setProcessedContainerIndex(containerIndex)
if (serviceType !== ProtocolEnum.Other) { if (serviceType !== ProtocolEnum.Other && isThirdPartyConfig) {
if (config[ContainerProps.containerTypeToString(containerIndex)]["isThirdPartyConfig"]) { ProtocolsModel.updateModel(config)
ProtocolsModel.updateModel(config) PageController.goToPage(PageEnum.PageProtocolRaw)
PageController.goToPage(PageEnum.PageProtocolRaw) return
return
}
} }
switch (containerIndex) { switch (containerIndex) {
@@ -31,8 +31,19 @@ Item {
value: true value: true
} }
ValueFilter {
id: installationAllowedFilter
roleName: "isInstallationAllowed"
value: true
}
AnyOf {
id: showProtocolFilter
filters: [ installedFilter, installationAllowedFilter ]
}
function getWriteAccessProtocolsListFilters() { function getWriteAccessProtocolsListFilters() {
return [vpnTypeFilter] return [ vpnTypeFilter, showProtocolFilter ]
} }
function getReadAccessProtocolsListFilters() { function getReadAccessProtocolsListFilters() {
return [vpnTypeFilter, installedFilter] return [vpnTypeFilter, installedFilter]
@@ -26,6 +26,10 @@ PageType {
ValueFilter { ValueFilter {
roleName: "isSupported" roleName: "isSupported"
value: true value: true
},
ValueFilter {
roleName: "isInstallationAllowed"
value: true
} }
] ]
sorters: RoleSorter { sorters: RoleSorter {
+2
View File
@@ -453,6 +453,8 @@ PageType {
root.connectionTypesModel.push(wireGuardConnectionFormat) root.connectionTypesModel.push(wireGuardConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-awg")) { } else if (index === ContainerProps.containerFromString("amnezia-awg")) {
root.connectionTypesModel.push(awgConnectionFormat) root.connectionTypesModel.push(awgConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-awg-go")) {
root.connectionTypesModel.push(awgConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-shadowsocks")) { } else if (index === ContainerProps.containerFromString("amnezia-shadowsocks")) {
root.connectionTypesModel.push(openVpnConnectionFormat) root.connectionTypesModel.push(openVpnConnectionFormat)
root.connectionTypesModel.push(shadowSocksConnectionFormat) root.connectionTypesModel.push(shadowSocksConnectionFormat)
+3 -1
View File
@@ -85,7 +85,9 @@ void VpnConnection::onConnectionStateChanged(Vpn::ConnectionState state)
IpcClient::Interface()->resetIpStack(); IpcClient::Interface()->resetIpStack();
IpcClient::Interface()->flushDns(); IpcClient::Interface()->flushDns();
if (container != DockerContainer::Awg && container != DockerContainer::WireGuard) { if (container != DockerContainer::Awg &&
container != DockerContainer::AwgLegacy &&
container != DockerContainer::WireGuard) {
QString dns1 = m_vpnConfiguration.value(config_key::dns1).toString(); QString dns1 = m_vpnConfiguration.value(config_key::dns1).toString();
QString dns2 = m_vpnConfiguration.value(config_key::dns2).toString(); QString dns2 = m_vpnConfiguration.value(config_key::dns2).toString();