ShadowSocks protocol fixes:
- remote for OpenVPN is set to real ip address - remote ip will be added as alias in docker container - ss-local graceful shutdown - crash fixes
This commit is contained in:
parent
84e4b776ac
commit
d831d68e73
14 changed files with 173 additions and 65 deletions
|
|
@ -63,7 +63,11 @@ enum ErrorCode
|
||||||
|
|
||||||
// VPN errors
|
// VPN errors
|
||||||
OpenVpnAdaptersInUseError,
|
OpenVpnAdaptersInUseError,
|
||||||
OpenVpnUnknownError
|
OpenVpnUnknownError,
|
||||||
|
|
||||||
|
// 3rd party utils errors
|
||||||
|
OpenVpnExecutableCrashed,
|
||||||
|
ShadowSocksExecutableCrashed
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace config {
|
namespace config {
|
||||||
|
|
|
||||||
|
|
@ -240,12 +240,7 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia
|
||||||
config.replace("redirect-gateway def1 bypass-dhcp", "");
|
config.replace("redirect-gateway def1 bypass-dhcp", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proto == Protocol::ShadowSocks) {
|
config.replace("$REMOTE_HOST", connData.host);
|
||||||
config.replace("$REMOTE_HOST", "10.8.0.1");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
config.replace("$REMOTE_HOST", connData.host);
|
|
||||||
}
|
|
||||||
config.replace("$REMOTE_PORT", "1194");
|
config.replace("$REMOTE_PORT", "1194");
|
||||||
config.replace("$CA_CERT", connData.caCert);
|
config.replace("$CA_CERT", connData.caCert);
|
||||||
config.replace("$CLIENT_CERT", connData.clientCert);
|
config.replace("$CLIENT_CERT", connData.clientCert);
|
||||||
|
|
@ -265,7 +260,9 @@ QString OpenVpnConfigurator::convertOpenSShKey(const QString &key)
|
||||||
p.setProcessChannelMode(QProcess::MergedChannels);
|
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
|
||||||
QTemporaryFile tmp;
|
QTemporaryFile tmp;
|
||||||
|
#ifdef QT_DEBUG
|
||||||
tmp.setAutoRemove(false);
|
tmp.setAutoRemove(false);
|
||||||
|
#endif
|
||||||
tmp.open();
|
tmp.open();
|
||||||
tmp.write(key.toUtf8());
|
tmp.write(key.toUtf8());
|
||||||
tmp.close();
|
tmp.close();
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
||||||
#include "sshconnectionmanager.h"
|
#include "sshconnectionmanager.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace QSsh;
|
using namespace QSsh;
|
||||||
|
|
@ -24,7 +25,7 @@ QString ServerController::getContainerName(DockerContainer container)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::runScript(DockerContainer container,
|
ErrorCode ServerController::runScript(const QHash<QString, QString> &vars,
|
||||||
const SshConnectionParameters &sshParams, QString script,
|
const SshConnectionParameters &sshParams, QString script,
|
||||||
const std::function<void(const QString &, QSharedPointer<SshRemoteProcess>)> &cbReadStdOut,
|
const std::function<void(const QString &, QSharedPointer<SshRemoteProcess>)> &cbReadStdOut,
|
||||||
const std::function<void(const QString &, QSharedPointer<SshRemoteProcess>)> &cbReadStdErr)
|
const std::function<void(const QString &, QSharedPointer<SshRemoteProcess>)> &cbReadStdErr)
|
||||||
|
|
@ -41,7 +42,11 @@ ErrorCode ServerController::runScript(DockerContainer container,
|
||||||
const QStringList &lines = script.split("\n", QString::SkipEmptyParts);
|
const QStringList &lines = script.split("\n", QString::SkipEmptyParts);
|
||||||
for (int i = 0; i < lines.count(); i++) {
|
for (int i = 0; i < lines.count(); i++) {
|
||||||
QString line = lines.at(i);
|
QString line = lines.at(i);
|
||||||
line.replace("$CONTAINER_NAME", getContainerName(container));
|
|
||||||
|
for (const QString &var : vars.keys()) {
|
||||||
|
//qDebug() << "Replacing" << var << vars.value(var);
|
||||||
|
line.replace(var, vars.value(var));
|
||||||
|
}
|
||||||
|
|
||||||
if (line.startsWith("#")) {
|
if (line.startsWith("#")) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -209,7 +214,7 @@ ErrorCode ServerController::signCert(DockerContainer container,
|
||||||
|
|
||||||
QStringList script {script_import, script_sign};
|
QStringList script {script_import, script_sign};
|
||||||
|
|
||||||
return runScript(container, sshParams(credentials), script.join("\n"));
|
return runScript(genVarsForScript(credentials, container), sshParams(credentials), script.join("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials)
|
ErrorCode ServerController::checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials)
|
||||||
|
|
@ -306,7 +311,7 @@ ErrorCode ServerController::removeServer(const ServerCredentials &credentials, P
|
||||||
scriptData = file.readAll();
|
scriptData = file.readAll();
|
||||||
if (scriptData.isEmpty()) return ErrorCode::InternalError;
|
if (scriptData.isEmpty()) return ErrorCode::InternalError;
|
||||||
|
|
||||||
return runScript(container, sshParams(credentials), scriptData);
|
return runScript(genVarsForScript(credentials, container), sshParams(credentials), scriptData);
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::setupServer(const ServerCredentials &credentials, Protocol proto)
|
ErrorCode ServerController::setupServer(const ServerCredentials &credentials, Protocol proto)
|
||||||
|
|
@ -351,7 +356,7 @@ ErrorCode ServerController::setupOpenVpnServer(const ServerCredentials &credenti
|
||||||
stdOut += data + "\n";
|
stdOut += data + "\n";
|
||||||
};
|
};
|
||||||
|
|
||||||
ErrorCode e = runScript(DockerContainer::OpenVpn, sshParams(credentials), scriptData, cbReadStdOut, cbReadStdErr);
|
ErrorCode e = runScript(genVarsForScript(credentials, DockerContainer::OpenVpn), sshParams(credentials), scriptData, cbReadStdOut, cbReadStdErr);
|
||||||
if (e) return e;
|
if (e) return e;
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
|
@ -384,7 +389,7 @@ ErrorCode ServerController::setupShadowSocksServer(const ServerCredentials &cred
|
||||||
stdOut += data + "\n";
|
stdOut += data + "\n";
|
||||||
};
|
};
|
||||||
|
|
||||||
ErrorCode e = runScript(DockerContainer::ShadowSocks, sshParams(credentials), scriptData, cbReadStdOut, cbReadStdErr);
|
ErrorCode e = runScript(genVarsForScript(credentials, DockerContainer::ShadowSocks), sshParams(credentials), scriptData, cbReadStdOut, cbReadStdErr);
|
||||||
if (e) return e;
|
if (e) return e;
|
||||||
|
|
||||||
// Create ss config
|
// Create ss config
|
||||||
|
|
@ -407,10 +412,27 @@ ErrorCode ServerController::setupShadowSocksServer(const ServerCredentials &cred
|
||||||
QString script = QString("sudo docker exec -d %1 sh -c \"ss-server -c %2\"").
|
QString script = QString("sudo docker exec -d %1 sh -c \"ss-server -c %2\"").
|
||||||
arg(getContainerName(DockerContainer::ShadowSocks)).arg(sSConfigPath);
|
arg(getContainerName(DockerContainer::ShadowSocks)).arg(sSConfigPath);
|
||||||
|
|
||||||
e = runScript(DockerContainer::ShadowSocks, sshParams(credentials), script);
|
e = runScript(genVarsForScript(credentials, DockerContainer::ShadowSocks), sshParams(credentials), script);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QHash<QString, QString> ServerController::genVarsForScript(const ServerCredentials &credentials, DockerContainer container)
|
||||||
|
{
|
||||||
|
QHash<QString, QString> vars;
|
||||||
|
|
||||||
|
vars.insert("$CONTAINER_NAME", getContainerName(container));
|
||||||
|
|
||||||
|
QString serverIp = Utils::getIPAddress(credentials.hostName);
|
||||||
|
if (!serverIp.isEmpty()) {
|
||||||
|
vars.insert("$SERVER_IP_ADDRESS", serverIp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qWarning() << "ServerController::genVarsForScript unable to resolve address for credentials.hostName";
|
||||||
|
}
|
||||||
|
|
||||||
|
return vars;
|
||||||
|
}
|
||||||
|
|
||||||
SshConnection *ServerController::connectToHost(const SshConnectionParameters &sshParams)
|
SshConnection *ServerController::connectToHost(const SshConnectionParameters &sshParams)
|
||||||
{
|
{
|
||||||
SshConnection *client = acquireConnection(sshParams);
|
SshConnection *client = acquireConnection(sshParams);
|
||||||
|
|
@ -470,5 +492,5 @@ ErrorCode ServerController::setupServerFirewall(const ServerCredentials &credent
|
||||||
file.open(QIODevice::ReadOnly);
|
file.open(QIODevice::ReadOnly);
|
||||||
|
|
||||||
QString script = file.readAll();
|
QString script = file.readAll();
|
||||||
return runScript(DockerContainer::OpenVpn, sshParams(credentials), script);
|
return runScript(genVarsForScript(credentials, DockerContainer::OpenVpn), sshParams(credentials), script);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,8 @@ public:
|
||||||
static ErrorCode setupServerFirewall(const ServerCredentials &credentials);
|
static ErrorCode setupServerFirewall(const ServerCredentials &credentials);
|
||||||
private:
|
private:
|
||||||
static QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams);
|
static QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams);
|
||||||
static ErrorCode runScript(DockerContainer container,
|
|
||||||
|
static ErrorCode runScript(const QHash<QString, QString> &vars,
|
||||||
const QSsh::SshConnectionParameters &sshParams, QString script,
|
const QSsh::SshConnectionParameters &sshParams, QString script,
|
||||||
const std::function<void(const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &cbReadStdOut = nullptr,
|
const std::function<void(const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &cbReadStdOut = nullptr,
|
||||||
const std::function<void(const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &cbReadStdErr = nullptr);
|
const std::function<void(const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &cbReadStdErr = nullptr);
|
||||||
|
|
@ -55,6 +56,8 @@ private:
|
||||||
static ErrorCode setupOpenVpnServer(const ServerCredentials &credentials);
|
static ErrorCode setupOpenVpnServer(const ServerCredentials &credentials);
|
||||||
static ErrorCode setupShadowSocksServer(const ServerCredentials &credentials);
|
static ErrorCode setupShadowSocksServer(const ServerCredentials &credentials);
|
||||||
|
|
||||||
|
|
||||||
|
static QHash<QString, QString> genVarsForScript(const ServerCredentials &credentials, DockerContainer container);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SERVERCONTROLLER_H
|
#endif // SERVERCONTROLLER_H
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ bool ManagementServer::isOpen() const
|
||||||
|
|
||||||
void ManagementServer::stop()
|
void ManagementServer::stop()
|
||||||
{
|
{
|
||||||
m_tcpServer->close();
|
if (m_tcpServer) m_tcpServer->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManagementServer::onAcceptError(QAbstractSocket::SocketError socketError)
|
void ManagementServer::onAcceptError(QAbstractSocket::SocketError socketError)
|
||||||
|
|
@ -37,7 +37,9 @@ qint64 ManagementServer::writeCommand(const QString& message)
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString command = message + "\n";
|
const QString command = message + "\n";
|
||||||
return m_socket->write(command.toStdString().c_str());
|
qint64 bytesWritten = m_socket->write(command.toStdString().c_str());
|
||||||
|
m_socket->flush();
|
||||||
|
return bytesWritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManagementServer::onNewConnection()
|
void ManagementServer::onNewConnection()
|
||||||
|
|
@ -45,7 +47,7 @@ void ManagementServer::onNewConnection()
|
||||||
qDebug() << "New incoming connection";
|
qDebug() << "New incoming connection";
|
||||||
|
|
||||||
m_socket = QPointer<QTcpSocket>(m_tcpServer->nextPendingConnection());
|
m_socket = QPointer<QTcpSocket>(m_tcpServer->nextPendingConnection());
|
||||||
m_tcpServer->close();
|
if (m_tcpServer) m_tcpServer->close();
|
||||||
|
|
||||||
QObject::connect(m_socket.data(), SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
|
QObject::connect(m_socket.data(), SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
|
||||||
QObject::connect(m_socket.data(), SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onSocketError(QAbstractSocket::SocketError)));
|
QObject::connect(m_socket.data(), SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onSocketError(QAbstractSocket::SocketError)));
|
||||||
|
|
@ -78,9 +80,7 @@ void ManagementServer::onReadyRead()
|
||||||
|
|
||||||
bool ManagementServer::start(const QString& host, unsigned int port)
|
bool ManagementServer::start(const QString& host, unsigned int port)
|
||||||
{
|
{
|
||||||
if (m_tcpServer) {
|
if (m_tcpServer) m_tcpServer->close();
|
||||||
m_tcpServer->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_tcpServer = QSharedPointer<QTcpServer>(new QTcpServer(this), [](QTcpServer *s){
|
m_tcpServer = QSharedPointer<QTcpServer>(new QTcpServer(this), [](QTcpServer *s){
|
||||||
if (s) s->deleteLater();
|
if (s) s->deleteLater();
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,15 @@ OpenVpnProtocol::OpenVpnProtocol(const QJsonObject &configuration, QObject* pare
|
||||||
|
|
||||||
OpenVpnProtocol::~OpenVpnProtocol()
|
OpenVpnProtocol::~OpenVpnProtocol()
|
||||||
{
|
{
|
||||||
qDebug() << "OpenVpnProtocol::stop()";
|
qDebug() << "OpenVpnProtocol::~OpenVpnProtocol()";
|
||||||
OpenVpnProtocol::stop();
|
OpenVpnProtocol::stop();
|
||||||
|
QThread::msleep(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenVpnProtocol::stop()
|
void OpenVpnProtocol::stop()
|
||||||
{
|
{
|
||||||
|
qDebug() << "OpenVpnProtocol::stop()";
|
||||||
|
|
||||||
// TODO: need refactoring
|
// TODO: need refactoring
|
||||||
// sendTermSignal() will even return true while server connected ???
|
// sendTermSignal() will even return true while server connected ???
|
||||||
if ((m_connectionState == VpnProtocol::ConnectionState::Preparing) ||
|
if ((m_connectionState == VpnProtocol::ConnectionState::Preparing) ||
|
||||||
|
|
@ -32,6 +35,8 @@ void OpenVpnProtocol::stop()
|
||||||
if (!sendTermSignal()) {
|
if (!sendTermSignal()) {
|
||||||
killOpenVpnProcess();
|
killOpenVpnProcess();
|
||||||
}
|
}
|
||||||
|
m_managementServer.stop();
|
||||||
|
qApp->processEvents();
|
||||||
setConnectionState(VpnProtocol::ConnectionState::Disconnecting);
|
setConnectionState(VpnProtocol::ConnectionState::Disconnecting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,26 +16,51 @@ ShadowSocksVpnProtocol::ShadowSocksVpnProtocol(const QJsonObject &configuration,
|
||||||
|
|
||||||
ShadowSocksVpnProtocol::~ShadowSocksVpnProtocol()
|
ShadowSocksVpnProtocol::~ShadowSocksVpnProtocol()
|
||||||
{
|
{
|
||||||
qDebug() << "ShadowSocksVpnProtocol::stop()";
|
qDebug() << "ShadowSocksVpnProtocol::~ShadowSocksVpnProtocol";
|
||||||
ShadowSocksVpnProtocol::stop();
|
ShadowSocksVpnProtocol::stop();
|
||||||
|
QThread::msleep(200);
|
||||||
|
m_ssProcess.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ShadowSocksVpnProtocol::start()
|
ErrorCode ShadowSocksVpnProtocol::start()
|
||||||
{
|
{
|
||||||
qDebug() << "ShadowSocksVpnProtocol::start()";
|
if (Utils::processIsRunning(Utils::executable("ss-local", false))) {
|
||||||
|
Utils::killProcessByName(Utils::executable("ss-local", false));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
m_shadowSocksCfgFile.setAutoRemove(false);
|
||||||
|
#endif
|
||||||
|
m_shadowSocksCfgFile.open();
|
||||||
|
m_shadowSocksCfgFile.write(QJsonDocument(m_shadowSocksConfig).toJson());
|
||||||
|
m_shadowSocksCfgFile.close();
|
||||||
|
|
||||||
|
QStringList args = QStringList() << "-c" << m_shadowSocksCfgFile.fileName()
|
||||||
|
<< "--no-delay";
|
||||||
|
|
||||||
|
qDebug().noquote() << "ShadowSocksVpnProtocol::start()"
|
||||||
|
<< shadowSocksExecPath() << args.join(" ");
|
||||||
|
|
||||||
m_ssProcess.setProcessChannelMode(QProcess::MergedChannels);
|
m_ssProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
|
||||||
m_ssProcess.setProgram(shadowSocksExecPath());
|
m_ssProcess.setProgram(shadowSocksExecPath());
|
||||||
m_ssProcess.setArguments(QStringList() << "-s" << m_shadowSocksConfig.value("server").toString()
|
m_ssProcess.setArguments(args);
|
||||||
<< "-p" << QString::number(m_shadowSocksConfig.value("server_port").toInt())
|
|
||||||
<< "-l" << QString::number(m_shadowSocksConfig.value("local_port").toInt())
|
|
||||||
<< "-m" << m_shadowSocksConfig.value("method").toString()
|
|
||||||
<< "-k" << m_shadowSocksConfig.value("password").toString()
|
|
||||||
);
|
|
||||||
|
|
||||||
connect(&m_ssProcess, &QProcess::readyRead, this, [this](){
|
connect(&m_ssProcess, &QProcess::readyReadStandardOutput, this, [this](){
|
||||||
qDebug().noquote() << m_ssProcess.readAll();
|
qDebug().noquote() << "ss-local:" << m_ssProcess.readAllStandardOutput();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(&m_ssProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus){
|
||||||
|
qDebug().noquote() << "ShadowSocksVpnProtocol finished, exitCode, exiStatus" << exitCode << exitStatus;
|
||||||
|
setConnectionState(VpnProtocol::ConnectionState::Disconnected);
|
||||||
|
if (exitStatus != QProcess::NormalExit){
|
||||||
|
emit protocolError(amnezia::ErrorCode::ShadowSocksExecutableCrashed);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
if (exitCode !=0 ){
|
||||||
|
emit protocolError(amnezia::ErrorCode::InternalError);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
m_ssProcess.start();
|
m_ssProcess.start();
|
||||||
|
|
@ -54,10 +79,14 @@ void ShadowSocksVpnProtocol::stop()
|
||||||
OpenVpnProtocol::stop();
|
OpenVpnProtocol::stop();
|
||||||
|
|
||||||
qDebug() << "ShadowSocksVpnProtocol::stop()";
|
qDebug() << "ShadowSocksVpnProtocol::stop()";
|
||||||
m_ssProcess.close();
|
m_ssProcess.terminate();
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
Utils::signalCtrl(m_ssProcess.processId(), CTRL_C_EVENT);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ShadowSocksVpnProtocol::shadowSocksExecPath() const
|
QString ShadowSocksVpnProtocol::shadowSocksExecPath()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
return Utils::executable(QString("ss/ss-local"), true);
|
return Utils::executable(QString("ss/ss-local"), true);
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,16 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void readShadowSocksConfiguration(const QJsonObject &configuration);
|
void readShadowSocksConfiguration(const QJsonObject &configuration);
|
||||||
QString shadowSocksExecPath() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QJsonObject m_shadowSocksConfig;
|
QJsonObject m_shadowSocksConfig;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static QString shadowSocksExecPath();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QProcess m_ssProcess;
|
QProcess m_ssProcess;
|
||||||
|
QTemporaryFile m_shadowSocksCfgFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHADOWSOCKSVPNPROTOCOL_H
|
#endif // SHADOWSOCKSVPNPROTOCOL_H
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
docker stop $CONTAINER_NAME
|
sudo docker stop $CONTAINER_NAME
|
||||||
docker rm -f $CONTAINER_NAME
|
sudo docker rm -f $CONTAINER_NAME
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
sysctl -w net.ipv4.ip_forward=1
|
sudo sysctl -w net.ipv4.ip_forward=1
|
||||||
iptables -P FORWARD ACCEPT
|
sudo iptables -P FORWARD ACCEPT
|
||||||
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
|
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
# CONTAINER_NAME=... this var will be set in ServerController
|
# CONTAINER_NAME=... this var will be set in ServerController
|
||||||
# Don't run commands in background like sh -c "openvpn &"
|
# Don't run commands in background like sh -c "openvpn &"
|
||||||
|
|
||||||
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; if [[ -f "/usr/bin/sudo" ]]; then $pm install -y sudo; fi
|
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; if [[ -f "/usr/bin/sudo" ]]; then $pm install -y -q sudo; fi
|
||||||
sudo iptables -P FORWARD ACCEPT
|
sudo iptables -P FORWARD ACCEPT
|
||||||
|
|
||||||
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; sudo $pm update -y
|
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; sudo $pm update -y -q
|
||||||
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; sudo $pm install -y curl
|
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; sudo $pm install -y -q curl
|
||||||
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then sudo $pm_apt install -y docker.io; else sudo $pm_yum install -y docker; fi
|
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then sudo export DEBIAN_FRONTEND=noninteractive; sudo $pm_apt install -y -q docker.io; else sudo $pm_yum install -y -q docker; fi
|
||||||
sudo systemctl start docker
|
sudo systemctl start docker
|
||||||
|
|
||||||
sudo docker stop $CONTAINER_NAME
|
sudo docker stop $CONTAINER_NAME
|
||||||
|
|
@ -14,6 +14,8 @@ sudo docker rm -f $CONTAINER_NAME
|
||||||
sudo docker pull amneziavpn/openvpn:latest
|
sudo docker pull amneziavpn/openvpn:latest
|
||||||
sudo docker run -d --restart always --cap-add=NET_ADMIN -p 1194:1194/udp --name $CONTAINER_NAME amneziavpn/openvpn:latest
|
sudo docker run -d --restart always --cap-add=NET_ADMIN -p 1194:1194/udp --name $CONTAINER_NAME amneziavpn/openvpn:latest
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
|
||||||
sudo docker exec -i $CONTAINER_NAME sh -c "mkdir -p /opt/amneziavpn_data/clients"
|
sudo docker exec -i $CONTAINER_NAME sh -c "mkdir -p /opt/amneziavpn_data/clients"
|
||||||
sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa init-pki"
|
sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa init-pki"
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
# CONTAINER_NAME=... this var will be set in ServerController
|
# CONTAINER_NAME=... this var will be set in ServerController
|
||||||
# Don't run commands in background like sh -c "openvpn &"
|
# Don't run commands in background like sh -c "openvpn &"
|
||||||
|
|
||||||
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; if [[ -f "/usr/bin/sudo" ]]; then $pm install -y sudo; fi
|
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; if [[ -f "/usr/bin/sudo" ]]; then $pm install -y -q sudo; fi
|
||||||
sudo iptables -P FORWARD ACCEPT
|
sudo iptables -P FORWARD ACCEPT
|
||||||
|
|
||||||
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; sudo $pm update -y
|
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; sudo $pm update -y -q
|
||||||
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; sudo $pm install -y curl
|
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else pm=$pm_yum; fi; sudo $pm install -y -q curl
|
||||||
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then sudo $pm_apt install -y docker.io; else sudo $pm_yum install -y docker; fi
|
pm_apt="/usr/bin/apt-get"; pm_yum="/usr/bin/yum"; if [[ -f "$pm_apt" ]]; then sudo export DEBIAN_FRONTEND=noninteractive; sudo $pm_apt install -y -q docker.io; else sudo $pm_yum install -y -q docker; fi
|
||||||
sudo systemctl start docker
|
sudo systemctl start docker
|
||||||
|
|
||||||
sudo docker stop $CONTAINER_NAME
|
sudo docker stop $CONTAINER_NAME
|
||||||
|
|
@ -14,6 +14,8 @@ sudo docker rm -f $CONTAINER_NAME
|
||||||
sudo docker pull amneziavpn/shadowsocks:latest
|
sudo docker pull amneziavpn/shadowsocks:latest
|
||||||
sudo docker run -d --restart always --cap-add=NET_ADMIN -p 1194:1194/tcp -p 6789:6789/tcp --name $CONTAINER_NAME amneziavpn/shadowsocks:latest
|
sudo docker run -d --restart always --cap-add=NET_ADMIN -p 1194:1194/tcp -p 6789:6789/tcp --name $CONTAINER_NAME amneziavpn/shadowsocks:latest
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
|
||||||
sudo docker exec -i $CONTAINER_NAME sh -c "mkdir -p /opt/amneziavpn_data/clients"
|
sudo docker exec -i $CONTAINER_NAME sh -c "mkdir -p /opt/amneziavpn_data/clients"
|
||||||
sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa init-pki"
|
sudo docker exec -i $CONTAINER_NAME sh -c "cd /opt/amneziavpn_data && easyrsa init-pki"
|
||||||
|
|
|
||||||
|
|
@ -9,19 +9,6 @@
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
QString Utils::toString(bool value)
|
|
||||||
{
|
|
||||||
return value ? "true" : "false";
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Utils::serverName()
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
return SERVICE_NAME;
|
|
||||||
#else
|
|
||||||
return QString("/tmp/%1").arg(SERVICE_NAME);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Utils::defaultVpnConfigFileName()
|
QString Utils::defaultVpnConfigFileName()
|
||||||
{
|
{
|
||||||
|
|
@ -153,3 +140,49 @@ bool Utils::checkIPFormat(const QString& ip)
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Utils::killProcessByName(const QString &name)
|
||||||
|
{
|
||||||
|
qDebug().noquote() << "Kill process" << name;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
QProcess::execute(QString("taskkill /im %1 /f").arg(name));
|
||||||
|
#else
|
||||||
|
QProcess::execute(QString("pkill %1").arg(name));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
// Inspired from http://stackoverflow.com/a/15281070/1529139
|
||||||
|
// and http://stackoverflow.com/q/40059902/1529139
|
||||||
|
bool Utils::signalCtrl(DWORD dwProcessId, DWORD dwCtrlEvent)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
DWORD thisConsoleId = GetCurrentProcessId();
|
||||||
|
// Leave current console if it exists
|
||||||
|
// (otherwise AttachConsole will return ERROR_ACCESS_DENIED)
|
||||||
|
bool consoleDetached = (FreeConsole() != FALSE);
|
||||||
|
|
||||||
|
if (AttachConsole(dwProcessId) != FALSE)
|
||||||
|
{
|
||||||
|
// Add a fake Ctrl-C handler for avoid instant kill is this console
|
||||||
|
// WARNING: do not revert it or current program will be also killed
|
||||||
|
SetConsoleCtrlHandler(nullptr, true);
|
||||||
|
success = (GenerateConsoleCtrlEvent(dwCtrlEvent, 0) != FALSE);
|
||||||
|
FreeConsole();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (consoleDetached)
|
||||||
|
{
|
||||||
|
// Create a new console if previous was deleted by OS
|
||||||
|
if (AttachConsole(thisConsoleId) == FALSE)
|
||||||
|
{
|
||||||
|
int errorCode = GetLastError();
|
||||||
|
if (errorCode == 31) // 31=ERROR_GEN_FAILURE
|
||||||
|
{
|
||||||
|
AllocConsole();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,19 @@
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#include "Windows.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class Utils {
|
class Utils {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QString configPath();
|
static QString configPath();
|
||||||
static QString defaultVpnConfigFileName();
|
static QString defaultVpnConfigFileName();
|
||||||
static QString executable(const QString& baseName, bool absPath);
|
static QString executable(const QString& baseName, bool absPath);
|
||||||
static QString serverName();
|
|
||||||
static QString systemLogPath();
|
static QString systemLogPath();
|
||||||
static QString toString(bool value);
|
|
||||||
static bool createEmptyFile(const QString& path);
|
static bool createEmptyFile(const QString& path);
|
||||||
static bool initializePath(const QString& path);
|
static bool initializePath(const QString& path);
|
||||||
static bool processIsRunning(const QString& fileName);
|
|
||||||
|
|
||||||
static QString getIPAddress(const QString& host);
|
static QString getIPAddress(const QString& host);
|
||||||
static QString getStringBetween(const QString& s, const QString& a, const QString& b);
|
static QString getStringBetween(const QString& s, const QString& a, const QString& b);
|
||||||
|
|
@ -23,6 +24,13 @@ public:
|
||||||
static QRegExp ipAddressRegExp() { return QRegExp("^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\\.(?!$)|$)){4}$"); }
|
static QRegExp ipAddressRegExp() { return QRegExp("^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\\.(?!$)|$)){4}$"); }
|
||||||
static QRegExp ipAddressPortRegExp() { return QRegExp("^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}"
|
static QRegExp ipAddressPortRegExp() { return QRegExp("^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}"
|
||||||
"(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\\:[0-9]{1,5}){0,1}$"); }
|
"(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\\:[0-9]{1,5}){0,1}$"); }
|
||||||
|
|
||||||
|
static bool processIsRunning(const QString& fileName);
|
||||||
|
static void killProcessByName(const QString &name);
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
static bool signalCtrl(DWORD dwProcessId, DWORD dwCtrlEvent);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // UTILS_H
|
#endif // UTILS_H
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue