46

I have installed RabbitMQ on a Debian Linux Squeeze machine, and I would like it to only listen to the localhost interface. I have added

RABBITMQ_NODE_IP_ADDRESS=127.0.0.1

to my /etc/rabbitmq/rabbitmq.conf file, and that makes it bind to only the localhost interface when listening on the amqp port (5672). However, it still binds to all interfaces when listening on ports epmd (4369) and 43380:

# lsof -n -a -i -urabbitmq
COMMAND   PID     USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
epmd     7353 rabbitmq    3u  IPv4 1177662      0t0  TCP *:epmd (LISTEN)
epmd     7353 rabbitmq    5u  IPv4 1177714      0t0  TCP 127.0.0.1:epmd->127.0.0.1:50877 (ESTABLISHED)
beam.smp 7365 rabbitmq   10u  IPv4 1177711      0t0  TCP *:43380 (LISTEN)
beam.smp 7365 rabbitmq   11u  IPv4 1177713      0t0  TCP 127.0.0.1:50877->127.0.0.1:epmd (ESTABLISHED)
beam.smp 7365 rabbitmq   19u  IPv4 1177728      0t0  TCP 127.0.0.1:amqp (LISTEN)

How do I prevent this? Do I have to set up iptables, or are there additional RabbitMQ configuration options that will make it do what I want?

Vebjorn Ljosa
  • 652
  • 1
  • 5
  • 13
  • epmd is not part of RabbitMQ. It is the Erlang naming daemon. Best way to bind only to localhost is to give rabbit the nodename 'rabbit@localhost'. This is the nodename used to cluster multiple RabbitMQ servers, and is used by Erlang to find the node across the network. The part after the @ is the hostname that is running Rabbit and clearly, localhost is not an externally accessible name. – Michael Dillon Jun 11 '11 at 06:40

5 Answers5

52

Putting the following in /etc/rabbitmq/rabbitmq-env.conf will make RabbitMQ and epmd listen on only localhost:

export RABBITMQ_NODENAME=rabbit@localhost
export RABBITMQ_NODE_IP_ADDRESS=127.0.0.1
export ERL_EPMD_ADDRESS=127.0.0.1

It takes a bit more work to configure Erlang to only use localhost for the higher numbered port (which is used for clustering nodes as far as I can tell). If you don't care about clustering and just want Rabbit to be run fully locally then you can pass Erlang a kernel option for it to only use the loopback interface.

To do so, create a new file in /etc/rabbitmq/ - I'll call it rabbit.config. In this file we'll put the Erlang option that we need to load on run time.

[{kernel,[{inet_dist_use_interface,{127,0,0,1}}]}].

If you're using the management plugin and also want to limit that to localhost, you'll need to configure its ports separately, making the rabbit.config include this:

[ {rabbitmq_management, [ {listener, [{port, 15672}, {ip, "127.0.0.1"}]} ]}, {kernel, [ {inet_dist_use_interface,{127,0,0,1}} ]} ].

(Note RabbitMQ leaves epmd running when it shuts down, so if you want to block off Erlang's clustering port, you will need to restart epmd separately from Rabbit.)

Next we need to have RabbitMQ load this at startup. Open up /etc/rabbitmq/rabbitmq.conf again and put the following at the top:

export RABBITMQ_CONFIG_FILE="/etc/rabbitmq/rabbit"

This loads that config file when the rabbit server is started and will pass the options to Erlang.

You should now have all Erlang/RabbitMQ processes listening only on localhost! This can be checked with netstat -ntlap

EDIT : In older versions of RabbitMQ, the configuration file is : /etc/rabbitmq/rabbitmq.conf. However, this file has been replaced by the rabbit-env.conf file.

Jenny D
  • 27,358
  • 21
  • 74
  • 110
David Wilemski
  • 636
  • 6
  • 2
  • 1
    Bravo! Thanks. Note: I needed 'rabbitmq-env.conf' on RabbitMQ for CentOS/RHEL via EPEL. And while the 'rabbit' export for 'rabbit.config' seemed strange to me, it worked sans suffix. – astrostl Feb 28 '13 at 22:29
  • "Open up `/etc/rabbitmq/rabbitmq.conf` again". Why "again"? Do you mean `rabbitmq-env.conf`? – phinz Sep 01 '19 at 08:33
  • 1
    The environment variable `ERL_EPMD_ADDRESS` only controls the listening IP of epmd, if you want to change the cluster port(25672) listening IP of RabbitMQ , then you need to uses the `inet_dist_use_interface` option. `NODE_IP_ADDRESS=127.0.0.1 ERL_EPMD_ADDRESS=127.0.0.1 SERVER_START_ARGS="-kernel inet_dist_use_interface {127,0,0,1}"` – Terry Sep 04 '19 at 08:03
14

To make RabbitMQ listen on localhost / bind only to localhost:

3 Different ways (all equivalent):

  • Put NODE_IP_ADDRESS=127.0.0.1 in the environment variables file (See http://www.rabbitmq.com/configure.html#define-environment-variables)

  • Put tcp_listeners and ssl_listeners properties in config file: The configuration entries tcp_listeners and ssl_listeners govern the interfaces that RabbitMQ listens on. An entry for just listening on localhost would be e.g., {tcp_listeners, [{'127.0.0.1', 5672}]} (Syntax might not be correct, check it) http://www.rabbitmq.com/configure.html#config-file

  • export the env. variable in the startup script (/etc/init.d/rabbitmq-server) export RABBITMQ_NODE_IP_ADDRESS=127.0.0.1

The latter worked for me.

EPMD:

The Epmd program makes distributed parts of Erlang runtime work. If you are building a multi-machine cluster you need to leave them accessible to other nodes and certainly localhost. But it has built-in protection via cookie file.

It hardly ever requires any attention. Just keep in mind that erlang programs (including rabbitmqctl, for example) need to access that port to contact other erlang programs.

But, if you are dealing with financial data or health records, protecting epmd may be a good idea. Default port epmd uses is 4369, other programs connect to it via tcp.

See also: http://www.erlang.org/doc/man/epmd.html#environment_variables

If you need to secure RabbitMQ any further,

  1. Disable the built-in guest account http://www.rabbitmq.com/admin-guide.html#default-state

  2. Consider using SSL and authenticating using the certificate chain

I got these answers from the RabbitMQ community IRC channel.

Would like to thank them.

http://dev.rabbitmq.com/irclog/index.php?date=2011-06-14

Hope the above saves some time for you (it took me 6 hours to find an answer).

Boris
  • 141
  • 1
  • 3
  • The epmd link above has an entry for ERL_EPMD_ADDRESS, presumably to set the addresses epmd will bind to, except I don't see where to set that environment variable for the rabbitmq user. – François Beausoleil Sep 07 '11 at 19:07
5

If you specify environment variables in the rabbitmq.conf file you have to drop the RABBITMQ_ prefix, so try:

NODE_IP_ADDRESS=127.0.0.1

cbz
  • 213
  • 2
  • 6
  • On my installation, either `RABBITMQ_NODE_IP_ADDRESS` or `NODE_IP_ADDRESS` works, but as mentioned only for the amqp port. – Vebjorn Ljosa Feb 15 '11 at 15:03
  • 1
    The epmd port is a function of the erlang port mapper, and afaik it's not possible to restrict it's bind address. – cbz Feb 15 '11 at 22:45
  • Also, the EPMD port is protected with cookies so nobody can connect unless they know your RabbitMQ server cookie. You would only give that cookie to other members of a RabbitMQ cluster. Same principle as an API key. – Michael Dillon Jul 12 '12 at 00:04
1

AFAIK you can't really configure epmd interfaces. You can only set up the epmd port: http://www.erlang.org/faq/how_do_i.html#id55132

Marek
  • 11
  • 1
0

With the recent versions of rabbitmq - this is sufficient to bind all ports to localhost (ipv4) only:

/etc/rabbitmq/rabbitmq-env.conf:

export ERL_EPMD_ADDRESS=127.0.0.1

/etc/rabbitmq/rabbitmq.conf

listeners.tcp.1 = 127.0.0.1:5672
distribution.listener.interface = 127.0.0.1
management.tcp.ip = 127.0.0.1
prometheus.tcp.ip = 127.0.0.1

And restart rabbitmq.

After this, hostname part of RABBITMQ_NODENAME (defaults to rabbit@node-hostname) must resolve to 127.0.0.1 for rabbitmqctl to work. If so - rabbitmqctl status and rabbitmqctl list_queues should work and show previously existed data, and you don't need further reading.

If this is not so, there are two ways:

  1. node-name entry might be added to /etc/hosts:

    127.0.0.1 node-hostname

, but this might reflect on the other software (e.g. node-hostname is required to resolve to public/other ip address).

  1. hostname part might be set to localhost in /etc/rabbitmq/rabbitmq-env.conf:

    export RABBITMQ_NODENAME=rabbit@localhost

, but before using this way and restarting rabbitmq - decide if you need existing rabbitmq data. If no data is needed - simple restart of rabbitmq should fix rabbitmqctl. Otherwise, here is the script that moves existing rabbitmq data from the old name to the new, it implies restart of rabbitmq (make backup of the data directory before running the script: stop rabbitmq and copy out /var/lib/rabbitmq directory):

#!/bin/bash

# place here your nodenames
old=rabbit@nodename
new=rabbit@localhost

set -e

service rabbitmq-server stop
export RABBITMQ_MNESIA_BASE=/var/lib/rabbitmq/mnesia/
export RABBITMQ_MNESIA_DIR="/var/lib/rabbitmq/mnesia/$old"
export RABBITMQ_FEATURE_FLAGS_FILE="$RABBITMQ_MNESIA_BASE/$old-feature_flags"
rabbitmqctl rename_cluster_node "$old" "$new"
cd /var/lib/rabbitmq/mnesia
rm -f "$old.pid"
mv "$old" "$new"
mv "$old-feature_flags" "$new-feature_flags"
mv "$old-plugins-expand" "$new-plugins-expand"
service rabbitmq-server start

echo "Remove ${RABBITMQ_MNESIA_DIR}-rename directory after checking renamed cluster status and data"

More info:

https://www.rabbitmq.com/networking.html

https://github.com/rabbitmq/rabbitmq-server/blob/main/deps/rabbit/priv/schema/rabbit.schema

urusha
  • 479
  • 4
  • 3