Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
3a73fbf
Remove certificate client as instance variable where it had no meaning.
fapifta May 20, 2023
120d162
Remove unnecessary parameter isMTLS, value was always true.
fapifta May 20, 2023
086fdca
Moving CertificateClient and related classes to hdds-common to be ava…
fapifta May 22, 2023
6ba6d56
Remove unnecessary package
fapifta May 22, 2023
b30a1ca
Moving OzoneSecurityException to the exception package.
fapifta May 22, 2023
d1a75aa
Moving SecurityConfig out of the X509 package as it contains general …
fapifta May 22, 2023
5a132ed
Remove unused config option from SecurityConfig and from OzoneConfigK…
fapifta May 22, 2023
9c4b5e0
Pull off OzoneConfiguration from CertificateClient and related logic …
fapifta May 24, 2023
ac7ac92
Fix compilation and test errors from refactorings so far.
fapifta May 30, 2023
470a6d9
Fix a compilation failure in tests after constructor visibility change.
fapifta May 30, 2023
9675813
Address findbugs issue found in DefaultCertificateClient.
fapifta Jun 8, 2023
5fef4f8
Add back accidentally deleted flag to skip certain validations in tests.
fapifta Jun 8, 2023
713f710
Make sure that DNCertificateClient and its SCM client is created afte…
fapifta Jun 14, 2023
5b9c6a1
Remove unused import from TokenHelper.
fapifta Jun 14, 2023
afef4a2
Fix junit test, and resolve a conflict in how we initialize the cert …
fapifta Jun 14, 2023
bc919a8
Fix initialization code to conform with test expectations and login t…
fapifta Jun 15, 2023
b08eb6d
Fix compilation issues after rebase.
fapifta Jun 16, 2023
dbfbb1f
Fix Junit test failure due to config validation.
fapifta Jun 16, 2023
23eb53b
Merge remote-tracking branch 'origin/master' into HDDS-8879
adoroszlai Jun 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
import org.apache.hadoop.hdds.scm.client.HddsClientUtils;
import org.apache.hadoop.hdds.scm.pipeline.Pipeline;
import org.apache.hadoop.hdds.security.SecurityConfig;
import org.apache.hadoop.hdds.security.exception.SCMSecurityException;
import org.apache.hadoop.hdds.security.x509.SecurityConfig;
import org.apache.hadoop.hdds.tracing.GrpcClientInterceptor;
import org.apache.hadoop.hdds.tracing.TracingUtil;
import org.apache.hadoop.ozone.OzoneConfigKeys;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
import org.apache.hadoop.hdds.ratis.RatisHelper;
import org.apache.hadoop.hdds.scm.client.HddsClientUtils;
import org.apache.hadoop.hdds.scm.pipeline.Pipeline;
import org.apache.hadoop.hdds.security.x509.SecurityConfig;
import org.apache.hadoop.hdds.security.SecurityConfig;
import org.apache.hadoop.hdds.tracing.TracingUtil;

import com.google.common.annotations.VisibleForTesting;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import org.apache.hadoop.hdds.ratis.retrypolicy.RetryPolicyCreator;
import org.apache.hadoop.hdds.scm.ScmConfigKeys;
import org.apache.hadoop.hdds.scm.pipeline.Pipeline;
import org.apache.hadoop.hdds.security.x509.SecurityConfig;
import org.apache.hadoop.hdds.security.SecurityConfig;

import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.ratis.RaftConfigKeys;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
*/

package org.apache.hadoop.hdds.security.x509;
package org.apache.hadoop.hdds.security;

import java.nio.file.Path;
import java.nio.file.Paths;
Expand All @@ -29,9 +29,13 @@
import java.util.regex.Pattern;

import org.apache.hadoop.hdds.conf.ConfigurationSource;
import org.apache.hadoop.ozone.OzoneConfigKeys;

import com.google.common.base.Preconditions;
import org.apache.hadoop.hdds.HddsConfigKeys;
import org.apache.ratis.thirdparty.io.netty.handler.ssl.SslProvider;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.apache.hadoop.hdds.HddsConfigKeys.HDDS_BLOCK_TOKEN_ENABLED;
import static org.apache.hadoop.hdds.HddsConfigKeys.HDDS_BLOCK_TOKEN_ENABLED_DEFAULT;
Expand Down Expand Up @@ -84,22 +88,17 @@
import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_SECURITY_ENABLED_DEFAULT;
import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_SECURITY_ENABLED_KEY;

import org.apache.ratis.thirdparty.io.netty.handler.ssl.SslProvider;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* A class that deals with all Security related configs in HDDS.
* <p>
* This class allows security configs to be read and used consistently across
* all of security related code base.
* all security related code base.
*/
public class SecurityConfig {
private static final Logger LOG =
LoggerFactory.getLogger(SecurityConfig.class);
private static volatile Provider provider;
private final ConfigurationSource configuration;
private final int size;
private final String keyAlgo;
private final String providerString;
Expand All @@ -110,6 +109,8 @@ public class SecurityConfig {
private final Duration maxCertDuration;
private final String x509SignatureAlgo;
private final boolean blockTokenEnabled;
private final long blockTokenExpiryDurationMs;
private final boolean tokenSanityChecksEnabled;
private final boolean containerTokenEnabled;
private final String certificateDir;
private final String certificateFileName;
Expand All @@ -118,14 +119,15 @@ public class SecurityConfig {
private final Duration renewalGracePeriod;
private final boolean isSecurityEnabled;
private final String crlName;
private boolean grpcTlsUseTestCert;
private final boolean grpcTlsUseTestCert;
private final String externalRootCaPublicKeyPath;
private final String externalRootCaPrivateKeyPath;
private final String externalRootCaCert;
private final Duration caCheckInterval;
private final String caRotationTimeOfDay;
private final Pattern caRotationTimeOfDayPattern =
Pattern.compile("\\d{2}:\\d{2}:\\d{2}");
private final SslProvider grpcSSLProvider;

/**
* Constructs a SecurityConfig.
Expand All @@ -134,58 +136,67 @@ public class SecurityConfig {
*/
public SecurityConfig(ConfigurationSource configuration) {
Preconditions.checkNotNull(configuration, "Configuration cannot be null");
this.configuration = configuration;
this.size = this.configuration.getInt(HDDS_KEY_LEN, HDDS_DEFAULT_KEY_LEN);
this.keyAlgo = this.configuration.get(HDDS_KEY_ALGORITHM,
this.size = configuration.getInt(HDDS_KEY_LEN, HDDS_DEFAULT_KEY_LEN);
this.keyAlgo = configuration.get(HDDS_KEY_ALGORITHM,
HDDS_DEFAULT_KEY_ALGORITHM);
this.providerString = this.configuration.get(HDDS_SECURITY_PROVIDER,
this.providerString = configuration.get(HDDS_SECURITY_PROVIDER,
HDDS_DEFAULT_SECURITY_PROVIDER);

// Please Note: To make it easy for our customers we will attempt to read
// HDDS metadata dir and if that is not set, we will use Ozone directory.
this.metadataDir = this.configuration.get(HDDS_METADATA_DIR_NAME,
this.metadataDir = configuration.get(HDDS_METADATA_DIR_NAME,
configuration.get(OZONE_METADATA_DIRS));
this.keyDir = this.configuration.get(HDDS_KEY_DIR_NAME,
this.keyDir = configuration.get(HDDS_KEY_DIR_NAME,
HDDS_KEY_DIR_NAME_DEFAULT);
this.privateKeyFileName = this.configuration.get(HDDS_PRIVATE_KEY_FILE_NAME,
this.privateKeyFileName = configuration.get(HDDS_PRIVATE_KEY_FILE_NAME,
HDDS_PRIVATE_KEY_FILE_NAME_DEFAULT);
this.publicKeyFileName = this.configuration.get(HDDS_PUBLIC_KEY_FILE_NAME,
this.publicKeyFileName = configuration.get(HDDS_PUBLIC_KEY_FILE_NAME,
HDDS_PUBLIC_KEY_FILE_NAME_DEFAULT);

String durationString = this.configuration.get(HDDS_X509_MAX_DURATION,
String durationString = configuration.get(HDDS_X509_MAX_DURATION,
HDDS_X509_MAX_DURATION_DEFAULT);
this.maxCertDuration = Duration.parse(durationString);
this.x509SignatureAlgo = this.configuration.get(HDDS_X509_SIGNATURE_ALGO,
this.x509SignatureAlgo = configuration.get(HDDS_X509_SIGNATURE_ALGO,
HDDS_X509_SIGNATURE_ALGO_DEFAULT);
this.certificateDir = this.configuration.get(HDDS_X509_DIR_NAME,
this.certificateDir = configuration.get(HDDS_X509_DIR_NAME,
HDDS_X509_DIR_NAME_DEFAULT);
this.certificateFileName = this.configuration.get(HDDS_X509_FILE_NAME,
this.certificateFileName = configuration.get(HDDS_X509_FILE_NAME,
HDDS_X509_FILE_NAME_DEFAULT);

this.blockTokenEnabled = this.configuration.getBoolean(
this.blockTokenEnabled = configuration.getBoolean(
HDDS_BLOCK_TOKEN_ENABLED,
HDDS_BLOCK_TOKEN_ENABLED_DEFAULT);
this.containerTokenEnabled = this.configuration.getBoolean(
this.blockTokenExpiryDurationMs = configuration.getTimeDuration(
HddsConfigKeys.HDDS_BLOCK_TOKEN_EXPIRY_TIME,
HddsConfigKeys.HDDS_BLOCK_TOKEN_EXPIRY_TIME_DEFAULT,
TimeUnit.MILLISECONDS);
tokenSanityChecksEnabled = configuration.getBoolean(
HddsConfigKeys.HDDS_X509_GRACE_DURATION_TOKEN_CHECKS_ENABLED,
HddsConfigKeys.HDDS_X509_GRACE_DURATION_TOKEN_CHECKS_ENABLED_DEFAULT);

this.containerTokenEnabled = configuration.getBoolean(
HDDS_CONTAINER_TOKEN_ENABLED,
HDDS_CONTAINER_TOKEN_ENABLED_DEFAULT);

this.grpcTlsEnabled = this.configuration.getBoolean(HDDS_GRPC_TLS_ENABLED,
this.grpcTlsEnabled = configuration.getBoolean(HDDS_GRPC_TLS_ENABLED,
HDDS_GRPC_TLS_ENABLED_DEFAULT);

if (grpcTlsEnabled) {
this.grpcTlsUseTestCert = this.configuration.getBoolean(
this.grpcTlsUseTestCert = configuration.getBoolean(
HDDS_GRPC_TLS_TEST_CERT, HDDS_GRPC_TLS_TEST_CERT_DEFAULT);
} else {
this.grpcTlsUseTestCert = false;
}

this.isSecurityEnabled = this.configuration.getBoolean(
this.isSecurityEnabled = configuration.getBoolean(
OZONE_SECURITY_ENABLED_KEY,
OZONE_SECURITY_ENABLED_DEFAULT);

String certDurationString =
this.configuration.get(HDDS_X509_DEFAULT_DURATION,
configuration.get(HDDS_X509_DEFAULT_DURATION,
HDDS_X509_DEFAULT_DURATION_DEFAULT);
defaultCertDuration = Duration.parse(certDurationString);
String renewalGraceDurationString = this.configuration.get(
String renewalGraceDurationString = configuration.get(
HDDS_X509_RENEW_GRACE_DURATION,
HDDS_X509_RENEW_GRACE_DURATION_DEFAULT);
renewalGracePeriod = Duration.parse(renewalGraceDurationString);
Expand All @@ -209,19 +220,23 @@ public SecurityConfig(ConfigurationSource configuration) {

validateCertificateValidityConfig();

this.externalRootCaCert = this.configuration.get(
this.externalRootCaCert = configuration.get(
HDDS_X509_ROOTCA_CERTIFICATE_FILE,
HDDS_X509_ROOTCA_CERTIFICATE_FILE_DEFAULT);
this.externalRootCaPublicKeyPath = this.configuration.get(
this.externalRootCaPublicKeyPath = configuration.get(
HDDS_X509_ROOTCA_PUBLIC_KEY_FILE,
HDDS_X509_ROOTCA_PUBLIC_KEY_FILE_DEFAULT);
this.externalRootCaPrivateKeyPath = this.configuration.get(
this.externalRootCaPrivateKeyPath = configuration.get(
HDDS_X509_ROOTCA_PRIVATE_KEY_FILE,
HDDS_X509_ROOTCA_PRIVATE_KEY_FILE_DEFAULT);

this.crlName = this.configuration.get(HDDS_X509_CRL_NAME,
this.crlName = configuration.get(HDDS_X509_CRL_NAME,
HDDS_X509_CRL_NAME_DEFAULT);

this.grpcSSLProvider = SslProvider.valueOf(
configuration.get(HDDS_GRPC_TLS_PROVIDER,
HDDS_GRPC_TLS_PROVIDER_DEFAULT));

// First Startup -- if the provider is null, check for the provider.
if (SecurityConfig.provider == null) {
synchronized (SecurityConfig.class) {
Expand Down Expand Up @@ -277,6 +292,14 @@ private void validateCertificateValidityConfig() {
HDDS_X509_CA_ROTATION_CHECK_INTERNAL +
" should be smaller than " + HDDS_X509_RENEW_GRACE_DURATION);
}

if (tokenSanityChecksEnabled
&& blockTokenExpiryDurationMs > renewalGracePeriod.toMillis()) {
throw new IllegalArgumentException(" Certificate grace period " +
HddsConfigKeys.HDDS_X509_RENEW_GRACE_DURATION +
" should be greater than maximum block/container token lifetime " +
HddsConfigKeys.HDDS_BLOCK_TOKEN_EXPIRY_TIME);
}
}

/**
Expand Down Expand Up @@ -415,15 +438,6 @@ public String getSignatureAlgo() {
return x509SignatureAlgo;
}

/**
* Returns the Configuration used for initializing this SecurityConfig.
*
* @return Configuration
*/
public ConfigurationSource getConfiguration() {
return configuration;
}

/**
* Returns the maximum length a certificate can be valid in SCM. The default
* value is 5 years. This can be changed by setting "hdds.x509.max.duration"
Expand All @@ -445,6 +459,10 @@ public boolean isBlockTokenEnabled() {
return this.blockTokenEnabled;
}

public long getBlockTokenExpiryDurationMs() {
return blockTokenExpiryDurationMs;
}

/**
* Whether to require short-lived tokens for container operations.
*/
Expand All @@ -467,8 +485,7 @@ public boolean isGrpcTlsEnabled() {
* @return the gRPC TLS Provider.
*/
public SslProvider getGrpcSslProvider() {
return SslProvider.valueOf(configuration.get(HDDS_GRPC_TLS_PROVIDER,
HDDS_GRPC_TLS_PROVIDER_DEFAULT));
return grpcSSLProvider;
}

public String getExternalRootCaPrivateKeyPath() {
Expand Down Expand Up @@ -509,24 +526,12 @@ public boolean useTestCert() {
* @param providerName - name of the provider.
*/
private Provider initSecurityProvider(String providerName) {
switch (providerName) {
case "BC":
if ("BC".equals(providerName)) {
Security.addProvider(new BouncyCastleProvider());
return Security.getProvider(providerName);
default:
LOG.error("Security Provider:{} is unknown", provider);
throw new SecurityException("Unknown security provider:" + provider);
}
}

/**
* Returns max date for which S3 auth info objects will be valid.
*/
public long getS3AuthInfoMaxDate() {
return getConfiguration().getTimeDuration(
OzoneConfigKeys.OZONE_S3_AUTHINFO_MAX_LIFETIME_KEY,
OzoneConfigKeys.OZONE_S3_AUTHINFO_MAX_LIFETIME_KEY_DEFAULT,
TimeUnit.MICROSECONDS);
LOG.error("Security Provider:{} is unknown", provider);
throw new SecurityException("Unknown security provider:" + provider);
}

public boolean isTokenEnabled() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hdds.security;
package org.apache.hadoop.hdds.security.exception;

import java.io.IOException;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.
*/

/**
* Security-related classes for HDDS.
*/
package org.apache.hadoop.hdds.security;
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
*/
package org.apache.hadoop.hdds.security.ssl;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.hadoop.hdds.annotation.InterfaceAudience;
import org.apache.hadoop.hdds.annotation.InterfaceStability;
import org.apache.hadoop.hdds.security.x509.SecurityConfig;
import org.apache.hadoop.hdds.security.SecurityConfig;
import org.apache.hadoop.hdds.security.x509.certificate.client.CertificateClient;
import org.apache.hadoop.hdds.security.x509.certificate.client.CertificateNotification;
import org.slf4j.Logger;
Expand Down Expand Up @@ -135,19 +134,21 @@ public synchronized void destroy() {
/**
* Returns the keymanagers for owned certificates.
*/
@SuppressFBWarnings("EI_EXPOSE_REP")
@Override
public synchronized KeyManager[] getKeyManagers() {
return keyManagers;
KeyManager[] copy = new KeyManager[keyManagers.length];
System.arraycopy(keyManagers, 0, copy, 0, keyManagers.length);
return copy;
}

/**
* Returns the trustmanagers for trusted certificates.
*/
@SuppressFBWarnings("EI_EXPOSE_REP")
@Override
public synchronized TrustManager[] getTrustManagers() {
return trustManagers;
TrustManager[] copy = new TrustManager[trustManagers.length];
System.arraycopy(trustManagers, 0, copy, 0, trustManagers.length);
return copy;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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.
*
*/
/**
* Classes related to Certificate Life Cycle or Certificate Authority Server.
*/
package org.apache.hadoop.hdds.security.x509.certificate.authority;
Loading