Skip to content

Commit

Permalink
Implement TLS Certificate Reload for the Management Interface
Browse files Browse the repository at this point in the history
This commit extends the functionality present in the main HTTP endpoint to the management interface. This feature enables the periodic reloading of TLS certificates, key stores, and trust stores.
  • Loading branch information
cescoffier committed Feb 8, 2024
1 parent dd6d8df commit 283f366
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ private boolean uriValid(HttpServerRequest httpServerRequest) {
private static HttpServerOptions httpMainServerOptions;
private static HttpServerOptions httpMainDomainSocketOptions;
private static HttpServerOptions httpManagementServerOptions;

private static final List<Long> taskIds = new CopyOnWriteArrayList<>();
final HttpBuildTimeConfig httpBuildTimeConfig;
final ManagementInterfaceBuildTimeConfig managementBuildTimeConfig;
final RuntimeValue<HttpConfiguration> httpConfiguration;
Expand Down Expand Up @@ -308,7 +310,8 @@ public void startServer(Supplier<Vertx> vertx, ShutdownContext shutdown,
ManagementInterfaceConfiguration managementConfig = this.managementConfiguration == null ? null
: this.managementConfiguration.getValue();
if (startSocket && (httpConfiguration.hostEnabled || httpConfiguration.domainSocketEnabled
|| managementConfig.hostEnabled || managementConfig.domainSocketEnabled)) {
|| (managementConfig != null && managementConfig.hostEnabled)
|| (managementConfig != null && managementConfig.domainSocketEnabled))) {
// Start the server
if (closeTask == null) {
var insecureRequestStrategy = getInsecureRequestStrategy(httpBuildTimeConfig,
Expand Down Expand Up @@ -622,13 +625,23 @@ private static CompletableFuture<HttpServer> initializeManagementInterface(Vertx
}

if (httpManagementServerOptions != null) {

vertx.createHttpServer(httpManagementServerOptions)
.requestHandler(managementRouter)
.listen(ar -> {
if (ar.failed()) {
managementInterfaceFuture.completeExceptionally(
new IllegalStateException("Unable to start the management interface", ar.cause()));
} else {
if (httpManagementServerOptions.isSsl()
&& managementConfig.ssl.certificate.reloadPeriod.isPresent()) {
long l = TlsCertificateReloadUtils.handleCertificateReloading(
vertx, ar.result(), httpManagementServerOptions, managementConfig.ssl);
if (l != -1) {
taskIds.add(l);
}
}

actualManagementPort = ar.result().actualPort();
managementInterfaceFuture.complete(ar.result());
}
Expand Down Expand Up @@ -809,6 +822,9 @@ public void handle(AsyncResult<Void> event) {

// shutdown the management interface
try {
for (Long id : taskIds) {
vertx.cancelTimer(id);
}
if (managementServer != null && !isVertxClose) {
managementServer.close(handler);
}
Expand Down Expand Up @@ -1190,7 +1206,7 @@ public void handle(AsyncResult<HttpServer> event) {

if (https && quarkusConfig.ssl.certificate.reloadPeriod.isPresent()) {
long l = TlsCertificateReloadUtils.handleCertificateReloading(
vertx, httpsServer, httpsOptions, quarkusConfig);
vertx, httpsServer, httpsOptions, quarkusConfig.ssl);
if (l != -1) {
reloadingTasks.add(l);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import org.jboss.logging.Logger;

import io.quarkus.vertx.http.runtime.HttpConfiguration;
import io.quarkus.vertx.http.runtime.ServerSslConfig;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
Expand All @@ -29,12 +29,12 @@
public class TlsCertificateReloadUtils {

public static long handleCertificateReloading(Vertx vertx, HttpServer server,
HttpServerOptions options, HttpConfiguration configuration) {
HttpServerOptions options, ServerSslConfig configuration) {
// Validation
if (configuration.ssl.certificate.reloadPeriod.isEmpty()) {
if (configuration.certificate.reloadPeriod.isEmpty()) {
return -1;
}
if (configuration.ssl.certificate.reloadPeriod.get().toMillis() < 30_000) {
if (configuration.certificate.reloadPeriod.get().toMillis() < 30_000) {
throw new IllegalArgumentException(
"Unable to configure TLS reloading - The reload period cannot be less than 30 seconds");
}
Expand All @@ -47,7 +47,7 @@ public static long handleCertificateReloading(Vertx vertx, HttpServer server,
}

Logger log = Logger.getLogger(TlsCertificateReloadUtils.class);
return vertx.setPeriodic(configuration.ssl.certificate.reloadPeriod.get().toMillis(), new Handler<Long>() {
return vertx.setPeriodic(configuration.certificate.reloadPeriod.get().toMillis(), new Handler<Long>() {
@Override
public void handle(Long id) {

Expand Down Expand Up @@ -89,17 +89,17 @@ public void handle(AsyncResult<Boolean> ar) {
});
}

private static SSLOptions reloadFileContent(SSLOptions ssl, HttpConfiguration configuration) throws IOException {
private static SSLOptions reloadFileContent(SSLOptions ssl, ServerSslConfig configuration) throws IOException {
var copy = new SSLOptions(ssl);

final List<Path> keys = new ArrayList<>();
final List<Path> certificates = new ArrayList<>();

if (configuration.ssl.certificate.keyFiles.isPresent()) {
keys.addAll(configuration.ssl.certificate.keyFiles.get());
if (configuration.certificate.keyFiles.isPresent()) {
keys.addAll(configuration.certificate.keyFiles.get());
}
if (configuration.ssl.certificate.files.isPresent()) {
certificates.addAll(configuration.ssl.certificate.files.get());
if (configuration.certificate.files.isPresent()) {
certificates.addAll(configuration.certificate.files.get());
}

if (!certificates.isEmpty() && !keys.isEmpty()) {
Expand All @@ -119,15 +119,15 @@ private static SSLOptions reloadFileContent(SSLOptions ssl, HttpConfiguration co
.setCertValues(certBuffer)
.setKeyValues(keysBuffer);
copy.setKeyCertOptions(opts);
} else if (configuration.ssl.certificate.keyStoreFile.isPresent()) {
} else if (configuration.certificate.keyStoreFile.isPresent()) {
var opts = ((KeyStoreOptions) copy.getKeyCertOptions());
opts.setValue(Buffer.buffer(getFileContent(configuration.ssl.certificate.keyStoreFile.get())));
opts.setValue(Buffer.buffer(getFileContent(configuration.certificate.keyStoreFile.get())));
copy.setKeyCertOptions(opts);
}

if (configuration.ssl.certificate.trustStoreFile.isPresent()) {
if (configuration.certificate.trustStoreFile.isPresent()) {
var opts = ((KeyStoreOptions) copy.getKeyCertOptions());
opts.setValue(Buffer.buffer(getFileContent(configuration.ssl.certificate.trustStoreFile.get())));
opts.setValue(Buffer.buffer(getFileContent(configuration.certificate.trustStoreFile.get())));
copy.setTrustOptions(opts);
}

Expand Down

0 comments on commit 283f366

Please sign in to comment.