Skip to content

Commit c8b0c9a

Browse files
committed
first push
1 parent f25da0c commit c8b0c9a

12 files changed

+279
-2
lines changed

CAcert/CA.conf

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[ req ]
2+
distinguished_name = req_distinguished_name
3+
x509_extensions = v3_ca
4+
prompt = no
5+
6+
[ req_distinguished_name ]
7+
CN = <SERVER_URL>
8+
9+
[ v3_ca ]
10+
basicConstraints = CA:TRUE
11+
keyUsage = keyCertSign, cRLSign
12+
subjectKeyIdentifier = hash
13+
authorityKeyIdentifier = keyid:always,issuer

README.md

+82-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,82 @@
1-
# broker
2-
FLUIDOS Broker
1+
<!-- markdownlint-disable first-line-h1 -->
2+
<p align="center">
3+
<a href="https://www.fluidos.eu/"> <img src="./docs/images/fluidoslogo.png" width="150"/> </a>
4+
<h3 align="center">FLUIDOS Broker</h3>
5+
</p>
6+
7+
# WAN Discovery – RabbitMQ Configuration Guide
8+
9+
This repository provides an example of configuration to set up a RabbitMQ message broker for WAN-based discovery of FLUIDOS Nodes.
10+
11+
## Prerequisites
12+
13+
A vanilla RabbitMQ installation is required on your server.
14+
Refer to the official <a href="https://www.rabbitmq.com/docs/configure"> RabbitMQ Configuration </a> to determine the correct location of the rabbitmq.conf file based on your system.
15+
16+
The provided `rabbitmq.conf` configuration enforces TLS peer authentication for both client and server communications. It configures RabbitMQ to use the default SSL port 5671 and disables the non-SSL TCP port 5672. The configuration also sets the Common Name (CN) of the SSL certificate as the authentication ID, additionally, it restricts access to the Management UI and `rabbitmqadmin` tools to localhost, enhancing the system’s security by limiting administrative access to the local machine only.
17+
To enable TLS-based authentication, activate the RabbitMQ TLS authentication plugin:
18+
`rabbitmq-plugins enable rabbitmq_auth_mechanism_ssl`
19+
20+
## Certificate Issuance
21+
22+
To enable TLS-based authentication, you must generate the self-signed root certificate and a server certificate issued by the root certificate.
23+
We use RSA 2048-bit encryption, and example configurations are provided below.
24+
25+
openssl req -x509 -newkey rsa:2048 -keyout CA_privKey.pem -out CA_cert.pem -days 365 -config CA.conf
26+
27+
openssl x509 -req -in serverCert/server.csr -CA CAcert/CA_cert.pem -CAkey CAcert/CA_privKey.pem -CAcreateserial -out serverCert/server_cert.pem -days 365 -sha256 -extfile serverCert/server.conf -extensions v3_req
28+
29+
30+
## User & Queue Configuration
31+
32+
Some scripts rely on `rabbitmqadmin`, so ensure that an administrator user is properly configured and that the default "guest" user is restricted to localhost access only.
33+
34+
From the `users.yaml` configuration, clients publish to the same exchange but use distinct routing keys, which correspond to their Common Name (CN) in their certificate.
35+
These routing keys determine message distribution across tiers (which act as exchanges).
36+
Each client is subscribed to its own private queue, which receives messages routed from the relevant tiers.
37+
38+
The `setup.sh` script automates the setup of queues, permissions, exchanges, and bindings as defined in `users.yaml`.
39+
Client certificates and private keys, ensuring each client can authenticate securely.
40+
41+
The `eraseRabbit.sh` script removes all queues, bindings, exchanges, and users, except for the default "guest" user, ensuring continued access via `rabbitmqadmin`.
42+
43+
The `deleteUserBindings.sh` script removes all the bindings for the user passed as argument.
44+
45+
Once the setup is over it it is possible to refine the configuration with specific `rabbitmqctl` and `rabbitmqadmin` commands to create more bindings.
46+
Previously issued certificates will continue to function as expected.
47+
48+
## Message Routing & Permissions
49+
50+
Each client can publish only using its assigned routing key to the defaultPeeringExchange and can subscribe only to its private queue.
51+
Clients are categorized into four arbitrary tiers for message routing.
52+
53+
### A simple schema that illustrates a possible broker architecture
54+
55+
<p align="center">
56+
<img src="./docs/images/broker_server.jpg"/>
57+
</p>
58+
59+
## Directory structure example compatible for setup.sh
60+
61+
~/
62+
├─ CAcert/
63+
│ ├─ CA.conf
64+
│ ├─ CA_privKey.pem
65+
│ ├─ CA_cert.pem
66+
├─ clientCert/
67+
│ ├─ clientA_priv.pem
68+
│ ├─ clientA_cert.pem
69+
│ ├─ clientB_priv.pem
70+
│ ├─ clientB_cert.pem
71+
│ ├─ client.conf
72+
│ ├─ clientA_request.csr
73+
│ ├─ clientB_request.csr
74+
├─ serverCert/
75+
│ ├─ server_cert.pem
76+
│ ├─ server_privKey.pem
77+
│ ├─ server.conf
78+
│ ├─ server.csr
79+
├─ users.yaml
80+
├─ setup.sh
81+
├─ cert_gen.sh
82+
├─ eraseRabbit.sh

cert_gen.sh

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/bash
2+
3+
#1-key and csr
4+
openssl req -new -newkey rsa:2048 -nodes -keyout clientCert/"$1"_priv.pem -config clientCert/client.conf -out clientCert/"$1"_request.csr -subj "/CN="$1""
5+
6+
#2-sign client cert
7+
openssl x509 -req -in clientCert/"$1"_request.csr -CA CAcert/CA_cert.pem -CAkey CAcert/CA_privKey.pem -CAcreateserial -out clientCert/"$1"_cert.pem -days 365 -extfile clientCert/client.conf -extensions v3_req -passin pass:<YOUR_PASSWORD>

clientCert/client.conf

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[ req ]
2+
req_extensions = v3_req
3+
prompt = no
4+
5+
[ v3_req ]
6+
basicConstraints = CA:FALSE
7+
keyUsage = digitalSignature, keyEncipherment
8+
extendedKeyUsage = clientAuth

deleteUserBindings.sh

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/bin/bash
2+
3+
# Check 1 param
4+
if [ -z "$1" ]; then
5+
echo "Need 1 parameter"
6+
exit 1
7+
fi
8+
9+
USR_NAME="$1"
10+
11+
# List binding
12+
BINDINGS=$(rabbitmqadmin list bindings source destination routing_key -f tsv)
13+
14+
# For each binding delete if contains USR_NAME
15+
while IFS=$'\t' read -r SOURCE DESTINATION ROUTING_KEY; do
16+
# check if USR_NAME is contained in a destination or routing key
17+
if [[ "$ROUTING_KEY" == *"$USR_NAME"* ]]; then
18+
echo "Remove binding: Exchange '$SOURCE' → Queue '$DESTINATION' with Routing Key '$ROUTING_KEY'..."
19+
rabbitmqadmin delete binding source="$SOURCE" destination="$DESTINATION" destination_type="exchange" properties_key="$ROUTING_KEY"
20+
fi
21+
if [[ "$DESTINATION" == *"$USR_NAME"* ]]; then
22+
echo "Remove binding: Exchange '$SOURCE' → Queue '$DESTINATION' with Routing Key '$ROUTING_KEY'..."
23+
rabbitmqadmin delete binding source="$SOURCE" destination="$DESTINATION" destination_type="queue"
24+
fi
25+
26+
done <<< "$BINDINGS"
27+
28+
echo "Deletion complete"

docs/images/broker_server.jpg

90.6 KB
Loading

docs/images/fluidoslogo.png

34.3 KB
Loading

eraseRabbit.sh

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/bash
2+
3+
# Delete users except guest (default admin only from localhost)
4+
echo "Retrieving users..."
5+
USERS=$(rabbitmqadmin list users name -f tsv)
6+
7+
for USER in $USERS; do
8+
if [ "$USER" != "guest" ]; then
9+
echo "Deleting user: $USER"
10+
rabbitmqadmin delete user name="$USER"
11+
else
12+
echo "Skipping guest"
13+
fi
14+
done
15+
16+
# Delete queues
17+
echo "Retrieving queues..."
18+
QUEUES=$(rabbitmqadmin list queues name -f tsv)
19+
20+
for QUEUE in $QUEUES; do
21+
echo "Deleting queue: $QUEUE"
22+
rabbitmqadmin delete queue name="$QUEUE"
23+
done
24+
25+
# Delete exchange except default (amq.*)
26+
echo "Retrieving exchanges..."
27+
EXCHANGES=$(rabbitmqadmin list exchanges name -f tsv | grep -vE '^amq\.')
28+
29+
for EXCHANGE in $EXCHANGES; do
30+
echo "Deleting exchange: $EXCHANGE"
31+
rabbitmqadmin delete exchange name="$EXCHANGE"
32+
done
33+
34+
echo "All clean!"

rabbitmq.conf

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
management.tcp.listen = 127.0.0.1
2+
listeners.tcp = none
3+
listeners.ssl.default = 5671
4+
ssl_options.cacertfile = /etc/rabbitmq/serverCert/CA_cert.pem
5+
ssl_options.certfile = /etc/rabbitmq/serverCert/server_cert.pem
6+
ssl_options.keyfile = /etc/rabbitmq/serverCert/server_privKey.pem
7+
ssl_options.verify = verify_peer
8+
ssl_options.password = <YOUR_PASSWORD>
9+
ssl_options.fail_if_no_peer_cert = true
10+
auth_mechanisms.1 = EXTERNAL
11+
ssl_cert_login_from = common_name
12+
ssl_handshake_timeout = 5000
13+
log.file = /var/log/rabbitmq/rabbitmq.log
14+
log.file.level = debug

serverCert/server.conf

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[ req ]
2+
distinguished_name = req_distinguished_name
3+
req_extensions = v3_req
4+
prompt = no
5+
6+
[ req_distinguished_name ]
7+
CN = <SERVER_URL>
8+
9+
[ v3_req ]
10+
basicConstraints = CA:FALSE
11+
keyUsage = digitalSignature, keyEncipherment
12+
extendedKeyUsage = serverAuth
13+
subjectAltName = DNS:<SERVER_URL>

setup.sh

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/bash
2+
#EXTERNAL DEFAULT EXCHANGE
3+
rabbitmqadmin declare exchange name=DefaultPeerRequest type=topic durable=true
4+
5+
#INTERNAL TIERS EXCHANGES
6+
rabbitmqadmin declare exchange name=Tier1 type=fanout durable=true internal=true
7+
rabbitmqadmin declare exchange name=Tier2 type=fanout durable=true internal=true
8+
rabbitmqadmin declare exchange name=Tier3 type=fanout durable=true internal=true
9+
rabbitmqadmin declare exchange name=Tier4 type=fanout durable=true internal=true
10+
11+
#read users from conf file and fill arrays
12+
config_file="users.yaml"
13+
users_array=()
14+
write_tier_array=()
15+
read_tier_array=()
16+
17+
USERS=$(rabbitmqadmin list users name -f tsv)
18+
19+
while IFS= read -r line || [[ -n "$line" ]]; do
20+
21+
if [[ "$line" =~ ^[[:space:]]*name[[:space:]]*:[[:space:]]*(.*)$ ]]; then
22+
users_array+=("${BASH_REMATCH[1]}")
23+
fi
24+
25+
if [[ "$line" =~ ^[[:space:]]*write[[:space:]]*:[[:space:]]*(.*)$ ]]; then
26+
write_tier_array+=("${BASH_REMATCH[1]}")
27+
fi
28+
29+
if [[ "$line" =~ ^[[:space:]]*read[[:space:]]*:[[:space:]]*(.*)$ ]]; then
30+
read_tier_array+=("${BASH_REMATCH[1]}")
31+
fi
32+
33+
done < "$config_file"
34+
35+
#for each user
36+
for user in "${!users_array[@]}"; do
37+
FOUND=0
38+
for USER in $USERS; do
39+
if [[ "$USER" == "${users_array[$user]}" ]]; then
40+
FOUND=1
41+
echo "User ${users_array[$user]} already exists"
42+
fi
43+
done
44+
#create rabbitmq user
45+
if [[ $FOUND -eq 0 ]]; then
46+
rabbitmqctl add_user "${users_array[$user]}" ""
47+
48+
#remove PW (auth only through certificates)
49+
rabbitmqctl clear_password ${users_array[$user]}
50+
fi
51+
#personal queue
52+
rabbitmqadmin declare queue name=${users_array[$user]}
53+
54+
#writing permission on default exchange with its route key and reading permission on its queue
55+
rabbitmqctl set_permissions -p / ${users_array[$user]} "\$" "^(DefaultPeerRequest)\$" "^(${users_array[$user]})\$"
56+
57+
#setting message routing to tiers (BINDING EXCHANGE TO EXHANGE)
58+
rabbitmqadmin declare binding source="DefaultPeerRequest" destination="${write_tier_array[$user]}" routing_key="${users_array[$user]}" destination_type="exchange"
59+
60+
#setting queues filling from tiers (BINDING EXCHANGE TO QUEUE)
61+
rabbitmqadmin declare binding source="${read_tier_array[$user]}" destination="${users_array[$user]}"
62+
#certificates generation
63+
if [[ "$FOUND" -eq 0 ]]; then
64+
./cert_gen.sh ${users_array[$user]}
65+
fi
66+
done

users.yaml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
- userA :
3+
name : clientA
4+
write : Tier1
5+
read : Tier1
6+
- userB :
7+
name : clientB
8+
write : Tier1
9+
read : Tier1
10+
# - userC :
11+
# name : clientC
12+
# write : Tier3
13+
# read : Tier3
14+
...

0 commit comments

Comments
 (0)