This is an automated email from the ASF dual-hosted git repository.

He-Pin pushed a commit to branch fix/tls-observability-3162
in repository https://gitbox.apache.org/repos/asf/pekko.git

commit 34a891115fa04e705f6121d61460eaea65a82024
Author: 虎鸣 <[email protected]>
AuthorDate: Wed Jun 24 04:04:31 2026 +0800

    fix: improve TLS observability - handshake failure logging and fail-fast 
SSL init
    
    Motivation:
    Classic remoting TLS handshake failures were silently swallowed: the
    NettySSLSupport handshake listener closed the channel without logging
    the failure reason or peer address. Additionally, SSLContext was lazily
    initialized, meaning keystore/truststore errors were only discovered on
    the first connection attempt rather than at startup.
    
    Modification:
    - NettySSLSupport: add MarkerLoggingAdapter parameter, log TLS handshake
      failures with peer address and cause
    - NettyTransport: pass log to NettySSLSupport
    - ConfigSSLEngineProvider: change sslContext from lazy val to val for
      eager initialization (fail-fast at provider construction time)
    
    Result:
    TLS handshake failures now produce actionable warning logs with peer
    address and error cause. Keystore/truststore configuration errors are
    detected at startup rather than on first connection.
    
    Tests:
    - remote / Test / testOnly 
org.apache.pekko.remote.ConfigSSLEngineProviderSpec
    - remote / Test / testOnly org.apache.pekko.remote.Ticket1978ConfigSpec
    
    References:
    Fixes #3162
---
 .../remote/transport/netty/NettySSLSupport.scala   |  8 +++-
 .../remote/transport/netty/NettyTransport.scala    |  2 +-
 .../remote/transport/netty/SSLEngineProvider.scala |  2 +-
 .../pekko/remote/ConfigSSLEngineProviderSpec.scala | 47 ++++++++++++++++++++++
 4 files changed, 56 insertions(+), 3 deletions(-)

diff --git 
a/remote/src/main/scala/org/apache/pekko/remote/transport/netty/NettySSLSupport.scala
 
b/remote/src/main/scala/org/apache/pekko/remote/transport/netty/NettySSLSupport.scala
index c127e4b0e8..fb71b826d8 100644
--- 
a/remote/src/main/scala/org/apache/pekko/remote/transport/netty/NettySSLSupport.scala
+++ 
b/remote/src/main/scala/org/apache/pekko/remote/transport/netty/NettySSLSupport.scala
@@ -21,6 +21,7 @@ import io.netty.handler.ssl.SslHandler
 import io.netty.util.concurrent.Future
 
 import com.typesafe.config.Config
+import org.apache.pekko.event.MarkerLoggingAdapter
 
 /**
  * INTERNAL API
@@ -60,13 +61,18 @@ private[pekko] object NettySSLSupport {
   /**
    * Construct a SSLHandler which can be inserted into a Netty server/client 
pipeline
    */
-  def apply(sslEngineProvider: SSLEngineProvider, isClient: Boolean): 
SslHandler = {
+  def apply(sslEngineProvider: SSLEngineProvider, isClient: Boolean, log: 
MarkerLoggingAdapter): SslHandler = {
     val sslEngine =
       if (isClient) sslEngineProvider.createClientSSLEngine()
       else sslEngineProvider.createServerSSLEngine()
     val handler = new SslHandler(sslEngine)
     handler.handshakeFuture().addListener((future: Future[Channel]) => {
       if (!future.isSuccess) {
+        val cause = if (future.cause() != null) future.cause() else null
+        log.warning(
+          "TLS handshake failed for remote address [{}]. {}",
+          sslEngine.getPeerHost,
+          if (cause != null) cause.getMessage else "unknown cause")
         handler.closeOutbound().channel().close()
       }
     })
diff --git 
a/remote/src/main/scala/org/apache/pekko/remote/transport/netty/NettyTransport.scala
 
b/remote/src/main/scala/org/apache/pekko/remote/transport/netty/NettyTransport.scala
index f64a39ac02..bba302ce03 100644
--- 
a/remote/src/main/scala/org/apache/pekko/remote/transport/netty/NettyTransport.scala
+++ 
b/remote/src/main/scala/org/apache/pekko/remote/transport/netty/NettyTransport.scala
@@ -423,7 +423,7 @@ class NettyTransport(val settings: NettyTransportSettings, 
val system: ExtendedA
   private def sslHandler(isClient: Boolean): SslHandler = {
     sslEngineProvider match {
       case OptionVal.Some(sslProvider) =>
-        NettySSLSupport(sslProvider, isClient)
+        NettySSLSupport(sslProvider, isClient, log)
       case _ =>
         throw new IllegalStateException("Expected enable-ssl=on")
     }
diff --git 
a/remote/src/main/scala/org/apache/pekko/remote/transport/netty/SSLEngineProvider.scala
 
b/remote/src/main/scala/org/apache/pekko/remote/transport/netty/SSLEngineProvider.scala
index ecab23e25a..88619cb8fa 100644
--- 
a/remote/src/main/scala/org/apache/pekko/remote/transport/netty/SSLEngineProvider.scala
+++ 
b/remote/src/main/scala/org/apache/pekko/remote/transport/netty/SSLEngineProvider.scala
@@ -62,7 +62,7 @@ class ConfigSSLEngineProvider(protected val log: 
MarkerLoggingAdapter, private v
 
   import settings._
 
-  private lazy val sslContext: SSLContext = {
+  private val sslContext: SSLContext = {
     try {
       val rng = createSecureRandom()
       val ctx = SSLContext.getInstance(SSLProtocol)
diff --git 
a/remote/src/test/scala/org/apache/pekko/remote/ConfigSSLEngineProviderSpec.scala
 
b/remote/src/test/scala/org/apache/pekko/remote/ConfigSSLEngineProviderSpec.scala
new file mode 100644
index 0000000000..08e21e5c75
--- /dev/null
+++ 
b/remote/src/test/scala/org/apache/pekko/remote/ConfigSSLEngineProviderSpec.scala
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * license agreements; and to You under the Apache License, version 2.0:
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * This file is part of the Apache Pekko project, which was derived from Akka.
+ */
+
+package org.apache.pekko.remote
+
+import scala.annotation.nowarn
+
+import org.apache.pekko
+import pekko.remote.transport.netty.ConfigSSLEngineProvider
+import pekko.testkit.PekkoSpec
+
+import com.typesafe.config.ConfigFactory
+
+@nowarn("msg=deprecated")
+class ConfigSSLEngineProviderSpec
+    extends PekkoSpec(
+      ConfigFactory.parseString("""
+    pekko {
+      actor.provider = remote
+      remote.classic.netty.ssl.security {
+        key-store = "/nonexistent/keystore.jks"
+        key-store-password = "changeme"
+        key-password = "changeme"
+        trust-store = "/nonexistent/truststore.jks"
+        trust-store-password = "changeme"
+        protocol = "TLSv1.3"
+        enabled-algorithms = [TLS_AES_128_GCM_SHA256]
+        random-number-generator = ""
+        require-mutual-authentication = off
+      }
+    }
+  """)) {
+
+  "ConfigSSLEngineProvider" must {
+    "fail fast when keystore cannot be loaded" in {
+      intercept[RemoteTransportException] {
+        new ConfigSSLEngineProvider(system)
+      }.getMessage should include("could not be established")
+    }
+  }
+}


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

Reply via email to