PageSourceSearch

https://www.rabbitmq.com/assets/js/3462ab2d.4883dde1.js

js rabbitmq.com collected 2026-10-01 06:33:33 UTC 28,942 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkrabbitmq_website=self.webpackChunkrabbitmq_website||[]).push([["2126"],{27995(e,n,i){i.r(n),i.d(n,{metadata:()=>t,default:()=>h,frontMatter:()=>o,contentTitle:()=>l,toc:()=>a,assets:()=>c});var t=JSON.parse('{"id":"troubleshooting-ssl","title":"Troubleshooting TLS-enabled Connections","description":"\x3c!--","source":"@site/versioned_docs/version-4.1/troubleshooting-ssl.md","sourceDirName":".","slug":"/troubleshooting-ssl","permalink":"/docs/4.1/troubleshooting-ssl","draft":false,"unlisted":false,"editUrl":"https://github.com/rabbitmq/rabbitmq-website/tree/main/versioned_docs/version-4.1/troubleshooting-ssl.md","tags":[],"version":"4.1","frontMatter":{"title":"Troubleshooting TLS-enabled Connections"},"sidebar":"docsSidebar","previous":{"title":"Troubleshooting Connectivity","permalink":"/docs/4.1/troubleshooting-networking"},"next":{"title":"Inter-node Heartbeats","permalink":"/docs/4.1/nettick"}}'),s=i(74848),r=i(28453);let o={title:"Troubleshooting TLS-enabled Connections"},l="Troubleshooting TLS-enabled Connections",c={},a=[{value:"Overview",id:"overview",level:2},{value:"Check Effective Node Configuration",id:"verify-config",level:2},{value:"Check TLS Listeners (Ports)",id:"verify-listeners",level:2},{value:"Check Certificate, Private Key and CA Bundle File Permissions",id:"verify-file-permissions",level:2},{value:"Check Certificate, Private Key and CA Bundle File Format",id:"verify-file-format",level:2},{value:"Check TLS Support in Erlang",id:"verify-tls-support-in-erlang",level:2},{value:"Use OpenSSL Tools to Test TLS Connections",id:"openssl-tools",level:2},{value:"Validate Available Cipher Suites",id:"verify-cipher-suites",level:2},{value:"Attempt TLS Connection to a RabbitMQ Node",id:"sclient-connection",level:2},{value:"Validate Client Connections with Stunnel",id:"stunnel",level:2},{value:"Validate RabbitMQ Client Connection to RabbitMQ Node",id:"client-connection",level:2},{value:"Certificate Chains and Verification Depth",id:"verify-verification-depth",level:2},{value:"Understanding TLS Connection Log Errors",id:"logs",level:2}];function d(e){let n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"troubleshooting-tls-enabled-connections",children:"Troubleshooting TLS-enabled Connections"})}),"\n",(0,s.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,s.jsxs)(n.p,{children:["This guide covers a methodology and some tooling that can help diagnose TLS connectivity issues and errors (TLS alerts).\nIt accompanies the main guide on ",(0,s.jsx)(n.a,{href:"./ssl",children:"TLS in RabbitMQ"}),".\nThe strategy is to test the required components with an alternative TLS\nimplementation in the process of elimination to identify the problematic end (client or server)."]}),"\n",(0,s.jsx)(n.p,{children:"Bear in mind that this process is not guaranteed to identify the problem if\nthe interaction between two specific components is responsible for the problem."}),"\n",(0,s.jsx)(n.p,{children:"The steps recommended in this guide are:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Verify ",(0,s.jsx)(n.a,{href:"#verify-config",children:"effective configuration"})]}),"\n",(0,s.jsxs)(n.li,{children:["Verify that the node ",(0,s.jsx)(n.a,{href:"#verify-listeners",children:"listens for TLS connections"})]}),"\n",(0,s.jsxs)(n.li,{children:["Verify ",(0,s.jsx)(n.a,{href:"#verify-file-permissions",children:"file permissions"})]}),"\n",(0,s.jsxs)(n.li,{children:["Verify ",(0,s.jsx)(n.a,{href:"#verify-file-format",children:"file format"})," used by the certificate and private key files"]}),"\n",(0,s.jsxs)(n.li,{children:["Verify ",(0,s.jsx)(n.a,{href:"#verify-tls-support-in-erlang",children:"TLS support in Erlang/OTP"})]}),"\n",(0,s.jsxs)(n.li,{children:["Verify certificate/key pairs and test with alternative TLS client or server ",(0,s.jsx)(n.a,{href:"#openssl-tools",children:"using OpenSSL command line tools"})]}),"\n",(0,s.jsxs)(n.li,{children:["Verify available and configured ",(0,s.jsx)(n.a,{href:"#verify-cipher-suites",children:"cipher suites"})," and certificate key usage options"]}),"\n",(0,s.jsxs)(n.li,{children:["Verify client connections ",(0,s.jsx)(n.a,{href:"#stunnel",children:"with a TLS-terminating proxy"})]}),"\n",(0,s.jsx)(n.li,{children:"And finally, test a real client connection against a real server connection again"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["When testing with a RabbitMQ node and/or a real RabbitMQ client it is important to inspect\n",(0,s.jsx)(n.a,{href:"./logging",children:"logs"})," for both server and client."]}),"\n",(0,s.jsx)(n.h2,{id:"verify-config",children:"Check Effective Node Configuration"}),"\n",(0,s.jsxs)(n.p,{children:["Setting up a RabbitMQ node with TLS involves modifying\nconfiguration. Before performing any other TLS\ntroubleshooting steps it is important to verify config file\nlocation and effective configuration (whether the node has\nloaded it successfully). See ",(0,s.jsx)(n.a,{href:"./configure",children:"Configuration guide"}),"\nfor details."]}),"\n",(0,s.jsx)(n.h2,{id:"verify-listeners",children:"Check TLS Listeners (Ports)"}),"\n",(0,s.jsxs)(n.p,{children:["This step checks that the broker is listening on the ",(0,s.jsx)(n.a,{href:"./networking",children:"expected port(s)"}),", such as\n5671 for AMQP 0-9-1 and 1.0, 8883 for MQTT, and so on."]}),"\n",(0,s.jsxs)(n.p,{children:["To verify that TLS has been enabled on the node, use ",(0,s.jsx)(n.code,{children:"[rabbitmq-diagnostics](./man/rabbitmq-diagnostics.8) listeners"}),"\nor the ",(0,s.jsx)(n.code,{children:"listeners"})," section in ",(0,s.jsx)(n.code,{children:"[rabbitmq-diagnostics](./man/rabbitmq-diagnostics.8) status"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The listeners section will look something like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"Interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication\nInterface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0\nInterface: [::], port: 5671, protocol: amqp/ssl, purpose: AMQP 0-9-1 and AMQP 1.0 over TLS\nInterface: [::], port: 15672, protocol: http, purpose: HTTP API\nInterface: [::], port: 15671, protocol: https, purpose: HTTP API over TLS (HTTPS)\n
1Interface: [::], port: 1883, protocol: mqtt, purpose: MQTT\n"})}),"\n",(0,s.jsx)(n.p,{children:"In the above example, there are 6 TCP listeners on the node. Two of them accept TLS-enabled connections:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Inter-node and CLI tool communication on port ",(0,s.jsx)(n.code,{children:"25672"})]}),"\n",(0,s.jsxs)(n.li,{children:["AMQP 0-9-1 (and 1.0, if enabled) listener for non-TLS connections on port ",(0,s.jsx)(n.code,{children:"5672"})]}),"\n",(0,s.jsxs)(n.li,{children:["AMQP 0-9-1 (and 1.0, if enabled) listener for TLS-enabled connections on port ",(0,s.jsx)(n.code,{children:"5671"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"./management",children:"HTTP API"})," listeners on ports 15672 (HTTP) and 15671 (HTTPS)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"./mqtt",children:"MQTT"})," listener for non-TLS connections 1883"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["If the above steps are not an option, inspecting node's ",(0,s.jsx)(n.a,{href:"./logging",children:"log file"})," can be a viable alternative.\nIt should contain an entry about a TLS listener being enabled, looking like this:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"2018-09-02 14:24:58.611 [info] <0.664.0> started TCP listener on [::]:5672\n2018-09-02 14:24:58.614 [info] <0.680.0> started SSL listener on [::]:5671\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the node is configured to use TLS but a message similar to the above is not logged,\nit is possible that the configuration file was placed at an incorrect location and was not read by\nthe broker or the node was not restarted after config file changes.\nSee the ",(0,s.jsx)(n.a,{href:"./configure",children:"configuration page"})," for details\non config file verification."]}),"\n",(0,s.jsxs)(n.p,{children:["Tools such as ",(0,s.jsx)(n.code,{children:"lsof"})," and ",(0,s.jsx)(n.code,{children:"netstat"})," can be used to verify what ports\na node is listening on, as covered in the ",(0,s.jsx)(n.a,{href:"./troubleshooting-networking",children:"Troubleshooting Networking"})," guide."]}),"\n",(0,s.jsx)(n.h2,{id:"verify-file-permissions",children:"Check Certificate, Private Key and CA Bundle File Permissions"}),"\n",(0,s.jsxs)(n.p,{children:["RabbitMQ must be able to read its configured CA certificate bundle, server certificate and private key.\nThe files must exist and have the appropriate permissions. Incorrect permissions (e.g. files\nbeing owned by ",(0,s.jsx)(n.code,{children:"root"})," or another superuser account that installed them) is a very common issue\nwith TLS setups."]}),"\n",(0,s.jsx)(n.p,{children:"On Linux, BSD and MacOS directory permissions can also affect node's ability to read the files."}),"\n",(0,s.jsx)(n.p,{children:"When certificate or private key files are not readable or do not exist,\nthe node will fail to accept TLS-enabled connections or TLS connections will just hang (the behavior\ndiffers between Erlang/OTP versions)."}),"\n",(0,s.jsxs)(n.p,{children:["When ",(0,s.jsx)(n.a,{href:"./configure#config-file-formats",children:"new style configuration format"})," is used to configure certificate and private\nkey paths, the node will check if the files exist on boot and refuse to start if that's not the case."]}),"\n",(0,s.jsx)(n.h2,{id:"verify-file-format",children:"Check Certificate, Private Key and CA Bundle File Format"}),"\n",(0,s.jsxs)(n.p,{children:["RabbitMQ nodes require that all certificate, private key and CA certificate bundle files be\nin the ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail",children:"PEM format"}),". Other formats will not be accepted."]}),"\n",(0,s.jsxs)(n.p,{children:["Files in other formats can be ",(0,s.jsx)(n.a,{href:"https://aboutssl.org/convert-certificate-to-pem-crt-to-pem-crt-to-pem-der-to-pem/",children:"converted to PEM files"}),"\nusing OpenSSL CLI tools."]}),"\n",(0,s.jsx)(n.h2,{id:"verify-tls-support-in-erlang",children:"Check TLS Support in Erlang"}),"\n",(0,s.jsx)(n.p,{children:"Another key requirement for establishing TLS connections to the broker\nis TLS support in the broker. Confirm that the Erlang VM has support\nfor TLS by running"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rabbitmq-diagnostics --silent tls_versions\n"})}),"\n",(0,s.jsx)(n.p,{children:"Or, on Windows"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rabbitmq-diagnostics.bat --silent tls_versions\n"})}),"\n",(0,s.jsx)(n.p,{children:"The output will look like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"tlsv1.2\ntlsv1.1\ntlsv1\nsslv3\n"})}),"\n",(0,s.jsxs)(n.p,{children:["With versions that do not provide ",(0,s.jsx)(n.code,{children:"rabbitmq-diagnostics tls_versions"}),", use"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rabbitmqctl eval 'ssl:versions().'\n"})}),"\n",(0,s.jsx)(n.p,{children:"Or, on Windows"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-PowerShell",children:"rabbitmqctl.bat eval 'ssl:versions().'\n"})}),"\n",(0,s.jsx)(n.p,{children:"The output in this case will look like so:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-erlang",children:"[{ssl_app,\"9.1\"},\n {supported,['tlsv1.2','tlsv1.1',tlsv1]},\n {supported_dtls,['dtlsv1.2',dtlsv1]},\n {available,['tlsv1.2','tlsv1.1',tlsv1,sslv3]},\n {available_dtls,['dtlsv1.2',dtlsv1]}]\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If an error is reported instead, confirm that the Erlang/OTP installation ",(0,s.jsx)(n.a,{href:"./ssl#erlang-otp-requirements",children:"includes TLS support"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"It is also possible to list cipher suites available on a node:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rabbitmq-diagnostics cipher_suites --format openssl --silent\n"})}),"\n",(0,s.jsx)(n.p,{children:"Or, on Windows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-PowerShell",children:"rabbitmq-diagnostics.bat cipher_suites --format openssl --silent\n"})}),"\n",(0,s.jsxs)(n.p,{children:["It is also possible to inspect what TLS versions are supported by the local Erlang runtime.\nTo do so, run ",(0,s.jsx)(n.code,{children:"erl"})," (or ",(0,s.jsx)(n.code,{children:"werl.exe"})," on Windows) on the command line to open an Erlang shell and\nenter"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-erlang",children:"%% the trailing dot is significant!\nssl:versions().\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Note that this will report supported versions on the local node (for the runtime found in ",(0,s.jsx)(n.code,{children:"PATH"}),"),\nwhich may be different from that used by RabbitMQ node(s) inspected."]}),"\n",(0,s.jsx)(n.h2,{id:"openssl-tools",children:"Use OpenSSL Tools to Test TLS Connections"}),"\n",(0,s.jsxs)(n.p,{children:["OpenSSL ",(0,s.jsx)(n.a,{href:"http://www.openssl.org/docs/apps/s_client.html",children:"s_client"}),"\nand ",(0,s.jsx)(n.a,{href:"http://www.openssl.org/docs/apps/s_server.html",children:"s_server"}),"\nare commonly used command line tools that can be used to test TLS connections\nand certificate/key pairs. They help narrow problems down by testing against\nalternative TLS client and server implementations. For example, if a certain TLS\nclient works successfully with ",(0,s.jsx)(n.code,{children:"s_server"})," but not a RabbitMQ node,\nthe root cause is likely on the server end. Likewise if an ",(0,s.jsx)(n.code,{children:"s_client"}),"\nclient can successfully connect to a RabbitMQ node but a different client cannot,\nit's the client setup that should be inspected closely first."]}),"\n",(0,s.jsxs)(n.p,{children:["The example below seeks to confirm that the certificates and ke
1ys can be used to\nestablish a TLS connection by connecting an ",(0,s.jsx)(n.code,{children:"s_client"})," client to an ",(0,s.jsx)(n.code,{children:"s_server"})," server\nin two separate shells (terminal windows)."]}),"\n",(0,s.jsxs)(n.p,{children:["The example will assume you have the following ",(0,s.jsx)(n.a,{href:"./ssl#certificates-and-keys",children:"certificate and key files"}),"\n(these filenames are used by ",(0,s.jsx)(n.a,{href:"https://github.com/rabbitmq/tls-gen",children:"tls-gen"}),"):"]}),"\n",(0,s.jsxs)("table",{children:[(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:"Item"}),(0,s.jsx)("td",{children:"Location"})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:"CA certificate (public key)"}),(0,s.jsx)("td",{children:(0,s.jsx)(n.code,{children:"ca_certificate.pem"})})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:"Server certificate (public key)"}),(0,s.jsx)("td",{children:(0,s.jsx)(n.code,{children:"server_certificate.pem"})})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:"Server private key"}),(0,s.jsx)("td",{children:(0,s.jsx)(n.code,{children:"server_key.pem"})})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:"Client certificate (public key)"}),(0,s.jsx)("td",{children:(0,s.jsx)(n.code,{children:"client_certificate.pem"})})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:"Client private key"}),(0,s.jsx)("td",{children:(0,s.jsx)(n.code,{children:"client_key.pem"})})]})]}),"\n",(0,s.jsx)(n.p,{children:"In one terminal window or tab execute the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"openssl s_server -accept 8443 \\\n  -cert server_certificate.pem -key server_key.pem -CAfile ca_certificate.pem\n"})}),"\n",(0,s.jsxs)(n.p,{children:["It will start an OpenSSL ",(0,s.jsx)(n.code,{children:"s_server"})," that uses the provided\nCA certificate bundler, server certificate and private key. It will be used\nto confidence check the certificates with test TLS connections against this example server."]}),"\n",(0,s.jsxs)(n.p,{children:["In another terminal window, run the following command, substituting ",(0,s.jsx)(n.code,{children:"CN_NAME"}),"\nwith the expected hostname or ",(0,s.jsx)(n.code,{children:"CN"})," name from the certificate:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"openssl s_client -connect localhost:8443 \\\n  -cert client_certificate.pem -key client_key.pem -CAfile ca_certificate.pem \\\n  -verify 8 -verify_hostname CN_NAME\n"})}),"\n",(0,s.jsxs)(n.p,{children:["It will open a new TLS connection to the example TLS server started above. You may leave\noff the ",(0,s.jsx)(n.code,{children:"-verify_hostname"})," argument but OpenSSL will no longer perform that\nverification."]}),"\n",(0,s.jsxs)(n.p,{children:["If the certificates and keys have been correctly created, a TLS connection output\nwill appear in both tabs. There is now a connection between the example client and the example\nserver, similar to ",(0,s.jsx)(n.code,{children:"telnet"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.a,{href:"./ssl#peer-verification",children:"trust chain"})," could be established, the second terminal will display\na verification confirmation with the code of ",(0,s.jsx)(n.code,{children:"0"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"Verify return code: 0 (ok)\n"})}),"\n",(0,s.jsx)(n.p,{children:"Just like with command line tools, a non-zero code communicates an error of some kind."}),"\n",(0,s.jsxs)(n.p,{children:["If an error is reported, confirm that the certificates and keys were\ngenerated correctly and that a matching certificate/private key pair is used.\nIn addition, certificates can have their ",(0,s.jsx)(n.a,{href:"https://tools.ietf.org/html/rfc5280#section-4.2.1.3",children:"usage scenarios restricted"}),"\nat generation time. This means a certificate meant to be used by clients to authenticate themselves\nwill be rejected by a server, such as a RabbitMQ node."]}),"\n",(0,s.jsxs)(n.p,{children:["For environments where self-signed certificates are appropriate,\nwe recommend using ",(0,s.jsx)(n.a,{href:"https://github.com/rabbitmq/tls-gen",children:"tls-gen"})," for generation."]}),"\n",(0,s.jsx)(n.h2,{id:"verify-cipher-suites",children:"Validate Available Cipher Suites"}),"\n",(0,s.jsxs)(n.p,{children:["RabbitMQ nodes and clients can be limited in what ",(0,s.jsx)(n.a,{href:"./ssl#cipher-suites",children:"cipher suites"})," they are allowed\nto use during TLS handshake. It is important to make sure that the two sides have\nsome cipher suites in common or otherwise the handshake will fail."]}),"\n",(0,s.jsx)(n.p,{children:"Certificate's key usage properties can also limit what cipher suites can be used."}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"./ssl#cipher-suites",children:"Configuring Cipher Suites"})," and ",(0,s.jsx)(n.a,{href:"./ssl#key-usage",children:"Public Key Usage Extensions"})," in the main TLS guide\nto learn more."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"openssl ciphers -v\n"})}),"\n",(0,s.jsx)(n.p,{children:"will display all cipher suites supported by the local build of OpenSSL."}),"\n",(0,s.jsx)(n.h2,{id:"sclient-connection",children:"Attempt TLS Connection to a RabbitMQ Node"}),"\n",(0,s.jsxs)(n.p,{children:["Once a RabbitMQ node was configured to listen on a TLS port,\nthe OpenSSL ",(0,s.jsx)(n.code,{children:"s_client"})," can be used to test TLS connection establishment, this time against the node.\nThis check establishes whether the broker is likely to be configured correctly, without needing\nto configure a RabbitMQ client. The tool can also be useful to compare the behaviour of different clients.\nThe example assumes a node running on ",(0,s.jsx)(n.code,{children:"localhost"})," on ",(0,s.jsx)(n.a,{href:"./networking#ports",children:"default TLS port for AMQP 0-9-1 and AMQP 1.0"}),", 5671:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"openssl s_client -connect localhost:5671 -cert client_certificate.pem -key client_key.pem -CAfile ca_certificate.pem\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The output should appear similar to the case where port 8443 was used. The node log file\nshould ",(0,s.jsx)(n.a,{href:"./logging#logged-events",children:"contain a new entry when the connection is established"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"2018-09-27 15:46:20 [info] <0.
11082.0> accepting AMQP connection <0.1082.0> (127.0.0.1:50915 -> 127.0.0.1:5671)\n2018-09-27 15:46:20 [info] <0.1082.0> connection <0.1082.0> (127.0.0.1:50915 -> 127.0.0.1:5671): user 'user' authenticated and granted access to vhost 'virtual_host'\n"})}),"\n",(0,s.jsx)(n.p,{children:"The node will expect clients to perform protocol handshake (AMQP 0-9-1, AMQP 1.0 and so on). If that doesn't\nhappen within a short time window (10 seconds by default for most protocols), the node will close the\nconnection."}),"\n",(0,s.jsx)(n.h2,{id:"stunnel",children:"Validate Client Connections with Stunnel"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"http://www.stunnel.org/",children:"stunnel"}),' is a tool that can be used to validate TLS-enabled clients.\nIn this configuration clients will make a secure connection to stunnel,\nwhich will pass the decrypted data through to a "regular" port of the broker (say, 5672 for AMQP 0-9-1 and AMQP 1.0).\nThis provides some confidence that the client TLS configuration is correct independently of the broker TLS configuration.']}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"stunnel"})," is a specialised proxy. In this example it will run in daemon mode on the same host as the broker.\nIn the discussion that follows it is assumed that stunnel will only be used temporarily. It is also possible to use stunnel to\nperform TLS termination but that is out of scope for this guide."]}),"\n",(0,s.jsxs)(n.p,{children:["In this example ",(0,s.jsx)(n.code,{children:"stunnel"})," will connect to the unencrypted port of the broker (5672) and accept\nTLS connections from TLS-capable clients on port 5679."]}),"\n",(0,s.jsxs)(n.p,{children:["Parameters are passed via a config file named ",(0,s.jsx)(n.code,{children:"stunnel.conf"}),". It has the following content:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ini",children:"foreground = yes\n\n[rabbit-amqp]\nconnect = localhost:5672\naccept = 5679\ncert = client/key-cert.pem\ndebug = 7\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"stunnel"})," is started as follows:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cat client_key.pem client_certificate.pem > client/key-cert.pem\nstunnel stunnel.conf\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"stunnel"})," requires a certificate and its corresponding private key. The certificate\nand private key files must be concatenated as shown above with the ",(0,s.jsx)(n.code,{children:"cat"})," command.\n",(0,s.jsx)(n.code,{children:"stunnel"})," requires that the key not be password-protected.\nTLS-capable clients should now be able to connect to port 5679 and any TLS errors will appear\non the console where ",(0,s.jsx)(n.code,{children:"stunnel"})," was started."]}),"\n",(0,s.jsx)(n.h2,{id:"client-connection",children:"Validate RabbitMQ Client Connection to RabbitMQ Node"}),"\n",(0,s.jsxs)(n.p,{children:["Assuming none of the previous steps produced errors then you can confidently connect the tested TLS-enabled\nclient to the TLS-enabled port of the broker, making sure to stop any running OpenSSL ",(0,s.jsx)(n.code,{children:"s_server"}),"\nor ",(0,s.jsx)(n.code,{children:"stunnel"})," instances first."]}),"\n",(0,s.jsx)(n.h2,{id:"verify-verification-depth",children:"Certificate Chains and Verification Depth"}),"\n",(0,s.jsxs)(n.p,{children:["When using a client certificate ",(0,s.jsx)(n.a,{href:"./ssl#peer-verification",children:"signed by an intermediate CA"}),", it may be necessary\nto configure RabbitMQ server to use a higher ",(0,s.jsx)(n.a,{href:"./ssl#peer-verification-depth",children:"verification depth"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Insufficient verification depth will result in TLS peer verification failures."}),"\n",(0,s.jsx)(n.h2,{id:"logs",children:"Understanding TLS Connection Log Errors"}),"\n",(0,s.jsx)(n.p,{children:"New broker logfile entries will be generated during many of the preceding steps. These entries\ntogether with diagnostic output from commands on the console should help to identify the cause\nof TLS-related errors. What follows is a list of the most common error entries:"}),"\n",(0,s.jsxs)("table",{children:[(0,s.jsx)("thead",{children:(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,s.jsx)("strong",{children:"Logged Errors"})}),(0,s.jsx)("td",{children:(0,s.jsx)("strong",{children:"Explanation"})})]})}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,s.jsxs)(n.p,{children:["Entries containing ",(0,s.jsx)(n.code,{children:"{undef, [{crypto,hash,..."})]})}),(0,s.jsx)("td",{children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"crypto"})," module is missing in the Erlang/OTP installation\nused or it is out of date. On Debian, Ubuntu, and other Debian-derived distributions\nit usually means that the ",(0,s.jsx)(n.a,{href:"http://packages.ubuntu.com/search?keywords=erlang-ssl",children:"erlang-ssl"})," package was not installed."]})})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,s.jsxs)(n.p,{children:["Entries containing ",(0,s.jsx)(n.code,{children:"{ssl_upgrade_error, ekeyfile}"}),"\nor ",(0,s.jsx)(n.code,{children:"{ssl_upgrade_error, ecertfile}"})]})}),(0,s.jsx)("td",{children:(0,s.jsxs)(n.p,{children:["This means the broker keyfile or certificate file is invali
1d.\nConfirm that the keyfile matches the certificate and that both are in PEM format.\nPEM format is a printable encoding with recognisable delimiters. The certificate\nwill start and end with ",(0,s.jsx)(n.code,{children:"-----BEGIN CERTIFICATE-----"})," and\n",(0,s.jsx)(n.code,{children:"-----END CERTIFICATE-----"})," respectively. The keyfile will likewise\nstart and end with ",(0,s.jsx)(n.code,{children:"-----BEGIN RSA PRIVATE KEY-----"})," and\n",(0,s.jsx)(n.code,{children:"-----END RSA PRIVATE KEY-----"})," respectively."]})})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,s.jsxs)(n.p,{children:["Entries containing ",(0,s.jsx)(n.code,{children:"{ssl_upgrade_failure, ... certify ...}"})]})}),(0,s.jsx)("td",{children:(0,s.jsxs)(n.p,{children:["This error is related to client verification. The client is presenting an invalid\ncertificate or no certificate. If the ssl_options has the ",(0,s.jsx)(n.code,{children:"verify"})," option\nset to ",(0,s.jsx)(n.code,{children:"verify_peer"})," then try using the value ",(0,s.jsx)(n.code,{children:"verify_none"}),"\ntemporarily. Ensure that the client certificate has been generated correctly, and that\nthe client is presenting the correct certificate."]})})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,s.jsxs)(n.p,{children:["Entries containing ",(0,s.jsx)(n.code,{children:"{ssl_upgrade_error, ...}"})]})}),(0,s.jsx)("td",{children:(0,s.jsx)(n.p,{children:"This is a generic error that could have many causes. Make sure you are\nusing the recommended version of Erlang."})})]}),(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,s.jsxs)(n.p,{children:["Entries containing ",(0,s.jsx)(n.code,{children:'{tls_alert,"bad record mac"}'})]})}),(0,s.jsx)("td",{children:(0,s.jsxs)(n.p,{children:["The server has tried verifying integrity of a piece of data it received\nand the check failed. This can be due to problematic network equipment, unintentional\nsocket sharing in the client (e.g. due to the use of ",(0,s.jsx)(n.code,{children:"fork(2)"}),") or a bug\nin the client implementation of TLS."]})})]})]})]})}function h(e={}){let{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453(e,n,i){i.d(n,{R:()=>o,x:()=>l});var t=i(96540);let s={},r=t.createContext(s);function o(e){let n=t.useContext(r);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.