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

Anton Vinogradov updated IGNITE-29211:
--------------------------------------
    Description: 
Load replacement TLS certificates before the current ones expire. An external 
source supplies the replacements. Ignite schedules the loads and uses accepted 
replacements for new connections.

h3. Configuration and timing

# Add {{SslContextFactory.setRenewalEnabled(boolean)}} and 
{{isRenewalEnabled()}}. Renewal is disabled by default. Changing the setting 
requires a restart.
# Each node schedules renewal for enabled factories used by its started TCP 
transports. Reject startup if an enabled factory's key store has no private-key 
entry with an X.509 chain.
# The renewal window opens when the first key chain to expire has 15% of its 
lifetime left. If that point has passed, start immediately. The lifetime begins 
when the leaf certificate becomes valid. It ends at the earliest expiry in the 
chain, including CA certificates. For chains with the same earliest expiry, use 
the longest lifetime.
# Add public {{SslContextFactory.getRenewalTime()}} and {{renew()}}. 
{{getRenewalTime()}} returns when the current renewal window opens, or {{0}} if 
renewal is disabled. {{renew()}} runs one attempt. It skips the load if renewal 
is disabled or the window has yet to open.

h3. Loading and retries

# An automatic replacement must contain a key chain. Every certificate in its 
key chains must be valid at the time of loading, and the earliest expiry must 
move later.
# If loading or validation fails, {{renew()}} throws and keeps the current 
context. Retry even after expiry. The base delay starts at one minute and 
doubles to a maximum of one hour. Add a random delay of up to half the base 
delay.
# Run manual and automatic loads of each factory one at a time. With renewal 
enabled, manual loads still require a key chain. They can keep the same expiry, 
for example when only trust changes.
# After a successful manual reload, update the schedule on that node. Run the 
next attempt immediately if it is due. Nodes sharing a factory have separate 
schedules and may both query the source in one renewal window.

h3. Shutdown and monitoring

# Once shutdown starts, admit no new attempts and count no more failures. An 
attempt waiting for another load of the same factory exits without loading. An 
attempt admitted earlier may finish and install a replacement that passes the 
checks.
# Log the next attempt and failures with the affected transports. Report 
{{ssl.ConsecutiveRenewalFailures}} as the sum of each factory's consecutive 
automatic failures on the node. Report zero on nodes without renewal.
# Count an automatic attempt with unchanged expiry as a failure. Clear the 
factory's count on that node after an accepted automatic replacement, any 
successful manual reload or a skipped attempt. Manual failures and shutdown 
cancellation do not add to the count.
# Document configuration, the metric, recovery, and overrides of 
{{loadKeyStore()}} or {{openFileInputStream()}}. An override must limit how 
long a load can take because a stuck load can delay node stop and manual reload.

h3. Acceptance

Verify the API, the disabled default, rejection at startup without a chain, 
scheduling and certificate dates from an overridden {{loadKeyStore()}}. Cover 
invalid and unchanged replacements, retries after expiry, manual reload, shared 
factories, shutdown and counters. Verify rotation on a new TLS connection while 
an established one stays usable.

Depends on [IGNITE-29210|https://issues.apache.org/jira/browse/IGNITE-29210]. 
[IGNITE-29212|https://issues.apache.org/jira/browse/IGNITE-29212] adds HTTPS 
renewal and its verification. A separate status command and certificate 
inventory are outside this ticket.

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


  was:
Load replacement TLS certificates before the current ones expire. An external 
source supplies the replacements. Ignite schedules the loads and applies 
accepted replacements to new connections.

h3. What to deliver

# Add {{SslContextFactory.setRenewalEnabled(boolean)}} and 
{{isRenewalEnabled()}}. Renewal is disabled by default. Changing the setting 
requires a node restart. Each node schedules attempts for renewal-enabled 
factories used by its started TCP transports. Fail startup if an enabled 
factory's key store has no private-key entry with an X.509 chain.
# The renewal window opens when the first key chain to expire has 15% of its 
lifetime left; if that time has passed, renewal starts at once. The lifetime 
runs from the leaf certificate's start to the earliest expiry in its chain, 
including CA certificates. For chains with the same earliest expiry, use the 
longest lifetime.
# Add public {{SslContextFactory.getRenewalTime()}} and {{renew()}}. The first 
returns the current window's opening time, or {{0}} when renewal is disabled. 
The second runs one automatic attempt and does nothing if renewal is disabled 
or the window is closed. An automatic replacement must have a key chain, every 
certificate in its key chains must be within its validity dates, and the 
earliest expiry must advance. On load or validation failure, {{renew()}} throws 
and keeps the current context. The node retries, even after expiry. The base 
retry delay starts at one minute and doubles up to one hour, with a random 
addition of up to half of each delay.
# Serialize manual and automatic loads of one factory. With renewal enabled, a 
manual replacement must provide a key chain and may keep the same expiry, for 
example for a trust-only change. A successful manual reload recalculates the 
schedule on that node and runs the next attempt immediately if it is already 
due. Nodes sharing a factory each keep their own schedule and may both query 
the source in one window.
# Once shutdown starts, the node starts no more attempts and counts no more 
failures. An attempt waiting for another load of the factory must exit without 
loading. An attempt admitted while the node was running may finish and install 
a replacement that passes the checks.
# Log the next attempt and failures with the affected transports. Publish 
{{ssl.ConsecutiveRenewalFailures}} as the node sum of consecutive automatic 
failures per factory, or zero on nodes without renewal. An unchanged expiry 
counts as a failure. An accepted automatic replacement or any successful manual 
reload clears that factory's count on the node. A skipped attempt also clears 
it. Manual failures and shutdown cancellation do not increment it.
# Document configuration, the {{ssl.ConsecutiveRenewalFailures}} metric, 
overrides of {{loadKeyStore()}} or {{openFileInputStream()}}, and recovery. An 
override must bound its load time because a stuck load can delay node stop and 
the reload command.

h3. Acceptance

Verify the API and default-off behavior, startup rejection without a chain, 
scheduling and dates from an overridden {{loadKeyStore()}}, invalid and 
unchanged replacements, retries after expiry, manual reload, shared factories, 
shutdown and counters. Verify rotation on a new TLS connection while an 
established connection remains usable.

Depends on [IGNITE-29210|https://issues.apache.org/jira/browse/IGNITE-29210]. 
[IGNITE-29212|https://issues.apache.org/jira/browse/IGNITE-29212] covers HTTPS 
and its renewal verification. No separate status command or certificate 
inventory is required.

[Implementation plan: 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
>
> Load replacement TLS certificates before the current ones expire. An external 
> source supplies the replacements. Ignite schedules the loads and uses 
> accepted replacements for new connections.
> h3. Configuration and timing
> # Add {{SslContextFactory.setRenewalEnabled(boolean)}} and 
> {{isRenewalEnabled()}}. Renewal is disabled by default. Changing the setting 
> requires a restart.
> # Each node schedules renewal for enabled factories used by its started TCP 
> transports. Reject startup if an enabled factory's key store has no 
> private-key entry with an X.509 chain.
> # The renewal window opens when the first key chain to expire has 15% of its 
> lifetime left. If that point has passed, start immediately. The lifetime 
> begins when the leaf certificate becomes valid. It ends at the earliest 
> expiry in the chain, including CA certificates. For chains with the same 
> earliest expiry, use the longest lifetime.
> # Add public {{SslContextFactory.getRenewalTime()}} and {{renew()}}. 
> {{getRenewalTime()}} returns when the current renewal window opens, or {{0}} 
> if renewal is disabled. {{renew()}} runs one attempt. It skips the load if 
> renewal is disabled or the window has yet to open.
> h3. Loading and retries
> # An automatic replacement must contain a key chain. Every certificate in its 
> key chains must be valid at the time of loading, and the earliest expiry must 
> move later.
> # If loading or validation fails, {{renew()}} throws and keeps the current 
> context. Retry even after expiry. The base delay starts at one minute and 
> doubles to a maximum of one hour. Add a random delay of up to half the base 
> delay.
> # Run manual and automatic loads of each factory one at a time. With renewal 
> enabled, manual loads still require a key chain. They can keep the same 
> expiry, for example when only trust changes.
> # After a successful manual reload, update the schedule on that node. Run the 
> next attempt immediately if it is due. Nodes sharing a factory have separate 
> schedules and may both query the source in one renewal window.
> h3. Shutdown and monitoring
> # Once shutdown starts, admit no new attempts and count no more failures. An 
> attempt waiting for another load of the same factory exits without loading. 
> An attempt admitted earlier may finish and install a replacement that passes 
> the checks.
> # Log the next attempt and failures with the affected transports. Report 
> {{ssl.ConsecutiveRenewalFailures}} as the sum of each factory's consecutive 
> automatic failures on the node. Report zero on nodes without renewal.
> # Count an automatic attempt with unchanged expiry as a failure. Clear the 
> factory's count on that node after an accepted automatic replacement, any 
> successful manual reload or a skipped attempt. Manual failures and shutdown 
> cancellation do not add to the count.
> # Document configuration, the metric, recovery, and overrides of 
> {{loadKeyStore()}} or {{openFileInputStream()}}. An override must limit how 
> long a load can take because a stuck load can delay node stop and manual 
> reload.
> h3. Acceptance
> Verify the API, the disabled default, rejection at startup without a chain, 
> scheduling and certificate dates from an overridden {{loadKeyStore()}}. Cover 
> invalid and unchanged replacements, retries after expiry, manual reload, 
> shared factories, shutdown and counters. Verify rotation on a new TLS 
> connection while an established one stays usable.
> Depends on [IGNITE-29210|https://issues.apache.org/jira/browse/IGNITE-29210]. 
> [IGNITE-29212|https://issues.apache.org/jira/browse/IGNITE-29212] adds HTTPS 
> renewal and its verification. A separate status command and certificate 
> inventory are outside this ticket.
> [Implementation plan 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