From 8e5f3251b5c81457dcf2dab1ecd008b7092b2a63 Mon Sep 17 00:00:00 2001 From: brindosch Date: Wed, 21 Aug 2019 16:09:28 +0200 Subject: [PATCH] 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 --- assets/webconfig/i18n/de.json | 8 ++ assets/webconfig/i18n/en.json | 8 ++ assets/webconfig/js/hyperion.js | 2 +- config/hyperion.config.json.commented | 10 ++- config/hyperion.config.json.default | 6 +- include/webserver/WebServer.h | 22 ++++- libsrc/hyperion/schema/schema-webConfig.json | 35 +++++++- libsrc/webserver/QtHttpServer.h | 2 + libsrc/webserver/WebServer.cpp | 87 +++++++++++++++++++- resources/CMakeLists.txt | 2 +- resources/ssl/hyperion.crt | 29 +++++++ resources/ssl/hyperion.key | 52 ++++++++++++ src/hyperiond/hyperiond.cpp | 16 +++- src/hyperiond/hyperiond.h | 1 + 14 files changed, 268 insertions(+), 12 deletions(-) create mode 100644 resources/ssl/hyperion.crt create mode 100644 resources/ssl/hyperion.key diff --git a/assets/webconfig/i18n/de.json b/assets/webconfig/i18n/de.json index d3e88210..47340a92 100644 --- a/assets/webconfig/i18n/de.json +++ b/assets/webconfig/i18n/de.json @@ -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.", diff --git a/assets/webconfig/i18n/en.json b/assets/webconfig/i18n/en.json index aa96b4af..d3ee60e7 100644 --- a/assets/webconfig/i18n/en.json +++ b/assets/webconfig/i18n/en.json @@ -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.", diff --git a/assets/webconfig/js/hyperion.js b/assets/webconfig/js/hyperion.js index fbccb33f..b19e8431 100644 --- a/assets/webconfig/js/hyperion.js +++ b/assets/webconfig/js/hyperion.js @@ -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"}); diff --git a/config/hyperion.config.json.commented b/config/hyperion.config.json.commented index b6b847ba..3080c4f2 100644 --- a/config/hyperion.config.json.commented +++ b/config/hyperion.config.json.commented @@ -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: diff --git a/config/hyperion.config.json.default b/config/hyperion.config.json.default index 8490b377..520fcde9 100644 --- a/config/hyperion.config.json.default +++ b/config/hyperion.config.json.default @@ -154,7 +154,11 @@ "webConfig" : { "document_root" : "", - "port" : 8090 + "port" : 8090, + "sslPort" : 8092, + "crtPath" : "", + "keyPath" : "", + "keyPassPhrase" : "" }, "effects" : diff --git a/include/webserver/WebServer.h b/include/webserver/WebServer.h index 573b53df..98ef7a5e 100644 --- a/include/webserver/WebServer.h +++ b/include/webserver/WebServer.h @@ -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; }; diff --git a/libsrc/hyperion/schema/schema-webConfig.json b/libsrc/hyperion/schema/schema-webConfig.json index ea33a383..17d9e60d 100644 --- a/libsrc/hyperion/schema/schema-webConfig.json +++ b/libsrc/hyperion/schema/schema-webConfig.json @@ -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 diff --git a/libsrc/webserver/QtHttpServer.h b/libsrc/webserver/QtHttpServer.h index 4c97cb15..ca8a9f02 100644 --- a/libsrc/webserver/QtHttpServer.h +++ b/libsrc/webserver/QtHttpServer.h @@ -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 & certs) { m_sslCerts = certs; }; + QSslKey getPrivateKey() { return m_sslKey; }; + QList getCertificates() { return m_sslCerts; }; signals: void started (quint16 port); diff --git a/libsrc/webserver/WebServer.cpp b/libsrc/webserver/WebServer.cpp index 723ec136..e1233a13 100644 --- a/libsrc/webserver/WebServer.cpp +++ b/libsrc/webserver/WebServer.cpp @@ -12,9 +12,10 @@ #include -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 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 validList; + QList 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); } diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 0305dec7..c24e105a 100644 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -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} ) diff --git a/resources/ssl/hyperion.crt b/resources/ssl/hyperion.crt new file mode 100644 index 00000000..ce1abc8b --- /dev/null +++ b/resources/ssl/hyperion.crt @@ -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----- diff --git a/resources/ssl/hyperion.key b/resources/ssl/hyperion.key new file mode 100644 index 00000000..aaec0067 --- /dev/null +++ b/resources/ssl/hyperion.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +d8b5Ntiu2G/qZODXNmFh9x3/AAnkhqk= +-----END PRIVATE KEY----- diff --git a/src/hyperiond/hyperiond.cpp b/src/hyperiond/hyperiond.cpp index 10f3f43c..8fde0c5c 100644 --- a/src/hyperiond/hyperiond.cpp +++ b/src/hyperiond/hyperiond.cpp @@ -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); diff --git a/src/hyperiond/hyperiond.h b/src/hyperiond/hyperiond.h index 334bbe7f..67f6fcd7 100644 --- a/src/hyperiond/hyperiond.h +++ b/src/hyperiond/hyperiond.h @@ -151,6 +151,7 @@ private: NetOrigin* _netOrigin; PythonInit* _pyInit; WebServer* _webserver; + WebServer* _sslWebserver; JsonServer* _jsonServer; V4L2Wrapper* _v4l2Grabber; DispmanxWrapper* _dispmanx;