CAMEL-22497: Make HTTPS easier for camel.server#22194
Conversation
- Move SSL configuration before HTTP server configuration so global SSL context is available when the server is created - Auto-enable useGlobalSslContextParameters on HTTP server and management server when camel.ssl.enabled=true - Generate self-signed certificate when SSL is enabled but no keystore is configured, for easy development use Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
🌟 Thank you for your contribution to the Apache Camel project! 🌟 🐫 Apache Camel Committers, please review the following items:
|
- Remove spurious @SuppressWarnings("restriction") - Replace deprecated Date methods with java.time APIs - Use wrapTag/encodeLength consistently in buildRdn - Import StandardCharsets instead of using fully-qualified names - Add SAN extension (DNS:localhost, IP:127.0.0.1) to self-signed cert - Reuse SecureRandom instance instead of creating multiple - Respect explicit camel.server.useGlobalSslContextParameters=false by checking if the property was explicitly set before auto-enabling - Add test verifying SAN extension in generated certificate Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
🧪 CI tested the following changed modules:
Build reactor — dependencies compiled but only changed modules were tested (4 modules)
|
squakez
left a comment
There was a problem hiding this comment.
I don't think it's a wise idea to add an hidden self signed certificate, even for development. If this is enabled I have the feeling it can expose potential security problems.
…s as secret - Add camel.ssl.selfSigned property to explicitly opt-in to self-signed certificate generation instead of auto-generating when no keystore is configured - Mark camel.ssl.keystorePassword and camel.ssl.trustStorePassword with secret=true in @metadata annotation - When SSL is enabled without keystore or selfSigned, log a warning and skip SSL context creation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Claude Code on behalf of Guillaume Nodet Thanks for the feedback @squakez! The latest push addresses the concerns raised: Self-signed certificate is now explicit opt-in only:
Secret annotations fixed:
Follow-up for broader secret/dev-setting warnings:
|
Self-Signed Certificate Generation: Framework ComparisonFor context on the approach we took with NettyUsed a two-tier fallback:
Both have downsides: BouncyCastle is a heavy optional dependency, and Vert.xDelegates entirely to Netty's QuarkusUses SmallRye Certs library ( Our Approach (Camel)Our
Claude Code on behalf of Guillaume Nodet |
squakez
left a comment
There was a problem hiding this comment.
I think we need to deeply think in the long term implications and the plethora of possibilities that can happen when we have a non opinionated and possibly a non-official JVM environment.
One potential scenario I invite you to diagnose is, what happen when I start doing a development with the selfsigned certificate on. Then, I'm happy with the development, and I turn the configuration off. The self signed certificate will be still there in the keystore.
Also, on environments where the JVM is shared among other processes, we are going to affect the same underlying keystore used by all processes (ie, what happen when we run in Tomcat or any other application server).
If we want to proceed with this scenario, my suggestion is to have this run in a component with a dedicated dependency and marked clearly with maven test scope. So, it will be up to the user to include/remove the dependency.
When we deal with security/threading and other core features that can have unforeseen side effects, I think we need to properly balance the tradeoff of introducing a feature vs potential disruption.
|
|
||
| X509Certificate cert = generateCertificate(keyPair, random); | ||
|
|
||
| KeyStore ks = KeyStore.getInstance("PKCS12"); |
There was a problem hiding this comment.
This one may fail if security provider is broken or missing. Also, not reliable on FIPS environment or OSGI.
There was a problem hiding this comment.
PKCS12 is the default keystore type since JDK 9 and is provided by the built-in SunJSSE provider — if it's unavailable, no SSL functionality would work at all. For FIPS environments, self-signed certificates wouldn't be appropriate anyway (FIPS is a production/compliance requirement, selfSigned=true is explicitly for dev use). If generation does fail for any reason, the exception propagates clearly and the context won't start silently without SSL.
There was a problem hiding this comment.
Thanks for the thorough review @squakez. Let me address each concern:
1. "The self-signed certificate will still be there in the keystore"
The certificate is generated entirely in-memory — it's never written to disk or to any system keystore. In SelfSignedCertificateGenerator.java:61, we call KeyStore.load(null, password.toCharArray()) where null means "create an empty in-memory keystore, don't read from any file". When the CamelContext stops, the KeyStore object is garbage collected. There is no persistent state.
2. "On environments where the JVM is shared (Tomcat, app servers), we affect the same underlying keystore"
The generated SSL context is set only on the CamelContext via camelContext.setSSLContextParameters(...) — it does not call SSLContext.setDefault() or modify the JVM-wide truststore/keystore. SSLContext.setDefault() is never called anywhere in the Camel codebase. The Vert.x HTTP server retrieves it from the CamelContext and applies it only to its own HttpServerOptions. Other processes, other webapps, or even other CamelContexts are unaffected.
More broadly, this feature targets standalone Camel applications (camel-main, JBang). In a Tomcat or app server scenario, you'd typically use Spring Boot or Quarkus which have their own SSL configuration mechanisms — camel-main and its camel.ssl.* properties wouldn't come into play.
3. "Separate component with test scope"
This feature is specifically for dev-time convenience (quickly enabling HTTPS without manually generating certificates), similar to how Quarkus offers quarkus tls generate-certificate --self-signed and Vert.x/Netty provide SelfSignedCertificate. It requires explicit opt-in via camel.ssl.selfSigned=true, and a WARN log is emitted at startup:
"Generating self-signed SSL certificate for development use. Do NOT use this in production."
Moving it to a test-scoped dependency would defeat the purpose — users need it at runtime during development, not just in tests.
4. Framework precedent
For reference, I posted a comparison of how other frameworks handle this. The approach is aligned with industry practice and Netty's own direction (they recently merged their own DER-based cert generation in PR #14263).
We also created CAMEL-23250 and #22269 to track broader improvements around warning on dev-only/insecure settings in production.
Claude Code on behalf of Guillaume Nodet
Summary
camel.ssl.*) before HTTP server configuration so global SSL context is available when the server is createduseGlobalSslContextParameterson both HTTP server and management server whencamel.ssl.enabled=true, removing the need to set it separately (respects explicitfalse)camel.ssl.selfSigned=trueoption to generate a self-signed certificate for development use (explicit opt-in required — no auto-generation)selfSigned, log a warning and skip SSL context creationcamel.ssl.keystorePasswordandcamel.ssl.trustStorePasswordwithsecret=true(fixes existing gap)With keystore (production)
Self-signed for development (explicit opt-in)
Follow-up
[CAMEL-23250|https://issues.apache.org/jira/browse/CAMEL-23250] tracks broader improvements for warning/preventing plain-text secrets in configuration and flagging development-only settings like
selfSignedandtrustAllCertificatesin production.Test plan
testMainSSLSelfSigned— verifies self-signed cert generation with SAN extension and valid SSLContext creationtestMainSSLSelfSignedFluent— same test using fluent APItestSelfSignedCertificateGenerator— unit test verifying KeyStore, key entry, and SAN extension