Skip to content

Latest commit

 

History

History
305 lines (207 loc) · 10.4 KB

File metadata and controls

305 lines (207 loc) · 10.4 KB

Certificate Requests and Renewals for AMQP/mTLS

This guide continues from the manual steps in the main README.md.


Table of Contents

  1. Generate a New Certificate Request
  2. Convert Binary Certificate to Human Readable
  3. Certificate Format Conversion
  4. Import and Export Certificates
  5. Extract Private Key and Certificate from PFX
  6. Automate the Process
  7. Generate CSR on Different Host
  8. Test mTLS Authentication

Verify peer

Scenario Client settings Server Setting Will it work?
Strict mTLS (Default) verify_peer verify_peer ❌ No (Server rejects expired client cert)

Server-Only Relaxed verify_peer verify_none Yes (Client trusts server; Server ignores client cert date)

Full Relaxed verify_none verify_none Yes (Both sides ignore all dates and signatures)

If you want to keep your remote RabbitMQ server secure while allowing this expired client certificate to connect temporarily, you have two configuration options on the server side:

Option A: Set verify = verify_none on the Server

  • This tells the server to completely ignore all validation parameters for any client certificate sent to it.
verify_none

Stay with Certificate Auth (mTLS Bypass) If you want to keep using the certificate files (even though the client cert is expired), you must change verify=verify_peer to verify=verify_none in the client URI, and keep your certificate paths.

{uris, ["amqps://pdp-shovel-1@xx.xx.xx.xx:5671?cacertfile=C:\\testca_store\\bundle\\pdp-shovel-1.ca-bundle&certfile=C:\\testca_store\\client\\client_certificate.pem&keyfile=C:\\testca_store\\client\\private_key.pem&verify=verify_none&fail_if_no_peer_cert=true&server_name_indication=pdp-shovel-2&auth_mechanism=external&heartbeat=15"]}

Note: As we uncovered earlier, some Erlang/RabbitMQ combinations will still fail auth_mechanism=external under a global verify_none server setting because the identity parsing is skipped. If it fails, use Choice B).

Option B: Turn off Client Certificate Requirement entirely

  • Alternatively, if you don't want to change the global verification mode, you can change the server's rabbitmq.conf to stop demanding client certificates entirely:
ssl_options.fail_if_no_peer_cert = false

If you change the remote server's configuration to ssl_options.fail_if_no_peer_cert = false, it means the server no longer demands a client certificate. It will happily accept standard TLS connections that only use a username and password.

{uris, ["amqps://pdp-shovel-1:password@xx.xx.xx.xx:5671?cacertfile=C:\\testca_store\\bundle\\pdp-shovel-1.ca-bundle&verify=verify_peer&server_name_indication=pdp-shovel-2&heartbeat=15"]}

1. Generate a New Certificate Request

Use certreq to create a new certificate request:

certreq -new request.inf certificate.req

📖 Reference: certreq command documentation


2. Convert Binary Certificate to Human Readable

Convert a .crt binary certificate to .cer Base64 format:

certutil -encode C:\tmp\server01.corp.logo.com.crt C:\tmp\server01.corp.logo.com.cer

Expected output:

Input Length = 2205
Output Length = 3088
CertUtil: -encode command completed successfully

3. Certificate Format Conversion

Format Description
.pem Base64 encoded X.509 certificate (commonly used in Apache/Tomcat)
.crt Certificate file - can be Base64 or binary
.cer Certificate file - can be Base64 or binary
.der Binary format certificate
.pfx / .p12 PKCS12 bundle containing certificate, chain, and private key

Converting PEM to Other Formats

📖 Reference: SSL Shopper Converter

To convert PEM to .crt or .cer: Simply rename the file (if Base64 encoded is desired).

⚠️ A PEM encoded certificate is already valid - using .cert extension is not standard. Use .cer, .pem, or .crt instead.


4. Import and Export Certificates

Step 1: Import Certificate

When the CSR is approved, import the certificate in MMC:

  • Add to Personal certificate store
  • If the cert shows as invalid, import all CA certificates to the store

💡 The shovel server needs server auth (at minimum server auth is required, since role is reciever).

💡 The shovel client (server) needs both server auth and client auth (since role is connect and send).

Step 2: Handle Binary Format Certificates

If the certificate is binary (content does not start with -----BEGIN CERTIFICATE-----):

  1. Import the .cer to local MMC (add signers for verification)
  2. Export from MMC as Base64 encoded .cer

Step 3: Verify Validity

  • After importing all CAs, the personal certificate should be valid
  • If not found in MMC Personal, import directly to Personal tab

Step 4: Export as PFX

Export the personal certificate from MMC:

  • Format: PFX (include private key)
  • Include all certificates in the chain if possible
  • Save the password for OpenSSL operations

5. Extract Private Key and Certificate from PFX

Prerequisites

Check OpenSSL version:

cd "c:\Program Files\OpenSSL-Win64\bin"
openssl version
OpenSSL 3.1.4 24 Oct 2023 (Library: OpenSSL 3.1.4 24 Oct 2023)

✅ Recommended: OpenSSL 3.1.4 24 Oct 2023 (Library: OpenSSL 3.1.4 24 Oct 2023)or later

Extract Private Key

openssl pkcs12 -in myfile.pfx -nocerts -out private.key.pem -nodes

Enter the password used during MMC export when prompted.

Extract Certificate

openssl pkcs12 -in myfile.pfx -clcerts -nokeys -out public.crt.pem -nodes

Enter the same password.

Verify the Certificate

Check CN (must be hostname.domain.something):

openssl x509 -noout -subject -in public.crt.pem

Check expiration date:

openssl x509 -noout -enddate -in public.crt.pem

Example output: notAfter=Jan 27 10:36:48 2026 GMT

Check serial number:

openssl x509 -noout -serial -in public.crt.pem

**Check .crt vs key**
**Rename public.crt.pem to public.crt, 
# Check the .crt and .key files match by comparing the modulus of each file. If they match, the key pair is valid.
openssl x509 -noout -modulus -in C:\OP\SSL\public.crt | openssl sha256 && openssl rsa -noout -modulus -in C:\OP\SSL\private.key.pem | openssl sha256

cert key and pem

View CA Bundle

** You can get info about all certs in the bundle if you need to**

openssl storeutl -noout -text -certs C:\RabbitmqBaseFolder\cert\ca.bundle

6. Automate the Process tbd

For automated certificate requests, see README_auto_ps1.md.

Basic Commands

# Make request
certreq -new request.inf certificate.req

# Accept the issued certificate (links private key with certificate)
certreq -accept certnew.cer

ℹ️ The -accept parameter links the previously generated private key with the issued certificate and removes the pending request from the system.


7. Generate CSR on Different Host

Yes! You can generate the CSR and private key on a different host, then transfer both to your app host for mTLS.

** Just make sure that to check .crt vs key** **Rename public.crt.pem to public.crt,

# Check the .crt and .key files match by comparing the modulus of each file. If they match, the key pair is valid.
openssl x509 -noout -modulus -in C:\OP\SSL\public.crt | openssl sha256 && openssl rsa -noout -modulus -in C:\OP\SSL\private.key.pem | openssl sha256

Process Overview

  1. Generate on Host A (Secure Machine)

    • Create private key and CSR or .pfx file (this requires a password that follows with it)
    • Send CSR to Certificate Authority (CA)
    • Or generate cert and key local
  2. Get Signed Certificate

    • CA signs and returns the certificate
    • Or sign the cert and key local
  3. Transfer to App Host (Host B)

    • Securely copy private key and certificate or the pfx file
    • Use secure methods: scp, rsync over SSH
    • Verify that cert and key matches and that all atributtes are present

Important Notes

  • Windows Certificate Manager on Host B will not have the original enrollment request
  • The pending request will appear as "orphaned" - this is harmless
  • Best Practice: Delete unused "Certificate Enrollment Request" entries to keep the store clean

8. Test mTLS Authentication

Port Reference

Protocol Port Description
AMQP 5672 Unencrypted
AMQPS 5671 TLS-encrypted (often with mTLS)

Test with OpenSSL

Server Side (Simulated)

openssl s_server -accept 5671 -CAfile C:\path\to\cacert.pem -cert C:\path\to\server.cert.pem -key C:\path\to\server.key.pem -state

Client Side (Simulated)

openssl s_client -connect 127.0.0.1:5671 -key C:\path\to\client.key.pem -cert C:\path\to\client.cert.pem -CAfile C:\path\to\cacert.pem -state

Test Against Real Broker (e.g., RabbitMQ)

openssl s_client -connect your-broker-host:5671 -key C:\path\to\client.key.pem -cert C:\path\to\client.cert.pem -CAfile C:\path\to\cacert.pem -state

Interpreting Results

✅ Successful mTLS Handshake

  • OpenSSL output: Verify return code: 0 (ok)
  • RabbitMQ logs: Successful TLS handshake (may show AMQP protocol header error after - this is expected as s_client does not send AMQP frames)

❌ Failed Handshake

  • OpenSSL output: SSL alert error
    error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
    
  • RabbitMQ logs: TLS handshake error: tls_alert_certificate_unknown

⚠️ Running openssl s_client to test does NOT disturb or interrupt current traffic on your RabbitMQ server.

test ssl

Notes

  • Public key is embedded in the SSL certificate
  • Private key is stored on the server and kept secret
  • The Shovel server requires both server auth and client auth for full mTLS support