Skip to main content

RabbitMQ Username Password Authentication

Introduction

Authentication is a critical aspect of securing your RabbitMQ message broker. One of the most common and straightforward authentication methods in RabbitMQ is username-password authentication. This mechanism verifies the identity of clients connecting to your RabbitMQ server by requiring them to provide valid credentials before gaining access.

In this guide, we'll explore how to:

  • Understand the default authentication mechanism in RabbitMQ
  • Create and manage users with different permissions
  • Configure password policies
  • Implement username-password authentication in various client applications

Understanding RabbitMQ's Default Authentication

RabbitMQ uses a built-in authentication backend that stores usernames and password hashes in its internal database. By default, a fresh RabbitMQ installation comes with a single user:

UsernamePasswordTags
guestguestadministrator
caution

The default guest user can only connect from localhost for security reasons. This is an important security measure that prevents remote access using these default credentials.

Creating and Managing Users

Adding a New User

You can create new users using the rabbitmqctl command-line tool:

bash
# Syntax
rabbitmqctl add_user <username> <password>

# Example
rabbitmqctl add_user myapp strong_password

Setting User Permissions

After creating a user, you need to grant them permissions to access specific virtual hosts:

bash
# Syntax
rabbitmqctl set_permissions [-p <vhost>] <username> <conf> <write> <read>

# Example: Grant full permissions on the default virtual host
rabbitmqctl set_permissions -p / myapp ".*" ".*" ".*"

The three permission patterns control:

  • conf: Configuration permissions for exchange and queue creation/deletion
  • write: Write permissions for sending messages
  • read: Read permissions for consuming messages

Setting User Tags

User tags determine the level of access a user has in the RabbitMQ management interface:

bash
# Syntax
rabbitmqctl set_user_tags <username> <tag>

# Example: Make a user an administrator
rabbitmqctl set_user_tags myapp administrator

Common user tags include:

  • administrator: Full management and administration rights
  • monitoring: Can view all connections, channels, and nodes
  • management: Can manage users, vhosts, and permissions
  • policymaker: Can manage policies and parameters
  • (no tags): Regular user with no management capabilities

Changing a User's Password

You can update a user's password with:

bash
rabbitmqctl change_password <username> <new_password>

# Example
rabbitmqctl change_password myapp new_strong_password

Deleting a User

To remove a user from the system:

bash
rabbitmqctl delete_user <username>

# Example
rabbitmqctl delete_user old_user

Listing Users

To view all existing users:

bash
rabbitmqctl list_users

This command will output something like:

Listing users ...
user tags
guest [administrator]
myapp [administrator]
worker []

Password Policy and Security

Password Hashing

RabbitMQ stores passwords in hashed form, not as plaintext. By default, it uses the SHA-256 algorithm with a salt for secure password storage.

Password Policy

While RabbitMQ doesn't enforce password complexity rules directly, you should implement strong password policies:

  1. Use long passwords (12+ characters)
  2. Include a mix of uppercase, lowercase, numbers, and special characters
  3. Avoid common words or patterns
  4. Rotate passwords periodically

Using Username-Password Authentication in Client Applications

Node.js with amqplib

javascript
const amqp = require('amqplib');

async function connect() {
try {
// Include username and password in the connection URL
const connection = await amqp.connect('amqp://username:password@localhost:5672');
const channel = await connection.createChannel();

// Rest of your code...

console.log('Connected to RabbitMQ');
} catch (error) {
console.error('Error connecting to RabbitMQ:', error);
}
}

connect();

Python with Pika

python
import pika

credentials = pika.PlainCredentials('username', 'password')
parameters = pika.ConnectionParameters(
host='localhost',
port=5672,
virtual_host='/',
credentials=credentials
)

connection = pika.BlockingConnection(parameters)
channel = connection.channel()

# Rest of your code...

print("Connected to RabbitMQ")

Java with RabbitMQ Java Client

java
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;

public class RabbitMQExample {
public static void main(String[] args) {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
factory.setVirtualHost("/");
factory.setUsername("username");
factory.setPassword("password");

try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
// Rest of your code...

System.out.println("Connected to RabbitMQ");
} catch (Exception e) {
e.printStackTrace();
}
}
}

Spring Boot Application

In application.properties or application.yml:

properties
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=username
spring.rabbitmq.password=password
spring.rabbitmq.virtual-host=/

Authentication Flow

Here's a diagram showing the authentication flow when a client connects to RabbitMQ:

Best Practices for Username-Password Authentication

  1. Never use the default guest user in production Always create custom users with appropriate permissions.

  2. Follow the principle of least privilege Grant users only the permissions they need to perform their tasks.

  3. Use virtual hosts to isolate environments Create separate virtual hosts for development, testing, and production.

  4. Implement credential rotation Change passwords regularly, especially for administrator accounts.

  5. Use environment variables for credentials Don't hardcode credentials in your application code or configuration files.

  6. Monitor failed login attempts Set up logging to detect potential brute force attacks.

  7. Consider additional security measures For production environments, consider combining username-password authentication with TLS and other security features.

Real-World Example: Multi-Service Application

Let's consider a microservices architecture with three services:

  1. Order Service - Creates and manages orders
  2. Inventory Service - Updates inventory levels
  3. Notification Service - Sends notifications to users

Each service requires different levels of access to RabbitMQ:

bash
# Create users for each service
rabbitmqctl add_user order_service password123
rabbitmqctl add_user inventory_service password456
rabbitmqctl add_user notification_service password789

# Set appropriate permissions
# Order service needs to publish to order exchanges and read from response queues
rabbitmqctl set_permissions -p / order_service "^order.*" "^order.*" "^(order|response).*"

# Inventory service needs access to inventory and order exchanges
rabbitmqctl set_permissions -p / inventory_service "^inventory.*" "^(inventory|response).*" "^(order|inventory).*"

# Notification service only needs to consume from notification queues
rabbitmqctl set_permissions -p / notification_service "" "" "^notification.*"

This setup ensures each service has only the permissions it needs to function.

Troubleshooting Authentication Issues

Common Error: ACCESS_REFUSED

If you see an error like ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN, check:

  1. Username and password correctness Ensure you're using the correct credentials without typos.

  2. User existence Verify the user exists using rabbitmqctl list_users.

  3. Virtual host permissions Check if the user has permissions on the virtual host using rabbitmqctl list_permissions.

  4. Remote access for guest user Remember that the guest user can only connect from localhost.

Debugging Authentication

Enable more verbose logging by editing the RabbitMQ configuration file to set the log level:

log.connection.level = debug

Summary

Username-password authentication is the foundation of RabbitMQ security, providing a straightforward way to control access to your message broker. In this guide, we've covered:

  • How to create and manage RabbitMQ users
  • Setting appropriate permissions and user tags
  • Implementing username-password authentication in different programming languages
  • Best practices for secure credential management
  • Troubleshooting common authentication issues

While username-password authentication is sufficient for many applications, consider exploring additional security measures like TLS encryption and OAuth 2.0 integration for enterprise-grade deployments.

Additional Resources

Exercises

  1. Create a new RabbitMQ user with limited permissions that can only publish to a specific exchange and consume from a specific queue.

  2. Write a simple application that connects to RabbitMQ using username-password authentication and publishes a message.

  3. Set up two different users with different permission levels and test their access restrictions.

  4. Configure your application to read RabbitMQ credentials from environment variables instead of hardcoding them.



If you spot any mistakes on this website, please let me know at feedback@compilenrun.com. I’d greatly appreciate your feedback! :)