mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-22 02:01:08 +07:00
Fix: selfhosted server installations
This commit is contained in:
@@ -63,16 +63,18 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
|
|||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
connData.caCert =
|
const QStringList certPaths = {
|
||||||
m_sshSession->getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::caCertPath, errorCode);
|
QString::fromLatin1(amnezia::protocols::openvpn::caCertPath),
|
||||||
connData.clientCert = m_sshSession->getTextFileFromContainer(
|
QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath).arg(connData.clientId),
|
||||||
container, credentials, QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath).arg(connData.clientId), errorCode);
|
QString::fromLatin1(amnezia::protocols::openvpn::taKeyPath)
|
||||||
|
};
|
||||||
|
const QList<QByteArray> certs = m_sshSession->getTextFilesFromContainer(container, credentials, certPaths, errorCode);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
connData.caCert = certs.value(0);
|
||||||
connData.taKey = m_sshSession->getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::taKeyPath, errorCode);
|
connData.clientCert = certs.value(1);
|
||||||
|
connData.taKey = certs.value(2);
|
||||||
|
|
||||||
if (connData.caCert.isEmpty() || connData.clientCert.isEmpty() || connData.taKey.isEmpty()) {
|
if (connData.caCert.isEmpty() || connData.clientCert.isEmpty() || connData.taKey.isEmpty()) {
|
||||||
errorCode = ErrorCode::SshScpFailureError;
|
errorCode = ErrorCode::SshScpFailureError;
|
||||||
|
|||||||
@@ -165,20 +165,16 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||||||
connData.clientIP = nextIp.toString();
|
connData.clientIP = nextIp.toString();
|
||||||
|
|
||||||
// Get keys
|
// Get keys
|
||||||
connData.serverPubKey =
|
const QList<QByteArray> keys =
|
||||||
m_sshSession->getTextFileFromContainer(container, credentials, m_serverPublicKeyPath, errorCode);
|
m_sshSession->getTextFilesFromContainer(container, credentials, {m_serverPublicKeyPath, m_serverPskKeyPath}, errorCode);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
return connData;
|
||||||
|
}
|
||||||
|
connData.serverPubKey = keys.value(0);
|
||||||
connData.serverPubKey.replace("\n", "");
|
connData.serverPubKey.replace("\n", "");
|
||||||
if (errorCode != ErrorCode::NoError) {
|
connData.pskKey = keys.value(1);
|
||||||
return connData;
|
|
||||||
}
|
|
||||||
|
|
||||||
connData.pskKey = m_sshSession->getTextFileFromContainer(container, credentials, m_serverPskKeyPath, errorCode);
|
|
||||||
connData.pskKey.replace("\n", "");
|
connData.pskKey.replace("\n", "");
|
||||||
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
return connData;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add client to config
|
// Add client to config
|
||||||
QString configPart = QString("[Peer]\n"
|
QString configPart = QString("[Peer]\n"
|
||||||
"PublicKey = %1\n"
|
"PublicKey = %1\n"
|
||||||
|
|||||||
@@ -90,10 +90,9 @@ InstallController::~InstallController()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode InstallController::setupContainer(const ServerCredentials &credentials, DockerContainer container, ContainerConfig &config,
|
ErrorCode InstallController::setupContainer(const ServerCredentials &credentials, DockerContainer container, ContainerConfig &config,
|
||||||
bool isUpdate)
|
SshSession &sshSession, bool isUpdate)
|
||||||
{
|
{
|
||||||
qDebug().noquote() << "InstallController::setupContainer" << ContainerUtils::containerToString(container);
|
qDebug().noquote() << "InstallController::setupContainer" << ContainerUtils::containerToString(container);
|
||||||
SshSession sshSession(this);
|
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
|
|
||||||
e = isUserInSudo(credentials, sshSession);
|
e = isUserInSudo(credentials, sshSession);
|
||||||
@@ -199,7 +198,7 @@ ErrorCode InstallController::updateContainer(const QString &serverId, DockerCont
|
|||||||
|
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
if (reinstallRequired) {
|
if (reinstallRequired) {
|
||||||
errorCode = setupContainer(credentials, container, newConfig, true);
|
errorCode = setupContainer(credentials, container, newConfig, sshSession, true);
|
||||||
} else {
|
} else {
|
||||||
errorCode = configureContainerWorker(credentials, container, newConfig, sshSession);
|
errorCode = configureContainerWorker(credentials, container, newConfig, sshSession);
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
@@ -1033,10 +1032,10 @@ ContainerConfig InstallController::generateConfig(DockerContainer container, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode InstallController::installContainer(const ServerCredentials &credentials, DockerContainer container, int port,
|
ErrorCode InstallController::installContainer(const ServerCredentials &credentials, DockerContainer container, int port,
|
||||||
TransportProto transportProto, ContainerConfig &config)
|
TransportProto transportProto, ContainerConfig &config, SshSession &sshSession)
|
||||||
{
|
{
|
||||||
config = generateConfig(container, port, transportProto);
|
config = generateConfig(container, port, transportProto);
|
||||||
return setupContainer(credentials, container, config, false);
|
return setupContainer(credentials, container, config, sshSession, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1142,7 +1141,7 @@ ErrorCode InstallController::installServer(const ServerCredentials &credentials,
|
|||||||
wasContainerInstalled = false;
|
wasContainerInstalled = false;
|
||||||
if (!installedContainers.contains(container)) {
|
if (!installedContainers.contains(container)) {
|
||||||
ContainerConfig config;
|
ContainerConfig config;
|
||||||
errorCode = installContainer(credentials, container, port, transportProto, config);
|
errorCode = installContainer(credentials, container, port, transportProto, config, sshSession);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
@@ -1212,7 +1211,7 @@ ErrorCode InstallController::installContainer(const QString &serverId, DockerCon
|
|||||||
wasContainerInstalled = false;
|
wasContainerInstalled = false;
|
||||||
if (!installedContainers.contains(container)) {
|
if (!installedContainers.contains(container)) {
|
||||||
ContainerConfig config;
|
ContainerConfig config;
|
||||||
errorCode = installContainer(credentials, container, port, transportProto, config);
|
errorCode = installContainer(credentials, container, port, transportProto, config, sshSession);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public:
|
|||||||
QObject *parent = nullptr);
|
QObject *parent = nullptr);
|
||||||
~InstallController();
|
~InstallController();
|
||||||
|
|
||||||
ErrorCode setupContainer(const ServerCredentials &credentials, DockerContainer container, ContainerConfig &config, bool isUpdate = false);
|
ErrorCode setupContainer(const ServerCredentials &credentials, DockerContainer container, ContainerConfig &config, SshSession &sshSession, bool isUpdate = false);
|
||||||
ErrorCode updateContainer(const QString &serverId, DockerContainer container, const ContainerConfig &oldConfig, ContainerConfig &newConfig);
|
ErrorCode updateContainer(const QString &serverId, DockerContainer container, const ContainerConfig &oldConfig, ContainerConfig &newConfig);
|
||||||
|
|
||||||
ErrorCode rebootServer(const QString &serverId);
|
ErrorCode rebootServer(const QString &serverId);
|
||||||
@@ -55,7 +55,7 @@ public:
|
|||||||
|
|
||||||
ErrorCode scanServerForInstalledContainers(const QString &serverId);
|
ErrorCode scanServerForInstalledContainers(const QString &serverId);
|
||||||
|
|
||||||
ErrorCode installContainer(const ServerCredentials &credentials, DockerContainer container, int port, TransportProto transportProto, ContainerConfig &config);
|
ErrorCode installContainer(const ServerCredentials &credentials, DockerContainer container, int port, TransportProto transportProto, ContainerConfig &config, SshSession &sshSession);
|
||||||
|
|
||||||
ErrorCode installServer(const ServerCredentials &credentials, DockerContainer container, int port, TransportProto transportProto,
|
ErrorCode installServer(const ServerCredentials &credentials, DockerContainer container, int port, TransportProto transportProto,
|
||||||
bool &wasContainerInstalled);
|
bool &wasContainerInstalled);
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ namespace libssh {
|
|||||||
ssh_options_set(m_session, SSH_OPTIONS_USER, hostUsername.c_str());
|
ssh_options_set(m_session, SSH_OPTIONS_USER, hostUsername.c_str());
|
||||||
ssh_options_set(m_session, SSH_OPTIONS_LOG_VERBOSITY, &logVerbosity);
|
ssh_options_set(m_session, SSH_OPTIONS_LOG_VERBOSITY, &logVerbosity);
|
||||||
|
|
||||||
|
long connectTimeoutSec = 30;
|
||||||
|
ssh_options_set(m_session, SSH_OPTIONS_TIMEOUT, &connectTimeoutSec);
|
||||||
|
|
||||||
QFutureWatcher<int> watcher;
|
QFutureWatcher<int> watcher;
|
||||||
QFuture<int> future = QtConcurrent::run([this]() {
|
QFuture<int> future = QtConcurrent::run([this]() {
|
||||||
return ssh_connect(m_session);
|
return ssh_connect(m_session);
|
||||||
@@ -103,6 +106,9 @@ namespace libssh {
|
|||||||
return fromLibsshErrorCode();
|
return fromLibsshErrorCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long sessionTimeoutSec = 86400;
|
||||||
|
ssh_options_set(m_session, SSH_OPTIONS_TIMEOUT, &sessionTimeoutSec);
|
||||||
}
|
}
|
||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ ErrorCode SshSession::runScript(const ServerCredentials &credentials, QString sc
|
|||||||
qDebug() << "SshSession::Run script";
|
qDebug() << "SshSession::Run script";
|
||||||
|
|
||||||
QString totalLine;
|
QString totalLine;
|
||||||
|
QStringList statements;
|
||||||
const QStringList &lines = script.split("\n", Qt::SkipEmptyParts);
|
const QStringList &lines = script.split("\n", Qt::SkipEmptyParts);
|
||||||
for (int i = 0; i < lines.count(); i++) {
|
for (int i = 0; i < lines.count(); i++) {
|
||||||
QString currentLine = lines.at(i);
|
QString currentLine = lines.at(i);
|
||||||
@@ -69,24 +70,31 @@ ErrorCode SshSession::runScript(const ServerCredentials &credentials, QString sc
|
|||||||
totalLine = totalLine + "\n" + currentLine;
|
totalLine = totalLine + "\n" + currentLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString lineToExec;
|
|
||||||
if (currentLine.endsWith("\\")) {
|
if (currentLine.endsWith("\\")) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
lineToExec = totalLine;
|
|
||||||
totalLine.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString lineToExec = totalLine;
|
||||||
|
totalLine.clear();
|
||||||
|
|
||||||
if (lineToExec.startsWith("#")) {
|
if (lineToExec.startsWith("#")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug().noquote() << lineToExec;
|
statements << lineToExec;
|
||||||
|
}
|
||||||
|
|
||||||
error = m_sshClient.executeCommand(lineToExec, cbReadStdOut, cbReadStdErr);
|
if (statements.isEmpty()) {
|
||||||
if (error != ErrorCode::NoError) {
|
qDebug().noquote() << "SshSession::runScript finished (no statements)\n";
|
||||||
return error;
|
return ErrorCode::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QString batchedScript = statements.join("\n");
|
||||||
|
qDebug().noquote() << batchedScript;
|
||||||
|
|
||||||
|
error = m_sshClient.executeCommand(batchedScript, cbReadStdOut, cbReadStdErr);
|
||||||
|
if (error != ErrorCode::NoError) {
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug().noquote() << "SshSession::runScript finished\n";
|
qDebug().noquote() << "SshSession::runScript finished\n";
|
||||||
@@ -97,30 +105,25 @@ ErrorCode SshSession::runContainerScript(const ServerCredentials &credentials, D
|
|||||||
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdOut,
|
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdOut,
|
||||||
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdErr)
|
const std::function<ErrorCode(const QString &, libssh::Client &)> &cbReadStdErr)
|
||||||
{
|
{
|
||||||
QString fileName = "/opt/amnezia/" + Utils::getRandomString(16) + ".sh";
|
|
||||||
|
|
||||||
ErrorCode e = uploadTextFileToContainer(container, credentials, script, fileName);
|
|
||||||
if (e)
|
|
||||||
return e;
|
|
||||||
|
|
||||||
const bool useSh = container == DockerContainer::Socks5Proxy || container == DockerContainer::MtProxy || container == DockerContainer::Telemt;
|
const bool useSh = container == DockerContainer::Socks5Proxy || container == DockerContainer::MtProxy || container == DockerContainer::Telemt;
|
||||||
QString runner = QString("sudo docker exec -i $CONTAINER_NAME %2 %1 ").arg(fileName, useSh ? "sh" : "bash");
|
const QString shell = useSh ? QStringLiteral("sh") : QStringLiteral("bash");
|
||||||
e = runScript(credentials, replaceVars(runner, amnezia::genBaseVars(credentials, container, QString(), QString())), cbReadStdOut, cbReadStdErr);
|
const QString b64 = QString::fromLatin1(script.toUtf8().toBase64());
|
||||||
|
|
||||||
QString remover = QString("sudo docker exec -i $CONTAINER_NAME rm %1 ").arg(fileName);
|
const QString command = QStringLiteral("printf '%s' '%1' | base64 -d | sudo docker exec -i $CONTAINER_NAME %2")
|
||||||
runScript(credentials, replaceVars(remover, amnezia::genBaseVars(credentials, container, QString(), QString())), cbReadStdOut, cbReadStdErr);
|
.arg(b64, shell);
|
||||||
|
|
||||||
return e;
|
return runScript(credentials,
|
||||||
|
replaceVars(command, amnezia::genBaseVars(credentials, container, QString(), QString())),
|
||||||
|
cbReadStdOut, cbReadStdErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode SshSession::uploadTextFileToContainer(DockerContainer container, const ServerCredentials &credentials, const QString &file,
|
ErrorCode SshSession::uploadTextFileToContainer(DockerContainer container, const ServerCredentials &credentials, const QString &file,
|
||||||
const QString &path, libssh::ScpOverwriteMode overwriteMode)
|
const QString &path, libssh::ScpOverwriteMode overwriteMode)
|
||||||
{
|
{
|
||||||
ErrorCode e = ErrorCode::NoError;
|
if (overwriteMode != libssh::ScpOverwriteMode::ScpOverwriteExisting
|
||||||
QString tmpFileName = QString("/tmp/%1.tmp").arg(Utils::getRandomString(16));
|
&& overwriteMode != libssh::ScpOverwriteMode::ScpAppendToExisting) {
|
||||||
e = uploadFileToHost(credentials, file.toUtf8(), tmpFileName);
|
return ErrorCode::NotImplementedError;
|
||||||
if (e)
|
}
|
||||||
return e;
|
|
||||||
|
|
||||||
QString stdOut;
|
QString stdOut;
|
||||||
auto cbReadStd = [&](const QString &data, libssh::Client &) {
|
auto cbReadStd = [&](const QString &data, libssh::Client &) {
|
||||||
@@ -128,45 +131,26 @@ ErrorCode SshSession::uploadTextFileToContainer(DockerContainer container, const
|
|||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
};
|
};
|
||||||
|
|
||||||
// mkdir
|
auto baseVars = amnezia::genBaseVars(credentials, container, QString(), QString());
|
||||||
QString mkdir = QString("sudo docker exec -i $CONTAINER_NAME mkdir -p \"$(dirname %1)\"").arg(path);
|
|
||||||
|
|
||||||
e = runScript(credentials, replaceVars(mkdir, amnezia::genBaseVars(credentials, container, QString(), QString())));
|
const QString b64 = QString::fromLatin1(file.toUtf8().toBase64());
|
||||||
|
const QString dir = QFileInfo(path).path();
|
||||||
|
const QString redirect = (overwriteMode == libssh::ScpOverwriteMode::ScpAppendToExisting)
|
||||||
|
? QStringLiteral(">>")
|
||||||
|
: QStringLiteral(">");
|
||||||
|
|
||||||
|
const QString command = QStringLiteral("printf '%s' '%1' | base64 -d | "
|
||||||
|
"sudo docker exec -i $CONTAINER_NAME sh -c 'mkdir -p \"%2\" && cat %3 \"%4\"'")
|
||||||
|
.arg(b64, dir, redirect, path);
|
||||||
|
|
||||||
|
ErrorCode e = runScript(credentials, replaceVars(command, baseVars), cbReadStd, cbReadStd);
|
||||||
if (e)
|
if (e)
|
||||||
return e;
|
return e;
|
||||||
|
|
||||||
if (overwriteMode == libssh::ScpOverwriteMode::ScpOverwriteExisting) {
|
|
||||||
e = runScript(credentials,
|
|
||||||
replaceVars(QStringLiteral("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName, path),
|
|
||||||
amnezia::genBaseVars(credentials, container, QString(), QString())),
|
|
||||||
cbReadStd, cbReadStd);
|
|
||||||
|
|
||||||
if (e)
|
|
||||||
return e;
|
|
||||||
} else if (overwriteMode == libssh::ScpOverwriteMode::ScpAppendToExisting) {
|
|
||||||
e = runScript(credentials,
|
|
||||||
replaceVars(QStringLiteral("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName, tmpFileName),
|
|
||||||
amnezia::genBaseVars(credentials, container, QString(), QString())),
|
|
||||||
cbReadStd, cbReadStd);
|
|
||||||
|
|
||||||
if (e)
|
|
||||||
return e;
|
|
||||||
|
|
||||||
e = runScript(credentials,
|
|
||||||
replaceVars(QStringLiteral("sudo docker exec -i $CONTAINER_NAME sh -c \"cat %1 >> %2\"").arg(tmpFileName, path),
|
|
||||||
amnezia::genBaseVars(credentials, container, QString(), QString())),
|
|
||||||
cbReadStd, cbReadStd);
|
|
||||||
|
|
||||||
if (e)
|
|
||||||
return e;
|
|
||||||
} else
|
|
||||||
return ErrorCode::NotImplementedError;
|
|
||||||
|
|
||||||
if (stdOut.contains("Error") && stdOut.contains("No such container")) {
|
if (stdOut.contains("Error") && stdOut.contains("No such container")) {
|
||||||
return ErrorCode::ServerContainerMissingError;
|
return ErrorCode::ServerContainerMissingError;
|
||||||
}
|
}
|
||||||
|
|
||||||
runScript(credentials, replaceVars(QString("sudo shred -u %1").arg(tmpFileName), amnezia::genBaseVars(credentials, container, QString(), QString())));
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,6 +172,38 @@ QByteArray SshSession::getTextFileFromContainer(DockerContainer container, const
|
|||||||
return QByteArray::fromHex(stdOut.toUtf8());
|
return QByteArray::fromHex(stdOut.toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QByteArray> SshSession::getTextFilesFromContainer(DockerContainer container, const ServerCredentials &credentials,
|
||||||
|
const QStringList &paths, ErrorCode &errorCode)
|
||||||
|
{
|
||||||
|
errorCode = ErrorCode::NoError;
|
||||||
|
QList<QByteArray> result;
|
||||||
|
if (paths.isEmpty()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString sep = QStringLiteral("ZZAMNSEPZZ");
|
||||||
|
QString inner;
|
||||||
|
for (const QString &path : paths) {
|
||||||
|
inner += QStringLiteral("xxd -p '%1'; echo '%2'; ").arg(path, sep);
|
||||||
|
}
|
||||||
|
QString script = QStringLiteral("sudo docker exec -i %1 sh -c \"%2\"")
|
||||||
|
.arg(ContainerUtils::containerToString(container), inner);
|
||||||
|
|
||||||
|
QString stdOut;
|
||||||
|
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
||||||
|
stdOut += data;
|
||||||
|
return ErrorCode::NoError;
|
||||||
|
};
|
||||||
|
errorCode = runScript(credentials, script, cbReadStdOut);
|
||||||
|
|
||||||
|
const QStringList parts = stdOut.split(sep);
|
||||||
|
for (int i = 0; i < paths.size(); ++i) {
|
||||||
|
const QString hex = (i < parts.size()) ? parts.at(i) : QString();
|
||||||
|
result.append(QByteArray::fromHex(hex.toUtf8()));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
ErrorCode SshSession::uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data, const QString &remotePath,
|
ErrorCode SshSession::uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data, const QString &remotePath,
|
||||||
libssh::ScpOverwriteMode overwriteMode)
|
libssh::ScpOverwriteMode overwriteMode)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ public:
|
|||||||
libssh::ScpOverwriteMode overwriteMode = libssh::ScpOverwriteMode::ScpOverwriteExisting);
|
libssh::ScpOverwriteMode overwriteMode = libssh::ScpOverwriteMode::ScpOverwriteExisting);
|
||||||
QByteArray getTextFileFromContainer(DockerContainer container, const ServerCredentials &credentials, const QString &path,
|
QByteArray getTextFileFromContainer(DockerContainer container, const ServerCredentials &credentials, const QString &path,
|
||||||
ErrorCode &errorCode);
|
ErrorCode &errorCode);
|
||||||
|
QList<QByteArray> getTextFilesFromContainer(DockerContainer container, const ServerCredentials &credentials,
|
||||||
|
const QStringList &paths, ErrorCode &errorCode);
|
||||||
|
|
||||||
static QString replaceVars(const QString &script, const Vars &vars);
|
static QString replaceVars(const QString &script, const Vars &vars);
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ dev tun
|
|||||||
ca /opt/amnezia/openvpn/ca.crt
|
ca /opt/amnezia/openvpn/ca.crt
|
||||||
cert /opt/amnezia/openvpn/AmneziaReq.crt
|
cert /opt/amnezia/openvpn/AmneziaReq.crt
|
||||||
key /opt/amnezia/openvpn/AmneziaReq.key
|
key /opt/amnezia/openvpn/AmneziaReq.key
|
||||||
dh /opt/amnezia/openvpn/dh.pem
|
dh none
|
||||||
|
ecdh-curve secp384r1
|
||||||
server $OPENVPN_SUBNET_IP $OPENVPN_SUBNET_MASK
|
server $OPENVPN_SUBNET_IP $OPENVPN_SUBNET_MASK
|
||||||
ifconfig-pool-persist ipp.txt
|
ifconfig-pool-persist ipp.txt
|
||||||
duplicate-cn
|
duplicate-cn
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ sudo docker run -d \
|
|||||||
-p $OPENVPN_PORT:$OPENVPN_PORT/$OPENVPN_TRANSPORT_PROTO \
|
-p $OPENVPN_PORT:$OPENVPN_PORT/$OPENVPN_TRANSPORT_PROTO \
|
||||||
--name $CONTAINER_NAME $CONTAINER_NAME
|
--name $CONTAINER_NAME $CONTAINER_NAME
|
||||||
|
|
||||||
|
# Wait until the container is actually running before the network/exec steps.
|
||||||
|
# DH generation was removed, so this phase now finishes in ~2s instead of up to
|
||||||
|
# minutes; without this guard a slow Docker daemon (or a leftover container from a
|
||||||
|
# previous deploy) could let later steps race ahead and fail with "No such
|
||||||
|
# container". Single-line on purpose (script runs as one batched shell). ~15s cap.
|
||||||
|
amn_i=0; while [ "$(sudo docker inspect -f '{{.State.Running}}' $CONTAINER_NAME 2>/dev/null)" != "true" ] && [ $amn_i -lt 30 ]; do sleep 0.5; amn_i=$((amn_i+1)); done
|
||||||
|
|
||||||
sudo docker network connect amnezia-dns-net $CONTAINER_NAME
|
sudo docker network connect amnezia-dns-net $CONTAINER_NAME
|
||||||
|
|
||||||
# Create tun device if not exist
|
# Create tun device if not exist
|
||||||
@@ -18,8 +25,7 @@ sudo docker exec -i $CONTAINER_NAME sh -c "ifconfig eth0:0 $SERVER_IP_ADDRESS ne
|
|||||||
# OpenVPN config
|
# OpenVPN config
|
||||||
sudo docker exec -i $CONTAINER_NAME bash -c 'mkdir -p /opt/amnezia/openvpn/clients; \
|
sudo docker exec -i $CONTAINER_NAME bash -c 'mkdir -p /opt/amnezia/openvpn/clients; \
|
||||||
cd /opt/amnezia/openvpn && easyrsa init-pki; \
|
cd /opt/amnezia/openvpn && easyrsa init-pki; \
|
||||||
cd /opt/amnezia/openvpn && easyrsa gen-dh; \
|
cd /opt/amnezia/openvpn && easyrsa build-ca nopass << EOF yes EOF && easyrsa gen-req AmneziaReq nopass << EOF2 yes EOF2;\
|
||||||
cd /opt/amnezia/openvpn && cp pki/dh.pem /opt/amnezia/openvpn && easyrsa build-ca nopass << EOF yes EOF && easyrsa gen-req AmneziaReq nopass << EOF2 yes EOF2;\
|
|
||||||
cd /opt/amnezia/openvpn && easyrsa sign-req server AmneziaReq << EOF3 yes EOF3;\
|
cd /opt/amnezia/openvpn && easyrsa sign-req server AmneziaReq << EOF3 yes EOF3;\
|
||||||
cd /opt/amnezia/openvpn && openvpn --genkey --secret ta.key << EOF4;\
|
cd /opt/amnezia/openvpn && openvpn --genkey --secret ta.key << EOF4;\
|
||||||
cd /opt/amnezia/openvpn && cp pki/ca.crt pki/issued/AmneziaReq.crt pki/private/AmneziaReq.key /opt/amnezia/openvpn;\
|
cd /opt/amnezia/openvpn && cp pki/ca.crt pki/issued/AmneziaReq.crt pki/private/AmneziaReq.key /opt/amnezia/openvpn;\
|
||||||
|
|||||||
Reference in New Issue
Block a user