Moved external http server to a daemon

This commit is contained in:
Ziver Koc 2021-08-28 14:09:41 +02:00
parent ee89eeb39d
commit 870be06255
3 changed files with 102 additions and 61 deletions

View file

@ -1,17 +1,13 @@
package se.hal;
import se.hal.daemon.HalExternalWebDaemon;
import se.hal.intf.*;
import se.hal.page.HalAlertManager;
import se.hal.struct.PluginConfig;
import se.hal.util.HalAcmeDataStore;
import zutil.db.DBConnection;
import zutil.io.file.FileUtil;
import zutil.log.LogUtil;
import zutil.net.acme.AcmeChallengeFactory;
import zutil.net.acme.AcmeClient;
import zutil.net.acme.AcmeHttpChallengeFactory;
import zutil.net.acme.AcmeManualDnsChallengeFactory;
import zutil.net.http.HttpPage;
import zutil.net.http.HttpServer;
import zutil.net.http.page.HttpFilePage;
@ -19,9 +15,6 @@ import zutil.net.http.page.HttpRedirectPage;
import zutil.plugin.PluginData;
import zutil.plugin.PluginManager;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
@ -31,8 +24,6 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.logging.Level;
import java.util.logging.Logger;
import static se.hal.HalContext.CONFIG_HTTP_EXTERNAL_DOMAIN;
import static se.hal.HalContext.CONFIG_HTTP_EXTERNAL_PORT;
/**
* Main class for Hal
@ -46,12 +37,10 @@ public class HalServer {
private static List<HalDaemon> daemons = new ArrayList<>();
private static HttpServer http;
private static HttpServer httpExternal;
private static HalExternalWebDaemon httpExternal;
private static PluginManager pluginManager;
public static void main(String[] args) {
try {
// ------------------------------------
@ -78,54 +67,6 @@ public class HalServer {
logger.info("Working directory: " + FileUtil.find(".").getAbsolutePath());
// ------------------------------------
// Initialize External HttpServer
// ------------------------------------
if (HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_DOMAIN) && HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_PORT)) {
String externalServerUrl = "https://" + HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_DOMAIN) +
":" + HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_PORT);
HalAcmeDataStore acmeDataStore = new HalAcmeDataStore();
X509Certificate certificate = acmeDataStore.getCertificate();
if (!AcmeClient.isCertificateValid(certificate)) {
// Prepare ACME Client
AcmeClient acme;
HttpServer tmpHttpServer = null;
if ("dns".equals(HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_ACME_TYPE, ""))) {
acme = new AcmeClient(acmeDataStore, new AcmeManualDnsChallengeFactory());
} else if ("http".equals(HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_ACME_TYPE, "http"))) {
tmpHttpServer = new HttpServer(80);
tmpHttpServer.start();
acme = new AcmeClient(acmeDataStore, new AcmeHttpChallengeFactory(tmpHttpServer));
} else {
throw new IllegalArgumentException("Unknown config value for " + externalServerUrl);
}
// Request certificate and start the external webserver
acme.addDomain(HalContext.getStringProperty(CONFIG_HTTP_EXTERNAL_DOMAIN));
acme.prepareRequest();
certificate = acme.requestCertificate();
acmeDataStore.storeCertificate(certificate);
// Cleanup
if (tmpHttpServer != null) {
tmpHttpServer.close();
}
}
httpExternal = new HttpServer(HalContext.getIntegerProperty(CONFIG_HTTP_EXTERNAL_PORT), acmeDataStore.getDomainKeyPair().getPrivate(), certificate);
httpExternal.start();
logger.info("External https server up and running at: " + externalServerUrl);
} else {
logger.warning("Missing '" + CONFIG_HTTP_EXTERNAL_PORT + "' and '" + CONFIG_HTTP_EXTERNAL_DOMAIN + "' configuration, will not setup external http server.");
}
// ------------------------------------
// Initialize Plugins
// ------------------------------------
@ -166,6 +107,9 @@ public class HalServer {
for (Iterator<HalDaemon> it = pluginManager.getSingletonIterator(HalDaemon.class); it.hasNext(); ) {
HalDaemon daemon = it.next();
registerDaemon(daemon);
if (daemon instanceof HalExternalWebDaemon) // Keep a reference of the external web server
httpExternal = (HalExternalWebDaemon) daemon;
}
// ------------------------------------

View file

@ -0,0 +1,96 @@
package se.hal.daemon;
import org.shredzone.acme4j.exception.AcmeException;
import se.hal.HalContext;
import se.hal.intf.HalDaemon;
import se.hal.util.HalAcmeDataStore;
import zutil.log.LogUtil;
import zutil.net.acme.AcmeClient;
import zutil.net.acme.AcmeHttpChallengeFactory;
import zutil.net.acme.AcmeManualDnsChallengeFactory;
import zutil.net.http.HttpPage;
import zutil.net.http.HttpServer;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.cert.X509Certificate;
import java.util.concurrent.ScheduledExecutorService;
import java.util.logging.Logger;
import static se.hal.HalContext.CONFIG_HTTP_EXTERNAL_DOMAIN;
import static se.hal.HalContext.CONFIG_HTTP_EXTERNAL_PORT;
public class HalExternalWebDaemon implements HalDaemon {
private static final Logger logger = LogUtil.getLogger();
private HttpServer httpExternal;
private String externalServerUrl;
private HalAcmeDataStore acmeDataStore = new HalAcmeDataStore();
private X509Certificate certificate;
@Override
public void initiate(ScheduledExecutorService executor) {
// ------------------------------------
// Initialize External HttpServer
// ------------------------------------
try {
if (HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_DOMAIN) && HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_PORT)) {
externalServerUrl = "https://" + HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_DOMAIN) + ":" + HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_PORT);
certificate = acmeDataStore.getCertificate();
renewCertificate();
startHttpServer();
} else {
logger.warning("Missing '" + CONFIG_HTTP_EXTERNAL_PORT + "' and '" + CONFIG_HTTP_EXTERNAL_DOMAIN + "' configuration, will not setup external http server.");
}
} catch (Exception e) {
logger.severe("Was unable to initiate external web server.");
}
}
private void renewCertificate() throws AcmeException, IOException {
if (!AcmeClient.isCertificateValid(certificate)) {
// Prepare ACME Client
AcmeClient acme;
HttpServer tmpHttpServer = null;
if ("dns".equals(HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_ACME_TYPE, ""))) {
acme = new AcmeClient(acmeDataStore, new AcmeManualDnsChallengeFactory());
} else if ("http".equals(HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_ACME_TYPE, "http"))) {
tmpHttpServer = new HttpServer(80);
tmpHttpServer.start();
acme = new AcmeClient(acmeDataStore, new AcmeHttpChallengeFactory(tmpHttpServer));
} else {
throw new IllegalArgumentException("Unknown config value for " + externalServerUrl);
}
// Request certificate and start the external webserver
acme.addDomain(HalContext.getStringProperty(CONFIG_HTTP_EXTERNAL_DOMAIN));
acme.prepareRequest();
certificate = acme.requestCertificate();
acmeDataStore.storeCertificate(certificate);
// Cleanup
if (tmpHttpServer != null) {
tmpHttpServer.close();
}
}
}
private void startHttpServer() throws GeneralSecurityException, IOException {
httpExternal = new HttpServer(HalContext.getIntegerProperty(CONFIG_HTTP_EXTERNAL_PORT), acmeDataStore.getDomainKeyPair().getPrivate(), certificate);
httpExternal.start();
logger.info("External https server up and running at: " + externalServerUrl);
}
public void setPage(String url, HttpPage page) {
if (httpExternal != null)
httpExternal.setPage(url, page);
}
}

View file

@ -8,6 +8,7 @@
{"se.hal.intf.HalAbstractControllerManager": "se.hal.EventControllerManager"},
{"se.hal.intf.HalAbstractControllerManager": "se.hal.SensorControllerManager"},
{"se.hal.intf.HalDaemon": "se.hal.daemon.HalExternalWebDaemon"},
{"se.hal.intf.HalDaemon": "se.hal.daemon.HalMulticastDnsDaemon"},
{"se.hal.intf.HalDaemon": "se.hal.daemon.SensorDataAggregatorDaemon"},
{"se.hal.intf.HalDaemon": "se.hal.daemon.SensorDataCleanupDaemon"},