Как заставить RabbitMQ слушать только на локальном хосте?

Вопрос или проблема

Я установил RabbitMQ на машине с Debian Linux Squeeze и хотел бы, чтобы он слушал только интерфейс localhost. Я добавил

RABBITMQ_NODE_IP_ADDRESS=127.0.0.1

в файл /etc/rabbitmq/rabbitmq.conf, и это заставляет его привязываться только к интерфейсу localhost при прослушивании порта amqp (5672). Однако он все равно привязывается ко всем интерфейсам при прослушивании портов epmd (4369) и 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)

Как мне этого избежать? Нужно ли мне настраивать iptables или есть дополнительные параметры конфигурации RabbitMQ, которые позволят сделать то, что я хочу?

Добавив следующее в /etc/rabbitmq/rabbitmq-env.conf, вы заставите RabbitMQ и epmd слушать только localhost:

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

Понадобится немного больше усилий, чтобы настроить Erlang на использование только localhost для порта с высоким номером (который, насколько я понимаю, используется для кластеризации узлов). Если вас не интересует кластеризация и вы просто хотите, чтобы Rabbit работал полностью локально, вы можете передать Erlang параметр ядра, чтобы использовать только интерфейс обратной связи.

Для этого создайте новый файл в /etc/rabbitmq/ — я назову его rabbit.config. В этом файле мы поместим необходимый параметр Erlang, который нужно будет загрузить во время выполнения.

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

Если вы используете плагин управления и также хотите ограничить его только localhost, вам нужно будет отдельно настроить его порты, добавив в rabbit.config следующее:

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

(Обратите внимание, что RabbitMQ оставляет epmd работающим при завершении работы, поэтому, если вы хотите заблокировать порт кластеризации Erlang, вам нужно будет перезапустить epmd отдельно от Rabbit.)

Далее нам нужно заставить RabbitMQ загружать это при старте. Снова откройте /etc/rabbitmq/rabbitmq.conf и добавьте следующее в начале:

export RABBITMQ_CONFIG_FILE="/etc/rabbitmq/rabbit"

Это загружает этот конфигурационный файл при запуске сервера rabbit и передаст параметры Erlang.

Теперь все процессы Erlang/RabbitMQ должны слушать только на localhost! Это можно проверить с помощью netstat -ntlap

EDIT : В старых версиях RabbitMQ конфигурационный файл был: /etc/rabbitmq/rabbitmq.conf. Однако этот файл был заменен на rabbit-env.conf.

Чтобы заставить RabbitMQ слушать на localhost / привязываться только к localhost:

3 разных способа (все эквивалентны):

  • Поместите NODE_IP_ADDRESS=127.0.0.1 в файл переменных окружения
    (Смотрите http://www.rabbitmq.com/configure.html#define-environment-variables)

  • Добавьте свойства tcp_listeners и ssl_listeners в конфигурационный файл:
    Записи конфигурации tcp_listeners и ssl_listeners определяют интерфейсы, на которых RabbitMQ слушает. Запись для прослушивания только на localhost будет, например, {tcp_listeners, [{‘127.0.0.1’, 5672}]}
    (Синтаксис может быть не совсем корректным, проверьте это)
    http://www.rabbitmq.com/configure.html#config-file

  • экспортируйте переменную окружения в скрипте запуска (/etc/init.d/rabbitmq-server)
    export RABBITMQ_NODE_IP_ADDRESS=127.0.0.1

Последний вариант сработал для меня.

EPMD:

Программа Epmd заставляет распределенные части среды выполнения Erlang работать. Если вы строите кластер из нескольких машин, вам нужно оставить их доступными для других узлов и, безусловно, для localhost. Но он имеет встроенную защиту через файл куки.

Ему редко требуется какое-либо внимание. Просто имейте в виду, что программы Erlang (включая rabbitmqctl, например) должны иметь доступ к этому порту, чтобы контактировать с другими программами Erlang.

Но если вы работаете с финансовыми данными или медицинскими записями, то защита epmd может быть хорошей идеей.
Порт по умолчанию, который использует epmd, – это 4369, другие программы подключаются к нему через tcp.

Смотрите также: http://www.erlang.org/doc/man/epmd.html#environment_variables

Если вам нужно дополнительно защитить RabbitMQ,

  1. Отключите встроенный гостевой аккаунт
    http://www.rabbitmq.com/admin-guide.html#default-state

  2. Рассмотрите возможность использования SSL и аутентификации с использованием цепочки сертификатов

Я получил эти ответы от канала IRC сообщества RabbitMQ.

Хотел бы поблагодарить их.

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

Надеюсь, вышеизложенное сэкономит вам время (мне понадобилось 6 часов, чтобы найти ответ).

Если вы указываете переменные окружения в файле rabbitmq.conf, вам нужно убрать префикс RABBITMQ_, попробуйте:

NODE_IP_ADDRESS=127.0.0.1

Насколько я знаю, вы не можете действительно настраивать интерфейсы epmd. Вы можете только настроить порт epmd: http://www.erlang.org/faq/how_do_i.html#id55132

С недавними версиями RabbitMQ это достаточно, чтобы привязать все порты только к localhost (ipv4):

/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

И перезапустите RabbitMQ.

После этого часть hostname в RABBITMQ_NODENAME (по умолчанию rabbit@node-hostname) должна разрешаться в 127.0.0.1, чтобы rabbitmqctl работал. Если это так, то rabbitmqctl status и rabbitmqctl list_queues должны работать и показывать ранее существовавшие данные, и вам не нужно дальнейшее чтение.

Если это не так, есть два способа:

  1. запись node-name может быть добавлена в /etc/hosts:

    127.0.0.1 node-hostname

, но это может отразиться на другом программном обеспечении (например, node-hostname необходимо разрешить на общедоступный/другой ip-адрес).

  1. часть hostname может быть установлена в localhost в /etc/rabbitmq/rabbitmq-env.conf:

    export RABBITMQ_NODENAME=rabbit@localhost

, но прежде чем использовать этот способ и перезапускать RabbitMQ, решите, нужны ли вам имеющиеся данные RabbitMQ. Если данные не нужны – простое перезапуск RabbitMQ должен устранить проблемы с rabbitmqctl. В противном случае, вот скрипт, который перемещает существующие данные RabbitMQ из старого имени в новое, он подразумевает перезапуск RabbitMQ (сделайте резервную копию директории данных перед запуском скрипта: остановите RabbitMQ и скопируйте директорию /var/lib/rabbitmq):

#!/bin/bash

# поместите сюда ваши имена узлов
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 "Удалите директорию ${RABBITMQ_MNESIA_DIR}-rename после проверки состояния и данных переименованного кластера"

Больше информации:

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

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

Для таких же, как я, ответ Давида был действительно полезным, но для моей версии RabbitMQ (3.11.11) мне нужно было
добавить эту строку

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

в /etc/rabbitmq/advanced.config, а не в /etc/rabbitmq/rabbit.conf. Таким образом, я также не использовал переменную RABBITMQ_CONFIG_FILE, поскольку advanced.config не является пользовательским файлом, а скорее встроенным

Также убедитесь, что добавляете пользователей и разрешения после изменения RABBITMQ_NODENAME. Похоже, что настройки связаны с именем узла, поэтому при изменении имени настройки сбрасываются

Тестировалось на Ubuntu 22.04, rabbitmq-server 3.9.13

1. :::5672 -> 127.0.0.1:5672

Раскомментируйте или напишите самостоятельно строку

NODE_IP_ADDRESS=127.0.0.1

в /etc/rabbitmq/rabbitmq-env.conf

2. 0.0.0.0:25672 -> 127.0.0.1:25672

Как в ответе urusha, добавьте

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

в /etc/rabbitmq/rabbitmq.conf

3. :::4369 -> 127.0.0.1:4369

Здесь нам нужно настроить сокет systemd для epmd.

  1. Проверьте, где находится конфигурация:
systemctl status epmd.socket

Ищите строку
Loaded: loaded (</path/to/the/configuration>)

У меня это /lib/systemd/system/epmd.socket

  1. Измените конфигурацию:

в этом файле в разделе [Socket] установите

ListenStream=127.0.0.1:4369

и удалите

BindIPv6Only=both
  1. Перезапустите все
sudo systemctl stop epmd
sudo systemctl stop epmd.socket
sudo systemctl daemon-reload
sudo systemctl restart rabbitmq-service

Ответ или решение

Чтобы настроить RabbitMQ так, чтобы он слушал только интерфейс localhost (127.0.0.1), вам нужно выполнить несколько шагов, поскольку RabbitMQ или его компоненты, такие как EPMD, могут слушать на других интерфейсах по умолчанию. Вот подробная инструкция для этого:

Шаг 1: Настройка RabbitMQ

  1. Настройка конфигурационного файла RabbitMQ:
    Откройте или создайте файл /etc/rabbitmq/rabbitmq.conf и добавьте следующие строки:

    listeners.tcp.default = 127.0.0.1:5672
    management.listener.port = 15672
    management.listener.ip = 127.0.0.1
    distribution.listener.interface = 127.0.0.1

    Эти строки указывают RabbitMQ слушать только на локальном интерфейсе.

  2. Добавление переменных окружения:
    Откройте файл /etc/rabbitmq/rabbitmq-env.conf и добавьте следующие строки:

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

    Это гарантирует, что RabbitMQ и EPMD будут слушать только на localhost.

Шаг 2: Настройка EPMD

EPMD (Erlang Port Mapper Daemon) также нужно настроить, чтобы он слушал только на локальном интерфейсе.

  1. Изменение порта EPMD:
    В некоторых версиях RabbitMQ можно настроить EPMD, добавив следующую строку в /etc/rabbitmq/rabbitmq.conf:

    epmd.port = 4369

    Однако обученные версии RabbitMQ, скорее всего, уже имеют порт EPMD, настроенный по умолчанию.

  2. Корректировка настроек systemd (если применимо):
    Если вы используете systemd, вам потребуется изменить настройки сокета для EPMD. Найдите файл конфигурации, обычно расположенный по пути /lib/systemd/system/epmd.socket, и измените его следующим образом:

    [Socket]
    ListenStream=127.0.0.1:4369

    Убедитесь, что вы удалили строку BindIPv6Only=both.

Шаг 3: Перезапуск

После внесения всех изменений, вам необходимо перезапустить сервисы RabbitMQ и EPMD:

sudo systemctl daemon-reload
sudo systemctl restart epmd
sudo systemctl restart rabbitmq-server

Шаг 4: Проверка

Проверьте, что RabbitMQ слушает только на localhost, используя команду:

netstat -ntpl | grep rabbitmq

Вы должны увидеть, что все порты, такие как 5672 (AMQP), 15672 (управление) и 4369 (EPMD), слушают только на 127.0.0.1.

Заключение

Следуя этим шагам, вы сможете настроить RabbitMQ для прослушивания только на локальном интерфейсе. Это не только повышает безопасность вашей системы, но и упрощает управление и настройку RabbitMQ, когда он используется в локальных или тестовых средах. Если у вас есть дополнительные требования по настройке безопасности, рассмотрите возможность отключения встроенной учетной записи guest и использование SSL для шифрования соединений.

Если у вас возникли дополнительные вопросы, не стесняйтесь спрашивать!

Оцените материал
Добавить комментарий

Капча загружается...