Setting up RabbitMQ on Centos 8

You decided you need a message queue, and a good one for that matter, so among the options you are definitely thinking that RabbitMQ is a good choice. You wouldn't be wrong. And also, setting it up, wouldn't be as difficult as you might expect!

By the end of this article we will have:

  • Installed RabbitMQ as a system service
  • Installed the RabbitMQ Management utilities
  • Created an administrator to manage the instance
  • Expose over our firewall the utilities portal
  • Configured the management utilities to run behind our reverse proxy, NGINX for better url management of our services

If you follow the installation instructions on RabbitMQ website for RHEL linux, you will probably be sucessfull. You should actually read it to see all the caveats you need to take in mind when doing so. But I tried here to gather all the different instructions in a single place to ease my server procurement process, and hopefully yours.

So let's get cranking.

Installing RabbitMQ

Although rabbitmq as a package exists on most linux distros by default, it's usually outdated along with it's entries on the usual yum repositories. So we should instead update it with the latest version.

To do so, we need to install the proper repository. A package exists on PackageCloud. We can put that on our repositories list by running:

curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash

Also, we need to have erlang pre-installed, so let's do that (assuming you have enabled EPEL-Repositories already):

yum install erlang

After that, install the server by running:

yum install rabbitmq-server

To test whether we succeeded, try running the server using systemd by issuing:

sudo systemctl start rabbitmq-server
sudo rabbitmqctl status

If everything went ok, you should see a bunch of status metrics for rabbitmq like the ones shown belowe. One of the most important ones that we want to check, it's the total file descriptors allowed. By default, linux allows only 1024 files open for a user, which are too low for a message queue. Anything beyond 32k should be fine. Eventually, values like that will require tinkering prior going in production, but that's something that the rabbitmq tutorials can cover much better.

Example of RabbitMQ status report

Finally, to finish our installation, let's enable rabbitmq as a service on our machine.

sudo systemctl enable rabbitmq-server

Perfect, now each time the server restarts, rabbitmq will auto start by default.

Installing the Management UI

$ sudo rabbitmq-plugins enable rabbitmq_management

Creating a RabbitMQ Management admin account

Now, let's create an admin account to manage our rabbitmq server. There are three commands that you need:

sudo rabbitmqctl add_user <username> <password>
sudo rabbitmqctl set_user_tags <username> administrator
sudo rabbitmqctl set_user_permissions <username> ".*" ".*" ".*"

So, what does each one do. The first, adds a rabbitmq user with the specified username and password.

The second, attaches the administrator tag on the user. RabbitMQ management UI access is controlled by user tags, like management, policymaker, monitoring, administrator. We wanna make our user an admin to be able to manage the rest of the users as well.

Finally, the last command gives permissions of the admin account to all the vhosts, queues etc. You might skip that if you don't want your user to be able to change what goes on the queues, but rather just be able to monitor it (which it will still be able to).

Expose the Management UI to the outside world

So, if you've been following my devops articles, your server should already have FirewallD enabled and configured to allow only specific ports. So if you were to try accessign the ManagementUI remotely, by trying http://<server-domain>:15672 you would fail, gloriously!

If you didn't, shame on you, and please go check out how you should harden your server, at least at the very basic level!

So, fow now, we want to allow that port over our firewall (we are gonna block it again later on). To do so, run:

sudo firewall-cmd --zone=public --permanent --add-port=15672/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --zone=public --list-all

The last command will just show us what ports/services are allowed based on our current config, and you should be able to see the new port we've just added.

Head on now to http://<server-domain>:15672 and login with your admin account!

Putting RabbitMQ behind NGINX reverse proxy

I hate accessing remote services using port numbers. First it feels insecure, and second, i never remember the f***ing ports. So we want to put our RabbitMQ Management UI behind our already running NGINX, using a nice domain/subdomain like

  • rabbit.example.com
  • example.com/infra/rabbit

or whatever.

This is fairly easy if you have your NGINX up and running. First, lets add a new site configuration in our /etc/nginx/conf.d/ . Create a new file with whatever name you want to. I usually like to name the conf files with the url they are going to be serving, so in this case I would create:

cd /etc/nginx/conf.d/
touch infra.example.com.conf
nano infra.example.com.conf

Then, paste the following into the file:

server {
    listen 80;
    server_name infra.example.com;
    location ~* /rabbitmq/api/(.*?)/(.*) {
        proxy_pass http://127.0.0.1:15672/api/$1/%2F/$2?$query_string;
        proxy_buffering                    off;
        proxy_set_header Host              $http_host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location ~* /rabbitmq/(.*) {
        rewrite ^/rabbitmq/(.*)$ /$1 break;
        proxy_pass http://127.0.0.1:15672;
        proxy_buffering                    off;
        proxy_set_header Host              $http_host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Finally, restart nginx to pickup the changes

systemctl restart nginx

If you now visit infra.example.com/rabbitmq/ (mind the last slash!), your management qui will show up!.

Before we finish this, let's close up the port we opened before for the management ui on our firewall.

sudo firewall-cmd --zone=public --permanent --remove-port=15672/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --zone=public --list-all

Conclusion

This was easier than I expected it to be. Of course, we haven't touched anything upon using the actual AMPQ protocol on RabbitMQ for messaging. The whole setup right now assumes you are going to be using RabbitMQ only locally on the server, and we just wanted to be able to easily monitor it remotely.

If you would like to access the messaging ports of RabbitMQ from a remote server, there are further actions to be taken (eg. open up the relevant ports on the firewall). Bare in mind that tunneling the AMPQ connections through NGINX is not natively supported and it's also not very suggested (NGINX is working with HTTP and does not implement AMPQ at all. Some 3rd party extensions have been developed but I am not aware of anything official at the moment of writing this). So you would be better exposing the proper AMPQ port over the firewall in order to use it.

Later.

jentamin

jentamin