Feat: Add SSL support for webserver + websocket (#612)

* Feat: Add SSL support for webserver + websocket

Finally, Hyperion reaches the SSL century!
- Uses by default a internal key and certificate to provide working HTTPS out-of-the-box
- Your browser won't like that, for a green ssl seal next to the browser address bar you need to use Let's Encrypt with a own legit domain. This is out of the scope of Hyperion
This commit is contained in:
brindosch 2019-08-21 16:09:28 +02:00 committed by GitHub
parent fe12b36fce
commit 8e5f3251b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 268 additions and 12 deletions

View File

@ -621,6 +621,14 @@
"edt_conf_webc_heading_title": "Web Konfiguration",
"edt_conf_webc_docroot_title": "Verzeichnis",
"edt_conf_webc_docroot_expl": "Lokaler Pfad zum WebUI Wurzelverzeichnis (Nur für WebUI Entwickler)",
"edt_conf_webc_sslport_title" : "HTTPS Port",
"edt_conf_webc_sslport_expl" : "Port des HTTPS webservers",
"edt_conf_webc_crtPath_title" : "Zertifikats-Pfad",
"edt_conf_webc_crtPath_expl" : "Pfad zur Zertifikats-Datei (Format sollte PEM sein)",
"edt_conf_webc_keyPath_title" : "Schlüssel-Pfad",
"edt_conf_webc_keyPath_expl" : "Pfad zum privaten Schlüssel (Format in PEM, verschlüsselt mit RSA)",
"edt_conf_webc_keyPassPhrase_title" : "Schlüsselpasswort",
"edt_conf_webc_keyPassPhrase_expl" : "Optional: Der Schlüssel könnte mit einem Passwort geschützt sein",
"edt_conf_effp_heading_title": "Effekt Pfade",
"edt_conf_effp_paths_title": "Effekt Pfad(e)",
"edt_conf_effp_paths_expl": "Es können mehrere Ordner definiert werden die Effekte enthalten. Der Effekt Konfigurator speichert immer im Ersten Ordner.",

View File

@ -620,6 +620,14 @@
"edt_conf_webc_heading_title" : "Web Configuration",
"edt_conf_webc_docroot_title" : "Document Root",
"edt_conf_webc_docroot_expl" : "Local webinterface root path (just for webui developer)",
"edt_conf_webc_sslport_title" : "HTTPS Port",
"edt_conf_webc_sslport_expl" : "Port oft the HTTPS webserver",
"edt_conf_webc_crtPath_title" : "Certificate path",
"edt_conf_webc_crtPath_expl" : "Path to the certification file (format should be PEM)",
"edt_conf_webc_keyPath_title" : "Private key path",
"edt_conf_webc_keyPath_expl" : "Path to the key file (format PEM, encrypted with RSA)",
"edt_conf_webc_keyPassPhrase_title" : "Key password",
"edt_conf_webc_keyPassPhrase_expl" : "Optional: The key might be protected with a password",
"edt_conf_effp_heading_title" : "Effect Paths",
"edt_conf_effp_paths_title" : "Effect Path(s)",
"edt_conf_effp_paths_expl" : "You could define more folders that contain effects. The effect configurator will always save inside the first folder.",

View File

@ -74,7 +74,7 @@ function initWebSocket()
if (window.websocket == null)
{
window.jsonPort = (document.location.port == '') ? '80' : document.location.port;
window.websocket = new WebSocket('ws://'+document.location.hostname+":"+window.jsonPort);
window.websocket = (document.location.protocol == "https:") ? new WebSocket('wss://'+document.location.hostname+":"+window.jsonPort) : new WebSocket('ws://'+document.location.hostname+":"+window.jsonPort);
window.websocket.onopen = function (event) {
$(window.hyperion).trigger({type:"open"});

View File

@ -266,10 +266,18 @@
/// Configuration of the Hyperion webserver
/// * document_root : path to hyperion webapp files (webconfig developer only)
/// * port : the port where hyperion webapp is accasible
/// * sslPort : the secure (HTTPS) port of the hyperion webapp
/// * crtPath : the path to a certificate file to allow HTTPS connections. Should be in PEM format
/// * keyPath : the path to a private key file to allow HTTPS connections. Should be in PEM format and RSA encrypted
/// * keyPassPhrase : optional: If the key file requires a password add it here
"webConfig" :
{
"document_root" : "/path/to/files",
"port" : 8090
"port" : 8090,
"sslPort" : 8092,
"crtPath" : "/path/to/mycert.crt",
"keyPath" : "/path/to/mykey.key",
"keyPassPhrase" : ""
},
/// The configuration of the effect engine, contains the following items:

View File

@ -154,7 +154,11 @@
"webConfig" :
{
"document_root" : "",
"port" : 8090
"port" : 8090,
"sslPort" : 8092,
"crtPath" : "",
"keyPath" : "",
"keyPassPhrase" : ""
},
"effects" :

View File

@ -15,11 +15,24 @@ class BonjourServiceRegister;
class StaticFileServing;
class QtHttpServer;
/*
OPENSSL command that generated the embedded key and cert file
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
-keyout hyperion.key -out hyperion.crt -extensions san -config \
<(echo "[req]";
echo distinguished_name=req;
echo "[san]";
echo subjectAltName=DNS:hyperion-project.org,IP:127.0.0.1
) \
-subj /CN=hyperion-project.org
*/
class WebServer : public QObject {
Q_OBJECT
public:
WebServer (const QJsonDocument& config, QObject * parent = 0);
WebServer (const QJsonDocument& config, const bool& useSsl, QObject * parent = 0);
virtual ~WebServer (void);
@ -67,6 +80,7 @@ public slots:
private:
QJsonDocument _config;
bool _useSsl;
Logger* _log;
QString _baseUrl;
quint16 _port;
@ -74,8 +88,10 @@ private:
QtHttpServer* _server;
bool _inited = false;
const QString WEBSERVER_DEFAULT_PATH = ":/webconfig";
const quint16 WEBSERVER_DEFAULT_PORT = 8090;
const QString WEBSERVER_DEFAULT_PATH = ":/webconfig";
const QString WEBSERVER_DEFAULT_CRT_PATH = ":/hyperion.crt";
const QString WEBSERVER_DEFAULT_KEY_PATH = ":/hyperion.key";
quint16 WEBSERVER_DEFAULT_PORT = 8090;
BonjourServiceRegister * _serviceRegister = nullptr;
};

View File

@ -17,8 +17,41 @@
"minimum" : 80,
"maximum" : 65535,
"default" : 8090,
"access" : "expert",
"propertyOrder" : 3
},
"sslPort" :
{
"type" : "integer",
"title" : "edt_conf_webc_sslport_title",
"required" : true,
"minimum" : 80,
"maximum" : 65535,
"default" : 8092,
"propertyOrder" : 4
},
"crtPath" :
{
"type" : "string",
"title" : "edt_conf_webc_crtPath_title",
"required" : true,
"default" : "",
"propertyOrder" : 5
},
"keyPath" :
{
"type" : "string",
"title" : "edt_conf_webc_keyPath_title",
"required" : true,
"default" : "",
"propertyOrder" : 6
},
"keyPassPhrase" :
{
"type" : "string",
"title" : "edt_conf_webc_keyPassPhrase_title",
"required" : true,
"default" : "",
"propertyOrder" : 7
}
},
"additionalProperties" : false

View File

@ -59,6 +59,8 @@ public slots:
void setServerName (const QString & serverName) { m_serverName = serverName; };
void setPrivateKey (const QSslKey & key) { m_sslKey = key; };
void setCertificates (const QList<QSslCertificate> & certs) { m_sslCerts = certs; };
QSslKey getPrivateKey() { return m_sslKey; };
QList<QSslCertificate> getCertificates() { return m_sslCerts; };
signals:
void started (quint16 port);

View File

@ -12,9 +12,10 @@
#include <utils/NetUtils.h>
WebServer::WebServer(const QJsonDocument& config, QObject * parent)
WebServer::WebServer(const QJsonDocument& config, const bool& useSsl, QObject * parent)
: QObject(parent)
, _config(config)
, _useSsl(useSsl)
, _log(Logger::getInstance("WEBSERVER"))
, _server()
{
@ -31,6 +32,12 @@ void WebServer::initServer()
_server = new QtHttpServer (this);
_server->setServerName (QStringLiteral ("Hyperion Webserver"));
if(_useSsl)
{
_server->setUseSecure();
WEBSERVER_DEFAULT_PORT = 8092;
}
connect (_server, &QtHttpServer::started, this, &WebServer::onServerStarted);
connect (_server, &QtHttpServer::stopped, this, &WebServer::onServerStopped);
connect (_server, &QtHttpServer::error, this, &WebServer::onServerError);
@ -98,9 +105,11 @@ void WebServer::handleSettingsUpdate(const settings::type& type, const QJsonDocu
Debug(_log, "Set document root to: %s", _baseUrl.toUtf8().constData());
_staticFileServing->setBaseUrl(_baseUrl);
if(_port != obj["port"].toInt(WEBSERVER_DEFAULT_PORT))
// ssl different port
quint16 newPort = _useSsl ? obj["sslPort"].toInt(WEBSERVER_DEFAULT_PORT) : obj["port"].toInt(WEBSERVER_DEFAULT_PORT);
if(_port != newPort)
{
_port = obj["port"].toInt(WEBSERVER_DEFAULT_PORT);
_port = newPort;
stop();
}
@ -108,6 +117,78 @@ void WebServer::handleSettingsUpdate(const settings::type& type, const QJsonDocu
if(!_server->isListening())
NetUtils::portAvailable(_port, _log);
// on ssl we want .key .cert and probably key password
if(_useSsl)
{
QString keyPath = obj["keyPath"].toString(WEBSERVER_DEFAULT_KEY_PATH);
QString crtPath = obj["crtPath"].toString(WEBSERVER_DEFAULT_CRT_PATH);
QSslKey currKey = _server->getPrivateKey();
QList<QSslCertificate> currCerts = _server->getCertificates();
// check keyPath
if ( (keyPath != WEBSERVER_DEFAULT_KEY_PATH) && !keyPath.trimmed().isEmpty())
{
QFileInfo kinfo(keyPath);
if (!kinfo.exists())
{
Error(_log, "No SSL key found at '%s' falling back to internal", keyPath.toUtf8().constData());
keyPath = WEBSERVER_DEFAULT_KEY_PATH;
}
}
else
keyPath = WEBSERVER_DEFAULT_KEY_PATH;
// check crtPath
if ( (crtPath != WEBSERVER_DEFAULT_CRT_PATH) && !crtPath.trimmed().isEmpty())
{
QFileInfo cinfo(crtPath);
if (!cinfo.exists())
{
Error(_log, "No SSL certificate found at '%s' falling back to internal", crtPath.toUtf8().constData());
crtPath = WEBSERVER_DEFAULT_CRT_PATH;
}
}
else
crtPath = WEBSERVER_DEFAULT_CRT_PATH;
// load and verify crt
QFile cfile(crtPath);
cfile.open(QIODevice::ReadOnly);
QList<QSslCertificate> validList;
QList<QSslCertificate> cList = QSslCertificate::fromDevice(&cfile, QSsl::Pem);
cfile.close();
// Filter for valid certs
for(const auto & entry : cList){
if(!entry.isNull() && QDateTime::currentDateTime().daysTo(entry.expiryDate()) > 0)
validList.append(entry);
else
Error(_log, "The provided SSL certificate is invalid/not supported/reached expiry date ('%s')", crtPath.toUtf8().constData());
}
if(!validList.isEmpty()){
Debug(_log,"Setup SSL certificate");
_server->setCertificates(validList);
} else {
Error(_log, "No valid SSL certificate has been found ('%s')", crtPath.toUtf8().constData());
}
// load and verify key
QFile kfile(keyPath);
kfile.open(QIODevice::ReadOnly);
// The key should be RSA enrcrypted and PEM format, optional the passPhrase
QSslKey key(&kfile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, obj["keyPassPhrase"].toString().toUtf8());
kfile.close();
if(key.isNull()){
Error(_log, "The provided SSL key is invalid or not supported use RSA encrypt and PEM format ('%s')", keyPath.toUtf8().constData());
} else {
Debug(_log,"Setup private SSL key");
_server->setPrivateKey(key);
}
}
start();
emit portChanged(_port);
}

View File

@ -5,7 +5,7 @@
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/resources)
# catch all files
FILE ( GLOB Hyperion_RESFILES "${CURRENT_SOURCE_DIR}/icons/*" )
FILE ( GLOB Hyperion_RESFILES "${CURRENT_SOURCE_DIR}/icons/*" "${CURRENT_SOURCE_DIR}/ssl/*" )
# fill resources.qrc with RESFILES
FOREACH( f ${Hyperion_RESFILES} )

View File

@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIE6jCCAtKgAwIBAgIJAJlO0qRW51TjMA0GCSqGSIb3DQEBCwUAMB8xHTAbBgNV
BAMMFGh5cGVyaW9uLXByb2plY3Qub3JnMB4XDTE5MDgyMDEyMjE1N1oXDTI5MDgx
NzEyMjE1N1owHzEdMBsGA1UEAwwUaHlwZXJpb24tcHJvamVjdC5vcmcwggIiMA0G
CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDbBa9e1Ez9qK4/qxcAJdadEIfgyaxR
O6q8UjAkklPhd7Vnql78omni9pukS24+sndla7Snyx06ajCrkJR4VM14uKMCecf+
fBTFNFp1oQJauh16Gh/rVlcN28HIW/BQLEsvC3QXxJhmRkSC5+oPO3NA7h2gYCVV
Pvg8kzoyBIF/1uUlMB7HXS952Vbswr9tCxo0qiqgf57l/bbUliSHrBgE0HnXGl8n
N7ZiQAtSa644gwvPXhg4PZjjLHDlM69RChsoE9osDCh0lLpML0pfMaH9xZd2Sehe
wV8Jd3yDnwZ7IGli3YtA+n1zqdFvYsePCdu7HxRfuLSJf1yoWJv8Eg+fhafT+9KU
uZFaPn9BmDbB6Q6g2NmNVzWWjpBeKHn8jhoYFxfmpqcikbjMlljv1lkJIC7ZIwxq
ei6d7wB/5GK7r7KcwTuHTYaV8uj6sG/qGP2KazE9bJWxCF34w0hvPcwRiPbA4IQH
7OfUYCZgi8pgVJjtuhRF0tF/JOPKyhShJ8+JENbw2QOOh869e7FF/rvHgZfwRjRq
V9EOWTclQyEWSN3SKXP2S9Om8zvIPdn5r7n3DYibJNDegHaGfDYzD0Ruh0H9eOwE
qiR6QHawQ7r5cDalz1YLcL21vd1GdtMJMSoxpsvjgJQV6sB2ZWL1BsAJ5lmJ2Mp3
NuPEb3r0DQZ+3wIDAQABoykwJzAlBgNVHREEHjAcghRoeXBlcmlvbi1wcm9qZWN0
Lm9yZ4cEfwAAATANBgkqhkiG9w0BAQsFAAOCAgEAgrgWwGW64JE7UbuYJP3fs2XF
wkhVY+1UTPpYrkk6ZQ//XqPKnJpLz51lLxPBaO04YvYh5RrLZ+cz1XWsLaHXZtRW
GEpOjGYsZsb5jaT4WS8hC+7PHmfbRWKGnWnDx93wG3ipBJ6/jIh01Dyb1V1YEo/X
F1bZrpLH6iN1c0aIcKIu2ewzxHEulZDNSaN8Wpr8mK+Hde3JBIFhS36y+Y8iXVbd
V4HegBm5XHwAkbkNPjpXsyJ0RPLAtv7Ba6gvJzii/u13Zrn7731nYACN2zMO/90o
U4TvW+u9NC8kzKs8iex7gBfSXKr724znMcQ+2Go1sY6QjRFHas4lJ7BeU6CA8ZsV
CKSgvDay7KX/DvhR4J0WhxCAZ+eX0HIyMZ50mm8W/BaDvTTqghT0+iWV7nxAuZ2p
kdkVd+giTT5kyNObA6WIn4qJdxcxoiwB1qvPmEDbGZ4ZxySfIJ44mNBZu0f9VxaC
5kfbnkVwuvjnvbyERwpaEs7q6+Kkz0uEyglLvmcLzaDn+8zmEEV4pVp5I1H7Cmji
pYA2dqwupTFlXGjDtaNG/mZKp2uD4Rmt2vq5vQDRd/zfPRIvu2ZBWHEHkXuH9Qfa
+IcrvtZxCkF9m39f0jHQ8bXOyVAzpLrWWia6fDP42F82vce4Q69ejZmdhyeMZteI
mMgFOwY2tPspNj8848g=
-----END CERTIFICATE-----

View File

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
d8b5Ntiu2G/qZODXNmFh9x3/AAnkhqk=
-----END PRIVATE KEY-----

View File

@ -64,6 +64,7 @@ HyperionDaemon::HyperionDaemon(const QString rootPath, QObject *parent, const bo
, _netOrigin(new NetOrigin(this))
, _pyInit(new PythonInit())
, _webserver(nullptr)
, _sslWebserver(nullptr)
, _jsonServer(nullptr)
, _v4l2Grabber(nullptr)
, _dispmanx(nullptr)
@ -170,6 +171,8 @@ void HyperionDaemon::freeObjects()
_ssdp->thread()->wait(1000);
_webserver->thread()->quit();
_webserver->thread()->wait(1000);
_sslWebserver->thread()->quit();
_sslWebserver->thread()->wait(1000);
// stop Hyperions (non blocking)
_instanceManager->stopAll();
@ -193,6 +196,7 @@ void HyperionDaemon::freeObjects()
_protoServer = nullptr;
_ssdp = nullptr;
_webserver = nullptr;
_sslWebserver = nullptr;
_jsonServer = nullptr;
}
@ -223,7 +227,7 @@ void HyperionDaemon::startNetworkServices()
pThread->start();
// Create Webserver in thread
_webserver = new WebServer(getSetting(settings::WEBSERVER));
_webserver = new WebServer(getSetting(settings::WEBSERVER), false);
QThread* wsThread = new QThread(this);
_webserver->moveToThread(wsThread);
connect( wsThread, &QThread::started, _webserver, &WebServer::initServer );
@ -232,6 +236,16 @@ void HyperionDaemon::startNetworkServices()
connect(this, &HyperionDaemon::settingsChanged, _webserver, &WebServer::handleSettingsUpdate);
wsThread->start();
// Create SSL Webserver in thread
_sslWebserver = new WebServer(getSetting(settings::WEBSERVER), true);
QThread* sslWsThread = new QThread(this);
_sslWebserver->moveToThread(sslWsThread);
connect( sslWsThread, &QThread::started, _sslWebserver, &WebServer::initServer );
connect( sslWsThread, &QThread::finished, _sslWebserver, &QObject::deleteLater );
connect( sslWsThread, &QThread::finished, sslWsThread, &QObject::deleteLater );
connect(this, &HyperionDaemon::settingsChanged, _sslWebserver, &WebServer::handleSettingsUpdate);
sslWsThread->start();
// Create SSDP server in thread
_ssdp = new SSDPHandler(_webserver, getSetting(settings::FLATBUFSERVER).object()["port"].toInt(), getSetting(settings::JSONSERVER).object()["port"].toInt());
QThread* ssdpThread = new QThread(this);

View File

@ -151,6 +151,7 @@ private:
NetOrigin* _netOrigin;
PythonInit* _pyInit;
WebServer* _webserver;
WebServer* _sslWebserver;
JsonServer* _jsonServer;
V4L2Wrapper* _v4l2Grabber;
DispmanxWrapper* _dispmanx;