[ 
https://issues.apache.org/jira/browse/IGNITE-29211?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Anton Vinogradov updated IGNITE-29211:
--------------------------------------
    Description: 
Administrators can reload TLS certificates with {{control.sh --ssl reload}}. 
Add optional automatic renewal so nodes can read replacements before expiry 
without that command. Ignite reads the configured source; it does not issue 
certificates.

h3. Schedule

* Renewal is off by default. Add 
{{SslContextFactory.setRenewalEnabled(boolean)}} and {{isRenewalEnabled()}}; 
changing the setting requires a restart. Cover enabled factories used by the 
node's started TCP transports.
* Read certificate chains from the key store actually loaded, including custom 
sources. With renewal enabled, require at least one private key and an X.509 
chain for every private key.
* A chain expires when any certificate in it expires. Select the chain with the 
earliest expiry. Start attempts with 15% of its lifetime remaining, measured 
from the key certificate's validity start. For equal expiries, use the longest 
lifetime. A date already due at startup triggers an immediate attempt.
* After an automatic load, read the resulting renewal date. If it is still due, 
record a failed renewal attempt even though the valid context was installed. 
Keep that context and retry. This includes identical certificates, 
trust-store-only changes and replacements already within their renewal window.
* After a failed automatic attempt, retry with a one-minute base delay, 
doubling up to one hour. Add a random delay of up to half the base delay. 
Continue retries after expiry.
* After a successful manual reload, reset that factory's failure count and 
schedule the next automatic attempt from its loaded certificates. Run 
immediately if renewal is still due. Otherwise, retain the future renewal date.

h3. Replacement rules

* Manual and automatic replacements in {{SslContextFactory}} use the same 
loading path. Check every certificate in the private-key chains against the 
current date. Accept valid certificates with equal, earlier or later expiry, 
including identical certificates and trust-store-only changes. Initial loading 
keeps its existing behavior, including recovery from expired certificates.
* Publish a replacement only after loading and validation succeed. A loading or 
validation failure keeps the current context and renewal date. Established 
connections remain open; new connections use the accepted context.
* The manual command reports {{reloaded}} after a successful load, including 
when the material has not changed. Verify new TLS connections to confirm the 
expected certificates and peer trust.
* Factories extending only {{AbstractSslContextFactory}} keep their own manual 
loading behavior.

h3. API and execution

Expose {{getRenewalTime()}} and {{void renew()}} on {{SslContextFactory}}. 
Preserve {{final void init()}}. The getter returns an epoch-millisecond date, 
or {{0}} if disabled or not initialized.

{{renew()}} rechecks the date after waiting for an active load. It skips 
loading when disabled, not initialized or not due. Before a due load, an 
interrupted thread throws {{IgniteInterruptedException}} without clearing the 
flag. A due call uses {{init()}}; loading and validation failures throw. After 
a normal return, the node rereads the date to decide whether renewal succeeded.

Run automatic attempts and manual reloads of enabled factories on one executor 
per node. Each factory serializes its loads. Each node keeps its own schedule; 
nodes sharing a factory may query the source in the same window. Startup may 
load the same factory twice, sequentially.

Once shutdown starts, start no further automatic attempts and count no further 
failures. Cancel queued work and interrupt an automatic attempt waiting for the 
factory. A load already started may finish and install a validated replacement. 
Startup initialization already waiting for the factory may still proceed. 
Custom sources must bound load time so shutdown can finish.

h3. Feedback and checks

* Log failures and the next attempt with the affected transports.
* {{ssl.ConsecutiveRenewalFailures}} sums consecutive automatic failures on the 
node. Reset a factory's count after a successful manual reload or an automatic 
attempt after which renewal is no longer due. Manual failures and shutdown 
cancellation do not increment it.
* Add {{ssl.ManualReloadAttempts}} and {{ssl.AutomaticRenewalAttempts}} so 
operators can track attempt frequency. Count calls per factory, including 
errors and automatic skips. A factory shared by several transports counts once 
per attempt. Exclude startup, direct application calls and queued calls 
cancelled before execution.
* Test dates, custom sources, identical and trust-only loads, error recovery, 
scheduling, shared factories, shutdown and metrics. Verify renewal through a 
new TLS connection and reload through the manual command.
* Document preparation, trust rollout, command results and recovery. Explain 
that a failed renewal can leave newly loaded material in use when renewal 
remains due.

Depends on IGNITE-29210. IGNITE-29212 adds HTTPS. A separate status command and 
certificate inventory are outside this ticket.

[Implementation in PR #13786|https://github.com/apache/ignite/pull/13786]


  was:
Administrators can reload TLS certificates with {{control.sh --ssl reload}}. 
Add optional automatic renewal so nodes can read replacements before expiry 
without that command. Ignite reads the configured source; it does not issue 
certificates.

h3. Schedule

* Renewal is off by default. Add 
{{SslContextFactory.setRenewalEnabled(boolean)}} and {{isRenewalEnabled()}}; 
changing the setting requires a restart. Cover enabled factories used by the 
node's started TCP transports.
* Read certificate chains from the key store actually loaded, including custom 
sources. With renewal enabled, require at least one private key and an X.509 
chain for every private key.
* A chain expires when any certificate in it expires. Select the chain with the 
earliest expiry. Start attempts with 15% of its lifetime remaining, measured 
from the key certificate's validity start. For equal expiries, use the longest 
lifetime. A date already due at startup triggers an immediate attempt.
* After a replacement, recalculate the schedule. If renewal is already due, 
warn and wait one hour before the next automatic attempt. Keep future dates, 
even if closer than one hour. Manual reload remains available during the wait.
* After a failed automatic attempt, retry with a one-minute base delay, 
doubling up to one hour. Add a random delay of up to half the base delay. 
Continue retries after expiry.

h3. Replacement rules

* Manual and automatic replacements in {{SslContextFactory}} must check every 
certificate in the private-key chains against the current date. Accept equal, 
earlier or later expiry. Allow trust-store-only changes. Initial loading keeps 
its existing behavior, including recovery from expired certificates.
* Publish a replacement only after loading and validation succeed. On failure, 
keep the current context and renewal date. Established connections remain 
usable; new connections use the accepted context.
* If keys, certificate chains, trust certificates and TLS settings are 
unchanged, keep the context. The manual command reports {{unchanged}}, 
preserves the retry schedule and failure count, and continues with other 
factories. An unchanged automatic attempt is logged and counted as a failure.
* If custom trust managers or non-exportable keys prevent a reliable 
comparison, reload instead of reporting {{unchanged}}. Factories extending only 
{{AbstractSslContextFactory}} keep their own manual loading behavior.

h3. API and execution

Expose {{getRenewalTime()}}, {{void renew()}} and {{boolean reload()}} on 
{{SslContextFactory}}. Preserve {{void init()}}. The getter returns an 
epoch-millisecond date, or {{0}} if disabled or not initialized. {{reload()}} 
returns whether it replaced the context.

{{renew()}} rechecks the date after waiting for an active load. It skips 
loading when disabled, not initialized or not due. Before a due load, an 
interrupted thread throws {{IgniteInterruptedException}} without clearing the 
flag. Loading, validation and unchanged-material failures also throw. After any 
normal return, the node rereads the date.

Manual and automatic loads run one at a time. Each node keeps its own schedule; 
nodes sharing a factory may query the source in the same window. Startup may 
load the same factory twice, sequentially.

Once shutdown starts, start no further automatic attempts and count no further 
failures. Cancel queued work and interrupt an automatic attempt waiting for the 
factory. A load already started may finish and install a validated replacement. 
Startup initialization already waiting for the factory may still proceed. 
Custom sources must bound load time so shutdown can finish.

h3. Feedback and checks

* Log failures and the next attempt with the affected transports.
* {{ssl.ConsecutiveRenewalFailures}} sums consecutive automatic failures on the 
node. Reset a factory's count after replacement or an automatic skip because 
renewal is no longer due. Manual failures and shutdown cancellation do not 
increment it.
* Add {{ssl.ManualReloadAttempts}} and {{ssl.AutomaticRenewalAttempts}}. Count 
calls per factory, including failures, unchanged material and automatic skips. 
A shared transport factory counts once per attempt. Exclude startup, direct 
application calls and queued calls cancelled before execution.
* Test dates, custom sources, unchanged and trust-only loads, error recovery, 
scheduling, shared factories, shutdown and metrics. Verify renewal through a 
new TLS connection and {{unchanged}} through the real manual command.
* Document preparation, trust rollout, command results and recovery.

Depends on IGNITE-29210. IGNITE-29212 adds HTTPS. A separate status command and 
certificate inventory are outside this ticket.

[Implementation in PR #13786|https://github.com/apache/ignite/pull/13786]



> Renew TLS certificates automatically before expiry
> --------------------------------------------------
>
>                 Key: IGNITE-29211
>                 URL: https://issues.apache.org/jira/browse/IGNITE-29211
>             Project: Ignite
>          Issue Type: Sub-task
>            Reporter: Anton Vinogradov
>            Assignee: Anton Vinogradov
>            Priority: Major
>              Labels: ise
>          Time Spent: 1h 10m
>  Remaining Estimate: 0h
>
> Administrators can reload TLS certificates with {{control.sh --ssl reload}}. 
> Add optional automatic renewal so nodes can read replacements before expiry 
> without that command. Ignite reads the configured source; it does not issue 
> certificates.
> h3. Schedule
> * Renewal is off by default. Add 
> {{SslContextFactory.setRenewalEnabled(boolean)}} and {{isRenewalEnabled()}}; 
> changing the setting requires a restart. Cover enabled factories used by the 
> node's started TCP transports.
> * Read certificate chains from the key store actually loaded, including 
> custom sources. With renewal enabled, require at least one private key and an 
> X.509 chain for every private key.
> * A chain expires when any certificate in it expires. Select the chain with 
> the earliest expiry. Start attempts with 15% of its lifetime remaining, 
> measured from the key certificate's validity start. For equal expiries, use 
> the longest lifetime. A date already due at startup triggers an immediate 
> attempt.
> * After an automatic load, read the resulting renewal date. If it is still 
> due, record a failed renewal attempt even though the valid context was 
> installed. Keep that context and retry. This includes identical certificates, 
> trust-store-only changes and replacements already within their renewal window.
> * After a failed automatic attempt, retry with a one-minute base delay, 
> doubling up to one hour. Add a random delay of up to half the base delay. 
> Continue retries after expiry.
> * After a successful manual reload, reset that factory's failure count and 
> schedule the next automatic attempt from its loaded certificates. Run 
> immediately if renewal is still due. Otherwise, retain the future renewal 
> date.
> h3. Replacement rules
> * Manual and automatic replacements in {{SslContextFactory}} use the same 
> loading path. Check every certificate in the private-key chains against the 
> current date. Accept valid certificates with equal, earlier or later expiry, 
> including identical certificates and trust-store-only changes. Initial 
> loading keeps its existing behavior, including recovery from expired 
> certificates.
> * Publish a replacement only after loading and validation succeed. A loading 
> or validation failure keeps the current context and renewal date. Established 
> connections remain open; new connections use the accepted context.
> * The manual command reports {{reloaded}} after a successful load, including 
> when the material has not changed. Verify new TLS connections to confirm the 
> expected certificates and peer trust.
> * Factories extending only {{AbstractSslContextFactory}} keep their own 
> manual loading behavior.
> h3. API and execution
> Expose {{getRenewalTime()}} and {{void renew()}} on {{SslContextFactory}}. 
> Preserve {{final void init()}}. The getter returns an epoch-millisecond date, 
> or {{0}} if disabled or not initialized.
> {{renew()}} rechecks the date after waiting for an active load. It skips 
> loading when disabled, not initialized or not due. Before a due load, an 
> interrupted thread throws {{IgniteInterruptedException}} without clearing the 
> flag. A due call uses {{init()}}; loading and validation failures throw. 
> After a normal return, the node rereads the date to decide whether renewal 
> succeeded.
> Run automatic attempts and manual reloads of enabled factories on one 
> executor per node. Each factory serializes its loads. Each node keeps its own 
> schedule; nodes sharing a factory may query the source in the same window. 
> Startup may load the same factory twice, sequentially.
> Once shutdown starts, start no further automatic attempts and count no 
> further failures. Cancel queued work and interrupt an automatic attempt 
> waiting for the factory. A load already started may finish and install a 
> validated replacement. Startup initialization already waiting for the factory 
> may still proceed. Custom sources must bound load time so shutdown can finish.
> h3. Feedback and checks
> * Log failures and the next attempt with the affected transports.
> * {{ssl.ConsecutiveRenewalFailures}} sums consecutive automatic failures on 
> the node. Reset a factory's count after a successful manual reload or an 
> automatic attempt after which renewal is no longer due. Manual failures and 
> shutdown cancellation do not increment it.
> * Add {{ssl.ManualReloadAttempts}} and {{ssl.AutomaticRenewalAttempts}} so 
> operators can track attempt frequency. Count calls per factory, including 
> errors and automatic skips. A factory shared by several transports counts 
> once per attempt. Exclude startup, direct application calls and queued calls 
> cancelled before execution.
> * Test dates, custom sources, identical and trust-only loads, error recovery, 
> scheduling, shared factories, shutdown and metrics. Verify renewal through a 
> new TLS connection and reload through the manual command.
> * Document preparation, trust rollout, command results and recovery. Explain 
> that a failed renewal can leave newly loaded material in use when renewal 
> remains due.
> Depends on IGNITE-29210. IGNITE-29212 adds HTTPS. A separate status command 
> and certificate inventory are outside this ticket.
> [Implementation in PR #13786|https://github.com/apache/ignite/pull/13786]



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to