-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add TLS CLI commands #41418
Add TLS CLI commands #41418
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -693,3 +693,193 @@ | |
%prod.quarkus.http.insecure-requests=disabled | ||
---- | ||
|
||
== Quarkus CLI commands and development CA (Certificate Authority) | ||
|
||
The TLS registry provides CLI commands to generate a development CA and trusted certificates. | ||
This avoids having to use self-signed certificates locally. | ||
|
||
[source, shell] | ||
---- | ||
> quarkus tls | ||
Install and Manage TLS development certificates | ||
Usage: tls [COMMAND] | ||
Commands: | ||
generate-quarkus-ca Generate Quarkus Dev CA certificate and private key. | ||
generate-certificate Generate a TLS certificate with the Quarkus Dev CA if | ||
available. | ||
---- | ||
|
||
In most cases, you generate the Quarkus Development CA once, and then generate certificates signed by this CA. | ||
The Quarkus Development CA is a Certificate Authority that can be used to sign certificates locally. | ||
It is only valid for development purposes and only trusted on the local machine. | ||
The generated CA is located in `$HOME/.quarkus/quarkus-dev-root-ca.pem`, and installed in the system trust store. | ||
Check warning on line 715 in docs/src/main/asciidoc/tls-registry-reference.adoc GitHub Actions / Linting with Vale
|
||
|
||
=== CA, signed vs. self-signed certificates | ||
Check warning on line 717 in docs/src/main/asciidoc/tls-registry-reference.adoc GitHub Actions / Linting with Vale
Check warning on line 717 in docs/src/main/asciidoc/tls-registry-reference.adoc GitHub Actions / Linting with Vale
Check warning on line 717 in docs/src/main/asciidoc/tls-registry-reference.adoc GitHub Actions / Linting with Vale
|
||
|
||
When developing with TLS, you can use two types of certificates: | ||
|
||
- a self-signed certificate: the certificate is signed by the same entity that uses it. It is not trusted by default. It's generally what we use when we don't have a CA, or don't want to dig too much into TLS. This is not a production setup, and may be used only for development. | ||
Check warning on line 721 in docs/src/main/asciidoc/tls-registry-reference.adoc GitHub Actions / Linting with Vale
|
||
- a signed certificate: the certificate is signed by a Certificate Authority (CA). The CA is a trusted entity that signs the certificate. The certificate is trusted by default. This is what we use in production. | ||
|
||
We could use self-signed certificate when running application locally, but it's not always convenient. | ||
Typically, browsers will not trust the certificate, and you will have to import it manually. | ||
`curl`, `wget`, `httpie` and other tools will also not trust the certificate. | ||
|
||
To avoid this, we can use a development CA to sign the certificates, and install it into the system trust store. | ||
Check warning on line 728 in docs/src/main/asciidoc/tls-registry-reference.adoc GitHub Actions / Linting with Vale
|
||
Thus, every certificate signed by this CA will be trusted by the system. | ||
Check warning on line 729 in docs/src/main/asciidoc/tls-registry-reference.adoc GitHub Actions / Linting with Vale
|
||
|
||
Quarkus makes it easy to generate a development CA and certificates signed by this CA. | ||
|
||
=== Generate a development CA | ||
|
||
The development CA is a Certificate Authority that can be used to sign certificates locally. | ||
Note that the generated CA is only valid for development purposes, and only trusted on the local machine. | ||
|
||
To generate a development CA, use the following command: | ||
|
||
[source, shell] | ||
---- | ||
quarkus tls generate-ca-certificate --install --renew --truststore | ||
---- | ||
|
||
`--install` installs the CA in the system trust store. | ||
Check warning on line 745 in docs/src/main/asciidoc/tls-registry-reference.adoc GitHub Actions / Linting with Vale
|
||
Windows, Mac and Linux (Fedora and Ubuntu) are supported. | ||
However, depending on your browser, you may need to import the generated CA manually. | ||
Check warning on line 747 in docs/src/main/asciidoc/tls-registry-reference.adoc GitHub Actions / Linting with Vale
Check warning on line 747 in docs/src/main/asciidoc/tls-registry-reference.adoc GitHub Actions / Linting with Vale
|
||
Refer to the browser documentation for more information. | ||
The generated CA is located in `$HOME/.quarkus/quarkus-dev-root-ca.pem`. | ||
|
||
WARNING: When installing the certificate, your system may ask for your password to install the certificate in the system trust store, or ask for confirmation in a dialog (on Windows). | ||
|
||
IMPORTANT: On Windows, makes sure you run from an elevated terminal (run as administrator) to install the CA in the system trust store. | ||
|
||
`--renew` renews the CA if it already exists. | ||
When this option is used, you need to re-generate the certificates that were signed by the CA, as the private key is changed. | ||
Note that if the CA expires, it will automatically be renewed (without passing `--renew`). | ||
|
||
`--truststore` also generates a PKCS12 trust store containing the CA certificate. | ||
|
||
=== Generate a trusted (signed) certificate | ||
|
||
Once you have installed the Quarkus Development CA, you can generate a trusted certificate. | ||
It will be signed by the Quarkus Development CA, and so trusted by your system. | ||
|
||
[source, shell] | ||
---- | ||
quarkus tls generate-certificate --name my-cert | ||
---- | ||
|
||
This generates a certificate signed by the Quarkus Development CA, and so if properly installed / imported, will be trusted by your system. | ||
|
||
The certificate is stored in `./.certs/`. | ||
cescoffier marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Two files are generated: | ||
|
||
- `$NAME-keystore.p12` - contains the private key and the certificate. It's password protected. | ||
- `$NAME-truststore.p12` - contains the CA certificate, that you can used as trust store (for test, for instance). | ||
|
||
More options are available: | ||
|
||
[source, shell] | ||
---- | ||
Usage: tls generate-certificate [-hrV] [-c=<cn>] [-d=<directory>] | ||
-n=<name> [-p=<password>] | ||
Generate a TLS certificate with the Quarkus Dev CA if available. | ||
-c, --cn=<cn> The common name of the certificate. Default is 'localhost' | ||
-d, --directory=<directory> | ||
The directory in which the certificates will be created. | ||
Default is `.certs` | ||
-n, --name=<name> Name of the certificate. It will be used as file name and | ||
alias in the keystore | ||
-p, --password=<password> | ||
The password of the keystore. Default is 'password' | ||
-r, --renew Whether existing certificates will need to be replaced | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it have value to be able to generate a certificate from a given CA? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you mean a CA you already own? I would need the private key. I would rather not do that for security reasons. |
||
---- | ||
|
||
When generating the certificate, a `.env` file is also generated making the Quarkus dev mode aware of these certificates. | ||
So, then, if you run your application in dev mode, it will use these certificates: | ||
|
||
[source, shell] | ||
---- | ||
./mvnw quarkus:dev | ||
... | ||
INFO [io.quarkus] (Quarkus Main Thread) demo 1.0.0-SNAPSHOT on JVM (powered by Quarkus 999-SNAPSHOT) started in 1.286s. Listening on: http://localhost:8080 and https://localhost:8443 | ||
---- | ||
|
||
Now, you can open the Dev UI using HTTPS: `https://localhost:8443/q/dev`, or issue a request using `curl`: | ||
|
||
[source, shell] | ||
---- | ||
curl https://localhost:8443/hello | ||
Hello from Quarkus REST% | ||
---- | ||
|
||
IMPORTANT: If the Quarkus Development CA is not installed, a self-signed certificate is generated. | ||
|
||
|
||
=== Generating a self-signed certificate | ||
|
||
Even if the Quarkus Development CA is installed, you can generate a self-signed certificate: | ||
|
||
[source, shell] | ||
---- | ||
quarkus tls generate-certificate --name my-cert --self-signed | ||
---- | ||
|
||
This generates a self-signed certificate, not signed by the Quarkus Development CA. | ||
|
||
=== Uninstalling the Quarkus Development CA | ||
|
||
Uninstalling the Quarkus Development CA from your system depends on your OS. | ||
|
||
==== Deleting the CA certificate on Windows | ||
|
||
To delete the CA certificate on Windows, use the following commands from a Powershell terminal with administrator rights: | ||
|
||
[source, shell] | ||
---- | ||
# First, we need to identify the serial number of the CA certificate | ||
> certutil -store -user Root | ||
root "Trusted Root Certification Authorities" | ||
================ Certificate 0 ================ | ||
Serial Number: 019036d564c8 | ||
Issuer: O=Quarkus, CN=quarkus-dev-root-ca # <-That's the CA, copy the Serial Number (the line above) | ||
NotBefore: 6/19/2024 11:07 AM | ||
NotAfter: 6/20/2025 11:07 AM | ||
Subject: C=Cloud, S=world, L=home, OU=Quarkus Dev, O=Quarkus Dev, CN=quarkus-dev-root-ca | ||
Signature matches Public Key | ||
Non-root Certificate uses same Public Key as Issuer | ||
Cert Hash(sha1): 3679bc95b613a2112a3d3256fe8321b6eccce720 | ||
No key provider information | ||
Cannot find the certificate and private key for decryption. | ||
CertUtil: -store command completed successfully. | ||
|
||
> certutil -delstore -user -v Root $Serial_Number | ||
---- | ||
|
||
Replace `$Serial_Number` with the serial number of the CA certificate. | ||
|
||
==== Deleting the CA certificate on Linux | ||
|
||
On Fedora, you can use the following command: | ||
|
||
[source, shell] | ||
---- | ||
sudo rm /etc/pki/ca-trust/source/anchors/quarkus-dev-root-ca.pem | ||
sudo update-ca-trust | ||
---- | ||
|
||
On Ubuntu, you can use the following command: | ||
|
||
[source, shell] | ||
---- | ||
sudo rm /usr/local/share/ca-certificates/quarkus-dev-root-ca.pem | ||
sudo update-ca-certificates | ||
---- | ||
|
||
==== Deleting the CA certificate on Mac | ||
|
||
On Mac, you can use the following command: | ||
|
||
[source, shell] | ||
---- | ||
sudo security -v remove-trusted-cert -d /Users/clement/.quarkus/quarkus-dev-root-ca.pem | ||
---- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
<?xml version="1.0"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-tls-registry-parent</artifactId> | ||
<version>999-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>quarkus-tls-registry-cli</artifactId> | ||
<name>Quarkus - TLS Registry - CLI</name> | ||
|
||
<properties> | ||
<main.class>io.quarkus.tls.cli.TlsCommand</main.class> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>info.picocli</groupId> | ||
<artifactId>picocli</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>io.smallrye.certs</groupId> | ||
<artifactId>smallrye-certificate-generator</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter-engine</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<configuration> | ||
<compilerArgs> | ||
<arg>-parameters</arg> | ||
</compilerArgs> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-surefire-plugin</artifactId> | ||
<configuration> | ||
<systemPropertyVariables> | ||
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager> | ||
<maven.home>${maven.home}</maven.home> | ||
</systemPropertyVariables> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-assembly-plugin</artifactId> | ||
|
||
<configuration> | ||
<descriptorRefs> | ||
<descriptorRef>jar-with-dependencies</descriptorRef> | ||
</descriptorRefs> | ||
<finalName>${project.artifactId}-${project.version}</finalName> | ||
<appendAssemblyId>false</appendAssemblyId> | ||
<archive> | ||
<manifest> | ||
<addClasspath>true</addClasspath> | ||
<mainClass>${main.class}</mainClass> | ||
</manifest> | ||
</archive> | ||
</configuration> | ||
|
||
<executions> | ||
<execution> | ||
<id>make-assembly</id> | ||
<phase>package</phase> | ||
<goals> | ||
<goal>single</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
|
||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package io.quarkus.tls.cli; | ||
|
||
import java.io.File; | ||
|
||
public interface Constants { | ||
|
||
String CA_FILE_NAME = "quarkus-dev-root-ca.pem"; | ||
String PK_FILE_NAME = "quarkus-dev-root-key.pem"; | ||
String KEYSTORE_FILE_NAME = "quarkus-dev-keystore.p12"; | ||
|
||
File BASE_DIR = new File(System.getenv("HOME"), ".quarkus"); | ||
|
||
File CA_FILE = new File(BASE_DIR, CA_FILE_NAME); | ||
File PK_FILE = new File(BASE_DIR, PK_FILE_NAME); | ||
File KEYSTORE_FILE = new File(BASE_DIR, KEYSTORE_FILE_NAME); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could optionally pull the
generate-
prefix as an intermediate sub-command:quarkus tls generate qukarus-ca quarkus tls generate certificate ```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. What's the recommendation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would keep it as it is for now. They are fundamentally different operations.