MQTT not working in HTTPS server - websocket

We are facing issue in MQTT connection in HTTPS server. Sometime it is working fine and some time it is getting error like below.
WebSocket connection to 'wss://MYHOST:8083/mqtt' failed: Error in connection establishment: net::ERR_INSECURE_RESPONSE
Let me share with you my mosquitto.conf file.
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
include_dir /etc/mosquitto/conf.d
listener 1883
listener 8083
protocol websockets
certfile /etc/mosquitto/certs/myhost.crt
cafile /etc/mosquitto/certs/ca.crt
keyfile /etc/mosquitto/certs/myhost.key
My Mosquitto WebSocket config file:
host = 'MYHOST'; // hostname or IP address
port = 8083;
topic = 'TOPIC'; // topic to subscribe to
useTLS = true;
username = "";
password = "";
path = "/mqtt";
cleansession = true;
Thanks.

Related

Issues establishing a secure connection to Mosquitto Broker 2.0.10 using M2MQTT v4.3.0.0 and signed certificates

I'm trying to implement MQTT in my program using M2MQTT v4.3.0.0 (github), but when I try to connect using signed certificates my code cannot establish a connection. I'm on a Windows 10 system, and using C# with .NET 4.8. The version of Mosquitto I have installed is 2.0.10.
To make the server certificate I followed this tutorial:
http://www.steves-internet-guide.com/mosquitto-tls/#server
To make the client certificate I followed this tutorial:
http://www.steves-internet-guide.com/creating-and-using-client-certificates-with-mqtt-and-mosquitto/
I also made a host name in my etc/hosts file for 127.0.0.1 that points to localhost.conrad.com.
The configuration for my Mosquitto Broker is:
bind_address localhost.conrad.com
port 8883
allow_anonymous true
cafile C:/mosquitto/certs/ca.crt
keyfile C:/mosquitto/certs/server.key
certfile C:/mosquitto/certs/server.crt
require_certificate true
tls_version tlsv1.2
log_dest file C:/mosquitto/log/mosquitto.log
log_type error
log_type warning
log_type notice
log_type information
I successfully tested that this configuration works using Mosquitto's command line publish tool with
mosquitto_pub --cafile C:\mosquitto\certs\ca.crt --cert C:\mosquitto\certs\client.crt --key C:\mosquitto\certs\client.key -d -h localhost.conrad.com -p 8883 -t herp/derp/test -m "hi"
I received this message after using the command.
Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending PUBLISH (d0, q0, r0, m1, 'herp/derp/test', ... (2 bytes))
Client (null) sending DISCONNECT
My Mosquitto log confirms a successful connection:
1621547553: New connection from 127.0.0.1:57874 on port 8883.
1621547553: New client connected from 127.0.0.1:57874 as auto-6A8387C3-E091-0EC6-CED7-0A78BAA63099 (p2, c1, k60).
1621547553: Client auto-6A8387C3-E091-0EC6-CED7-0A78BAA63099 disconnected.
However when I try to connect using M2MQTT I run into a problem when trying to connect using signed certificates. My code is as follows:
int securePort = 8883;
MqttClient client = null;
string subTopic1 = "herp/derp/test";
string subTopic2 = "herp/derp/test2";
X509Certificate caCert = new X509Certificate("C:/mosquitto/certs/ca.crt");
X509Certificate clientCert = new X509Certificate("C:/mosquitto/certs/client.crt");
string clientID = "TestClientID";
public MQTTTest()
{
try
{
client = new MqttClient("localhost.conrad.com", securePort, true, caCert, clientCert, MqttSslProtocols.TLSv1_2, RemoteCertificateValidationCallback);
client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
client.MqttMsgPublished += client_MqttMsgPublished;
client.MqttMsgSubscribed += client_MqttMsgSubscribed;
client.ConnectionClosed += client_ConnectionClosed;
client.Connect(clientID, "", "", true, 1000);
client.Subscribe(new string[] { subTopic1, subTopic2 }, new byte[] { MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE, MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE });
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
I get the following exception when trying at client.Connect.
Exception message: "A call to SSPI failed, see inner exception."
Inner exception: "The message received was unexpected or badly formatted"
My Mosquitto logs show:
1621547793: New connection from 127.0.0.1:57896 on port 8883.
1621547793: OpenSSL Error[0]: error:1417C0C7:SSL routines:tls_process_client_certificate:peer did not return a certificate
1621547793: Client <unknown> disconnected: protocol error.
I can establish insecure connections just fine. As it is written my code also connects when I set require_certificate to false in my Mosquitto config file; however I am worried that if require_certificate is set to false that I won't have the security I want. Any help would be greatly appreciated.
Thanks to Brits' comment I was able to figure it out (link to answer). I made a pfx certificate and used that instead of using a crt.
Instead of...
X509Certificate caCert = new X509Certificate("C:/mosquitto/certs/ca.crt");
X509Certificate clientCert = new X509Certificate("C:/mosquitto/certs/client.crt");
I used...
X509Certificate2 caCert = new X509Certificate2("C:/mosquitto/certs/ca.pfx", "password");
X509Certificate2 clientCert = new X509Certificate2("C:/mosquitto/certs/client.pfx", "password");

express-gateway on Heroku - {$PORT} binding error

I have deployed my express-gateway on Heroku, using env variables in this way in the gateway.config.yml file:
http:
port: ${PORT:-8080}
host: ${HOST:-localhost}
https:
port: ${PORT:-8080}
host: ${HOST:-localhost}
apiEndpoints:
....
Anyway Heroku keeps giving this error:
[EG:gateway] gateway http server listening on :::8080
State changed from starting to crashed
Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
I have used the notation ${ENV_VAR_NAME:-DEFAULT} according to official documentation. Why Heroku tries to bind the 8080?
====== UPDATE
Just an out-of-topic tip, for who is going to use Heroku, here's how I get the redis url from the env vars.
var redis_Url = process.env.REDIS_URL;
var groups = /^redis:\/\/(.*?)\:(.+?)\#(.+?)\:(.+)$/gi.exec(redis_Url);
var nm = groups[1];
var pasw = groups[2];
var host = groups[3];
var port = groups[4];
process.env.REDIS_NM = nm;
process.env.REDIS_PASW = pasw;
process.env.REDIS_HOST = host;
process.env.REDIS_PORT = port;
console.log('redis url --> '+process.env.REDIS_URL);
console.log('nm --> '+process.env.REDIS_NM);
console.log('pasw --> '+process.env.REDIS_PASW);
console.log('host --> '+process.env.REDIS_HOST);
console.log('port --> '+process.env.REDIS_PORT);
You should not make listen both the http and the https server on the same port, otherwise it's going to fail.
Heroku provides its own router handling the SSL termination for you, so you can just remove the whole https section.

Not receiving payloads from mosquitto via websockets

I'm using a VPS and I'm sending data from my Arduino to the server via MQTT.
Mosquitto print payloads via terminal successfully but when I try to print it in real time via a web page nothing happens.
Knowing that I've already allowed websockets in Mosquitto conf, if I run :
sudo netstat -plnt
I get :
tcp 0 0 0.0.0.0:1883 0.0.0.0:* LISTEN
13248/mosquitto
tcp 0 0 0.0.0.0:1884 0.0.0.0:* LISTEN
20169/mosquitto
tcp6 0 0 :::1883 :::* LISTEN 13248/mosquitto
the topic I'm sending name : /pression and the code I'm using is:
<script>
var websocket="myserver.ovh.net";
var port= 1884;
var user="username";
var pass="password";
client = new Paho.MQTT.Client(websocket, port, "innovation");
// set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
var options = {
useSSL: false,
userName: user,
password: pass,
onSuccess:onConnect,
onFailure:doFail
}
// connect the client
client.connect(options);
// called when the client connects
function onConnect() {
// Once a connection has been made, make a subscription and send a
message.
document.getElementById("connstatus").innerHTML = "Mqtt Connected";
console.log("Mqtt Connected");
client.subscribe("/pression");
}
function doFail(e){
console.log(e);
}
// called when the client loses its connection
function onConnectionLost(responseObject) {
document.getElementById("connstatus").innerHTML = "Mqtt Not Connected";
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
}
}
function onMessageArrived(message) {
console.log("Pression is :");
document.getElementById("connstatus").innerHTML = message.payloadString;
console.log(message.payloadString);
}
</script>
when I run the script it says "Mqtt Connected" than nothing happened.
However if I run in the terminal :
mosquitto_sub -t '/pression'
I get the pressure values.
if I keep the web page on for some minutes I get this message :
Mqtt Connected
test.html:76 onConnectionLost:AMQJS0008I Socket closed.
config file :
# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
include_dir /etc/mosquitto/conf.d
#password_file /etc/mosquitto/passwd
#allow_anonymous false
listener 1884
protocol websockets
mosquitto log :
1557922249: Config loaded from /etc/mosquitto/mosquitto.conf.
1557922249: Opening websockets listen socket on port 1884.
1557922254: New client connected from xx.xx.11.163 as innovation (c1, k60, u'innovation').
1557922279: Socket error on client innovation, disconnecting.
1557922279: New client connected from xx.xx.11.163 as innovation (c1, k60, u'innovation').
1557922318: Socket error on client innovation, disconnecting.
1557922318: New client connected from xx.xx.11.163 as innovation (c1, k60, u'innovation').
1557922346: Socket error on client innovation, disconnecting.
1557922346: New client connected from xx.xx.11.163 as innovation (c1, k60, u'innovation').
1557922363: Socket error on client innovation, disconnecting.
1557922364: New client connected from xx.xx.11.163 as innovation (c1, k60, u'innovation').
1557922463: Socket error on client innovation, disconnecting.
OK, the problem here is most likely that you are using a fixed client id (innovation) in the HTML.
You can only ever have 1 client connected with a given client id, so the broker will disconnect the oldest one when a new client with the same id connects (e.g. when you reload the page).
Try changing the connection line to something like this:
var clientID = "innovation_" + new Date().getTime();
client = new Paho.MQTT.Client(websocket, port, clientID);

Setting up ejabberd via websockets

I have an ejabberd server up and running.
I can test it via web clients and it works fine using BOSH connections.
I would like to connect to it via web sockets now, and I am not sure what I am missing for it to work, I just know it doesn't.
Here is an extract from my ejabberd.yml
hosts:
- "localhost"
- "somedomain.com"
- "im.somedomain.com"
listen :
port: 5280
ip: "::"
module: ejabberd_http
request_handlers:
"/websocket": ejabberd_http_ws
"/pub/archive": mod_http_fileserver
web_admin: true
http_bind: true
## register: true
## captcha: true
tls: true
certfile: "/etc/ejabberd/ejabberd.pem"
Now I tried to open a web socket via javascript as follows :
var ws = new WebSocket("ws://somedomain:5280/websocket/");
I get ERR_CONNECTION_TIMED_OUT in return. I have nothing within ejabberd's logs when I try to open a weksocket. I do have logs of the BOSH connections.
I am not sure if I am testing appropriately, nor if my server is setup correctly.
Any suggestion is most welcome.
Connection timeout error will throw by the server when the client does not send pong response to the server make sure you are sending the pong response.If you are using Strophe.js kindly check Handlers http://strophe.im/strophejs/doc/1.2.14/files/strophe-js.html#Strophe.Connection.addHandler
connection = new WebSocket("ws://somedomain:5280/websocket/");
//Adding ping handler using strophe connection
connection.addHandler(pingHandler, "urn:xmpp:ping", "iq", "get");
//Ping Handler Call back function
function pingHandler(ping) {
var pingId = ping.getAttribute("id");
var from = ping.getAttribute("from");
var to = ping.getAttribute("to");
var pong = strophe.$iq({
type: "result",
"to": from,
id: pingId,
"from": to
});
connection.send(pong);
return true;
}
Also, consider you are adding this configuration to your ejabberd.yml
websocket_ping_interval: 50
websocket_timeout: 60

reconcile unable to talk with Consul backend

Im trying to setup a docker container for my vault/consul but get the following error:-
2017/06/22 18:15:58.335293 [WARN ] physical/consul: reconcile unable to talk with Consul backend: error=service registration failed: Put http://127.0.0.1:8500/v1/agent/service/register: dial tcp 127.0.0.1:8500: getsockopt: connection refused
Here is my vault config file.
storage "consul" {
address = "127.0.0.1:8500"
redirect_addr = "http:/127.0.0.1:8500"
path = "vault"
scheme = "http"
}
listener "tcp" {
address = "127.0.0.1:8200"
tls_disable = 1
}
#telemetry {
# statsite_address = "127.0.0.1:8125"
# disable_hostname = true
#}
where is Consul?
This error is saying I'm trying to reach this URL: http://127.0.0.1:8500/v1/agent/service/register and can't.
This implies that either Consul isn't running, or it's running somewhere other than at http://127.0.0.1:8500
Find your consul, and then update your config to point to it.

Resources