Skip to content

Commit

Permalink
[ARTEMIS-5219] load all certificates
Browse files Browse the repository at this point in the history
In the JAAS login module for Kubernetes, the current implementation is
loading only a single CA from the bundle that is given by OpenShift,
which in turn leads to an issue where the broker don't find a proper
PKIX path.

This is fixing the issue by loading every certificates from the bundle.

The commit also brings in a new command line that can be used to
test if pod is well configured to perform token reviews or not.
  • Loading branch information
lavocatt committed Dec 17, 2024
1 parent 7eaea5a commit 2577fc8
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.apache.activemq.artemis.cli.commands.PrintVersion;
import org.apache.activemq.artemis.cli.commands.Run;
import org.apache.activemq.artemis.cli.commands.Stop;
import org.apache.activemq.artemis.cli.commands.TokenReview;
import org.apache.activemq.artemis.cli.commands.Upgrade;
import org.apache.activemq.artemis.cli.commands.activation.ActivationGroup;
import org.apache.activemq.artemis.cli.commands.address.AddressGroup;
Expand All @@ -53,6 +54,7 @@
import org.apache.activemq.artemis.cli.commands.messages.perf.PerfGroup;
import org.apache.activemq.artemis.cli.commands.queue.QueueGroup;
import org.apache.activemq.artemis.cli.commands.tools.DataGroup;
import org.apache.activemq.artemis.cli.commands.tools.Kubernetes;
import org.apache.activemq.artemis.cli.commands.tools.journal.PerfJournal;
import org.apache.activemq.artemis.cli.commands.user.UserGroup;
import org.apache.activemq.artemis.dto.ManagementContextDTO;
Expand Down Expand Up @@ -308,6 +310,8 @@ public static CommandLine buildCommand(boolean includeInstanceCommands, boolean

commandLine.addSubcommand(new Completion());

commandLine.addSubcommand(new Kubernetes(commandLine));

return commandLine;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* 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.
*/

package org.apache.activemq.artemis.cli.commands;

import org.apache.activemq.artemis.spi.core.security.jaas.kubernetes.client.KubernetesClient;
import org.apache.activemq.artemis.spi.core.security.jaas.kubernetes.client.KubernetesClientImpl;
import picocli.CommandLine;

@CommandLine.Command(name = "token-review", description = "Perform a kubernetes token review")
public class TokenReview extends InputAbstract {

@CommandLine.Option(names = "--kube-host", description = "hostname for kubernetes api server")
protected String kubeHost;

@CommandLine.Option(names = "--kube-port", description = "port for kubernetes api server")
protected String kubeport;

@CommandLine.Option(names = "--token-path", description = "path to the token to access the kubernetes api server with access to token reviews")
protected String tokenpath;

@CommandLine.Option(names = "--ca-path", description = "path to the kubernetes api server trusted CAs")
protected String capath;

@CommandLine.Option(names = "--token", description = "token to review")
protected String token;

@Override
public Object execute(ActionContext context) throws Exception {
super.execute(context);

context.out.println();
if (kubeHost == null) {
kubeHost = input("--kube-host", "What is the cluster host?", "api.crc.testing");
}
if (kubeport == null) {
kubeport = input("--kube-port", "What is the cluster port?", "6443");
}
if (tokenpath == null) {
tokenpath = input("--token-path", "What is the token path?", "/var/run/secrets/kubernetes.io/serviceaccount/token");
}
if (capath == null) {
capath = input("--ca-path", "What is the ca path?", "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt");
}
if (token == null) {
token = input("--token", "What is the token?", "sha256~Cg_LIHObUgJHvF_Ziv9k9eHZQ3_UUNihRD9vA96hQKU");
}
String prevKSH = System.getProperty("KUBERNETES_SERVICE_HOST", kubeHost);
String prevKSP = System.getProperty("KUBERNETES_SERVICE_PORT", kubeport);
String prevTP = System.getProperty("KUBERNETES_TOKEN_PATH", tokenpath);
String prevCP = System.getProperty("KUBERNETES_CA_PATH", capath);
System.setProperty("KUBERNETES_SERVICE_HOST", kubeHost);
System.setProperty("KUBERNETES_SERVICE_PORT", kubeport);
System.setProperty("KUBERNETES_TOKEN_PATH", tokenpath);
System.setProperty("KUBERNETES_CA_PATH", capath);
try {
KubernetesClient client = new KubernetesClientImpl();
org.apache.activemq.artemis.spi.core.security.jaas.kubernetes.model.TokenReview tr = client.getTokenReview(token);
context.out.println("*******************************************************************************************************************************");
context.out.println("* Performing a token review on:");
context.out.println("* host:: " + kubeHost);
context.out.println("* port:: " + kubeport);
context.out.println("* tokenpath:: " + tokenpath);
context.out.println("* capath:: " + capath);
context.out.println("*");
context.out.println("* Result:");
context.out.println("* token:: " + token);
context.out.println("* username:: " + tr.getUsername());
context.out.println("*******************************************************************************************************************************");
context.out.println();
} finally {
System.setProperty("KUBERNETES_SERVICE_HOST", prevKSH);
System.setProperty("KUBERNETES_SERVICE_PORT", prevKSP);
System.setProperty("KUBERNETES_TOKEN_PATH", prevTP);
System.setProperty("KUBERNETES_CA_PATH", prevCP);
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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.
*/

package org.apache.activemq.artemis.cli.commands.tools;

import org.apache.activemq.artemis.cli.commands.HelpAction;
import org.apache.activemq.artemis.cli.commands.TokenReview;
import org.apache.activemq.artemis.cli.commands.tools.journal.CompactJournal;
import org.apache.activemq.artemis.cli.commands.tools.journal.DecodeJournal;
import org.apache.activemq.artemis.cli.commands.tools.journal.EncodeJournal;
import org.apache.activemq.artemis.cli.commands.tools.xml.XmlDataExporter;
import org.apache.activemq.artemis.cli.commands.tools.xml.XmlDataImporter;
import picocli.CommandLine;
import picocli.CommandLine.Command;

@Command(name = "kube", description = "use 'help kube' for sub commands list", subcommands = {TokenReview.class})
public class Kubernetes implements Runnable {

CommandLine commandLine;

public Kubernetes(CommandLine commandLine) {
this.commandLine = commandLine;
}

@Override
public void run() {
HelpAction.help(commandLine, "data");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Iterator;
import java.util.Scanner;
import java.util.UUID;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
Expand Down Expand Up @@ -160,9 +163,13 @@ private SSLContext buildSSLContext() throws Exception {
try (InputStream fis = new FileInputStream(certFile)) {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(fis);
Collection c = certFactory.generateCertificates(fis);
Iterator i = c.iterator();
trustStore.load(null, null);
trustStore.setCertificateEntry(certFile.getName(), certificate);
while (i.hasNext()) {
Certificate cert = (Certificate)i.next();
trustStore.setCertificateEntry(UUID.randomUUID().toString(), cert);
}
TrustManagerFactory tmFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmFactory.init(trustStore);
Expand Down

0 comments on commit 2577fc8

Please sign in to comment.