Skip to content

Block updates to log level for org.apache.http if less specific than INFO #105020

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

Merged
merged 27 commits into from
Feb 21, 2024

Conversation

mosche
Copy link
Contributor

@mosche mosche commented Feb 1, 2024

The apache http client supports logging detailed information about requests, including authorization information, if logging
at DEBUG, TRACE, ... . This PR prevents setting the log level to anything less specific than INFO for a number of restricted loggers (currently org.apache.http only).

There's a couple of ways to do so:

  • Setting the level directly, e.g. for org.apache.http or org.apache.http.client: This might trigger a validation error when attempting to update the setting.
  • Setting the level indirectly through an ancestor, e.g. org.apache or simply the root logger. If necessary the restriction will be enforced by explicitly setting restricted loggers to INFO level.
  • And finally, if setting the default level to anything less specific than INFO. This case is similar to above.

@mosche mosche added >non-issue :Core/Infra/Logging Log management and logging utilities Team:Core/Infra Meta label for core/infra team labels Feb 1, 2024
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (Team:Core/Infra)

Copy link
Contributor

@ldematte ldematte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but it seems you need to adjust some tests/assertions/mocks (e.g. OpenIdConnectAuthenticatorTests)

Copy link
Member

@rjernst rjernst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks pretty good. I left a few nits.

Copy link
Contributor

@DaveCTurner DaveCTurner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See this comment: if org.elasticsearch.transport.NetworkTraceFlag#TRACE_ENABLED is set (i.e. -Des.insecure_network_trace_enabled=true) then we should still permit this level of detailed logging.

Also this definitely needs to be mentioned in the docs, it's going to cause surprises otherwise.

Also should we block the AWS SDK request logging mentioned here (unless -Des.insecure_network_trace_enabled=true)?

from the logs emitted by the storage system, configure {es} to log every
request it makes to the S3 API by <<configuring-logging-levels,setting the
logging level>> of the `com.amazonaws.request` logger to `DEBUG`:

Also we link to some AWS docs that specifically say to enable wire tracing here, so should also mention that this requires -Des.insecure_network_trace_enabled=true:

problem. See the
https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-logging.html[AWS Java SDK]
documentation for further information, including details about other loggers
that can be used to obtain even more verbose logs. When you have finished

@mosche
Copy link
Contributor Author

mosche commented Feb 5, 2024

Also this definitely needs to be mentioned in the docs, it's going to cause surprises otherwise.

@DaveCTurner WDYT, are the changes to the docs sufficient or would you like me to be more specific. Can you think of any other place where this should be mentioned?

Copy link
Contributor

@DaveCTurner DaveCTurner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs changes look good; however I think we can't simply start rejecting previously-valid settings for bwc reasons.

@DaveCTurner
Copy link
Contributor

DaveCTurner commented Feb 5, 2024 via email

@rjernst
Copy link
Member

rjernst commented Feb 5, 2024

we just can't reject the config as invalid if it's already there in the cluster state.

We could ignore the cluster state in this case, converting the typical error to a warning log message?

@mosche
Copy link
Contributor Author

mosche commented Feb 6, 2024

we just can't reject the config as invalid if it's already there in the cluster state.

We could ignore the cluster state in this case, converting the typical error to a warning log message?

Just verifying I understood this right, so in case the cluster state already contains a persistent setting violating some logger restrictions (e.g. org.apache.http at DEBUG) we log a warning that the logger configuration is ignored.
If, however, a user wants to set org.apache.http to DEBUG using the cluster settings API or start a node with that setting, it fails.

Any recommendations how to best approach this? It looks like that requires a Settings update consumer that is aware of the current cluster metadata, so make that a ClusterStateListener and hook it up in NodeConstruction? Or is there a simpler, less intrusive way to achieve this?

@mosche mosche requested a review from a team as a code owner February 12, 2024 07:35
@@ -151,8 +151,19 @@ if (BuildParams.isSnapshotBuild() == false) {
}
}

tasks.register('testNetworkTraceNotEnabled', Test) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a huge fan of introducing another test task here. What exaclty does the es.insecure_network_trace_enabled system property do?

Copy link
Contributor Author

@mosche mosche Feb 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mark-vieira I'm absolutely on the same page with you, I just don't see much of an alternative. Also, I admit, having test depend on testNetworkTraceNotEnabled is broken. If you run :server:test --tests XYZ the dependency would still run ...

es.insecure_network_trace_enabled sets this flag, which gates the behavior added in this PR. Goal of the PR is to prevent setting dangerous loggers that might leak sensitive information. However, in order to investigate test failures, we are enabling this flag for most tests including :server:test

public class NetworkTraceFlag {

    private NetworkTraceFlag() {
        // no instances;
    }

    public static final String PROPERTY_NAME = "es.insecure_network_trace_enabled";

    public static final boolean TRACE_ENABLED;

    static {
        final var propertyValue = System.getProperty(PROPERTY_NAME);
        if (propertyValue == null) {
            TRACE_ENABLED = false;
        } else if ("true".equals(propertyValue)) {
            TRACE_ENABLED = true;
        } else {
            throw new IllegalArgumentException(
                Strings.format("system property [%s] may only be set to [true], but was [%s]", PROPERTY_NAME, propertyValue)
            );
        }
    }
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, is there anyway we can finagle this in a way that would allow updating this property inside specific tests? Initializing statics makes this tricky but perhaps some way to "reinitialize" this flag dynamically?

We definitely don't want test tasks depending on other test tasks. At worst we'd have check depend on this additional task.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, is there anyway we can finagle this in a way that would allow updating this property inside specific tests? Initializing statics makes this tricky but perhaps some way to "reinitialize" this flag dynamically?

IMHO that would pretty much defeat the purpose of that flag.

An alternative to a separate test task (using a different configuration) might be to extend the test runner to support forking tests into a new JVM. Though, while convenient, something like would probably be quickly adopted all around with a terrible impact on test run performance :/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we're overthinking this. AIUI we are trying to run the entire test suite twice, to ensure coverage of both states of this flag. That seems unnecessary to me, I think we only really need to run a few specific tests with tracing on (or off) and the rest of the test suite needn't care either way. We could make a dedicated suite in /qa for the otherwise-untested state. Or we could randomize it in :server:test and have two dedicated suites in /qa just for the tests that need it switched on or off.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that we have some other :qa suites that are similarly tightly-focussed, e.g. :qa:unconfigured-node-name and :qa:custom-rest-controller.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AIUI we are trying to run the entire test suite twice, to ensure coverage of both states of this flag. That seems unnecessary to me, I think we only really need to run a few specific tests with tracing on (or off) and the rest of the test suite needn't care either way.

Only the three test cases below are included when running testNetworkTraceNotEnabled. And none of these will run during test as their assumption fails. Though, we're obviously still scanning the entire test classpath twice to find test cases...

  filter {
    // following test require es.insecure_network_trace_enabled to NOT be enabled
    includeTestsMatching "org.elasticsearch.common.logging.LoggersTests.testCheckRestrictedLoggers"
    includeTestsMatching "org.elasticsearch.common.logging.LoggersTests.testSetLevelWithRestrictions"
    includeTestsMatching "org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequestTests.testValidateLoggers"
  }

But I like the idea of adding a focused :qa suite. Thanks for the pointer @DaveCTurner , I'll have a look at that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to having an explicit QA project for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rjernst I think this is a good compromise: In 7f57feb I've moved the tests to :qa:restricted-loggers. But I am also keeping similar tests in :server that are using an internal API allowing to explicitly pass restricted loggers. This should address your concern to keep tests close by the code. And at the same time we don't have to compromise on the static / final initialization of TRACE_ENABLED / RESTRICTED_LOGGERS.

@mosche
Copy link
Contributor Author

mosche commented Feb 19, 2024

@elasticmachine update branch

@mosche
Copy link
Contributor Author

mosche commented Feb 21, 2024

@DaveCTurner any more feedback from your side?

@DaveCTurner
Copy link
Contributor

Nothing to add, no. Thanks for the ping, sorry I didn't realise I was still blocking this.

@mosche
Copy link
Contributor Author

mosche commented Feb 21, 2024

@elasticmachine update branch

Copy link
Member

@rjernst rjernst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I left one very minor nit, just thinking ahead to when we can isolate logging config, I want to keep internals as private as possible to aid in that future work.

* Side Public License, v 1.
*/

package org.elasticsearch.action.admin.cluster.settings;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test could be in o.e.c.logging, then Loggers.RESTRICTED_LOGGERS could be package private?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@mosche mosche merged commit 6b50b6d into elastic:main Feb 21, 2024
@mosche mosche deleted the ES-7617_restricted_loggers branch February 21, 2024 16:45
ywangd added a commit to ywangd/elasticsearch that referenced this pull request May 27, 2024
With logging restriction (elastic#105020), the networkTrace flag needs to be
set for AWS request debug logging.

Relates: elastic#101608
elasticsearchmachine pushed a commit that referenced this pull request May 28, 2024
With logging restriction (#105020), the networkTrace flag needs to be
set for AWS request debug logging.

Relates: #101608
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Core/Infra/Logging Log management and logging utilities >non-issue Team:Core/Infra Meta label for core/infra team v8.14.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants