安装配置RabbitMQ(启动SSL)及测试案例
安装配置RabbitMQ(启动SSL)及测试案例
- 一. RabbitMQ依赖环境及其安装
- 1. 在Ubuntu中下载安装SSL
- 2. 在ubuntu中安装RabbitMQ服务
- 2.1 下载安装Erlang
- 2.2 下载安装RabbitMQ服务
- 二. RabbitMQ服务配置
- 1. 开启RabbitMQ web端管理界面
- 2. 配置监听支持SSL的端口
- 2.1 生成证书
- 2.2 修改RabbitMQ的配置文件(开启SSL)
- 三. 简单测试RabbitMQ(支持SSL)是否配置成功
- 1. 验证RabbitMQ服务端是否配置成功
- 2. 使用rabbitmq-c的第三方库作为客户端连接RabbitMQ broker
一. RabbitMQ依赖环境及其安装
1. 在Ubuntu中下载安装SSL
下载并安装OpenSSL
sudo apt-get install openssl
安装完之后可查看安装版本情况
openssl version
2. 在ubuntu中安装RabbitMQ服务
2.1 下载安装Erlang
由于安装RabbitMQ需要Erlang环境支持,所以执行命令
sudo apt-get install erlang
安装完毕之后可查看安装情况
erl
2.2 下载安装RabbitMQ服务
sudo apt-get install rabbitmq-server
安装完后启动服务
sudo service rabbitmq-server start
查看服务状态
service rabbitmq-server status
二. RabbitMQ服务配置
1. 开启RabbitMQ web端管理界面
如果想要开启RabbitMQ的 web端管理界面执行如下命令:
/sbin/rabbitmq-plugins enable rabbitmq_management
安装插件完后需要重启RabbitMQ服务
service rabbitmq-server restart
在游览器中输入http://localhost:15672登录,使用默认用户名:guest,默认用户密码:guest,见下图所示
2. 配置监听支持SSL的端口
2.1 生成证书
从github上克隆生成证书的项目,执行如下命令:
git clone https://github.com/Berico-Technologies/CMF-AMQP-Configuration.git && cd CMF-AMQP-Configuration/ssl
生成证书签发机构
sh setup_ca.sh xxx //为自定义的证书签发机构名称,该脚本会在当前目录下生成一个ca目录,存储证书颁发机构的信息以及已经签发的一些证书
生成服务端公钥和私钥
sh make_server_cert.sh rabbit-server 123456 //rabbit-client:生成的密钥前缀名,自定义 123456: 访问该密钥的密码,自定义。
生成客户端公钥和私钥
sh create_client_cert.sh rabbit-client 123456 //同理如上
执行完脚本后ca、server和client的目录分别为:
配置RabbitMQ服务(支持SSL)需要用到三个文件如下:
ca/cacert.pem
server/rabbitmq-server.cert.pem
server/rabbitmq-server.key.pem
2.2 修改RabbitMQ的配置文件(开启SSL)
修改/rabbitmqinaction/rabbitmq/etc/rabbitmq/rabbitmq.config文件,若没有则新建
vi /rabbitmqinaction/rabbitmq/etc/rabbitmq/rabbitmq.config
在rabbitmq.config文件内添加:
[ {ssl, [{versions, ['tlsv1.2', 'tlsv1.1']}]}, {rabbit, [ {tcp_listeners, [5672]}, {ssl_listeners, [5671]}, {ssl_options, [ {cacertfile,"/etc/rabbitmq/ssl/ca/cacert.pem"}, {certfile,"/etc/rabbitmq/ssl/server/rabbitmq-server.cert.pem"}, {keyfile,"/etc/rabbitmq/ssl/server/rabbitmq-server.key.pem"}, {verify, verify_peer}, {fail_if_no_peer_cert, true}, {versions, ['tlsv1.2', 'tlsv1.1']} ]} ]}].
注意: Windows用户zai 配置文件中的反斜杠("")会被解释为转义序列- 因此如果将CA证书的路径指定为c:\cacert.pem,那么你需要输入{cacertfile, “c:\cacert.pem”}或{cacertfile, “c:/cacert.pem”}
ssl_listeners 指定SSL监听5671端口。
设置{fail_if_no_peer_cert,false},声明了我们准备接受客户端,它们可以不向我们发送证书。
设置{verify,verify_peer},声明如果客户端没有向我们发送证书, 我们必须能建立信任链。
设置{verify, verify_none},声明在客户端和服务器之间将不会发生证书交换。
重启RabbitMQ服务
sudo rabbitmqctl stopsudo rabbitmq-server -detached
重启完RabbitMQ服务,可在web界面查看是否开启了SSL监听端口
三. 简单测试RabbitMQ(支持SSL)是否配置成功
1. 验证RabbitMQ服务端是否配置成功
当RabbitMQ服务端监听SSL端口后,可以使用OpenSSL命令行来验证是否可以连接
openssl s_client -connect localhost:5671 -cert client/rabbit-client.cert.pem -key client/rabbit-client.key.pem -CAfile ca/cacert.pem
连接完后,查看RabbitMQ日志,日志文件位置可在web界面查看
当连接建立的时候,broker日志文件应该包含一个新的条目,如下图所示:
至此配置RabbitMQ服务端配置完成!
2. 使用rabbitmq-c的第三方库作为客户端连接RabbitMQ broker
从github上拉取项目:
git clone https://github.com/alanxz/rabbitmq-c.git
安装编译过程不再赘述!
注意:ENABLE_SSL_SUPPORT=ON 选项要设置为ON
测试程序如下:
int main(int argc, char const *const *argv){char const *hostname;int port, status;int timeout;amqp_socket_t *socket;amqp_connection_state_t conn;struct timeval tval;struct timeval *tv;hostname = "192.168.9.101";port = 5671;char const * exchange = "iotng.notification";char const * messagebody = "hello world";char const * nameusr = "jiangyao";char const * password = "jiangyao";char const *cacertfile = "E:/MyWork/jywork/GitCode/rabbittest/cacert.pem";char const *key = "E:/MyWork/jywork/GitCode/rabbittest/rabbit-client.key.pem";char const *cert ="E:/MyWork/jywork/GitCode/rabbittest/rabbit-client.cert.pem";timeout = atoi("3");tv = &tval;tv->tv_sec = timeout;tv->tv_usec = 0;conn = amqp_new_connection();socket = amqp_ssl_socket_new(conn);if (!socket) {printf("creating TCP socket failed\n");}amqp_ssl_socket_set_verify_peer(socket, 0);amqp_ssl_socket_set_verify_hostname(socket, 0);die_on_error(amqp_ssl_socket_set_cacert(socket, cacertfile),"setting CA certificate");amqp_ssl_socket_set_verify_peer(socket, 1);/*amqp_ssl_socket_set_verify_hostname(socket, 1);*/die_on_error(amqp_ssl_socket_set_key(socket, cert, key),"setting client key");status = amqp_socket_open_noblock(socket, hostname, port, tv);if (AMQP_STATUS_OK != status) {printf("opening TCP socket error:%d\n", status);return false;}bool success = amqp_error(amqp_login(conn, "/", AMQP_DEFAULT_MAX_CHANNELS, AMQP_DEFAULT_FRAME_SIZE, 0, AMQP_SASL_METHOD_PLAIN, nameusr, password),"Logging in");if (!success) {printf("amqp_login error\n");return success;}amqp_channel_open(conn, 1);success = amqp_error(amqp_get_rpc_reply(conn), "Opening channel");if (!success) {printf("Opening channel error\n");return success;}{amqp_table_entry_t entries[1];entries[0].key = amqp_cstring_bytes("x-message-ttl");entries[0].value.kind = AMQP_FIELD_KIND_UTF8;entries[0].value.value.bytes = amqp_cstring_bytes("900");amqp_table_t table;table.entries = entries;table.num_entries = 1;amqp_exchange_declare(conn, 1, amqp_cstring_bytes("iotng.notification"), amqp_cstring_bytes("topic"), 0, 1, 0, 0, table);}success = amqp_error(amqp_get_rpc_reply(conn), "Declaring exchange");amqp_basic_properties_t props;props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG;props.content_type = amqp_cstring_bytes("text/plain");props.delivery_mode = 2; /* persistent delivery mode */int ret = amqp_basic_publish(conn, 1, amqp_cstring_bytes("iotng.notification"), amqp_cstring_bytes("mq_sender_test_topic"), 0, 0, &props, amqp_cstring_bytes("hello world!"));if (ret < 0) {printf("amqp_basic_publish ret[%d]\n", ret);}else{printf("send message success!\n");}return 0;}
参考博客:
https://www.cnblogs.com/web424/p/6761153.html.
http://www.blogjava.net/qbna350816/archive/2016/08/02/431433.aspx.