mirror of https://github.com/apache/druid.git
Ease of hidding sensitive properties from /status/proper… (#12950)
* apache#12063 Ease of hidding sensitive properties from /status/properties endpoint * apache#12063 Ease of hidding sensitive properties from /status/properties endpoint * apache#12063 Ease of hidding sensitive properties from /status/properties endpoint using one property for hiding properties, updated the index.md to document hiddenProperties * apache#12063 Ease of hidding sensitive properties from /status/properties endpoint Added java docs * apache#12063 Ease of hidding sensitive properties from /status/properties endpoint Add "password", "key", "token", "pwd" as default druid.server.hiddenProperties fixed typo and removed redundant space Co-authored-by: zemin <zemin.piao@adyen.com>
This commit is contained in:
parent
0ae515bd3c
commit
6805a7f9c2
|
@ -770,6 +770,14 @@ All Druid components can communicate with each other over HTTP.
|
|||
|`druid.global.http.unusedConnectionTimeout`|The timeout for idle connections in connection pool. The connection in the pool will be closed after this timeout and a new one will be established. This timeout should be less than `druid.global.http.readTimeout`. Set this timeout = ~90% of `druid.global.http.readTimeout`|`PT4M`|
|
||||
|`druid.global.http.numMaxThreads`|Maximum number of I/O worker threads|`max(10, ((number of cores * 17) / 16 + 2) + 30)`|
|
||||
|
||||
### Common endpoints Configuration
|
||||
|
||||
This section contains the configuration options for endpoints that are supported by all processes.
|
||||
|
||||
|Property| Description | Default |
|
||||
|--------|----------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|
|
||||
|`druid.server.hiddenProperties`| If property names or substring of property names (case insensitive) is in this list, responses of the `/status/properties` endpoint do not show these properties | `["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password", "password", "key", "token", "pwd"]` |
|
||||
|
||||
## Master Server
|
||||
|
||||
This section contains the configuration options for the processes that reside on Master servers (Coordinators and Overlords) in the suggested [three-server configuration](../design/processes.md#server-types).
|
||||
|
|
|
@ -131,7 +131,7 @@ druid.indexing.doubleStorage=double
|
|||
#
|
||||
# Security
|
||||
#
|
||||
druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password"]
|
||||
druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password", "password", "key", "token", "pwd"]
|
||||
|
||||
|
||||
#
|
||||
|
|
|
@ -131,7 +131,7 @@ druid.indexing.doubleStorage=double
|
|||
#
|
||||
# Security
|
||||
#
|
||||
druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password"]
|
||||
druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password", "password", "key", "token", "pwd"]
|
||||
|
||||
|
||||
#
|
||||
|
|
|
@ -131,7 +131,7 @@ druid.indexing.doubleStorage=double
|
|||
#
|
||||
# Security
|
||||
#
|
||||
druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password"]
|
||||
druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password", "password", "key", "token", "pwd"]
|
||||
|
||||
|
||||
#
|
||||
|
|
|
@ -131,7 +131,7 @@ druid.indexing.doubleStorage=double
|
|||
#
|
||||
# Security
|
||||
#
|
||||
druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password"]
|
||||
druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password", "password", "key", "token", "pwd"]
|
||||
|
||||
|
||||
#
|
||||
|
|
|
@ -131,7 +131,7 @@ druid.indexing.doubleStorage=double
|
|||
#
|
||||
# Security
|
||||
#
|
||||
druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password"]
|
||||
druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password", "password", "key", "token", "pwd"]
|
||||
|
||||
|
||||
#
|
||||
|
|
|
@ -131,7 +131,7 @@ druid.indexing.doubleStorage=double
|
|||
#
|
||||
# Security
|
||||
#
|
||||
druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password"]
|
||||
druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password", "password", "key", "token", "pwd"]
|
||||
|
||||
|
||||
#
|
||||
|
|
|
@ -131,7 +131,7 @@ druid.indexing.doubleStorage=double
|
|||
#
|
||||
# Security
|
||||
#
|
||||
druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password"]
|
||||
druid.server.hiddenProperties=["druid.s3.accessKey","druid.s3.secretKey","druid.metadata.storage.connector.password", "password", "key", "token", "pwd"]
|
||||
|
||||
|
||||
#
|
||||
|
|
|
@ -47,7 +47,9 @@ public class DruidServerConfig
|
|||
|
||||
@JsonProperty
|
||||
@NotNull
|
||||
private Set<String> hiddenProperties = Sets.newHashSet("druid.s3.accessKey", "druid.s3.secretKey", "druid.metadata.storage.connector.password");
|
||||
private Set<String> hiddenProperties = Sets.newHashSet("druid.s3.accessKey", "druid.s3.secretKey",
|
||||
"druid.metadata.storage.connector.password",
|
||||
"password", "key", "token", "pwd");
|
||||
|
||||
private SegmentLoaderConfig segmentLoaderConfig;
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.apache.druid.server.http.security.StateResourceFilter;
|
|||
import org.apache.druid.utils.JvmUtils;
|
||||
import org.apache.druid.utils.RuntimeInfo;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.GET;
|
||||
|
@ -48,6 +49,7 @@ import java.util.Properties;
|
|||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Path("/status")
|
||||
public class StatusResource
|
||||
|
@ -60,7 +62,8 @@ public class StatusResource
|
|||
public StatusResource(
|
||||
final Properties properties,
|
||||
final DruidServerConfig druidServerConfig,
|
||||
final ExtensionsLoader extnLoader)
|
||||
final ExtensionsLoader extnLoader
|
||||
)
|
||||
{
|
||||
this.properties = properties;
|
||||
this.druidServerConfig = druidServerConfig;
|
||||
|
@ -74,8 +77,30 @@ public class StatusResource
|
|||
public Map<String, String> getProperties()
|
||||
{
|
||||
Map<String, String> allProperties = Maps.fromProperties(properties);
|
||||
Set<String> hidderProperties = druidServerConfig.getHiddenProperties();
|
||||
return Maps.filterEntries(allProperties, (entry) -> !hidderProperties.contains(entry.getKey()));
|
||||
Set<String> hiddenProperties = druidServerConfig.getHiddenProperties();
|
||||
return filterHiddenProperties(hiddenProperties, allProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* filter out entries from allProperties with key containing elements in hiddenProperties (case insensitive)
|
||||
*
|
||||
* @return map of properties that are not filtered out.
|
||||
*/
|
||||
@Nonnull
|
||||
private Map<String, String> filterHiddenProperties(
|
||||
Set<String> hiddenProperties,
|
||||
Map<String, String> allProperties
|
||||
)
|
||||
{
|
||||
return Maps.filterEntries(
|
||||
allProperties,
|
||||
(entry) -> hiddenProperties
|
||||
.stream()
|
||||
.anyMatch(
|
||||
hiddenPropertyElement ->
|
||||
!StringUtils.toLowerCase(entry.getKey()).contains(StringUtils.toLowerCase(hiddenPropertyElement))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@GET
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.google.inject.Injector;
|
|||
import org.apache.druid.guice.PropertiesModule;
|
||||
import org.apache.druid.initialization.DruidModule;
|
||||
import org.apache.druid.initialization.ServerInjectorBuilderTest;
|
||||
import org.apache.druid.java.util.common.StringUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -35,6 +36,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class StatusResourceTest
|
||||
{
|
||||
|
@ -62,13 +64,36 @@ public class StatusResourceTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testPropertiesWithRestrictedConfigs()
|
||||
public void testHiddenProperties()
|
||||
{
|
||||
testHiddenPropertiesWithPropertyFileName("status.resource.test.runtime.properties");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHiddenPropertiesContain()
|
||||
{
|
||||
testHiddenPropertiesWithPropertyFileName("status.resource.test.runtime.hpc.properties");
|
||||
}
|
||||
|
||||
private void testHiddenPropertiesWithPropertyFileName(String fileName)
|
||||
{
|
||||
Injector injector = Guice.createInjector(Collections.singletonList(new PropertiesModule(Collections.singletonList(
|
||||
"status.resource.test.runtime.properties"))));
|
||||
fileName))));
|
||||
Map<String, String> returnedProperties = injector.getInstance(StatusResource.class).getProperties();
|
||||
Set<String> lowerCasePropertyNames = returnedProperties.keySet()
|
||||
.stream()
|
||||
.map(StringUtils::toLowerCase)
|
||||
.collect(Collectors.toSet());
|
||||
Set<String> hiddenProperties = new HashSet<>();
|
||||
Splitter.on(",").split(returnedProperties.get("druid.server.hiddenProperties")).forEach(hiddenProperties::add);
|
||||
hiddenProperties.forEach((property) -> Assert.assertNull(returnedProperties.get(property)));
|
||||
hiddenProperties.forEach(
|
||||
(property) -> {
|
||||
lowerCasePropertyNames.forEach(
|
||||
lowerCasePropertyName -> Assert.assertFalse(lowerCasePropertyName.contains(StringUtils.toLowerCase(
|
||||
property)))
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
druid.server.hiddenProperties=["password","key","token","pwd"]
|
||||
druid.storage.type=s3
|
||||
druid.storage.bucket=your-bucket
|
||||
druid.storage.baseKey=druid/segments
|
||||
druid.s3.accessKey=s3accesskey
|
||||
druid.s3.secretKey=s3secretkey
|
||||
|
||||
druid.metadata.storage.type=mysql
|
||||
druid.metadata.storage.connector.connectURI=jdbc:mysql://db.example.com:3306/druid
|
||||
druid.metadata.storage.connector.user=druiduser
|
||||
druid.metadata.storage.connector.password=password123
|
Loading…
Reference in New Issue