1
votes

I have Mosquitto running on a local server, and my aim is to have 3 listeners:

  1. all local network clients to connect without TLS on port 1883 (port 1883 is closed by router to public)
  2. External clients to connect using TLS on port 8883
  3. External client to connect without TLS on port 8880

which using this config works fine;

# Local MQTT
listener 1883
# End Local MQTT

# Insecure MQTT
listener 8880
# End Insecure MQTT

# Secure MQTT
listener 8883
## This is standard and should always be this
cafile   /etc/ssl/certs/DST_Root_CA_X3.pem
## These are from your installation of LE
certfile /home/pi/.node-red/certs/fullchain.pem
keyfile  /home/pi/.node-red/certs/privkey.pem
## Force all clients in this listener to provide a valid certificate, change th$
require_certificate true
## Stop all unauthorised connections
allow_anonymous false
## Use password file
password_file /etc/mosquitto/passwordfile

and which results in healthy Mosquitto log entries;

1575720819: Opening ipv4 listen socket on port 1883.
1575720819: Opening ipv6 listen socket on port 1883.
1575720819: Opening ipv4 listen socket on port 8883.
1575720819: Opening ipv6 listen socket on port 8883.
1575720819: Opening ipv4 listen socket on port 8880.
1575720819: Opening ipv6 listen socket on port 8880.
1575720820: New connection from 140.238.70.128 on port 8880.
1575719390: New client connected from 140.238.70.128 as telegraf (c1, k60, u'raspPi').

BUT... I want to ensure that only the client at 140.238.70.128 is able to connect on port 8880 (TLS isn't an option) so I added the IP address to the config;

# Insecure MQTT
listener 8880 140.238.70.128
# End Insecure MQTT

but that causes Mosquitto to stop, and the log shows;

1575720699: Opening ipv4 listen socket on port 1883.
1575720699: Opening ipv6 listen socket on port 1883.
1575720699: Opening ipv4 listen socket on port 8883.
1575720699: Opening ipv6 listen socket on port 8883.
1575720699: Opening ipv4 listen socket on port 8880.
1575720699: Error: Cannot assign requested address

I would be grateful for any advice as to why this doesn't work, or an alternative solution.

Edit. I also tried restricting the listener to ipv4, but that gave exactly same result;

# Insecure MQTT
listener 8880 140.238.70.128
socket_domain ipv4
# End Insecure MQTT
1

1 Answers

1
votes

The listen directive can only take a address that is local to the machine the broker is running on. This is used to bind a socket to that address on the required port.

You can not use it as a filter for a remote machine, in fact there is no way to configure a port to only accept connections from a specific IP address in mosquitto* (or any other broker that I am aware of).

The only way to achieve what you want to do is to use the machines firewall to drop any packets from other IP addresses addressed to that port. You can use iptables to do this. Something like

iptables -A INPUT -p tcp --dport 8880 ! -s 140.238.70.129 DROP

This should drop any TCP packet destined for port 8880 that is not from 140.238.70.129

While this will work it will only block ipv4 clients, so if your networks has a properly routed IPv6 setup you will need to block access with ip6tables as well (and block access to port 1883).

* you might be able to write a custom auth plugin to do this, but I'm not sure if you get the remote IP address in the details about the user connecting. Also I don't think you can bind authentication to just one listener.