How to connect to RabbitMQ server with TLS without certificate in Node - ssl

I need help connecting to RabbitMQ with TLS using Node.
The client gave us credentials for connecting to their RabbitMQ server.
They say we don’t need any certificates for TLS connection, and I’m using NodeJS.
We’re getting this error.
OperationalError: certificate has expired
We’re trying to use this Node client library https://github.com/amqp-node/amqplib and in their SSL guide(https://amqp-node.github.io/amqplib/ssl.html) it’s written
If you're not going to use a client certificate, you need only to make sure you will trust the server certificate:
var opts = {
ca: [fs.readFileSync('cacert.pem')]
};
this is our current code
const conn = await connect({
hostname: process.env.RABBITMQ_HOST,
port: Number(process.env.RABBITMQ_PORT),
username: process.env.RABBITMQ_USER,
password: process.env.RABBITMQ_PASSWORD,
vhost: process.env.RABBITMQ_VHOST,
protocol: 'amqps',
}

Related

How to configure Mosca for mqtts without the client having a certificate?

I have a Mosca MQTT broker running on a node instance and I would like to encrypt all the incoming communications with SSL/TLS (MQTTs protocol) but without the client having to link any certificate to the connexion (I guess it has to do with self-signed certificates) just as https works. I want all my clients to connect just with credentials specifying the MQTTs protocol and the communication can be encrypted. I was using Amazon MQ just before and that's how it works so I want the same.
I can't figure how to configure properly Mosca to do so, I don't know what kind of certificate I must use.
I added the secure field in the configuration as shown here
For the certificate I tried to create a self signed certificate as shown here
I also tried with certbot certificates (Let's Encrypt) registered for my domain name : mq.xxx.com .
I'm running everything on a ec2 (ubuntu 18) and my network and firewall are open for 1883 and 8883. My key and cert are at the root of my project where the deamon is running with good rights and ownership. I know my instance access them correctly.
new mosca.Server({
port: 1883,
secure: {
keyPath: "./privkey.pem",
certPath: "./cert.pem"
},
backend: {
type: 'redis',
redis: require('redis'),
host: "localhost",
port: 6379,
db: 0,
return_buffers: true,
},
persistence: {
factory: mosca.persistence.Redis
}
});
My server is running and working with simple mqtt on port 1883 but when I try to connect with ssl/tls with a client on port 8883 specifying that the server uses self-signed certificates (I tried with MQTT.fx) it fails saying : "unable to find valid certification path to requested target".
I can't make my head around this issue, I think somehow the client cannot "accept" or "verify" the certificate provided. Maybe I'm providing the wrong key or certificate to Mosca but there is only one of each resulting openssl or certbot. Maybe I created wrong but I follow many tutorials on the very same subject such as this one
What kind of certificate do I need to do ?
Is there something more to do with them ?
Thank you.
If you are using a self created certificate then the client will need a copy of certificate that signed the broker's certificate. This certificate will be added to the list of trusted sources so it can prove the broker is who it claims to be.
If you do not want to / can not distribute a certificate then you will need to use a certificate for your broker that is issued by CA (Certificate Authority) whoes signing certificate you already have (bundled into the OS/client that you are using).
The Lets Encrypt signing certificates should be bundled into most OSes by now but they are also cross signed by IdenTrust again who's certs should be bundled with most OSes. If you are having problems with the Lets Encrypt certs then I suggest you ask a new question with the exact details of how you configured mosca with those certs and more details of how you are configuring MQTT.fx and the errors you receive.

How to get Remote server untrusted SSL certificate using Apache HTTP Client API

I have a remote server which may or may not be running using a valid SSL cert (using self-signed SSL cert).
We are making connection to remote server, which may fail if remote server is using self-signed SSL cert. So, we want to be able to download/view the remote server cert if our SSL handshake fails.
If I use Apache HTTP Client then I couldn't find a method which could allow me to view remote server certificate (you can do it with HttpsURLConnection but we are trying to avoid using it see this example).
I also looked into Spring RestTemplate, and it didn't provide any option either - I searched on Google and didn't find anything around Spring or Apache HTTP Client.
This should give you pretty much a complete control over the process of trust verification.
SSLContext sslContext = SSLContextBuilder.create()
.loadTrustMaterial((chain, authType) -> {
for (X509Certificate cert: chain) {
System.out.println(cert.getSubjectDN());
}
// Let the standard trust managers decide
// whether or not the cert chain is trusted
return false;
})
.build();
CloseableHttpClient client = HttpClientBuilder.create()
.setSSLContext(sslContext)
.build();

React-native websocket TLS Connection

I am trying to use websocket to connect to a TLS server using react-native. Below is my code (running on windows + android ):
var ws = new WebSocket('wss://hub.fingi-staging.com:20020',{
rejectUnauthorized: false
});
ws.onopen = () => {
// connection opened
ws.send('something'); // send a message
};
ws.onmessage = (e) => {
// a message was received
console.log('message : ' + e.data);
};
ws.onerror = (e) => {
// an error occurred
console.log('error:'+e.message);
};
ws.onclose = (e) => {
// connection closed
console.log('close:'+e.code, e.reason);
};
However, it fails with : error:java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. This is because the server uses a self signed certificate.
Is there any way to fix this?
Replying a bit late, but hopefully this can point other people in the right direction.
I believe the error you are getting suggests you are missing the certificate chain file, which is used to verify if the CA used to sign your server's certificate is valid, i.e if the chain of trust is valid.
This, however, usually fails (is troublesome, at least) if you are working with self signed certificates. You can take a look here if you need some help generating some self-signed certificates and the appropriate certificate chain. Also, see if you need to specify the trusted CA's by having the client use that file as a parameter when connecting.
I have been struggling with setting up a secure websocket server using a self sign certificate (for development purposes, in production a proper certificate/CA must be used) but haven't had much success and reverted back to using non-TLS websocket server.
If anyone else happens to be struggling with implementing secure websocket connections in React-Native, here is what I found tonight: React-Native wants to use port 443 when working with secure websocket connections.
Let's take the original poster above's code. He has:
var ws = new WebSocket('wss://hub.fingi-staging.com:20020',{
rejectUnauthorized: false
});
What I've found that works for me is:
var ws = new WebSocket('wss://hub.fingi-staging.com');
And then on your WebSocket server, make sure you are serving everything up on port 443, and not port 20020 (or whatever port you happened to be using previously). For example, my Python websocket server was previously using port 8765. However, in React-Native you need to be using port 443 for secure websocket connections or things simply aren't going to work.

How to fix certificate subject does not match configureed hostname issue in SSL

I'm trying to do a secured transfer to syslog server via tcp from a device. I have generated certificates in server side and copied the cacert.pem to client side. When i try to send a message from to server i receive following error.
"Certificate subject does not match configured hostname;
hostname='10.17.31.33', certificate='SP'"
Please have a look at following config files
Server Side config:
tcp
(
port(1999)
tls
(
ca_dir("/etc/syslog-ng/ras.d/demoCA/")
key_file("/etc/syslog-ng/ras.d/my_ipv4-server.key")
cert_file("/etc/syslog-ng/ras.d/my_ipv4-server.csr")
peer_verify(optional-untrusted)
)
);
};
Client side config:
destination df_remote_1 {tcp("10.17.31.33" port(1999)
tls(ca_dir("/etc/syslog-ng/ca.d")));};
log { source(s_all); filter(f_remote); destination(df_remote_1);};
I'm new to syslog someone please help me understand the issue and fix it.

Dovecot with virtual hosts and SSL - wrong certificate?

I'm trying to set up Dovecot with multiple vhosts using SSL.
I've set up my main domain (example.de) and for my vhosts (example2.com & example3.co.uk) I'm using the local -option.
My problem:
When I connect to my server, it complains about a wrong hostname
(example3.co.uk) on my main and other domain for the certificate.
How can I make dovecot use the correct certificate for each host?
Here's my dovecot config:
listen = *
ssl = yes
protocols = imap pop3
disable_plaintext_auth = no
auth_mechanisms = plain login
mail_access_groups = vmail
default_login_user = vmail
first_valid_uid = 2222
first_valid_gid = 2222
#mail_location = maildir:~/Maildir
mail_location = maildir:/home/vmail/%d/%n
passdb {
driver = passwd-file
args = scheme=SHA1 /etc/dovecot/passwd
}
userdb {
driver = static
args = uid=2222 gid=2222 home=/home/vmail/%d/%n allow_all_users=yes
}
service auth {
unix_listener auth-client {
group = postfix
mode = 0660
user = root
}
user = root
}
service imap-login {
process_min_avail = 1
user = vmail
}
ssl_cert = </etc/pki/tls/certs/example.de.crt
ssl_key = </etc/pki/tls/private/example.de.key
local ohmygodpresents.com {
ssl_cert = </etc/pki/tls/certs/example2.com.crt
ssl_key = </etc/pki/tls/private/example2.com.key
}
local ohmygodpresents.co.uk {
ssl_cert = </etc/pki/tls/certs/example3.co.uk.crt
ssl_key = </etc/pki/tls/private/example3.co.uk.key
}
How can I make dovecot use the correct certificate for each host?
Its not Dovecot per se.
The client needs to use TLS 1.0 or above, and it needs to utilize the Server Name Indication (SNI) extension. Otherwise, Dovecot does not know which virtual server the client is attempting to connect to when the channel is being set up.
You can duplicate/test it with OpenSSL s_client. For example, a "good" connection:
openssl s_client -tls1 -starttls smtp -connect mail.example.com:587 -servername mail.example.com
In the above example, Dovecot will know to send the certificate for example.com when the SSL/TLS connection is started. Even though a STARTTLS extension is used in mail, Dovecot does not know the virtual server because the RCPT command has not yet been sent. Because the RCPT command has not been sent, Dovecot does not know the user or his/her domain.
Here's a "bad" connection. Its SSLv3, so it cannot utilize SNI (SNI is a TLS extension):
openssl s_client -ssl3 -starttls smtp -connect mail.example.com:587
Here's another "bad" connection. Its TLS 1.0, but it does not utlize SNI:
openssl s_client -tls1 -starttls smtp -connect mail.example.com:587
You can also duplicate/test/observe with Wireshark. SNI is sent in the plain text as part of the ClientHello. So you will be able to see protocols, cipher suites, extensions like SNI, and other parameters. Everything in SSL/TLS's handshake and key exchange are plain text (some hand waiving). The plain text messages are integrity checked later when the Finished messages are sent.
You can disable SSLv2/SSLv3 and force TLS, and things will work as expected for most clients. However, a client does not have to send the SNI extension. Windows XP clients will be a problem - they utilize TLS 1.0 but omit SNI. So there's really no fix other than using a modern client.
Your other option is to create a "super certificate". That is, use a certificates with all the DNS names that the mail server serves. In your case, use one certificate with SANs of DNS:3und80.de, DNS:ohmygodpresents.co.uk, DNS:example1.com, etc. Every time you add a new domain or remove an existing domain, you will have to get a new certificate.
See https://doc.dovecot.org/configuration_manual/dovecot_ssl_configuration/
it is not
local domain.com { ...
it is
local_name domain.com { ...