WireGuard protocol fix

This commit is contained in:
pokamest 2021-12-25 21:14:55 +03:00
parent e7dd964825
commit 68a51c9c63
10 changed files with 70 additions and 19 deletions

View file

@ -940,8 +940,8 @@ void SshConnectionPrivate::connectToHost()
this, &SshConnectionPrivate::handleSocketConnected);
connect(m_socket, &QIODevice::readyRead,
this, &SshConnectionPrivate::handleIncomingData);
connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this,
SLOT(handleSocketError()));
connect(m_socket, &QAbstractSocket::errorOccurred,
this, &SshConnectionPrivate::handleSocketError);
connect(m_socket, &QAbstractSocket::disconnected,
this, &SshConnectionPrivate::handleSocketDisconnected);
connect(&m_timeoutTimer, &QTimer::timeout, this, &SshConnectionPrivate::handleTimeout);

View file

@ -50,7 +50,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
}
WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardConfig(const ServerCredentials &credentials,
DockerContainer container, ErrorCode *errorCode)
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
{
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
connData.host = credentials.hostName;
@ -61,6 +61,49 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
}
ErrorCode e = ErrorCode::NoError;
// Get list of already created clients (only IP addreses)
QString nextIpNumber;
{
QString script = QString("cat %1 | grep AllowedIPs").arg(amnezia::protocols::wireguard::serverConfigPath);
QString stdOut;
auto cbReadStdOut = [&](const QString &data, QSharedPointer<QSsh::SshRemoteProcess> proc) {
stdOut += data + "\n";
};
ServerController::runContainerScript(credentials, container, script, cbReadStdOut);
stdOut.replace("AllowedIPs = ", "");
stdOut.replace("/32", "");
QStringList ips = stdOut.split("\n", Qt::SkipEmptyParts);
// Calc next IP address
if (ips.isEmpty()) {
nextIpNumber = "2";
}
else {
int next = ips.last().split(".").last().toInt() + 1;
if (next > 254) {
if (errorCode) *errorCode = ErrorCode::AddressPoolError;
return connData;
}
nextIpNumber = QString::number(next);
}
}
QString subnetIp = containerConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
{
QStringList l = subnetIp.split(".", Qt::SkipEmptyParts);
if (l.isEmpty()) {
if (errorCode) *errorCode = ErrorCode::AddressPoolError;
return connData;
}
l.removeLast();
l.append(nextIpNumber);
connData.clientIP = l.join(".");
}
// Get keys
connData.serverPubKey = ServerController::getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPublicKeyPath, &e);
connData.serverPubKey.replace("\n", "");
if (e) {
@ -76,18 +119,15 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
return connData;
}
// Add client to config
QString configPart = QString(
"[Peer]\n"
"PublicKey = %1\n"
"PresharedKey = %2\n"
"AllowedIPs = $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR\n\n").
"AllowedIPs = %3/32\n\n").
arg(connData.clientPubKey).
arg(connData.pskKey);
configPart = ServerController::replaceVars(configPart, ServerController::genVarsForScript(credentials, container));
qDebug().noquote() << "Adding wg conf part to server" << configPart;
arg(connData.pskKey).
arg(connData.clientIP);
e = ServerController::uploadTextFileToContainer(container, credentials, configPart,
protocols::wireguard::serverConfigPath, QSsh::SftpOverwriteMode::SftpAppendToExisting);
@ -116,12 +156,13 @@ QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &crede
QString config = ServerController::replaceVars(amnezia::scriptData(ProtocolScriptType::wireguard_template, container),
ServerController::genVarsForScript(credentials, container, containerConfig));
ConnectionData connData = prepareWireguardConfig(credentials, container, errorCode);
ConnectionData connData = prepareWireguardConfig(credentials, container, containerConfig, errorCode);
if (errorCode && *errorCode) {
return "";
}
config.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", connData.clientPrivKey);
config.replace("$WIREGUARD_CLIENT_IP", connData.clientIP);
config.replace("$WIREGUARD_SERVER_PUBLIC_KEY", connData.serverPubKey);
config.replace("$WIREGUARD_PSK", connData.pskKey);
@ -130,6 +171,7 @@ QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &crede
jConfig[config_key::hostName] = connData.host;
jConfig[config_key::client_priv_key] = connData.clientPrivKey;
jConfig[config_key::client_ip] = connData.clientIP;
jConfig[config_key::client_pub_key] = connData.clientPubKey;
jConfig[config_key::psk_key] = connData.pskKey;
jConfig[config_key::server_pub_key] = connData.serverPubKey;

View file

@ -15,6 +15,7 @@ public:
struct ConnectionData {
QString clientPrivKey; // client private key
QString clientPubKey; // client public key
QString clientIP; // internal client IP address
QString serverPubKey; // tls-auth key
QString pskKey; // preshared key
QString host; // host ip
@ -29,7 +30,7 @@ public:
private:
static ConnectionData prepareWireguardConfig(const ServerCredentials &credentials,
DockerContainer container, ErrorCode *errorCode = nullptr);
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
static ConnectionData genClientKeys();

View file

@ -60,6 +60,7 @@ enum ErrorCode
OpenVpnAdaptersInUseError,
OpenVpnUnknownError,
OpenVpnTapAdapterError,
AddressPoolError,
// 3rd party utils errors
OpenSslFailed,

View file

@ -45,6 +45,7 @@ QString errorString(ErrorCode code){
// VPN errors
case (OpenVpnAdaptersInUseError): return QObject::tr("Can't connect: another VPN connection is active");
case (OpenVpnTapAdapterError): return QObject::tr("Can't setup OpenVPN TAP network adapter");
case (AddressPoolError): return QObject::tr("VPN pool error: no available addresses");
case(InternalError):
default:

View file

@ -667,9 +667,9 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
vars.append({{"$FAKE_WEB_SITE_ADDRESS", cloakConfig.value(config_key::site).toString(protocols::cloak::defaultRedirSite) }});
// Wireguard vars
vars.append({{"$WIREGUARD_SUBNET_IP", openvpnConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) }});
vars.append({{"$WIREGUARD_SUBNET_CIDR", openvpnConfig.value(config_key::subnet_cidr).toString(protocols::wireguard::defaultSubnetCidr) }});
vars.append({{"$WIREGUARD_SUBNET_MASK", openvpnConfig.value(config_key::subnet_mask).toString(protocols::wireguard::defaultSubnetMask) }});
vars.append({{"$WIREGUARD_SUBNET_IP", wireguarConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) }});
vars.append({{"$WIREGUARD_SUBNET_CIDR", wireguarConfig.value(config_key::subnet_cidr).toString(protocols::wireguard::defaultSubnetCidr) }});
vars.append({{"$WIREGUARD_SUBNET_MASK", wireguarConfig.value(config_key::subnet_mask).toString(protocols::wireguard::defaultSubnetMask) }});
vars.append({{"$WIREGUARD_SERVER_PORT", wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) }});

View file

@ -40,6 +40,7 @@ constexpr char server_priv_key[] = "server_priv_key";
constexpr char server_pub_key[] = "server_pub_key";
constexpr char psk_key[] = "psk_key";
constexpr char client_ip[] = "client_ip"; // internal ip address
constexpr char site[] = "site";
constexpr char block_outside_dns[] = "block_outside_dns";

View file

@ -1,5 +1,5 @@
[Interface]
Address = 10.8.1.2/32
Address = $WIREGUARD_CLIENT_IP/32
DNS = $PRIMARY_DNS, $SECONDARY_DNS
PrivateKey = $WIREGUARD_CLIENT_PRIVATE_KEY

View file

@ -50,9 +50,6 @@ void QrDecoderLogic::onDetectedQrCode(const QString &code)
s >> m_chunks[chunkId];
set_receivedChunksCount(m_chunks.size());
qDebug() << "Received chunks:" << receivedChunksCount() << "/" << chunksCount << "cur" << chunkId << m_chunks[chunkId].size();
qDebug() << chunkId << m_chunks[chunkId];
if (m_chunks.size() == totalChunksCount()) {
QByteArray data;
for (int i = 0; i < totalChunksCount(); ++i) {

View file

@ -2,6 +2,7 @@
#include <QImage>
#include <QDataStream>
#include <QZXing>
#include <QMessageBox>
#include "ShareConnectionLogic.h"
@ -15,6 +16,7 @@
#include "defines.h"
#include "core/defs.h"
#include "core/errorstrings.h"
#include <functional>
#include "../uilogic.h"
@ -194,6 +196,12 @@ void ShareConnectionLogic::onPushButtonShareWireGuardGenerateClicked()
ErrorCode e = ErrorCode::NoError;
QString cfg = WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, &e);
if (e) {
QMessageBox::warning(nullptr, APPLICATION_NAME,
tr("Error occurred while configuring server.") + "\n" +
errorString(e));
return;
}
cfg = VpnConfigurator::processConfigWithExportSettings(container, Proto::WireGuard, cfg);
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString();