This is an automated email from the ASF dual-hosted git repository. pinal pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/master by this push: new 307a3044f ATLAS:4558: Fix AtlasRepairIndex tool when tls is enabled 307a3044f is described below commit 307a3044faf52c3e6b9526994da1b1e0ab9cab2f Author: Pinal Shah <pinal.s...@freestoneinfotech.com> AuthorDate: Thu Jul 7 13:37:08 2022 +0530 ATLAS:4558: Fix AtlasRepairIndex tool when tls is enabled Signed-off-by: Pinal Shah <pinal.s...@freestoneinfotech.com> --- docs/src/documents/Tools/AtlasRepairIndex.md | 14 +- .../main/java/org/apache/atlas/utils/SSLUtil.java | 230 +++++++++++++++++++++ .../java/org/apache/atlas/tools/RepairIndex.java | 5 + 3 files changed, 248 insertions(+), 1 deletion(-) diff --git a/docs/src/documents/Tools/AtlasRepairIndex.md b/docs/src/documents/Tools/AtlasRepairIndex.md index 416d58a89..0161cb1cb 100644 --- a/docs/src/documents/Tools/AtlasRepairIndex.md +++ b/docs/src/documents/Tools/AtlasRepairIndex.md @@ -69,7 +69,19 @@ Example: </SyntaxHighlighter> For Atlas installation that uses kerberos as authentication mode, -use: kinit -kt /etc/security/keytabs/atlas.service.keytab atlas/fqdn@DOMAIN +use: + - Add below to DEFAULT_JVM_OPTS in repair_index.py + <SyntaxHighlighter wrapLines={true} language="powershell" style={theme.dark}> + {`-Djavax.security.auth.useSubjectCredsOnly=false -Djava.security.auth.login.config=atlas_jaas.conf`} + </SyntaxHighlighter> + + - kinit -kt /etc/security/keytabs/atlas.service.keytab atlas/fqdn@DOMAIN + + +For Atlas installation that uses SSL, we need to make sure to add Solr cert or RootCA certificate, use below atlas-application properties: +- keystore.file {path to keystore jks file} +- truststore.file {path to truststore jks file} +- cert.stores.credential.provider.path {path to jceks file} Example: <SyntaxHighlighter wrapLines={true} language="powershell" style={theme.dark}> diff --git a/intg/src/main/java/org/apache/atlas/utils/SSLUtil.java b/intg/src/main/java/org/apache/atlas/utils/SSLUtil.java new file mode 100644 index 000000000..f2b627f67 --- /dev/null +++ b/intg/src/main/java/org/apache/atlas/utils/SSLUtil.java @@ -0,0 +1,230 @@ +/** + * 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. + */ + +package org.apache.atlas.utils; + +import org.apache.atlas.ApplicationProperties; +import org.apache.atlas.AtlasException; +import org.apache.atlas.security.SecurityProperties; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; + +import static org.apache.atlas.security.SecurityProperties.CERT_STORES_CREDENTIAL_PROVIDER_PATH; +import static org.apache.atlas.security.SecurityProperties.DEFATULT_TRUSTORE_FILE_LOCATION; +import static org.apache.atlas.security.SecurityProperties.DEFAULT_KEYSTORE_FILE_LOCATION; +import static org.apache.atlas.security.SecurityProperties.KEYSTORE_FILE_KEY; +import static org.apache.atlas.security.SecurityProperties.KEYSTORE_PASSWORD_KEY; +import static org.apache.atlas.security.SecurityProperties.KEYSTORE_TYPE; +import static org.apache.atlas.security.SecurityProperties.TRUSTSTORE_FILE_KEY; +import static org.apache.atlas.security.SecurityProperties.TRUSTSTORE_PASSWORD_KEY; +import static org.apache.atlas.security.SecurityProperties.TRUSTSTORE_TYPE; +import static org.apache.atlas.security.SecurityUtil.getPassword; + +public class SSLUtil { + private static final Logger LOG = LoggerFactory.getLogger(SSLUtil.class); + public static final String ATLAS_KEYSTORE_FILE_TYPE_DEFAULT = "jks"; + public static final String ATLAS_TRUSTSTORE_FILE_TYPE_DEFAULT = "jks"; + public static final String ATLAS_TLS_CONTEXT_ALGO_TYPE = "TLS"; + public static final String ATLAS_TLS_KEYMANAGER_DEFAULT_ALGO_TYPE = KeyManagerFactory.getDefaultAlgorithm(); + public static final String ATLAS_TLS_TRUSTMANAGER_DEFAULT_ALGO_TYPE = TrustManagerFactory.getDefaultAlgorithm(); + + + protected Configuration getConfiguration() { + try { + return ApplicationProperties.get(); + } catch (AtlasException e) { + throw new RuntimeException("Unable to load configuration: " + ApplicationProperties.APPLICATION_PROPERTIES); + } + } + + private boolean isTLSEnabled() { + return getConfiguration().getBoolean(SecurityProperties.TLS_ENABLED); + } + + public void setSSLContext() { + + if (isTLSEnabled()) { + KeyManager[] kmList = getKeyManagers(); + TrustManager[] tmList = getTrustManagers(); + SSLContext sslContext = null; + if (tmList != null) { + try { + sslContext = SSLContext.getInstance(ATLAS_TLS_CONTEXT_ALGO_TYPE); + sslContext.init(kmList, tmList, new SecureRandom()); + } catch (NoSuchAlgorithmException e) { + LOG.error("SSL algorithm is not available in the environment. Reason: " + e.toString()); + } catch (KeyManagementException e) { + LOG.error("Unable to initials the SSLContext. Reason: " + e.toString()); + } + } + + if (sslContext != null) { + SSLContext.setDefault(sslContext); + } + } + } + + private KeyManager[] getKeyManagers() { + KeyManager[] kmList = null; + try { + + String keyStoreFile = getConfiguration().getString(KEYSTORE_FILE_KEY, + System.getProperty(KEYSTORE_FILE_KEY, DEFAULT_KEYSTORE_FILE_LOCATION)); + String keyStoreFilepwd = getPassword(getConfiguration(), KEYSTORE_PASSWORD_KEY, CERT_STORES_CREDENTIAL_PROVIDER_PATH); + + if (StringUtils.isNotEmpty(keyStoreFile) && StringUtils.isNotEmpty(keyStoreFilepwd)) { + InputStream in = null; + + try { + in = getFileInputStream(keyStoreFile); + + if (in != null) { + KeyStore keyStore = KeyStore.getInstance(getConfiguration().getString(KEYSTORE_TYPE , ATLAS_KEYSTORE_FILE_TYPE_DEFAULT)); + + keyStore.load(in, keyStoreFilepwd.toCharArray()); + + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(ATLAS_TLS_KEYMANAGER_DEFAULT_ALGO_TYPE); + + keyManagerFactory.init(keyStore, keyStoreFilepwd.toCharArray()); + + kmList = keyManagerFactory.getKeyManagers(); + } else { + LOG.error("Unable to obtain keystore from file [" + keyStoreFile + "]"); + } + } catch (KeyStoreException e) { + LOG.error("Unable to obtain from KeyStore :" + e.getMessage(), e); + } catch (NoSuchAlgorithmException e) { + LOG.error("SSL algorithm is NOT available in the environment", e); + } catch (CertificateException e) { + LOG.error("Unable to obtain the requested certification ", e); + } catch (FileNotFoundException e) { + LOG.error("Unable to find the necessary TLS Keystore Files", e); + } catch (IOException e) { + LOG.error("Unable to read the necessary TLS Keystore Files", e); + } catch (UnrecoverableKeyException e) { + LOG.error("Unable to recover the key from keystore", e); + } finally { + close(in, keyStoreFile); + } + } + + }catch (IOException exception) { + LOG.error(exception.getMessage(), exception); + } + return kmList; + } + + /** + * Generating the TrustManager using the provided truststore + * @return + */ + private TrustManager[] getTrustManagers() { + TrustManager[] tmList = null; + try { + String truststoreFile = getConfiguration().getString(TRUSTSTORE_FILE_KEY, + System.getProperty(TRUSTSTORE_FILE_KEY, DEFATULT_TRUSTORE_FILE_LOCATION)); + String trustStoreFilepwd = getPassword(getConfiguration(), TRUSTSTORE_PASSWORD_KEY, CERT_STORES_CREDENTIAL_PROVIDER_PATH); + + if (StringUtils.isNotEmpty(truststoreFile) && StringUtils.isNotEmpty(trustStoreFilepwd)) { + InputStream in = null; + + try { + in = getFileInputStream(truststoreFile); + + if (in != null) { + KeyStore trustStore = KeyStore.getInstance(getConfiguration().getString(TRUSTSTORE_TYPE , ATLAS_TRUSTSTORE_FILE_TYPE_DEFAULT)); + + trustStore.load(in, trustStoreFilepwd.toCharArray()); + + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(ATLAS_TLS_TRUSTMANAGER_DEFAULT_ALGO_TYPE); + + trustManagerFactory.init(trustStore); + + tmList = trustManagerFactory.getTrustManagers(); + } else { + LOG.error("Unable to obtain truststore from file [" + truststoreFile + "]"); + } + } catch (KeyStoreException e) { + LOG.error("Unable to obtain from KeyStore", e); + } catch (NoSuchAlgorithmException e) { + LOG.error("SSL algorithm is NOT available in the environment :" + e.getMessage(), e); + } catch (CertificateException e) { + LOG.error("Unable to obtain the requested certification :" + e.getMessage(), e); + } catch (FileNotFoundException e) { + LOG.error("Unable to find the necessary TLS TrustStore File:" + truststoreFile, e); + } catch (IOException e) { + LOG.error("Unable to read the necessary TLS TrustStore Files :" + truststoreFile, e); + } finally { + close(in, truststoreFile); + } + } + + }catch (IOException exception) { + LOG.error(exception.getMessage(), exception); + } + return tmList; + } + + private InputStream getFileInputStream(String fileName) throws IOException { + InputStream in = null; + if (StringUtils.isNotEmpty(fileName)) { + File f = new File(fileName); + if (f.exists()) { + in = new FileInputStream(f); + } else { + in = ClassLoader.getSystemResourceAsStream(fileName); + } + } + return in; + } + + /** + * Closing file-stream. + * @param str + * @param filename + */ + private void close(InputStream str, String filename) { + if (str != null) { + try { + str.close(); + } catch (IOException excp) { + LOG.error("Error while closing file: [" + filename + "]", excp); + } + } + } +} diff --git a/tools/atlas-index-repair/src/main/java/org/apache/atlas/tools/RepairIndex.java b/tools/atlas-index-repair/src/main/java/org/apache/atlas/tools/RepairIndex.java index 37565188e..8a8e8cafc 100644 --- a/tools/atlas-index-repair/src/main/java/org/apache/atlas/tools/RepairIndex.java +++ b/tools/atlas-index-repair/src/main/java/org/apache/atlas/tools/RepairIndex.java @@ -26,7 +26,9 @@ import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo; import org.apache.atlas.repository.graphdb.AtlasVertex; import org.apache.atlas.repository.graphdb.janus.AtlasJanusGraphDatabase; import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2; +import org.apache.atlas.security.SecurityProperties; import org.apache.atlas.utils.AuthenticationUtil; +import org.apache.atlas.utils.SSLUtil; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.Options; @@ -99,6 +101,9 @@ public class RepairIndex { private static void process(String guid) throws Exception { RepairIndex repairIndex = new RepairIndex(); + SSLUtil sslUtil = new SSLUtil(); + sslUtil.setSSLContext(); + setupGraph(); if (isSelectiveRestore) {