Ikev2 support

This commit is contained in:
pokamest 2021-10-04 19:07:49 +03:00
parent a5bcf1a02d
commit fa151cd320
27 changed files with 626 additions and 90 deletions

View file

@ -0,0 +1,67 @@
#include "ikev2_configurator.h"
#include <QApplication>
#include <QProcess>
#include <QString>
#include <QTemporaryDir>
#include <QDebug>
#include <QTemporaryFile>
#include <QJsonDocument>
#include "sftpdefs.h"
#include "core/server_defs.h"
#include "containers/containers_defs.h"
#include "core/scripts_registry.h"
#include "utils.h"
Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials,
DockerContainer container, ErrorCode *errorCode)
{
Ikev2Configurator::ConnectionData connData;
connData.host = credentials.hostName;
connData.clientId = Utils::getRandomString(16);
connData.password = Utils::getRandomString(16);
QString certFileName = "/opt/amnezia/ikev2/clients/" + connData.clientId + ".p12";
QString scriptCreateCert = QString("certutil -z <(head -c 1024 /dev/urandom) "\
"-S -c \"IKEv2 VPN CA\" -n \"%1\" "\
"-s \"O=IKEv2 VPN,CN=%1\" "\
"-k rsa -g 3072 -v 120 "\
"-d sql:/etc/ipsec.d -t \",,\" "\
"--keyUsage digitalSignature,keyEncipherment "\
"--extKeyUsage serverAuth,clientAuth -8 \"%1\"")
.arg(connData.clientId);
ErrorCode e = ServerController::runContainerScript(credentials, container, scriptCreateCert);
QString scriptExportCert = QString("pk12util -W \"%1\" -d sql:/etc/ipsec.d -n \"%2\" -o \"%3\"")
.arg(connData.password)
.arg(connData.clientId)
.arg(certFileName);
e = ServerController::runContainerScript(credentials, container, scriptExportCert);
connData.cert = ServerController::getTextFileFromContainer(container, credentials, certFileName, &e);
qDebug() << "Ikev2Configurator::ConnectionData cert size:" << connData.cert.size();
return connData;
}
QString Ikev2Configurator::genIkev2Config(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
{
ConnectionData connData = prepareIkev2Config(credentials, container, errorCode);
if (errorCode && *errorCode) {
return "";
}
QJsonObject config;
config[config_key::hostName] = connData.host;
config[config_key::userName] = connData.clientId;
config[config_key::cert] = QString(connData.cert.toBase64());
config[config_key::password] = connData.password;
return QJsonDocument(config).toJson();
}

View file

@ -0,0 +1,30 @@
#ifndef IKEV2_CONFIGURATOR_H
#define IKEV2_CONFIGURATOR_H
#include <QObject>
#include <QProcessEnvironment>
#include "core/defs.h"
#include "core/servercontroller.h"
class Ikev2Configurator
{
public:
struct ConnectionData {
QByteArray cert; // p12 client cert
QString clientId;
QString password; // certificate password
QString host; // host ip
};
static QString genIkev2Config(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
private:
static ConnectionData prepareIkev2Config(const ServerCredentials &credentials,
DockerContainer container, ErrorCode *errorCode = nullptr);
};
#endif // IKEV2_CONFIGURATOR_H

View file

@ -248,10 +248,6 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia
QString OpenVpnConfigurator::processConfigWithLocalSettings(QString config)
{
// TODO replace DNS if it already set
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
if (m_settings().routeMode() != Settings::VpnAllSites) {
config.replace("redirect-gateway def1 bypass-dhcp", "");
}
@ -277,9 +273,6 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(QString config)
QString OpenVpnConfigurator::processConfigWithExportSettings(QString config)
{
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
if(!config.contains("redirect-gateway def1 bypass-dhcp")) {
config.append("redirect-gateway def1 bypass-dhcp\n");
}
@ -308,5 +301,5 @@ ErrorCode OpenVpnConfigurator::signCert(DockerContainer container,
QStringList scriptList {script_import, script_sign};
QString script = ServerController::replaceVars(scriptList.join("\n"), ServerController::genVarsForScript(credentials, container));
return ServerController::runScript(ServerController::sshParams(credentials), script);
return ServerController::runScript(credentials, script);
}

View file

@ -3,6 +3,7 @@
#include "cloak_configurator.h"
#include "shadowsocks_configurator.h"
#include "wireguard_configurator.h"
#include "ikev2_configurator.h"
#include <QFile>
#include <QJsonObject>
@ -10,6 +11,11 @@
#include "containers/containers_defs.h"
Settings &VpnConfigurator::m_settings()
{
static Settings s;
return s;
}
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials,
DockerContainer container, const QJsonObject &containerConfig, Protocol proto, ErrorCode *errorCode)
@ -27,6 +33,9 @@ QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentia
case Protocol::WireGuard:
return WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, errorCode);
case Protocol::Ikev2:
return Ikev2Configurator::genIkev2Config(credentials, container, containerConfig, errorCode);
default:
return "";
}
@ -34,6 +43,9 @@ QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentia
QString VpnConfigurator::processConfigWithLocalSettings(DockerContainer container, Protocol proto, QString config)
{
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
if (proto == Protocol::OpenVpn) {
return OpenVpnConfigurator::processConfigWithLocalSettings(config);
}
@ -42,6 +54,9 @@ QString VpnConfigurator::processConfigWithLocalSettings(DockerContainer containe
QString VpnConfigurator::processConfigWithExportSettings(DockerContainer container, Protocol proto, QString config)
{
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
if (proto == Protocol::OpenVpn) {
return OpenVpnConfigurator::processConfigWithExportSettings(config);
}

View file

@ -7,6 +7,7 @@
#include "settings.h"
#include "core/servercontroller.h"
// Retrieve connection settings from server
class VpnConfigurator
{
public:
@ -21,6 +22,7 @@ public:
static void updateContainerConfigAfterInstallation(DockerContainer container,
QJsonObject &containerConfig, const QString &stdOut);
static Settings &m_settings();
};
#endif // VPN_CONFIGURATOR_H

View file

@ -130,7 +130,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
return connData;
}
e = ServerController::runScript(ServerController::sshParams(credentials),
e = ServerController::runScript(credentials,
ServerController::replaceVars("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip /opt/amnezia/wireguard/wg0.conf)'",
ServerController::genVarsForScript(credentials, container)));