mirror of
https://github.com/Graylog2/graylog2-server.git
synced 2026-03-13 09:32:21 +08:00
Refactoring/opensearch security setup (#16087)
* Start datanode jersey only after ssl configuration resolved, listen to change events * Adapted DatanodeSecuritySetupIT to work with https version of the datanode interface * simplify hostnames in DatanodeSecuritySetupIT * code cleanup * added changelog * code cleanup * disable security plugin and perf analyzer in matrix tests opensearch * Fixed datanode jersey service * Fixed opensearch instance env * Opensearch security setup refactored * code cleanup * removed commented out code from datanodes JerseyService * add fqdn to the http cert in the DatanodeSecuritySetupIT * configure truststore only if the security is enabled * code cleanup * reintroduced root certificate finder * adjusted class and methods visibility of RootCertificateFinder
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.graylog.datanode.configuration;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.bouncycastle.asn1.x500.X500Name;
|
||||
import org.bouncycastle.cert.X509CertificateHolder;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||
@@ -24,13 +25,16 @@ import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
|
||||
import org.bouncycastle.operator.ContentSigner;
|
||||
import org.bouncycastle.operator.OperatorCreationException;
|
||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
import org.graylog.datanode.configuration.variants.KeystoreInformation;
|
||||
import org.graylog.security.certutil.CertConstants;
|
||||
import org.graylog.security.certutil.keystore.storage.KeystoreContentMover;
|
||||
import org.graylog.security.certutil.keystore.storage.KeystoreFileStorage;
|
||||
import org.graylog.security.certutil.keystore.storage.location.KeystoreFileLocation;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.file.Path;
|
||||
import java.security.GeneralSecurityException;
|
||||
@@ -41,7 +45,6 @@ import java.security.cert.X509Certificate;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -51,33 +54,23 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
|
||||
public class TruststoreCreatorTest {
|
||||
|
||||
private TruststoreCreator toTest;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
toTest = new TruststoreCreator();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTrustStoreCreation(@TempDir Path tempDir) throws Exception {
|
||||
final Path trustStoreFile = tempDir.resolve("truststore.sec");
|
||||
final char[] truststorePassword = "caramba! caramba!".toCharArray();
|
||||
|
||||
toTest.createTruststore(
|
||||
Map.of(
|
||||
"root", prepareSimpleCert("CN=ROOT", BigInteger.ONE),
|
||||
"boot", prepareSimpleCert("CN=BOOT", BigInteger.TWO)
|
||||
),
|
||||
truststorePassword,
|
||||
trustStoreFile);
|
||||
final KeystoreInformation root = createKeystore(tempDir.resolve("root.p12"), "root","CN=ROOT", BigInteger.ONE);
|
||||
final KeystoreInformation boot = createKeystore(tempDir.resolve("boot.p12"), "boot","CN=BOOT", BigInteger.TWO);
|
||||
|
||||
assertTrue(trustStoreFile.toFile().exists());
|
||||
final KeystoreInformation truststore = TruststoreCreator.newTruststore()
|
||||
.addRootCert("root", root, "root")
|
||||
.addRootCert("boot", boot, "boot")
|
||||
.persist(tempDir.resolve("truststore.sec"), "caramba! caramba!".toCharArray());
|
||||
|
||||
assertTrue(truststore.location().toFile().exists());
|
||||
|
||||
KeystoreFileStorage keystoreFileStorage = new KeystoreFileStorage(mock(KeystoreContentMover.class));
|
||||
final Optional<KeyStore> keyStoreOptional = keystoreFileStorage.readKeyStore(new KeystoreFileLocation(trustStoreFile), truststorePassword);
|
||||
final Optional<KeyStore> keyStoreOptional = keystoreFileStorage.readKeyStore(new KeystoreFileLocation(truststore.location()), truststore.password());
|
||||
|
||||
assertTrue(keyStoreOptional.isPresent());
|
||||
|
||||
@@ -102,7 +95,7 @@ public class TruststoreCreatorTest {
|
||||
assertEquals(cnName, x509Certificate.getIssuerX500Principal().getName());
|
||||
}
|
||||
|
||||
private X509Certificate prepareSimpleCert(final String cnName, final BigInteger serialNumber) throws GeneralSecurityException, OperatorCreationException {
|
||||
private KeystoreInformation createKeystore(Path path, String alias, final String cnName, final BigInteger serialNumber) throws GeneralSecurityException, OperatorCreationException, IOException {
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(KEY_GENERATION_ALGORITHM);
|
||||
java.security.KeyPair certKeyPair = keyGen.generateKeyPair();
|
||||
X500Name name = new X500Name(cnName);
|
||||
@@ -117,8 +110,20 @@ public class TruststoreCreatorTest {
|
||||
|
||||
ContentSigner signer = new JcaContentSignerBuilder(SIGNING_ALGORITHM).build(certKeyPair.getPrivate());
|
||||
X509CertificateHolder certHolder = builder.build(signer);
|
||||
return new JcaX509CertificateConverter().getCertificate(certHolder);
|
||||
|
||||
final X509Certificate signedCert = new JcaX509CertificateConverter().getCertificate(certHolder);
|
||||
|
||||
KeyStore trustStore = KeyStore.getInstance(CertConstants.PKCS12);
|
||||
trustStore.load(null, null);
|
||||
|
||||
final char[] password = RandomStringUtils.randomAlphabetic(256).toCharArray();
|
||||
|
||||
trustStore.setKeyEntry(alias, certKeyPair.getPrivate(), password, new Certificate[]{signedCert});
|
||||
|
||||
|
||||
try (final FileOutputStream fileOutputStream = new FileOutputStream(path.toFile())) {
|
||||
trustStore.store(fileOutputStream, password);
|
||||
}
|
||||
return new KeystoreInformation(path, password);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,9 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.Path;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
@@ -65,7 +67,7 @@ public class DatanodeSecuritySetupIT {
|
||||
private Path httpCert;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
void setUp() throws UnknownHostException {
|
||||
|
||||
String containerHostname = "graylog-datanode-host-" + RandomStringUtils.random(8, "0123456789abcdef");
|
||||
// first generate a self-signed CA
|
||||
|
||||
Reference in New Issue
Block a user