Следуя странице поддержки RabbitMQ TLS, я развернул сервер RabbitMQ на GCP, используя следующий скрипт terraform:
provider "google" {
project = var.project_id
region = var.region
}
resource "google_compute_network" "vpc_network" {
name = "rabbitmq-ssl-network"
}
resource "google_compute_address" "static_ip" {
name = "rabbitmq--ssl-static-ip"
address_type = "EXTERNAL"
}
resource "google_compute_instance" "rabbitmq_instance" {
name = "rabbitmq-vm-ssl"
machine_type = "e2-micro"
zone = "europe-west1-d"
boot_disk {
initialize_params {
image = "debian-cloud/debian-11"
}
}
network_interface {
network = google_compute_network.vpc_network.name
access_config {
nat_ip = google_compute_address.static_ip.address
}
}
metadata_startup_script = <<-EOT
#! /bin/bash
sudo su <<EOF
apt-get update
apt-get install -y docker.io
apt-get install -y git
apt-get install -y make
# Clone tls-gen repository
git clone https://github.com/rabbitmq/tls-gen tls-gen
cd tls-gen/basic
make PASSWORD=bunnies
make verify
make info
ls -l ./result
# Copy the contents of the result directory to /etc/rabbitmq/ssl
mkdir -p /etc/rabbitmq/ssl
cp -r ./result/* /etc/rabbitmq/ssl
# Give permissions so that RabbitMQ can read the files
chmod 755 /etc/rabbitmq/ssl/*
# Create RabbitMQ configuration file
mkdir -p /etc/rabbitmq/conf
cat <<EOC | tee /etc/rabbitmq/conf/rabbitmq.conf
listeners.ssl.default = 5671
mqtt.listeners.ssl.default = 8883
mqtt.listeners.tcp.default = 1883
mqtt.allow_anonymous = true
mqtt.default_user = guest
mqtt.default_pass = guest
mqtt.vhost = /
ssl_options.cacertfile = /etc/rabbitmq/ssl/ca_certificate.pem
ssl_options.certfile = /etc/rabbitmq/ssl/server_rabbitmq-vm-ssl_certificate.pem
ssl_options.keyfile = /etc/rabbitmq/ssl/server_rabbitmq-vm-ssl_key.pem
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = false
EOC
# Start RabbitMQ container with SSL
echo "Starting RabbitMQ container with SSL"
docker run -d --name rabbitmq_mqtt -p 5672:5672 -p 15672:15672 -p 8883:8883 -p 1883:1883 -p 8443:8443 \
-v /etc/rabbitmq/ssl:/etc/rabbitmq/ssl \
-v /etc/rabbitmq/conf/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf \
rabbitmq:3-management
docker exec rabbitmq_mqtt rabbitmq-plugins enable --offline rabbitmq_mqtt
docker restart rabbitmq_mqtt
EOF
EOT
}
resource "google_compute_firewall" "allow_rabbitmq" {
name = "allow-rabbitmq-sll-server"
network = google_compute_network.vpc_network.name
allow {
protocol = "tcp"
ports = ["5672", "15672", "8883", "1883", "8443"]
}
source_ranges = ["0.0.0.0/0"]
}
resource "google_compute_firewall" "allow_ssh" {
name = "allow-ssh-ssl-server"
network = google_compute_network.vpc_network.name
allow {
protocol = "tcp"
ports = ["22"]
}
source_ranges = ["0.0.0.0/0"]
}
output "rabbitmq_ip" {
value = google_compute_address.static_ip.address
}
Это сгенерировало следующие файлы:
root@rabbitmq-vm-ssl:/etc/rabbitmq/ssl# ls
ca_certificate.pem client_rabbitmq-vm-ssl_certificate.pem server_rabbitmq-vm-ssl_certificate.pem
ca_key.pem client_rabbitmq-vm-ssl_key.pem server_rabbitmq-vm-ssl_key.pem
client_rabbitmq-vm-ssl.p12 server_rabbitmq-vm-ssl.p12
У меня есть скрипт Python paho mqtt для публикации данных (я могу добавить его, если интересно - он также не может подключиться), однако сначала я хочу подписаться на клиент Mosquitto для прослушивания опубликованных событий, однако получаю сообщение «Ошибка протокола». " сообщение.
mosquitto_sub -h <public-ip-address> -t testssl/topic --cafile ca_certificate.pem
Error: Protocol error
При подключении через порт TCP (без TLS) связь проходит нормально.
После устранения неполадок TLS Rabbit-mq я убедился, что:
# rabbitmq-diagnostics listeners
Asking node rabbit@<random-string> to report its protocol listeners ...
Interface: [::], port: 15672, protocol: http, purpose: HTTP API
Interface: [::], port: 1883, protocol: mqtt, purpose: MQTT
Interface: [::], port: 8883, protocol: mqtt/ssl, purpose: MQTT over TLS
Interface: [::], port: 15692, protocol: http/prometheus, purpose: Prometheus exporter API over HTTP
Interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Interface: [::], port: 5671, protocol: amqp/ssl, purpose: AMQP 0-9-1 and AMQP 1.0 over TLS
Проверенная версия TLS:
# rabbitmq-diagnostics --silent tls_versions
tlsv1.3tlsv1.2tlsv1.1tlsv1
Я проверил соединение клиент (мой ноутбук)-сервер (предоставленный сервер RabbitMQ) следующим образом:
root@rabbitmq-vm-ssl:/etc/rabbitmq/ssl# openssl s_server -accept 8443 -cert server_rabbitmq-vm-ssl_certificate.pem -key server_rabbitmq-vm-ssl_key.pem -CAfile ca_certificate.pem
Enter pass phrase for server_rabbitmq-vm-ssl_key.pem:
Using default temp DH parameters
ACCEPT
и увидите ошибку, которая может помочь кому-то знающему:
openssl s_client -connect <static-ip>:8443 -cert client_certificate.pem -key client_key.pem -CAfile ca_certificate.pem -verify 8 -verify_hostname rabbitmq-vm-ssl
verify depth is 8
Enter pass phrase for client_key.pem:
000C8AF401000000:error:8000003D:system library:BIO_connect:Connection refused:crypto/bio/bio_sock2.c:178:calling connect()
000C8AF401000000:error:10000067:BIO routines:BIO_connect:connect error:crypto/bio/bio_sock2.c:180:
connect:errno=61
Учитывая, что я не делаю этого каждый день (и по большей части не знаю, что делаю), мне интересно, не упускаю ли я что-то в части сертификата. Обратите внимание, что сертификаты создаются с помощью инструмента tls-gen
, и я не указываю порт/IP-адрес и ожидаю, что при подключении с моего локального компьютера к хосту gcp сервер примет соединение.
А что произойдет, если вы явно укажете порт с помощью -p 8883
в командной строке mosquitto_sub?
@Brits, спасибо за полезный комментарий, я изменил ssl_options.fail_if_no_peer_cert на false, так как считаю, что лучше сначала протестировать только сертификат CA. Я тестирую 8443 в соответствии с руководством RabbitMQ, чтобы проверить работу SSL. Когда я попробовал 8883, я не добрался до части ACCEPT на стороне сервера. Ожидание проверки правильности работы Fail_if_no_peer_cert false.
@hardillb спасибо за комментарий, проверяю сейчас - снова получил ошибку протокола: ``` ❯ mosquitto_sub -h <static-ip> -ttestssl/topic --cafile ./ca_certificate.pem -p 8883 ``` Ошибка: протокол ошибка
Извините, когда вы сказали openssl s_client -connect <static-ip>
... я предположил, что static-ip
был вашим сервером (но теперь посмотрите, что вы просто тестировали на своем локальном компьютере). Пожалуйста, попробуйте запустить это на сервере (порт 8883
), так как это проверит, можно ли установить TLS-соединение. Также добавьте параметр -d
(отладка) к mosquitto_sub
(некоторые версии сообщают об «ошибке протокола» при сбое соединения TLS) и отредактируйте вопрос с полным выводом.
Ошибка mosquitto_sub
не очень полезна, а ошибка openssl s_client
кажется несвязанной. Однако я думаю, что это не удалось, потому что CN сертификата неверен.
Вы можете проверить, передав --insecure
на mosquitto_sub
. Если это поможет, повторно сгенерируйте сертификат, указав CN, установленный на общедоступный IP-адрес сервера.
Кроме того, вы можете повысить уровень детализации, добавив -v
к команде mosquitto_sub
. Это может привести к более полезному сообщению об ошибке.
Спасибо. Я установил общедоступный IP-адрес, но продолжали возникать такие ошибки, как: ``` ~/workspace/experimentation/rabbitmq-mqtt-pubsub/ssl_authentication ············· Rabbitmq-mqtt 3.11 17:31:54 ❯ mosquitto_sub -h <public-ip> -ttestssl/topic --cafile ./ca_certificate.pem -p 8883 -v -d Отправка нуля клиента CONNECT OpenSSL Ошибка [0]: ошибка: 0A000126:SSL подпрограммы::unexpected eof при чтении Ошибка: ошибка протокола ``` Каким-то образом я понял, что устанавливаю пароль в сценарии запуска, используя make PASSWORD=bunnies
. Итак, теперь он говорит только make CN=<public ip> и соединение наконец установлено успешно.
Не могли бы вы проверить порты во всех ваших командах (MQTT прослушивает
8883
, но вы, похоже, тестируете другой порт,8443
). Также предоставьте полнуюmosquitto_sub
командную строку для неудачной попытки (вы указываетеssl_options.fail_if_no_peer_cert
, поэтому необходимо будет предоставить сертификат/ключ клиента).