-
Notifications
You must be signed in to change notification settings - Fork 282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Identify extension Transport requests and permit handshake and extension registration actions #2599
Changes from 17 commits
e2b750d
478523a
3444295
eb03f38
85dba00
3419692
9ef4e0f
b7686dd
298aa27
5a64ef7
62a076c
87c421b
40b9c98
b1f7369
a740ea4
6cdda66
bec4270
bca8b36
e3e45ef
67a541e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,7 @@ | |
import org.opensearch.action.support.replication.TransportReplicationAction.ConcreteShardRequest; | ||
import org.opensearch.cluster.service.ClusterService; | ||
import org.opensearch.common.transport.TransportAddress; | ||
import org.opensearch.common.util.FeatureFlags; | ||
import org.opensearch.common.util.concurrent.ThreadContext; | ||
import org.opensearch.search.internal.ShardSearchRequest; | ||
import org.opensearch.security.auditlog.AuditLog; | ||
|
@@ -195,6 +196,7 @@ else if(!Strings.isNullOrEmpty(injectedUserHeader)) { | |
//also allow when issued from a remote cluster for cross cluster search | ||
if ( !HeaderHelper.isInterClusterRequest(getThreadContext()) | ||
&& !HeaderHelper.isTrustedClusterRequest(getThreadContext()) | ||
&& !HeaderHelper.isExtensionRequest(getThreadContext()) | ||
&& !task.getAction().equals("internal:transport/handshake") | ||
&& (task.getAction().startsWith("internal:") || task.getAction().contains("["))) { | ||
|
||
|
@@ -216,14 +218,14 @@ else if(!Strings.isNullOrEmpty(injectedUserHeader)) { | |
transportChannel.sendResponse(ex); | ||
return; | ||
} else { | ||
|
||
if(getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_ORIGIN) == null) { | ||
getThreadContext().putTransient(ConfigConstants.OPENDISTRO_SECURITY_ORIGIN, Origin.TRANSPORT.toString()); | ||
} | ||
|
||
//network intercluster request or cross search cluster request | ||
if(HeaderHelper.isInterClusterRequest(getThreadContext()) | ||
|| HeaderHelper.isTrustedClusterRequest(getThreadContext())) { | ||
|| HeaderHelper.isTrustedClusterRequest(getThreadContext()) | ||
|| HeaderHelper.isExtensionRequest(getThreadContext())) { | ||
|
||
final String userHeader = getThreadContext().getHeader(ConfigConstants.OPENDISTRO_SECURITY_USER_HEADER); | ||
final String injectedRolesHeader = getThreadContext().getHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES_HEADER); | ||
|
@@ -256,7 +258,6 @@ else if(!Strings.isNullOrEmpty(injectedUserHeader)) { | |
} | ||
|
||
} else { | ||
|
||
//this is a netty request from a non-server node (maybe also be internal: or a shard request) | ||
//and therefore issued by a transport client | ||
|
||
|
@@ -326,6 +327,11 @@ protected void addAdditionalContextValues(final String action, final TransportRe | |
} | ||
} | ||
|
||
String extensionUniqueId = getThreadContext().getHeader("extension_unique_id"); | ||
if (FeatureFlags.isEnabled(FeatureFlags.EXTENSIONS) && extensionUniqueId != null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this check be stronger? Absolutely, this check is basic at the moment and only checks for the presence of the header. A simple improvement on this would be to check not only the existence of the header, but also that it is a value contained in There should also be a check similar to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I modified this to check for the ID in the extensions registry. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a way we could remove the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 to removing redundant check. Also, we should add automated tests to verify this behavior There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @DarshitChanpura sure I will remove the check. I do think the check should remain, but I'll remove it since it if it seems redundant. I'll look into how a test can be written to verify this behavior. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cwperks Seems like there is a principal you'd like to see in how some features work that is at odds with our other practices. If you were to ask me what I think your principal is I'd state it as "Functionality for extensions should be behind a feature flag(s) to prevent issues on clusters that do not have extensions enabled". Does this seem correct, did you want to expand on this? This is a counterpoint to "Reduce coupling whenever possible". When we make a call to a static function call to determine global state the responsibility of the code has been broadly increased, making maintenance more difficult. I think this dialog represents different principals we'd like to see prioritized in the code, it might documenting and discussing as a tenant, what do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @peternied Yes that's correct. In this particular case its new functionality in the security plugin that would directly let an extension handshake with an opensearch node and also submit transport requests to initialize the extension like registering its REST handlers with OpenSearch - all of this is specific to extensions and is not permitted for anything other than an extension. In this case, I can't see any abstraction to add here because it is functionality for extensions and since other extension functionality is gated with a feature flag I think its appropriate to include here too. I don't see this as coupling necessarily except that there are 3 places that now rely on the same threadcontext header and I'm not sure how to do that otherwise. Cross cluster scenarios are simpler because its the security plugin that populates the threadcontext header so the security plugin is the only codebase that needs to be aware of what that header is. I can't see a better way here currently. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @DarshitChanpura @peternied I removed the feature flag check. There currently is no great way to test this change in an automated test. I think the best way to automate a check for this change will be an integration test that verifies that an extension can be initialized when connecting with an opensearch node with the security plugin installed. There is an open issue on the sdk repo for integration tests that will eventually validate this change. |
||
getThreadContext().putTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_EXTENSION_REQUEST, Boolean.TRUE); | ||
} | ||
|
||
super.addAdditionalContextValues(action, request, localCerts, peerCerts, principal); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For follow up PR, can we put this in a constant in core and use that constant here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@peternied yes that's a good idea to import the constant from core. After this PR, I plan to expand on the TLS logic to introduce
extension_dns
similar tonode_dns
that make this check stronger by verifying that the principal extracted from the extension certificate is present in a list of known principals and will include the change to make this a constant.For the FeatureFlags, I do think it makes sense to include a reference to the feature flag since this feature is directly related to extensions though its not necessarily needed.