Mosquitto - Internal & External Client Configuration - ssl

I was wondering if there is a way to configure Mosquitto to require TLS and client certificates if it is connecting to an external clients and not to require TLS and client certificate for internal clients. Should I do anything with the CA(Certficiate Authority) or .conf files? What would I need to do to configure it properly to accomplish this? Any help on this would be greatly appreciated.

If you want to use the same port (1883) for both internal and external then you will probably need the broker machine to have 2 network interfaces (one internal, one external) so you can bind the listeners to different IP addresses (e.g. not doing port forwarding).
If you are doing port forwarding then you will have to use different ports for internal/external.
Assuming 2 interfaces:
# internal
port 1883
bind_address <internal-ip>
#external
listener <external-ip>:1883
cafile /path/to/ca/cert
keyfile /path/to/key
certfiel /path/to/cert
require_certificate true
This should allow anonymous none ssl connections internally and SSL + Client certificates from outside.
If you are doing port forwarding remove the external ip address and change the port number it listens on, you can still forward 1883 from the router.

Related

How is TLS termination implemented in AWS NLB?

AWS NLB supports TLS termination
https://aws.amazon.com/blogs/aws/new-tls-termination-for-network-load-balancers/
NLB being a Layer 4 load balancer I would expect it to work in a passthrough mode by directing the incoming packets to one of the backends without much of state maintenance (except for the flow tracking)
Are there any details available on how AWS implements the TLS termination in NLB ?
Is it possible to do it with open source tooling (like IPVS or haproxy) or AWS has some secret sauce here ?
The TLS termination itself is just what it says it is. TLS is a generic streaming protocol just like TCP one level up so you can unwrap it at the LB in a generic way. The magic is that they keep the IPs intact probably with very fancy routing magic, but it seems unlikely AWS will tell you how they did it.
In my SO question here, I have an example of how to terminate a TCP session in HAProxy and pass the unencrypted traffic to a backend.
In short, you need to use ssl in the frontend bind section and both frontend and backend configurations require use of tcp mode. Here is an example of terminating on port 443 and forwarding to port 4567.
frontend tcp-proxy
bind :443 ssl crt combined-cert-key.pem
mode tcp
default_backend bk_default
backend bk_default
mode tcp
server server1 1.2.3.4:4567

haproxy reverse ssl termination

How can I achieve reverse SSL termination with ha proxy?
From my backend via HAproxy I need to a https enabled web service. How can I successfully proxy all traffic to that service via HAProxy?
Below results in Unable to communicate securely with peer: requested domain name does not match the server's certificate.
frontend foofront
bind 127.0.0.1:443
mode tcp
default_backend foo
backend fooback
mode tcp
balance leastconn
server foo foo.bar.com:443 check
With HAProxy you usually have two options for handling TLS-related scenarios. TLS Passthrough and TLS Termination.
TLS Passthrough
Looks like you're trying to do this in the example you gave.
In this mode, HAProxy does not touch traffic in any way, but is just forwarding it to the backend. When TLS is involved, that means that the backend has to have a proper certificate for a domain it's accessed from - if your HAProxy is handling traffic for myexample.com, backend servers will need to have appropriate certificates for myexample.com installed.
You can always check which certificate is served by using openssl s_client:
openssl s_client -connect localhost:443
TLS Termination
Alternatively, you can terminate TLS traffic on HAProxy itself. This will allow you to use any backend (both encrypted and unencrypted). In this case, HAProxy itself decrypts traffic for myexample.com and forwards it to backend.
In your case, configuration would look something like:
frontend foofront
bind 127.0.0.1:80
bind 127.0.0.1:443 ssl crt /path/to/cert/for/myexample.com
mode tcp
default_backend foo
backend foo
mode tcp
balance leastconn
server foo foo.bar.com:443 check ssl verify none # or verify all to enforce ssl checking
You can find more info on both approaches here.
Hope this helps.

Multiple application under SSL (TCP 443)

I implemented a server with two deploy of different services(Apache and OpenFire).
And I want to implement https for my server, so my question is.
How to implement the SSL certificate on my server with two different application working with different ports?
I was looking about how to create a NAT network but I'm not sure if this is the best way to do it.
Apache is an HTTP Server and for SSL by default HTTP Servers use 443 port.
However, Openfire in an XMPP Server and you can enable TLS in it which will by default use 5222 port. And for Openfire's admin application, HTTPS will be on 9091 port by default.
So you can have both servers on same machine with SSL enabled.

HTTPS client - certificate

I write raw HTTPS client in C - a program that takes domain name, resolves it to IP address (via DNS), connects to the IP address on port 443 (SSL), performs SSL handshake and then sends HTTP request via the SSL socket.
To try this program I have a domain hosted on a webserver. I installed Let's encrypt certificate for the domain.
I found out that there are many domain names sharing the same IP address as my domain. So when I connect to the IP address on port 443 to perform SSL handshake who ensures that mydomain's SSL certificate will be sent from the server to the client and not another certificate belonging to other domain name sharing the same IP address?
There exists a TLS extension called Server Name Indication (SNI) which is widely used (and is e.g. require for http/2 clients). You can find the formal specification of this extension in RFC 6066.
Using SNI, a client can send a desired hostname in its Hello request which allows the server to select a matching key/certificate combination for this connection.

SSL/TLS with Eclipse Paho JavaScript Client

I've got a JavaScript-based WebApp that includes the Eclipse Paho client.
The WebApp is stored and executed on an NGINX webserver.
On the same Server where the webserver is installed, the MQTT broker mosquitto is running. I've defined port 8884 as listener port for secured connections.
Running mosquitto_sub (simple C client) with --cafile and -p 8884 works fine!
Now I want to secure the WebApp using SSL by passing mqttOptions = { useSSL: true } in my MQTT client implementation.
I can see that the app is trying to establish an connection to wss://ip instead of ws://ip. But the server responds with a connection refused which is totally clear because I did not configure anything on the webserver as I do not have a clue how to manage this. Will the wss connection be 'mapped' to a https or something? Do I need a websocket proxy in NGINX? Thanks in advance for any help.
You can not use the same port for raw MQTT and MQTT over websockets with mosquitto, you need to create 2 separate listeners.
The fact that you can connect with mosquitto_sub implies you have only set up a listener with the raw MQTT.
e.g.
listener 8883
listener 8884
protocol websockets
This will create a native MQTT listener on 8883 and a MQTT over websockets on port 8884
I did so. Here is the mosquitto conf entry:
listener 8884 127.0.0.1
protocol websockets
cafile /path/to/ca.crt
certfile /path/to/certfile.crt
keyfile /path/to/keyfile.key
require_certificate false
and so the app is trying to connect to myip:8884