고정된 사설 IP·호스트명과 AMQP를 허용할 애플리케이션 CIDR
MESSAGE BROKER
RabbitMQ 설치·vhost·Management UI
RabbitMQ 공식 저장소를 서명키와 함께 구성하고 애플리케이션별 vhost·사용자·정규식 권한, 로컬 Management UI와 사설망 AMQP 경계를 만든 뒤 실제 연결과 복구를 검증합니다.BEFORE YOU START
시작 전에 준비하세요
Management UI에 접근할 SSH 터널 또는 TLS 역방향 프록시
강한 자격증명을 안전하게 저장할 비밀 관리 시스템
큐·메시지 내구성 요구와 단일 노드 장애 허용 여부에 대한 합의
권장 대상 기본 guest 계정이나 전체 권한을 원격에 노출하지 않고 애플리케이션과 운영자 권한을 분리해 RabbitMQ를 처음 배치하려는 운영자
FOLLOW THE RECIPE
8단계 구성·점검 레시피
노드·클라이언트·vhost 경계 확정
단일 노드는 설치 학습과 비핵심 워크로드 기준입니다. 운영 HA가 필요하면 quorum queue와 3노드 이상 클러스터를 별도로 설계하고, 환경·애플리케이션마다 vhost와 계정을 분리합니다.
cat /etc/os-release
uname -mhostnamectl
ip -brief address
ip routetimedatectl statusnproc
free -h
df -hT /var/lib- Ubuntu 24.04 amd64와 공식 저장소 지원 여부를 확인했습니다.
- 브로커 사설 IP와 애플리케이션 CIDR을 기록했습니다.
- 단일 노드의 장애·메시지 손실 위험을 서비스 소유자가 승인했습니다.
- vhost·애플리케이션 사용자·모니터링 사용자를 분리했습니다.
Management UI가 있다고 메시지 내구성과 HA가 생기지는 않습니다. 큐 유형, publisher confirm, consumer ack, 백업·복구 목표를 애플리케이션과 함께 정합니다.
기존 설치·포트·데이터와 노드 이름을 점검합니다.
기존 노드·포트·데이터 사전 점검
Erlang 노드 이름과 데이터 디렉터리는 호스트명 변경에 민감합니다. 기존 설치가 있으면 새로 설치하거나 노드 이름을 바꾸지 않고 definitions와 데이터 상태를 먼저 확인합니다.
dpkg-query -W rabbitmq-server erlang-basesystemctl status rabbitmq-server.service --no-pagersudo ss -lntup | grep -E ':(4369|5672|15672|25672)[[:space:]]'sudo stat -c '%U %G %a %n' /var/lib/rabbitmq /etc/rabbitmq내용과 Erlang cookie를 출력하지 않습니다.sudo rabbitmq-diagnostics status기존 실행 노드에서만 성공합니다.- 기존 노드명·RabbitMQ·Erlang 버전과 feature flag 상태를 기록했습니다.
- 기존 데이터나 클러스터가 있으면 신규 단일 노드 절차를 중단했습니다.
- 4369·25672는 클러스터 내부 외에는 노출하지 않을 계획입니다.
- 5672·15672의 현재 소유 프로세스를 확인했습니다.
기존 /var/lib/rabbitmq를 지우거나 다른 호스트명의 빈 노드로 시작하면 별도 노드로 보일 수 있습니다. 데이터 초기화로 해결하지 않습니다.
공식 서명키와 배포판별 저장소를 수동으로 구성합니다.
자동 기동을 막고 공식 패키지 설치
RabbitMQ Debian 패키지는 설치 직후 daemon을 시작하므로, 기존 노드가 없음을 확인한 신규 설치에서 unit을 먼저 mask합니다. 그 뒤 공식 키를 파일로 내려받아 지문을 확인하고 Ubuntu Noble용 저장소에서 설치합니다.
sudo systemctl mask rabbitmq-server.serviceprecheck에서 기존 패키지·데이터·노드가 없음을 확인한 신규 설치 분기에서만 실행합니다.curl --fail --location --output /tmp/rabbitmq-release-signing-key.asc "https://github.com/rabbitmq/signing-keys/releases/download/3.0/rabbitmq-release-signing-key.asc"gpg --show-keys --with-fingerprint /tmp/rabbitmq-release-signing-key.asc공식 RabbitMQ 서명 문서의 현재 지문과 별도 대조합니다.gpg --dearmor --output /tmp/com.rabbitmq.team.gpg /tmp/rabbitmq-release-signing-key.asc
sudo install -m 0644 -o root -g root /tmp/com.rabbitmq.team.gpg /usr/share/keyrings/com.rabbitmq.team.gpgsudoedit /etc/apt/sources.list.d/rabbitmq.listsudo apt update
apt-cache policy erlang-base rabbitmq-serversudo apt install erlang-base erlang-asn1 erlang-crypto erlang-eldap erlang-inets erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key erlang-runtime-tools erlang-snmp erlang-ssl erlang-syntax-tools erlang-tools erlang-xmerl rabbitmq-server출처와 변경 목록을 읽고 승인하며 무인 옵션을 사용하지 않습니다.systemctl is-enabled rabbitmq-server.service
systemctl is-active rabbitmq-server.service
sudo ss -lntup | grep -E ':(4369|5672|15672|25672)[[:space:]]'신규 설치 직후에는 masked·inactive이고 네 포트 모두 출력이 없어야 합니다. 다르면 설정 전에 중단합니다.deb [arch=amd64 signed-by=/usr/share/keyrings/com.rabbitmq.team.gpg] https://deb1.rabbitmq.com/rabbitmq-erlang/ubuntu/noble noble main
deb [arch=amd64 signed-by=/usr/share/keyrings/com.rabbitmq.team.gpg] https://deb2.rabbitmq.com/rabbitmq-erlang/ubuntu/noble noble main
deb [arch=amd64 signed-by=/usr/share/keyrings/com.rabbitmq.team.gpg] https://deb1.rabbitmq.com/rabbitmq-server/ubuntu/noble noble main
deb [arch=amd64 signed-by=/usr/share/keyrings/com.rabbitmq.team.gpg] https://deb2.rabbitmq.com/rabbitmq-server/ubuntu/noble noble main- 서명키 지문을 공식 문서와 대조했습니다.
- APT 후보가 Team RabbitMQ 저장소를 가리킵니다.
- RabbitMQ와 Erlang 호환 버전 조합을 공식 문서에서 확인했습니다.
- 패키지 설치 중 서비스는 masked·inactive였고 기본 리스너가 열리지 않았습니다.
- 데이터 디렉터리를 초기화하거나 기존 노드를 덮어쓰지 않았습니다.
GPG·TLS·Release 파일 검증 오류를 trusted=yes나 검증 우회로 넘기지 않습니다. 시간·CA·프록시·저장소 배포판 코드를 확인합니다.
서비스를 계속 중지한 채 사설 AMQP·로컬 Management UI를 먼저 구성합니다.
중지 상태에서 안전한 리스너 구성
서비스를 masked·inactive로 유지한 채 Management UI는 루프백, AMQP는 지정한 사설 IP로 제한합니다. Management plugin은 노드에 접속하지 않는 offline 모드로 다음 시작 시점에만 활성화합니다.
date -u +%Y%m%dT%H%M%SZ출력값 하나를 이번 변경의 <BACKUP_SUFFIX>로 기록하고 이후 모든 백업·복원에 동일하게 사용합니다.sudo cp --archive --no-clobber /etc/rabbitmq/rabbitmq.conf /etc/rabbitmq/rabbitmq.conf.<BACKUP_SUFFIX>.bak기존 파일이 있을 때만 실행합니다.sudoedit /etc/rabbitmq/rabbitmq.confsudo rabbitmq-plugins enable --offline rabbitmq_management노드를 시작하거나 기본 주소로 Management UI를 열지 않고 enabled_plugins만 갱신합니다.sudo stat -c '%U %G %a %n' /etc/rabbitmq/rabbitmq.conf /etc/rabbitmq/enabled_plugins
systemctl is-enabled rabbitmq-server.service
systemctl is-active rabbitmq-server.service설정 파일을 외부 공유하지 않고 service가 여전히 masked·inactive인지 확인합니다.listeners.tcp.1 = <BROKER_PRIVATE_IP>:5672
management.tcp.ip = 127.0.0.1
management.tcp.port = 15672
loopback_users.guest = true
vm_memory_high_watermark.relative = 0.4
disk_free_limit.relative = 1.5외부·사이트 간 트래픽은 TLS listener를 별도로 구성하고 평문 5672를 공인망에 노출하지 않습니다.- 5672는 지정한 사설 IP에만, 15672는 127.0.0.1에만 바인딩됩니다.
- guest 원격 접속을 허용하는 loopback 완화 설정을 추가하지 않았습니다.
- rabbitmq_management는 offline 모드로만 활성화했습니다.
- 설정 완료 뒤에도 서비스는 masked·inactive이고 포트가 열리지 않았습니다.
권한 정규식은 vhost 내 리소스 이름에 적용됩니다. 너무 좁으면 앱이 실패하고 .*는 전체 권한이므로 실제 이름 규칙을 테스트 프로젝트에서 먼저 검증합니다.
제한된 주소로 처음 시작한 뒤 운영·앱·모니터 계정을 만들고 guest를 제거합니다.
제한된 리스너로 첫 기동·계정 부트스트랩
상위 방화벽에서 5672를 승인된 앱 CIDR로 제한한 상태로 unit을 unmask하고 처음 시작합니다. 명명된 운영 관리자·앱·모니터 계정을 대화형으로 만든 뒤 알려진 기본 guest 계정을 즉시 삭제합니다.
sudo systemctl unmask rabbitmq-server.service
sudo systemctl enable --now rabbitmq-server.service이 가이드에서 설정한 신규 노드 분기에서만 실행합니다. 시작 실패 시 reset하지 말고 로그와 설정을 확인합니다.systemctl is-active rabbitmq-server.service
sudo rabbitmq-diagnostics statussudo rabbitmq-diagnostics listenerssudo rabbitmqctl add_user <BREAK_GLASS_ADMIN_USER>
sudo rabbitmqctl set_user_tags <BREAK_GLASS_ADMIN_USER> administrator고유한 강한 비밀번호는 프롬프트에만 입력하고 평상시 공유 계정으로 사용하지 않습니다.sudo rabbitmqctl add_vhost <APP_VHOST>
sudo rabbitmqctl add_user <APP_USER>앱 비밀번호도 대화형 프롬프트에만 입력합니다.sudo rabbitmqctl set_permissions -p <APP_VHOST> <APP_USER> '^<APP_PREFIX>[A-Za-z0-9._-]*$' '^(<APP_PREFIX>[A-Za-z0-9._-]*|amq\.default)$' '^<APP_PREFIX>[A-Za-z0-9._-]*$'실제 exchange·queue 이름 규칙보다 넓게 허용하지 않습니다.sudo rabbitmqctl add_user <MONITOR_USER>
sudo rabbitmqctl set_user_tags <MONITOR_USER> monitoring
sudo rabbitmqctl set_permissions -p <APP_VHOST> <MONITOR_USER> '^$' '^$' '^$'UI 메트릭은 볼 수 있지만 메시지 리소스를 만들거나 읽고 쓰지 못하게 합니다.sudo rabbitmqctl delete_user guest
sudo rabbitmqctl list_users운영 관리자와 앱·모니터 계정 생성이 모두 성공한 뒤에만 삭제하고 목록에 guest가 없음을 확인합니다.sudo rabbitmq-diagnostics environment
sudo rabbitmq-diagnostics alarms
sudo journalctl -u rabbitmq-server.service -n 140 --no-pager환경·로그의 내부 호스트 정보는 외부 공유 전 가립니다.- 서비스가 active이고 rabbitmq-diagnostics status가 성공합니다.
- 리스너 주소가 사설 IP·루프백 설계와 일치합니다.
- 메모리·디스크 경보가 없습니다.
- 명명된 break-glass 운영 관리자, 앱 사용자, 모니터 사용자만 남고 guest는 삭제됐습니다.
- 앱 사용자에는 관리 태그가 없고 모니터 사용자에는 빈 리소스 권한만 있습니다.
서비스 active라도 Erlang cookie·nodename·데이터 권한 오류가 로그에 있을 수 있습니다. listeners·alarms·실제 인증 연결까지 확인합니다.
서로 다른 앱·모니터 자격증명으로 두 번째 연결을 검증합니다.
AMQP 권한과 Management UI 실제 검증
애플리케이션 비밀 저장소에서 자격증명을 주입해 허용 접두사의 테스트 exchange·queue만 생성·publish·consume합니다. 가이드에는 URI나 비밀번호를 넣지 않습니다.
sudo rabbitmqctl list_vhosts name
sudo rabbitmqctl list_userssudo rabbitmqctl list_permissions -p <APP_VHOST>sudo rabbitmq-diagnostics listeners
sudo rabbitmqctl list_connections user vhost peer_host statecurl --fail --silent --show-error --head http://127.0.0.1:15672/sudo rabbitmq-diagnostics check_running
sudo rabbitmq-diagnostics check_local_alarms- 애플리케이션이 허용 접두사의 테스트 리소스로 publish·consume·ack에 성공했습니다.
- 허용하지 않은 이름의 리소스 생성은 거부됐습니다.
- 모니터링 사용자가 SSH 터널 또는 TLS 프록시로 UI에 로그인했지만 메시지를 읽거나 쓸 수 없습니다.
- 두 번째 연결에서도 같은 vhost·권한 경계가 유지됩니다.
- list_users 결과에 guest가 없고 명명된 운영 관리자만 administrator 태그를 가집니다.
연결 성공만으로 메시지 안전성이 확인되지는 않습니다. publisher confirm, consumer ack, 큐 내구성·복제 정책을 실제 클라이언트로 검증합니다.
TLS·네트워크·정의 백업과 리소스 경보를 강화합니다.
TLS·권한·정의 백업 강화
공인망에는 AMQP와 Management UI를 직접 노출하지 않습니다. 원격 AMQP가 필요하면 인증서 hostname 검증을 포함한 TLS와 사설 네트워크를 사용하고, 환경별 vhost·계정을 분리합니다.
sudo ss -lntup | grep -E ':(4369|5672|15672|25672)[[:space:]]'sudo rabbitmqctl list_users
sudo rabbitmqctl list_permissions -p <APP_VHOST>sudo rabbitmq-diagnostics alarms
sudo rabbitmqctl list_queues -p <APP_VHOST> name durable messages_ready messages_unacknowledgedsudo install -d -m 0700 -o rabbitmq -g rabbitmq /var/lib/rabbitmq/backupsudo rabbitmqctl export_definitions /var/lib/rabbitmq/backup/definitions.<BACKUP_SUFFIX>.json파일에는 사용자·권한·해시 등 민감한 운영 정보가 포함될 수 있으므로 외부 공유하지 않습니다.- guest 원격 허용과 management administrator 남용이 없습니다.
- AMQP·클러스터·Management 포트를 승인된 사설 소스만 접근합니다.
- definitions 백업은 0700 경로에 보관하고 별도 암호화 백업 정책을 적용합니다.
- 디스크·메모리·파일 디스크립터·큐 적체 경보를 운영합니다.
- RabbitMQ·Erlang 호환 릴리스와 feature flag 업그레이드 절차를 문서화했습니다.
definitions는 토폴로지와 사용자·권한을 복구하지만 큐의 메시지 데이터 백업은 아닙니다. 메시지 복구 목표는 큐 유형·클러스터·애플리케이션 재처리 설계로 해결합니다.
문제가 생기면 신규 연결을 차단하고 설정·정의를 보존한 롤백으로 이동합니다.
연결 차단과 설정·정의 보존
클라이언트 측 신규 publish를 중지하고 연결 수와 미확인 메시지를 확인한 뒤 서비스를 정상 중지합니다. /var/lib/rabbitmq를 삭제하거나 reset·force_reset을 실행하지 않습니다.
sudo rabbitmqctl list_connections user vhost peer_host state
sudo rabbitmqctl list_queues -p <APP_VHOST> name messages_ready messages_unacknowledgedsudo systemctl stop rabbitmq-server.service
systemctl is-active rabbitmq-server.servicesudo cp --preserve=all /etc/rabbitmq/rabbitmq.conf.<BACKUP_SUFFIX>.bak /etc/rabbitmq/rabbitmq.conf기존 설치의 검증된 같은 시점 백업이 있을 때만 실행합니다.sudo mv --no-clobber /etc/rabbitmq/rabbitmq.conf /etc/rabbitmq/rabbitmq.conf.disabled.<BACKUP_SUFFIX>기존 설정 백업이 없는 최초 설치 분기에서만 실행합니다.sudo systemctl disable rabbitmq-server.service
sudo systemctl mask rabbitmq-server.service신규 설치 롤백 분기에서 실행합니다.sudo stat -c '%U %G %a %n' /var/lib/rabbitmq /var/lib/rabbitmq/backup
sudo du -sh /var/lib/rabbitmq- 애플리케이션 publish를 중지하고 미확인 메시지를 기록했습니다.
- 서비스를 정상 중지한 뒤 설정을 복원·비활성화했습니다.
- reset·force_reset·데이터 삭제 명령을 사용하지 않았습니다.
- 기존 definitions와 Mnesia 데이터, Erlang cookie를 보존했습니다.
- 노출 가능성이 있는 사용자 비밀번호는 비밀 저장소와 RabbitMQ에서 회전 계획을 세웠습니다.
설정 복원만으로 feature flag·데이터 형식이 이전 버전으로 돌아가지는 않습니다. 패키지 다운그레이드 전 공식 호환성과 백업 복원을 별도 검증합니다.
격리된 복제 환경에서 definitions·클라이언트 재연결을 검증한 후 운영 복구를 승인합니다.
SECURITY CHECK
운영 전 마지막 보안 점검
- 알려진 guest 계정을 삭제하고 명명된 break-glass 관리자와 애플리케이션별 vhost·계정을 분리한다.
- 비밀번호를 CLI 인자·URI·설정 파일에 넣지 않고 대화형 입력·비밀 저장소를 사용한다.
- 5672·15672·25672·4369를 공인망에 직접 노출하지 않는다.
- Management 사용자 태그와 메시지 리소스 권한을 별도로 최소화한다.
- definitions 백업의 민감성과 메시지 데이터 복구의 차이를 이해한다.
COMMON ERRORS
자주 막히는 지점
노드가 시작되지 않음
- 증상
- 서비스가 failed이고 nodename·cookie·Mnesia 오류가 보입니다.
- 가능한 원인
- 호스트명 변경, Erlang cookie 권한, 데이터 소유권 또는 호환되지 않는 버전이 원인입니다.
- 확인 순서
- 데이터를 초기화하지 말고 기존 nodename·cookie·패키지 조합과 로그를 대조합니다.
ACCESS_REFUSED
- 증상
- 애플리케이션이 vhost 로그인 또는 리소스 작업에서 거부됩니다.
- 가능한 원인
- 사용자에게 vhost 권한이 없거나 리소스 이름이 정규식 범위를 벗어났습니다.
- 확인 순서
- list_permissions와 실제 exchange·queue 이름을 비교하고 전체 .* 권한으로 우회하지 않습니다.
디스크 경보로 publish 차단
- 증상
- 연결은 되지만 publisher가 block되고 disk alarm이 표시됩니다.
- 가능한 원인
- disk_free_limit보다 여유공간이 작거나 로그·큐가 급증했습니다.
- 확인 순서
- 신규 publish를 줄이고 파일시스템·큐 적체·로그를 확인해 안전하게 공간을 확보합니다.
PRIMARY REFERENCES
공식 문서
- RabbitMQ — Debian·Ubuntu 공식 저장소 설치
- RabbitMQ — 인증·사용자·vhost 권한
- RabbitMQ — Management Plugin
- RabbitMQ — rabbitmq-plugins 오프라인 활성화
- RabbitMQ — Production Deployment Checklist
설치 저장소와 지원 버전은 바뀔 수 있습니다. 검토일 이후에는 링크된 공식 문서와 현재 서버의 패키지 후보 버전을 함께 확인하세요.