Session Ticket RFC 5077 hint no -- no lifetime advertised
SSL Session ID support no
Session Resumption Tickets no, ID: no
TLS clock skew Random values, no fingerprinting possible
Certificate Compression none
Client Authentication optional
CA List for Client Auth L=$$$,ドルCN=TLSGenSelfSignedtRootCA 2022年03月22日T11:27:45.010198
Signature Algorithm SHA256 with RSA
Server key size RSA 2048 bits (exponent is 65537)
Server key usage Digital Signature, Key Encipherment
Server extended key usage TLS Web Server Authentication
Serial 01 (OK: length 1)
Fingerprints SHA1 A4346FA6FDC61FCD4C0199EA14B8AE0F5D5121B1
SHA256 C81025DA6F9BB646239659420D58E73F62CEB7D2AD5AC13FF12A9DE057394953
Common Name (CN) [redacted]
subjectAltName (SAN) [redacted] localhost
Trust (hostname) Ok via SAN (same w/o SNI)
Chain of trust NOT ok (self signed CA in chain)
EV cert (experimental) no
Certificate Validity (UTC) 2779>= 60 days (2022年03月22日 07:27 --> 2032年03月19日 07:27)
>= 10 years is way too long
ETS/"eTLS", visibility info not present
Certificate Revocation List --
OCSP URI --
NOT ok -- neither CRL nor OCSP URI provided
OCSP stapling not offered
OCSP must staple extension --
DNS CAA RR (experimental) not offered
Certificate Transparency N/A
Certificates provided 2
Issuer TLSGenSelfSignedtRootCA 2022年03月22日T11:27:45.010198
Intermediate cert validity #1: ok> 40 days (2032年03月19日 07:27). $$$$ <-- $$$$
Intermediate Bad OCSP (exp.) Ok


Testing vulnerabilities

Heartbleed (CVE-2014-0160) not vulnerable (OK), no heartbeat extension
CCS (CVE-2014-0224) not vulnerable (OK)
Ticketbleed (CVE-2016-9244), experiment. (applicable only for HTTPS)
ROBOT Server does not support any cipher suites that use RSA key transport
Secure Renegotiation (RFC 5746) not vulnerable (OK)
Secure Client-Initiated Renegotiation not vulnerable (OK)
CRIME, TLS (CVE-2012-4929) not vulnerable (OK)
POODLE, SSL (CVE-2014-3566) not vulnerable (OK), no SSLv3 support
TLS_FALLBACK_SCSV (RFC 7507) No fallback possible (OK), TLS 1.3 is the only protocol
SWEET32 (CVE-2016-2183, CVE-2016-6329) not vulnerable (OK)
FREAK (CVE-2015-0204) not vulnerable (OK)
DROWN (CVE-2016-0800, CVE-2016-0703) not vulnerable on this host and port (OK)
make sure you don't use this certificate elsewhere with SSLv2 enabled services, see
https://search.censys.io/search?resource=hosts&virtual_hosts=INCLUDE&q=C81025DA6F9BB646239659420D58E73F62CEB7D2AD5AC13FF12A9DE057394953
LOGJAM (CVE-2015-4000), experimental not vulnerable (OK): no DH EXPORT ciphers, no DH key detected with <= TLS 1.2
BEAST (CVE-2011-3389) not vulnerable (OK), no SSL3 or TLS1
LUCKY13 (CVE-2013-0169), experimental not vulnerable (OK)
Winshock (CVE-2014-6321), experimental not vulnerable (OK)
RC4 (CVE-2013-2566, CVE-2015-2808) not vulnerable (OK)

Could not determine the protocol, only simulating generic clients.

Running client simulations via sockets

Browser Protocol Cipher Suite Name (OpenSSL) Forward Secrecy
------------------------------------------------------------------------------------------------
Android 8.1 (native) No connection
Android 9.0 (native) TLSv1.3 TLS_AES_128_GCM_SHA256 253 bit ECDH (X25519)
Android 10.0 (native) TLSv1.3 TLS_AES_128_GCM_SHA256 253 bit ECDH (X25519)
Android 11 (native) TLSv1.3 TLS_AES_128_GCM_SHA256 253 bit ECDH (X25519)
Android 12 (native) TLSv1.3 TLS_AES_128_GCM_SHA256 253 bit ECDH (X25519)
Java 7u25 No connection
Java 8u161 No connection
Java 11.0.2 (OpenJDK) TLSv1.3 TLS_AES_128_GCM_SHA256 256 bit ECDH (P-256)
Java 17.0.3 (OpenJDK) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519)
go 1.17.8 TLSv1.3 TLS_AES_128_GCM_SHA256 253 bit ECDH (X25519)
LibreSSL 2.8.3 (Apple) No connection
OpenSSL 1.0.2e No connection
OpenSSL 1.1.0l (Debian) No connection
OpenSSL 1.1.1d (Debian) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519)
OpenSSL 3.0.3 (git) TLSv1.3 TLS_AES_256_GCM_SHA384 253 bit ECDH (X25519)

Evaluation of a TLS 1.2 Setup with Restricted Cipher Suites

The following example configuration that accepts TLSv1.2 connections passes key testssl.sh tests on Erlang 26.2:

listeners.ssl.default = 5671
ssl_options.cacertfile = /path/to/ca_certificate.pem
ssl_options.certfile = /path/to/server_certificate.pem
ssl_options.keyfile = /path/to/server_key.pem
ssl_options.versions.1 = tlsv1.2

ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = false

ssl_options.honor_cipher_order = true
ssl_options.honor_ecc_order = true

# These are highly recommended for TLSv1.2 but cannot be used
# with TLSv1.3. If TLSv1.3 is enabled, these lines MUST be removed.
ssl_options.client_renegotiation = false
ssl_options.secure_renegotiate = true

ssl_options.ciphers.1 = ECDHE-ECDSA-AES256-GCM-SHA384
ssl_options.ciphers.2 = ECDHE-RSA-AES256-GCM-SHA384
ssl_options.ciphers.3 = ECDH-ECDSA-AES256-GCM-SHA384
ssl_options.ciphers.4 = ECDH-RSA-AES256-GCM-SHA384
ssl_options.ciphers.5 = DHE-RSA-AES256-GCM-SHA384
ssl_options.ciphers.6 = DHE-DSS-AES256-GCM-SHA384
ssl_options.ciphers.7 = ECDHE-ECDSA-AES128-GCM-SHA256
ssl_options.ciphers.8 = ECDHE-RSA-AES128-GCM-SHA256
ssl_options.ciphers.9 = ECDH-ECDSA-AES128-GCM-SHA256
ssl_options.ciphers.10 = ECDH-RSA-AES128-GCM-SHA256
ssl_options.ciphers.11 = DHE-RSA-AES128-GCM-SHA256
ssl_options.ciphers.12 = DHE-DSS-AES128-GCM-SHA256

This TLSv1.2-enabled setup is reported as not vulnerable to a set of known high profile vulnerabilities:

Using "OpenSSL 3.3.1 4 Jun 2024 (Library: OpenSSL 3.3.1 4 Jun 2024)" [~94 ciphers]
on [redacted]:/opt/homebrew/bin/openssl
(built: "Jun 4 12:53:04 2024", platform: "darwin64-arm64-cc")


Start 2024年08月08日 13:42:36 -->> 127.0.0.1:5671 (localhost) <<--

A record via: /etc/hosts
rDNS (127.0.0.1): localhost.
Service detected: certificate-based authentication without providing client certificate and private key => skipping all HTTP checks


Testing protocols via sockets except NPN+ALPN

SSLv2 not offered (OK)
SSLv3 not offered (OK)
TLS 1 not offered
TLS 1.1 not offered
TLS 1.2 offered (OK)
TLS 1.3 not offered and downgraded to a weaker protocol
NPN/SPDY not offered
ALPN/HTTP2 not offered

Testing cipher categories

NULL ciphers (no encryption) not offered (OK)
Anonymous NULL Ciphers (no authentication) not offered (OK)
Export ciphers (w/o ADH+NULL) not offered (OK)
LOW: 64 Bit + DES, RC[2,4], MD5 (w/o export) not offered (OK)
Triple DES Ciphers / IDEA not offered
Obsoleted CBC ciphers (AES, ARIA etc.) not offered
Strong encryption (AEAD ciphers) with no FS not offered
Forward Secrecy strong encryption (AEAD ciphers) offered (OK)


Testing server's cipher preferences

Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits Cipher Suite Name (IANA/RFC)
-----------------------------------------------------------------------------------------------------------------------------
SSLv2
-
SSLv3
-
TLSv1
-
TLSv1.1
-
TLSv1.2 (server order)
xc030 ECDHE-RSA-AES256-GCM-SHA384 ECDH 253 AESGCM 256 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
x9f DHE-RSA-AES256-GCM-SHA384 DH 2048 AESGCM 256 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
xc02f ECDHE-RSA-AES128-GCM-SHA256 ECDH 253 AESGCM 128 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
x9e DHE-RSA-AES128-GCM-SHA256 DH 2048 AESGCM 128 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLSv1.3
-

Has server cipher order? yes (OK)


Testing robust forward secrecy (FS) -- omitting Null Authentication/Encryption, 3DES, RC4

FS is offered (OK) ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256
Elliptic curves offered: prime256v1 secp384r1 secp521r1 brainpoolP256r1 brainpoolP384r1 brainpoolP512r1 X25519 X448
DH group offered: RFC3526/Oakley Group 14 (2048 bits)
TLS 1.2 sig_algs offered: RSA+SHA256 RSA+SHA384 RSA+SHA512 RSA-PSS-RSAE+SHA256

Testing server defaults (Server Hello)

TLS extensions (standard) "renegotiation info/#65281" "EC point formats/#11" "max fragment length/#1"
Session Ticket RFC 5077 hint no -- no lifetime advertised
SSL Session ID support yes
Session Resumption Tickets no, Client Auth: ID resumption test not supported
TLS clock skew -1 sec from localtime
Client Authentication required
CA List for Client Auth L=$$$,ドルCN=TLSGenSelfSignedtRootCA 2022年03月22日T11:27:45.010198
Signature Algorithm SHA256 with RSA
Server key size RSA 2048 bits (exponent is 65537)
Server key usage Digital Signature, Key Encipherment
Server extended key usage TLS Web Server Authentication
Serial 01 (OK: length 1)
Fingerprints SHA1 A4346FA6FDC61FCD4C0199EA14B8AE0F5D5121B1
SHA256 C81025DA6F9BB646239659420D58E73F62CEB7D2AD5AC13FF12A9DE057394953
Common Name (CN) [redacted]
subjectAltName (SAN) [redacted] localhost
Trust (hostname) Ok via SAN (same w/o SNI)
Chain of trust NOT ok (self signed CA in chain)
EV cert (experimental) no
Certificate Validity (UTC) 2779>= 60 days (2022年03月22日 07:27 --> 2032年03月19日 07:27)
>= 10 years is way too long
ETS/"eTLS", visibility info not present
Certificate Revocation List --
OCSP URI --
NOT ok -- neither CRL nor OCSP URI provided
OCSP stapling not offered
OCSP must staple extension --
DNS CAA RR (experimental) not offered
Certificate Transparency --
Certificates provided 2
Issuer TLSGenSelfSignedtRootCA 2022年03月22日T11:27:45.010198
Intermediate cert validity #1: ok> 40 days (2032年03月19日 07:27). $$$$ <-- $$$$
Intermediate Bad OCSP (exp.) Ok


Testing vulnerabilities

Heartbleed (CVE-2014-0160) not vulnerable (OK), no heartbeat extension
CCS (CVE-2014-0224) not vulnerable (OK)
Ticketbleed (CVE-2016-9244), experiment. not vulnerable (OK), no session ticket extension
ROBOT Server does not support any cipher suites that use RSA key transport
Secure Renegotiation (RFC 5746) supported (OK)
Secure Client-Initiated Renegotiation not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested
CRIME, TLS (CVE-2012-4929) not vulnerable (OK)
BREACH (CVE-2013-3587) not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested
POODLE, SSL (CVE-2014-3566) not vulnerable (OK), no SSLv3 support
TLS_FALLBACK_SCSV (RFC 7507) No fallback possible (OK), no protocol below TLS 1.2 offered
SWEET32 (CVE-2016-2183, CVE-2016-6329) not vulnerable (OK)
FREAK (CVE-2015-0204) not vulnerable (OK)
DROWN (CVE-2016-0800, CVE-2016-0703) not vulnerable on this host and port (OK)
make sure you don't use this certificate elsewhere with SSLv2 enabled services, see
https://search.censys.io/search?resource=hosts&virtual_hosts=INCLUDE&q=C81025DA6F9BB646239659420D58E73F62CEB7D2AD5AC13FF12A9DE057394953
LOGJAM (CVE-2015-4000), experimental common prime with 2048 bits detected: RFC3526/Oakley Group 14 (2048 bits),
but no DH EXPORT ciphers
BEAST (CVE-2011-3389) not vulnerable (OK), no SSL3 or TLS1
LUCKY13 (CVE-2013-0169), experimental not vulnerable (OK)
Winshock (CVE-2014-6321), experimental not vulnerable (OK) - CAMELLIA or ECDHE_RSA GCM ciphers found
RC4 (CVE-2013-2566, CVE-2015-2808) no RC4 ciphers detected (OK)

Could not determine the protocol, only simulating generic clients.

Running client simulations via sockets

Browser Protocol Cipher Suite Name (OpenSSL) Forward Secrecy
------------------------------------------------------------------------------------------------
Android 8.1 (native) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519)
Android 9.0 (native) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519)
Android 10.0 (native) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519)
Android 11 (native) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519)
Android 12 (native) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519)
Java 7u25 No connection
Java 8u161 TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 521 bit ECDH (P-521)
Java 11.0.2 (OpenJDK) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 521 bit ECDH (P-521)
Java 17.0.3 (OpenJDK) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519)
go 1.17.8 TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519)
LibreSSL 2.8.3 (Apple) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519)
OpenSSL 1.0.2e TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 521 bit ECDH (P-521)
OpenSSL 1.1.0l (Debian) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519)
OpenSSL 1.1.1d (Debian) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519)
OpenSSL 3.0.3 (git) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 253 bit ECDH (X25519)

TLS Certificate and Private Key Rotation

Server TLS certificates (public keys) and private keys have expiration dates and will need to be replaced (rotated) every so often.

The replacement process involves the following steps:

  1. Replace the files on disk
  2. Clear the certificate and private key store cache on the node

Without the second step, the new certificate/key pair will be used by the node after a period of time, as the TLS implementation in the runtimes purges its certificate store cache.

Replacing Certificate and Private Key Files on Disk

Simply replace the server certificate, server private key and (if needed) the certificate authority bundle files with their new versions.

Clearing the Certificate and Private Key Store Cache

rabbitmqctl eval-n[target-node@hostname]'ssl:clear_pem_cache().'

The Trust Store Plugin

In some environments, there's a set of leaf (client) trusted certificates that must be trusted and that's it, the chain is not traversed and the traditional trust roots (CAs) are not used.

This approach is often used in environments where client certificates are also used as identities, must be unique, and churn (change: some are added, others removed) often.

rabbitmq_trust_store is a plugin that overrides the peer verification algorithm to do just that: verify that the connected client's certificate belongs to a set (a whitelist).

The whitelist comes from either a local filesystem directory or an HTTP API endpoint that follows a small set of conventions. The list is refreshed at a configurable interval, allowing certificates to be added or removed without restarting the node or affecting existing connections.

Certificate Providers

The trust store supports two sources (providers) of trusted leaf client certificates:

Filesystem Provider

To use the filesystem provider, configure a directory that contains the trusted client certificates in the PEM format:

# will monitor `/path/to/trust-store/whitelist` for files additions and deletion
trust_store.directory = /path/to/trust-store/whitelist
# scan the above directory every 30 seconds
trust_store.refresh_interval = 30

Setting refresh_interval to 0 will disable automatic reloading.

HTTP Provider

To retrieve certificates from a remote HTTPS endpoint that follows certain convention:

trust_store.providers.1 = http
trust_store.url = https://certs.example.com/trusted
trust_store.refresh_interval = 30

Provider HTTP API

The remote server must expose an HTTP API that lists certificates and allows for fetching individual certificates.

GET <url> must respond with a 200 OK and the following body:

{
"certificates":[
{"id":"certificate-1","path":"/certificates/1.pem"},
{"id":"certificate-2","path":"/certificates/2.pem"}
// , ...
]
}

Certificate IDs must be valid filenames and be unique.

GET <url>/<relative-url>, such as "/certificates/1.pem" in the example above, must respond with a 200 OK and return a PEM-encoded certificate in its body.

The provider uses the If-Modified-Since header to avoid unnecessary re-downloads.

If the HTTPS endpoint itself authenticates clients using a x.509 certificate, configure its CA certificate bundle, public and private keys:

trust_store.ssl_options.certfile = /path/to/client/client_certificate.pem
trust_store.ssl_options.keyfile = /path/to/client/client_key.pem
trust_store.ssl_options.cacertfile = /path/to/ca/trusted_ca_bundle.pem

Finally, a request timeout can be set with trust_store.https_request_timeout.

Using the Trust Store for Client (x509) Certificate Authentication

The aforementioned Trust Store plugin and the rabbitmq_auth_mechanism_ssl plugin serve two complementary roles:

Combined with the EXTERNAL authentication mechanism, they allow clients to authenticate with just their x.509 certificate.

This setup requires two plugins to be enabled:

rabbitmq-plugins enable rabbitmq_trust_store
rabbitmq-plugins enable rabbitmq_auth_mechanism_ssl

Then configure TLS, the trust store, and the authentication mechanism in rabbitmq.conf:

# TLS listener
listeners.ssl.default = 5671

ssl_options.cacertfile = /path/to/ca_certificate.pem
ssl_options.certfile = /path/to/server_certificate.pem
ssl_options.keyfile = /path/to/server_key.pem
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = true

# Trust store: directory containing whitelisted client certificates
trust_store.directory = /path/to/trust-store/whitelist
trust_store.refresh_interval = 30

# Enable the EXTERNAL mechanism so clients can authenticate with a certificate
auth_mechanisms.1 = EXTERNAL
auth_mechanisms.2 = PLAIN

# Extract the username from the certificate's Common Name (CN) field.
# Other supported options: distinguished_name (default), subject_alternative_name
ssl_cert_login_from = common_name

The ssl_cert_login_from setting controls which field of the client certificate is used as the RabbitMQ username:

A RabbitMQ user matching the extracted name must exist in the configured authentication and authorisation backend(s).

When the EXTERNAL mechanism is used, the client-provided password is ignored.

Inspecting and Refreshing the Whitelist

To list currently loaded certificates:

rabbitmq-diagnostics list_trust_store_certificates

To manually trigger a whitelist refresh:

rabbitmqctl refresh_trust_store

TLS Session Caching

TLS session caching bypasses trust store certificate validation. When a client resumes a cached TLS session, the trust store is not consulted. To ensure that removed certificates are immediately rejected, disable TLS session caching:

ssl_options.reuse_sessions = false

Please refer to the plugin README for additional details and advanced configuration options.

Using TLS in the Erlang Client

Enabling TLS in the RabbitMQ Erlang client is similar to configuring other settings related to networking. The #amqp_params_network record provides a field, ssl_options, for all the standard Erlang TLS options.

Erlang TLS Options

The three important options which must be supplied are:

server_name_indication - set this option to the host name of the server to which a TLS connection will be made to enable "Server Name Indication" verification of the certificate presented by the server. This ensures that the server certificate's CN= value will be verified during TLS connection establishment. You can override this behavior by setting server_name_indication to a different host name or to the special value disable to disable this verification. Note that, by default, SNI is not enabled. This default will change in a future RabbitMQ Erlang client release.

verify - set this option to verify_peer to enable X509 certificate chain verification. The depth option configures certificate verification depth. Note that, by default, verify is set to verify_none, which disables certificate chain verification. This default will change in a future RabbitMQ Erlang client release.

Code Example

SslOpts=[{cacertfile,"/path/to/ca_certificate.pem"},
{certfile,"/path/to/client/certificate.pem"},
{keyfile,"/path/to/client/private_key.pem"},

%% only necessary with intermediate CAs
%% {depth, 2},

%% Note: it is recommended to set 'verify' to
%% to 'verify_peer' to ensure that X509
%% certificate chain validation is enabled
%%
%% Do not set 'verify' or set it to verify_none
%% if x509 certificate chain validation is
%% not desired
{verify,verify_peer},

%% If Server Name Indication validation is desired,
%% set the following option to the host name to which
%% the connection is made. If necessary, this option
%% may be set to another host name to match the server
%% certificate's CN= value.
%% Do not set this option or set it to the atom 'disable'
%% to disable SNI validation
{server_name_indication,"my.rmq-server.net"}],

Params=#amqp_params_network{host="my.rmq-server.net",
port=5671,
ssl_options=SslOpts}

{ok,Conn}=amqp_connection:start(Params),

You can now go ahead and use Conn as a normal connection.

Manually Generating a CA, Certificates and Private Keys

This section of the guide explains how to generate a Certificate Authority and use it to generate and sign two certificate/key pairs, one for the server and one for client libraries. Note that the process can be automated using existing tools, which is recommended. This section is intended for those who would like to improve their understanding of the process, OpenSSL command line tools and some important aspects of OpenSSL configuration.

This guide assumes a UNIX-like operating system (Linux, MacOS, a BSD variant and so on) and a recent version of OpenSSL available in PATH.

First let's create a directory for our test Certificate Authority:

mkdir testca
cd testca
mkdir certs private
chmod700 private
echo 01 > serial
touch index.txt

Now add the following OpenSSL configuration file, openssl.cnf, within the newly created testca directory:

[ ca ]
default_ca = testca

[ testca ]
dir = .
certificate = $dir/ca_certificate.pem
database = $dir/index.txt
new_certs_dir = $dir/certs
private_key = $dir/private/ca_private_key.pem
serial = $dir/serial

default_crl_days = 7
default_days = 365
default_md = sha256

policy = testca_policy
x509_extensions = certificate_extensions

[ testca_policy ]
commonName = supplied
stateOrProvinceName = optional
countryName = optional
emailAddress = optional
organizationName = optional
organizationalUnitName = optional
domainComponent = optional

[ certificate_extensions ]
basicConstraints = CA:false

[ req ]
default_bits = 2048
default_keyfile = ./private/ca_private_key.pem
default_md = sha256
prompt = yes
distinguished_name = root_ca_distinguished_name
x509_extensions = root_ca_extensions

[ root_ca_distinguished_name ]
commonName = hostname

[ root_ca_extensions ]
basicConstraints = CA:true
keyUsage = keyCertSign, cRLSign

[ client_ca_extensions ]
basicConstraints = CA:false
keyUsage = digitalSignature,keyEncipherment
extendedKeyUsage = 1.3.6.1.5.5.7.3.2

[ server_ca_extensions ]
basicConstraints = CA:false
keyUsage = digitalSignature,keyEncipherment
extendedKeyUsage = 1.3.6.1.5.5.7.3.1

Next we need to generate the key and certificates that our test Certificate Authority will use. Still within the testca directory:

openssl req -x509-config openssl.cnf -newkey rsa:2048 -days365\
-out ca_certificate.pem -outform PEM -subj /CN=MyTestCA/ -nodes
openssl x509 -in ca_certificate.pem -out ca_certificate.cer -outform DER

This is all that is needed to generate a test Certificate Authority. The root certificate is in ca_certificate.pem and is also in testca/ca_certificate.cer. These two files contain the same information, but in different formats, PEM and DER. Most software uses the former but some tools require the latter.

Having set up our Certificate Authority, we now need to generate private keys and certificates for the clients and the server. RabbitMQ broker uses certificates and private keys in the PEM format. Some client libraries use the PEM format, others will require conversion to a different format (e.g. PKCS#12).

Java and .NET clients use a certificate format called PKCS#12 and custom certificate stores. Certificate store contains both the client's certificate and key. The PKCS store is usually password protected, and so that a password must be provided.

The process for creating server and client certificates is very similar. First the server:

cd..
ls
# => testca
mkdir server
cd server
openssl genrsa -out private_key.pem 2048
openssl req -new-key private_key.pem -out req.pem -outform PEM \
-subj /CN=$(hostname)/O=server/ -nodes
cd../testca
openssl ca -config openssl.cnf -in../server/req.pem -out\
../server/server_certificate.pem -notext-batch-extensions server_ca_extensions
cd../server
openssl pkcs12 -export-out server_certificate.p12 -in server_certificate.pem -inkey private_key.pem \
-passout pass:MySecretPassword

And now the client:

cd..
ls
# => server testca
mkdir client
cd client
openssl genrsa -out private_key.pem 2048
openssl req -new-key private_key.pem -out req.pem -outform PEM \
-subj /CN=$(hostname)/O=client/ -nodes
cd../testca
openssl ca -config openssl.cnf -in../client/req.pem -out\
../client/client_certificate.pem -notext-batch-extensions client_ca_extensions
cd../client
openssl pkcs12 -export-out client_certificate.p12 -in client_certificate.pem -inkey private_key.pem \
-passout pass:MySecretPassword

The two examples above generate private keys that are 2048 bits in size. It is possible to use longer (and thus more secure but also slower to generate) keys by providing a different value to openssl genrsa, e.g.:

openssl genrsa -out private_key.pem 4096

Another option would be to generate a key using Elliptic Curve Cryptography. Instead of openssl genrsa use openssl ecparam like so:

openssl ecparam -out private_key.pem -genkey-name prime256v1

prime256v1 in the example above is an Elliptic curve name. Different versions of OpenSSL will have a different set of curves available, list them with openssl ecparam -list_curves.

AltStyle によって変換されたページ (->オリジナル) /