Skip to content

IGNITE-28867 Implement TLS certificate hot redeployment via control.sh --ssl reload#13335

Open
anton-vinogradov wants to merge 1 commit into
apache:masterfrom
anton-vinogradov:ignite-28867
Open

IGNITE-28867 Implement TLS certificate hot redeployment via control.sh --ssl reload#13335
anton-vinogradov wants to merge 1 commit into
apache:masterfrom
anton-vinogradov:ignite-28867

Conversation

@anton-vinogradov

Copy link
Copy Markdown
Contributor

Overview

Implements IGNITE-28867: hot redeployment of TLS certificates on running nodes, without a full restart.

TLS certificates were previously loaded once at node startup, so rotating them required restarting every node. This PR adds a new control.sh --ssl reload command that re-reads the configured key and trust stores from disk and replaces the active SSLContext. New connections use the updated certificates while established sessions are not interrupted.

Mechanism

  • AbstractSslContextFactory.reload() rebuilds the cached SSLContext from the current factory configuration (re-reading the key/trust stores from disk). On failure the previously cached context is kept intact.
  • GridNioSslFilter.sslCtx is now volatile with updateSslContext(...); new sessions build their SSLEngine from the new context, existing sessions keep their engines.
  • A new SslContextReloadable interface (reloadSslContext()) is implemented by each SSL-enabled transport.

Coverage per transport:

Transport How a reload is applied
Communication (node ↔ node) inbound — new context pushed into the NIO SSL filter; outbound — picked up automatically from the reloaded factory
Discovery (TCP) sslSockFactory / sslSrvSockFactory rebuilt
Thin client (client connector, JDBC/ODBC) new context pushed into the NIO SSL filter
Binary (TCP) REST new context pushed into the NIO SSL filter

Command

control.(sh|bat) --ssl reload

A new root --ssl command group with a reload sub-command. It broadcasts a VisorMultiNodeTask to all server nodes; each node reloads its own certificates locally and reports which transports were reloaded. Modelled after encryption change_master_key.

Known limitation (documented)

For the discovery transport, new outgoing connections use the reloaded certificates immediately, but the already-bound listening server socket keeps serving the previously loaded certificate to incoming connections until it is recreated (e.g. when the node re-enters the ring), because SSLServerSocket captures the SSL context at creation time. Recreating the discovery server socket at runtime is intentionally avoided as too disruptive for the ring.

The Jetty HTTP REST protocol manages its own SSL and is out of scope (the default GridRestProtocol.reloadSslContext() is a no-op).

Tests

  • SslContextFactoryReloadTest — a real loopback TLS handshake confirms that after the key store file is replaced on disk, reload() serves a different certificate, while create() keeps its caching semantics.
  • SslContextReloadNodeTest — a two-node SSL cluster runs the actual --ssl reload task; asserts communication/discovery/client-connector are reloaded and the cluster keeps operating (established sessions are not interrupted); a non-SSL node reports nothing to reload.

Both control.sh --help golden files were updated. Strict -Pcheckstyle passes.

Docs / Release Notes

  • docs/_docs/tools/control-script.adoc — new "TLS Certificate Hot Reload" section (Docs Required flag).

🤖 Generated with Claude Code

…h --ssl reload

Reload TLS certificates on running nodes without a restart. The new
`control.sh --ssl reload` command re-reads the configured key and trust stores
from disk and replaces the active SSL context for the communication, discovery,
thin client (client connector) and binary (TCP) REST transports. New connections
use the updated certificates while established sessions are not interrupted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant