Sergey Soldatov created HDDS-16035:
--------------------------------------

             Summary: Secure SCM HA cluster cannot start: the primary SCM 
refuses to sign certificates for the other SCMs when there is no leader
                 Key: HDDS-16035
                 URL: https://issues.apache.org/jira/browse/HDDS-16035
             Project: Apache Ozone
          Issue Type: Bug
          Components: SCM HA, Security
    Affects Versions: 2.2.0, 1.4.1
            Reporter: Sergey Soldatov
            Assignee: Sergey Soldatov


I hit this while turning on security on a 3 node SCM HA cluster that had been 
running without it. SCM was unable to build the quorum. The only recovery was 
deleting the SCM data, which is not acceptable in production. The same symptom 
is reported by another user in apache/ozone discussion #7616 (Ozone 1.4.1 on 
Kubernetes with Kerberos, no vendor tooling involved).
RCA:
In a secure SCM HA cluster, an SCM cannot start until it has a sub CA 
certificate, and it asks the primary SCM for one over SCMSecurityProtocol. 
SCMSecurityProtocolServerSideTranslatorPB.submitRequest() rejects every request 
on that protocol unless the SCM serving it is the Ratis leader. So the other 
SCMs wait for  a certificate, and the certificate waits for a leader that 
cannot be elected until those SCMs are up. Nothing breaks the loop, and the 
cluster never starts. The primary is running and reachable the whole time: it 
signed its own certificate without any leader, and it holds the root CA, but it 
answers every request with ServerNotLeaderException ("Could not determine the 
leader node"). Ozone's  SCM HA documentation says only the primordial SCM can 
issue certificates for the other SCMs, so the leader check does not fit what 
this call does. Before 1.4.0 the same method had an explicit exemption for 
GetSCMCertificate; HDDS-8286 removed it so that a new SCM joining a healthy 
cluster is signed by whichever node leads, and bootstrap then inherited that 
rule. 

Suggested fix:
Let a single narrow case skip the leader check: a GetSCMCertificate request 
that is not a renewal, served by the primary SCM (the one holding the root CA), 
at a moment when no leader is known. Signing on that path also needs a serial 
number and a database write, which normally go through Ratis, so it would use a 
direct serial allocator next to the existing 
SequenceIdGenerator.upgradeToCertificateSequenceId() and the existing 
unreplicated storeValidScmCertificate() write that persistPrimarySCMCerts() 
already uses on every primary start. The current checkValidCertID() check 
stays, so a repeated serial is refused and never issued, and the path logs a 
warning so an operator can see it ran. Everything else keeps the leader check: 
renewals, non primary SCMs, and OM and datanode certificates. When a leader 
exists nothing changes, so this is not a revert of HDDS-8286. It needs no proto 
change, no new config key, and no interface change. One known gap to note: a 
certificate signed this way is written only in the primary's local database, 
which is the same exposure persistPrimarySCMCerts() already has, and each SCM 
keeps its own certificate on local disk, so startup does not depend on the 
replicated copy.

[~Sammi] I would really appreciate your feedback about the suggested fix.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to