Skip to content

Commit a103b84

Browse files
authored
[FEATURE] Broaden SecureSettingsFactory to include http transports (opensearch-project#12907)
Signed-off-by: Andriy Redko <andriy.redko@aiven.io>
1 parent 8ad0dc0 commit a103b84

16 files changed

+596
-155
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
116116

117117
### Changed
118118
- [BWC and API enforcement] Enforcing the presence of API annotations at build time ([#12872](https://github.com/opensearch-project/OpenSearch/pull/12872))
119+
- Improve built-in secure transports support ([#12907](https://github.com/opensearch-project/OpenSearch/pull/12907))
119120

120121
### Deprecated
121122

modules/transport-netty4/src/main/java/org/opensearch/http/netty4/ssl/SecureNetty4HttpServerTransport.java

+70-8
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,27 @@
3737
import org.opensearch.core.xcontent.NamedXContentRegistry;
3838
import org.opensearch.http.HttpChannel;
3939
import org.opensearch.http.HttpHandlingSettings;
40+
import org.opensearch.http.HttpServerTransport;
4041
import org.opensearch.http.netty4.Netty4HttpChannel;
4142
import org.opensearch.http.netty4.Netty4HttpServerTransport;
42-
import org.opensearch.plugins.SecureTransportSettingsProvider;
43+
import org.opensearch.plugins.SecureHttpTransportSettingsProvider;
44+
import org.opensearch.plugins.TransportExceptionHandler;
4345
import org.opensearch.telemetry.tracing.Tracer;
4446
import org.opensearch.threadpool.ThreadPool;
4547
import org.opensearch.transport.SharedGroupFactory;
48+
import org.opensearch.transport.TransportAdapterProvider;
4649
import org.opensearch.transport.netty4.ssl.SslUtils;
4750

4851
import javax.net.ssl.SSLEngine;
4952

53+
import java.util.List;
54+
import java.util.Optional;
55+
import java.util.stream.Collectors;
56+
5057
import io.netty.channel.Channel;
5158
import io.netty.channel.ChannelHandler;
5259
import io.netty.channel.ChannelHandlerContext;
60+
import io.netty.channel.ChannelInboundHandlerAdapter;
5361
import io.netty.handler.codec.DecoderException;
5462
import io.netty.handler.ssl.ApplicationProtocolNames;
5563
import io.netty.handler.ssl.ApplicationProtocolNegotiationHandler;
@@ -59,9 +67,14 @@
5967
* @see <a href="https://github.com/opensearch-project/security/blob/d526c9f6c2a438c14db8b413148204510b9fe2e2/src/main/java/org/opensearch/security/ssl/http/netty/SecuritySSLNettyHttpServerTransport.java">SecuritySSLNettyHttpServerTransport</a>
6068
*/
6169
public class SecureNetty4HttpServerTransport extends Netty4HttpServerTransport {
70+
public static final String REQUEST_HEADER_VERIFIER = "HeaderVerifier";
71+
public static final String REQUEST_DECOMPRESSOR = "RequestDecompressor";
72+
6273
private static final Logger logger = LogManager.getLogger(SecureNetty4HttpServerTransport.class);
63-
private final SecureTransportSettingsProvider secureTransportSettingsProvider;
64-
private final SecureTransportSettingsProvider.ServerExceptionHandler exceptionHandler;
74+
private final SecureHttpTransportSettingsProvider secureHttpTransportSettingsProvider;
75+
private final TransportExceptionHandler exceptionHandler;
76+
private final ChannelInboundHandlerAdapter headerVerifier;
77+
private final TransportAdapterProvider<HttpServerTransport> decompressorProvider;
6578

6679
public SecureNetty4HttpServerTransport(
6780
final Settings settings,
@@ -72,7 +85,7 @@ public SecureNetty4HttpServerTransport(
7285
final Dispatcher dispatcher,
7386
final ClusterSettings clusterSettings,
7487
final SharedGroupFactory sharedGroupFactory,
75-
final SecureTransportSettingsProvider secureTransportSettingsProvider,
88+
final SecureHttpTransportSettingsProvider secureHttpTransportSettingsProvider,
7689
final Tracer tracer
7790
) {
7891
super(
@@ -86,9 +99,45 @@ public SecureNetty4HttpServerTransport(
8699
sharedGroupFactory,
87100
tracer
88101
);
89-
this.secureTransportSettingsProvider = secureTransportSettingsProvider;
90-
this.exceptionHandler = secureTransportSettingsProvider.buildHttpServerExceptionHandler(settings, this)
91-
.orElse(SecureTransportSettingsProvider.ServerExceptionHandler.NOOP);
102+
103+
this.secureHttpTransportSettingsProvider = secureHttpTransportSettingsProvider;
104+
this.exceptionHandler = secureHttpTransportSettingsProvider.buildHttpServerExceptionHandler(settings, this)
105+
.orElse(TransportExceptionHandler.NOOP);
106+
107+
final List<ChannelInboundHandlerAdapter> headerVerifiers = secureHttpTransportSettingsProvider.getHttpTransportAdapterProviders(
108+
settings
109+
)
110+
.stream()
111+
.filter(p -> REQUEST_HEADER_VERIFIER.equalsIgnoreCase(p.name()))
112+
.map(p -> p.create(settings, this, ChannelInboundHandlerAdapter.class))
113+
.filter(Optional::isPresent)
114+
.map(Optional::get)
115+
.collect(Collectors.toList());
116+
117+
if (headerVerifiers.size() > 1) {
118+
throw new IllegalArgumentException("Cannot have more than one header verifier configured, supplied " + headerVerifiers.size());
119+
}
120+
121+
final Optional<TransportAdapterProvider<HttpServerTransport>> decompressorProviderOpt = secureHttpTransportSettingsProvider
122+
.getHttpTransportAdapterProviders(settings)
123+
.stream()
124+
.filter(p -> REQUEST_DECOMPRESSOR.equalsIgnoreCase(p.name()))
125+
.findFirst();
126+
// There could be multiple request decompressor providers configured, using the first one
127+
decompressorProviderOpt.ifPresent(p -> logger.debug("Using request decompressor provider: {}", p));
128+
129+
this.headerVerifier = headerVerifiers.isEmpty() ? null : headerVerifiers.get(0);
130+
this.decompressorProvider = decompressorProviderOpt.orElseGet(() -> new TransportAdapterProvider<HttpServerTransport>() {
131+
@Override
132+
public String name() {
133+
return REQUEST_DECOMPRESSOR;
134+
}
135+
136+
@Override
137+
public <C> Optional<C> create(Settings settings, HttpServerTransport transport, Class<C> adapterClass) {
138+
return Optional.empty();
139+
}
140+
});
92141
}
93142

94143
@Override
@@ -152,7 +201,7 @@ protected SslHttpChannelHandler(final Netty4HttpServerTransport transport, final
152201
protected void initChannel(Channel ch) throws Exception {
153202
super.initChannel(ch);
154203

155-
final SSLEngine sslEngine = secureTransportSettingsProvider.buildSecureHttpServerEngine(
204+
final SSLEngine sslEngine = secureHttpTransportSettingsProvider.buildSecureHttpServerEngine(
156205
settings,
157206
SecureNetty4HttpServerTransport.this
158207
).orElseGet(SslUtils::createDefaultServerSSLEngine);
@@ -166,4 +215,17 @@ protected void configurePipeline(Channel ch) {
166215
ch.pipeline().addLast(new Http2OrHttpHandler());
167216
}
168217
}
218+
219+
protected ChannelInboundHandlerAdapter createHeaderVerifier() {
220+
if (headerVerifier != null) {
221+
return headerVerifier;
222+
} else {
223+
return super.createHeaderVerifier();
224+
}
225+
}
226+
227+
@Override
228+
protected ChannelInboundHandlerAdapter createDecompressor() {
229+
return decompressorProvider.create(settings, this, ChannelInboundHandlerAdapter.class).orElseGet(super::createDecompressor);
230+
}
169231
}

modules/transport-netty4/src/main/java/org/opensearch/transport/Netty4ModulePlugin.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import org.opensearch.http.netty4.ssl.SecureNetty4HttpServerTransport;
5050
import org.opensearch.plugins.NetworkPlugin;
5151
import org.opensearch.plugins.Plugin;
52+
import org.opensearch.plugins.SecureHttpTransportSettingsProvider;
5253
import org.opensearch.plugins.SecureTransportSettingsProvider;
5354
import org.opensearch.telemetry.tracing.Tracer;
5455
import org.opensearch.threadpool.ThreadPool;
@@ -160,7 +161,7 @@ public Map<String, Supplier<HttpServerTransport>> getSecureHttpTransports(
160161
NetworkService networkService,
161162
HttpServerTransport.Dispatcher dispatcher,
162163
ClusterSettings clusterSettings,
163-
SecureTransportSettingsProvider secureTransportSettingsProvider,
164+
SecureHttpTransportSettingsProvider secureHttpTransportSettingsProvider,
164165
Tracer tracer
165166
) {
166167
return Collections.singletonMap(
@@ -174,7 +175,7 @@ public Map<String, Supplier<HttpServerTransport>> getSecureHttpTransports(
174175
dispatcher,
175176
clusterSettings,
176177
getSharedGroupFactory(settings),
177-
secureTransportSettingsProvider,
178+
secureHttpTransportSettingsProvider,
178179
tracer
179180
)
180181
);

modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/ssl/SecureNetty4Transport.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.opensearch.core.common.io.stream.NamedWriteableRegistry;
4343
import org.opensearch.core.indices.breaker.CircuitBreakerService;
4444
import org.opensearch.plugins.SecureTransportSettingsProvider;
45+
import org.opensearch.plugins.TransportExceptionHandler;
4546
import org.opensearch.telemetry.tracing.Tracer;
4647
import org.opensearch.threadpool.ThreadPool;
4748
import org.opensearch.transport.SharedGroupFactory;
@@ -72,7 +73,7 @@ public class SecureNetty4Transport extends Netty4Transport {
7273

7374
private static final Logger logger = LogManager.getLogger(SecureNetty4Transport.class);
7475
private final SecureTransportSettingsProvider secureTransportSettingsProvider;
75-
private final SecureTransportSettingsProvider.ServerExceptionHandler exceptionHandler;
76+
private final TransportExceptionHandler exceptionHandler;
7677

7778
public SecureNetty4Transport(
7879
final Settings settings,
@@ -100,7 +101,7 @@ public SecureNetty4Transport(
100101

101102
this.secureTransportSettingsProvider = secureTransportSettingsProvider;
102103
this.exceptionHandler = secureTransportSettingsProvider.buildServerTransportExceptionHandler(settings, this)
103-
.orElse(SecureTransportSettingsProvider.ServerExceptionHandler.NOOP);
104+
.orElse(TransportExceptionHandler.NOOP);
104105
}
105106

106107
@Override

0 commit comments

Comments
 (0)