|
| 1 | +From 22fff64167758481f7c66a85bc86df1467928e00 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Lars Francke <git@lars-francke.de> |
| 3 | +Date: Wed, 13 Aug 2025 14:16:55 +0200 |
| 4 | +Subject: NIFI-14858: Make SNI checking configurable |
| 5 | + |
| 6 | +Introduces two new properties: |
| 7 | +- nifi.web.https.sni.required (default: false) |
| 8 | +- nifi.web.https.sni.host.check (default: true) |
| 9 | + |
| 10 | +These defaults mean that SNI is not required (this is the current behavior already) but if SNI is provided then the host has to match. |
| 11 | +--- |
| 12 | + .../StandardServerConnectorFactory.java | 24 +++++++++++++++++++ |
| 13 | + .../org/apache/nifi/util/NiFiProperties.java | 10 ++++++++ |
| 14 | + .../FrameworkServerConnectorFactory.java | 4 ++++ |
| 15 | + 3 files changed, 38 insertions(+) |
| 16 | + |
| 17 | +diff --git a/nifi-commons/nifi-jetty-configuration/src/main/java/org/apache/nifi/jetty/configuration/connector/StandardServerConnectorFactory.java b/nifi-commons/nifi-jetty-configuration/src/main/java/org/apache/nifi/jetty/configuration/connector/StandardServerConnectorFactory.java |
| 18 | +index 26d09706a1..132973cad5 100644 |
| 19 | +--- a/nifi-commons/nifi-jetty-configuration/src/main/java/org/apache/nifi/jetty/configuration/connector/StandardServerConnectorFactory.java |
| 20 | ++++ b/nifi-commons/nifi-jetty-configuration/src/main/java/org/apache/nifi/jetty/configuration/connector/StandardServerConnectorFactory.java |
| 21 | +@@ -70,6 +70,10 @@ public class StandardServerConnectorFactory implements ServerConnectorFactory { |
| 22 | + |
| 23 | + private int requestHeaderSize = 8192; |
| 24 | + |
| 25 | ++ private boolean sniRequired = false; |
| 26 | ++ |
| 27 | ++ private boolean sniHostCheck = true; |
| 28 | ++ |
| 29 | + /** |
| 30 | + * Standard Server Connector Factory Constructor with required properties |
| 31 | + * |
| 32 | +@@ -181,6 +185,24 @@ public class StandardServerConnectorFactory implements ServerConnectorFactory { |
| 33 | + this.requestHeaderSize = requestHeaderSize; |
| 34 | + } |
| 35 | + |
| 36 | ++ /** |
| 37 | ++ * Set to true if a SNI certificate is required, else requests will be rejected with 400 response. |
| 38 | ++ * |
| 39 | ++ * @param sniRequired SNI Required status |
| 40 | ++ */ |
| 41 | ++ public void setSniRequired(final boolean sniRequired) { |
| 42 | ++ this.sniRequired = sniRequired; |
| 43 | ++ } |
| 44 | ++ |
| 45 | ++ /** |
| 46 | ++ * Set to true if the SNI Host name must match when there is an SNI certificate. |
| 47 | ++ * |
| 48 | ++ * @param sniHostCheck SNI Host Check status |
| 49 | ++ */ |
| 50 | ++ public void setSniHostCheck(final boolean sniHostCheck) { |
| 51 | ++ this.sniHostCheck = sniHostCheck; |
| 52 | ++ } |
| 53 | ++ |
| 54 | + protected Server getServer() { |
| 55 | + return server; |
| 56 | + } |
| 57 | +@@ -195,6 +217,8 @@ public class StandardServerConnectorFactory implements ServerConnectorFactory { |
| 58 | + httpConfiguration.setSendServerVersion(SEND_SERVER_VERSION); |
| 59 | + |
| 60 | + final SecureRequestCustomizer secureRequestCustomizer = new SecureRequestCustomizer(); |
| 61 | ++ secureRequestCustomizer.setSniRequired(sniRequired); |
| 62 | ++ secureRequestCustomizer.setSniHostCheck(sniHostCheck); |
| 63 | + httpConfiguration.addCustomizer(secureRequestCustomizer); |
| 64 | + } |
| 65 | + |
| 66 | +diff --git a/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java b/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java |
| 67 | +index 9e85c05d22..89d81813f4 100644 |
| 68 | +--- a/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java |
| 69 | ++++ b/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java |
| 70 | +@@ -205,6 +205,8 @@ public class NiFiProperties extends ApplicationProperties { |
| 71 | + public static final String WEB_HTTPS_CIPHERSUITES_INCLUDE = "nifi.web.https.ciphersuites.include"; |
| 72 | + public static final String WEB_HTTPS_CIPHERSUITES_EXCLUDE = "nifi.web.https.ciphersuites.exclude"; |
| 73 | + public static final String WEB_HTTPS_NETWORK_INTERFACE_PREFIX = "nifi.web.https.network.interface."; |
| 74 | ++ public static final String WEB_HTTPS_SNI_REQUIRED = "nifi.web.https.sni.required"; |
| 75 | ++ public static final String WEB_HTTPS_SNI_HOST_CHECK = "nifi.web.https.sni.host.check"; |
| 76 | + public static final String WEB_WORKING_DIR = "nifi.web.jetty.working.directory"; |
| 77 | + public static final String WEB_THREADS = "nifi.web.jetty.threads"; |
| 78 | + public static final String WEB_MAX_HEADER_SIZE = "nifi.web.max.header.size"; |
| 79 | +@@ -709,6 +711,14 @@ public class NiFiProperties extends ApplicationProperties { |
| 80 | + return Arrays.stream(protocols.split("\\s+")).collect(Collectors.toSet()); |
| 81 | + } |
| 82 | + |
| 83 | ++ public boolean isWebHttpsSniRequired() { |
| 84 | ++ return Boolean.parseBoolean(getProperty(WEB_HTTPS_SNI_REQUIRED, "true")); |
| 85 | ++ } |
| 86 | ++ |
| 87 | ++ public boolean isWebHttpsSniHostCheck() { |
| 88 | ++ return Boolean.parseBoolean(getProperty(WEB_HTTPS_SNI_HOST_CHECK, "true")); |
| 89 | ++ } |
| 90 | ++ |
| 91 | + public String getWebMaxHeaderSize() { |
| 92 | + return getProperty(WEB_MAX_HEADER_SIZE, DEFAULT_WEB_MAX_HEADER_SIZE); |
| 93 | + } |
| 94 | +diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/connector/FrameworkServerConnectorFactory.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/connector/FrameworkServerConnectorFactory.java |
| 95 | +index 72986669d5..993b23889c 100644 |
| 96 | +--- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/connector/FrameworkServerConnectorFactory.java |
| 97 | ++++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/connector/FrameworkServerConnectorFactory.java |
| 98 | +@@ -90,6 +90,10 @@ public class FrameworkServerConnectorFactory extends StandardServerConnectorFact |
| 99 | + |
| 100 | + // Set Transport Layer Security Protocols based on platform configuration |
| 101 | + setIncludeSecurityProtocols(TlsPlatform.getPreferredProtocols().toArray(new String[0])); |
| 102 | ++ |
| 103 | ++ // Set SNI configuration from properties |
| 104 | ++ setSniRequired(properties.isWebHttpsSniRequired()); |
| 105 | ++ setSniHostCheck(properties.isWebHttpsSniHostCheck()); |
| 106 | + } |
| 107 | + } |
| 108 | + |
0 commit comments