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

sewen pushed a commit to branch release-1.10
in repository https://gitbox.apache.org/repos/asf/flink.git

commit 7ddd746b2b9d26c02826cc92c58ed9134f34bf0b
Author: Stephan Ewen <se...@apache.org>
AuthorDate: Fri Jan 10 17:21:11 2020 +0100

    [FLINK-15174][security] (follow-up) Add a test for exceptions on invalid / 
malformed fingerprint and refine docs.
---
 docs/ops/security-ssl.md                           | 30 ++++++++++++++--------
 .../org/apache/flink/runtime/net/SSLUtilsTest.java | 17 ++++++++++++
 2 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/docs/ops/security-ssl.md b/docs/ops/security-ssl.md
index 4bb4e93..fd26599 100644
--- a/docs/ops/security-ssl.md
+++ b/docs/ops/security-ssl.md
@@ -51,15 +51,24 @@ Internal connectivity includes:
 All internal connections are SSL authenticated and encrypted. The connections 
use **mutual authentication**, meaning both server
 and client side of each connection need to present the certificate to each 
other. The certificate acts effectively as a shared
 secret when a dedicated CA is used to exclusively sign an internal cert.
+The certificate for internal communication is not needed by any other party to 
interact with Flink, and can be simply
+added to the container images, or attached to the YARN deployment.
 
-It is highly recommended to generate a dedicated certificate (self-signed) for 
a Flink deployment. The certificate for internal communication
-is not needed by any other party to interact with Flink, and can be simply 
added to the container images, or attached to the YARN deployment.
+  - The easiest way to realize this setup is by generating a dedicated 
public/private key pair and self-signed certificate
+    for the Flink deployment. The key- and truststore are identical and 
contains only that key pair / certificate.
+    An example is [shown below](#example-ssl-setup-standalone-and-kubernetes).
 
-An environment where operators are constrained to use firm wide Internal CA 
and can not generate self-signed certificate, specify the SHA1 certificate 
fingerprint to protect the cluster allowing only specific certificate to 
trusted by the cluster.
+  - In an environment where operators are constrained to use firm-wide 
Internal CA (cannot generate self-signed certificates),
+    the recommendation is to still have a dedicated key pair / certificate for 
the Flink deployment, signed by that CA.
+    However, the TrustStore must then also contain the CA's public certificate 
tho accept the deployment's certificate
+    during the SSL handshake (requirement in JDK TrustStore implementation).
+    
+    **NOTE:** Because of that, it is critical that you specify the fingerprint 
of the deployment certificate
+    (`security.ssl.internal.cert.fingerprint`), when it is not self-signed, to 
pin that certificate as the only trusted
+    certificate and prevent the TrustStore from trusting all certificates 
signed by that CA.
 
-*Note: Because internal connections are mutually authenticated with shared 
certificates, Flink can skip hostname verification. This makes container-based 
setups easier.*
-
-*IMPORTANT: Do not use certificate issued by public CA without pinning the 
fingerprint of the certificate.*
+*Note: Because internal connections are mutually authenticated with shared 
certificates, Flink can skip hostname verification.
+This makes container-based setups easier.*
 
 ### External / REST Connectivity
 
@@ -107,9 +116,9 @@ need to be set up such that the truststore trusts the 
keystore's certificate.
 
 #### Internal Connectivity
 
-Because internal communication is mutually authenticated, keystore and 
truststore typically contain the same dedicated certificate.
-The certificate can use wild card hostnames or addresses, because the 
certificate is expected to be a shared secret and host
-names are not verified. It is even possible to use the same file (the 
keystore) also as the truststore.
+Because internal communication is mutually authenticated between server and 
client side, keystore and truststore typically refer to a dedicated
+certificate that acts as a shared secret. In such a setup, the certificate can 
use wild card hostnames or addresses.
+WHen using self-signed certificates, it is even possible to use the same file 
as keystore and truststore.
 
 {% highlight yaml %}
 security.ssl.internal.keystore: /path/to/file.keystore
@@ -119,7 +128,8 @@ security.ssl.internal.truststore: /path/to/file.truststore
 security.ssl.internal.truststore-password: truststore_password
 {% endhighlight %}
 
-When using certificate from public CA, Use certificate pinning to allow only 
specific internal certificate to establish the connectivity.
+When using a certificate that is not self-signed, but signed by a CA, you need 
to use certificate pinning to allow only a 
+a specific certificate to be trusted when establishing the connectivity.
 
 {% highlight yaml %}
 security.ssl.internal.cert.fingerprint: 
00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
diff --git 
a/flink-runtime/src/test/java/org/apache/flink/runtime/net/SSLUtilsTest.java 
b/flink-runtime/src/test/java/org/apache/flink/runtime/net/SSLUtilsTest.java
index 2c3bb05..863cf71 100644
--- a/flink-runtime/src/test/java/org/apache/flink/runtime/net/SSLUtilsTest.java
+++ b/flink-runtime/src/test/java/org/apache/flink/runtime/net/SSLUtilsTest.java
@@ -49,6 +49,7 @@ import java.util.List;
 import java.util.Locale;
 
 import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
+import static org.hamcrest.Matchers.containsString;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -455,6 +456,22 @@ public class SSLUtilsTest extends TestLogger {
                        arrayContainingInAnyOrder(sslAlgorithms));
        }
 
+       @Test
+       public void testInvalidFingerprintParsing() throws Exception {
+               final Configuration config = 
createInternalSslConfigWithKeyAndTrustStores();
+               final String fingerprint = getCertificateFingerprint(config, 
"flink.test");
+
+               config.setString(SecurityOptions.SSL_INTERNAL_CERT_FINGERPRINT, 
fingerprint.substring(0, fingerprint.length() - 3));
+
+               try {
+                       SSLUtils.createInternalServerSSLEngineFactory(config);
+                       fail("expected exception");
+               }
+               catch (IllegalArgumentException e) {
+                       assertThat(e.getMessage(), containsString("malformed 
fingerprint"));
+               }
+       }
+
        // ------------------------------- utils 
----------------------------------
 
        private Configuration createRestSslConfigWithKeyStore() {

Reply via email to