Skip to content

Commit ef9370c

Browse files
authored
68 as a library user i want to connect to rabbit through tls/ssl (#69)
* added tls certs and makefile * added tls params + test * fixed certificate filenames between local and ci * cleanup magic string (cn in local is different from ci) * fixed lint issue
1 parent 92a9103 commit ef9370c

File tree

9 files changed

+99
-13
lines changed

9 files changed

+99
-13
lines changed

.github/workflows/main.yml

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,34 @@ jobs:
2727
RABBITMQ_DEFAULT_USER: "test-user"
2828
RABBITMQ_DEFAULT_PASS: "test-password"
2929
ports:
30+
- 5671:5671
3031
- 5672:5672
3132
- 15672:15672
3233
volumes:
33-
- ./conf/:/etc/rabbitmq/
34+
- ${{ github.workspace }}/conf/:/etc/rabbitmq/
35+
- ${{ github.workspace }}/certs/:/certs/
3436

3537
steps:
38+
- name: Add the rabbitmq service to /etc/hosts
39+
run: sudo echo "127.0.0.1 test-node" | sudo tee -a /etc/hosts
3640
- uses: actions/checkout@v3
3741
- name: Use Node.js ${{ matrix.node-version }}
3842
uses: actions/setup-node@v3
3943
with:
4044
node-version: ${{ matrix.node-version }}
4145
cache: "npm"
42-
# - name: Generate certificates
43-
# env:
44-
# CN: test-node
45-
# run: |
46-
# git clone https://github.com/rabbitmq/tls-gen tls-gen
47-
# cd tls-gen/basic
48-
# make
49-
# cd ../..
50-
# cp -a tls-gen/basic/result certs/
51-
# sudo chown -R 999:999 certs
52-
# sudo mv certs/server_test-node_certificate.pem certs/server_rabbitmq_certificate.pem
53-
# sudo mv certs/server_test-node_key.pem certs/server_rabbitmq_key.pem
46+
- name: Generate certificates
47+
env:
48+
CN: test-node
49+
run: |
50+
git clone https://github.com/rabbitmq/tls-gen tls-gen
51+
cd tls-gen/basic
52+
make
53+
cd ../..
54+
cp -a tls-gen/basic/result certs/
55+
sudo chown -R 999:999 certs
56+
sudo mv certs/server_test-node_certificate.pem certs/server_rabbitmq_certificate.pem
57+
sudo mv certs/server_test-node_key.pem certs/server_rabbitmq_key.pem
5458
- name: Restart RabbitMQ
5559
run: |
5660
docker restart test-node
@@ -65,6 +69,7 @@ jobs:
6569
docker exec test-node rabbitmqctl set_permissions 'O=client,CN=test-node' '.*' '.*' '.*'
6670
- run: npm test
6771
env:
72+
CN: test-node
6873
RABBITMQ_USER: "test-user"
6974
RABBITMQ_PASSWORD: "test-password"
7075
# - run: cd example && npm install && npm start

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
dist/
22
node_modules/
3+
tls-gen/
34
.envrc

Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
rabbitmq-test:
2+
rm -rf tls-gen;
3+
git clone https://github.com/rabbitmq/tls-gen tls-gen; cd tls-gen/basic; CN=rabbitmq make
4+
chmod -R 755 tls-gen
5+
docker compose down
6+
docker compose up -d
7+
sleep 5
8+
docker exec rabbitmq-js-client rabbitmqctl await_startup
9+
docker exec rabbitmq-js-client rabbitmqctl add_user 'O=client,CN=rabbitmq' ''
10+
docker exec rabbitmq-js-client rabbitmqctl clear_password 'O=client,CN=rabbitmq'
11+
docker exec rabbitmq-js-client rabbitmqctl set_permissions 'O=client,CN=rabbitmq' '.*' '.*' '.*'

conf/rabbitmq.conf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,18 @@ log.console.level = debug
66
log.exchange = true
77

88
listeners.tcp.default = 5672
9+
listeners.ssl.default = 5671
910

1011
deprecated_features.permit.amqp_address_v1 = false
1112

13+
ssl_options.cacertfile = /certs/ca_certificate.pem
14+
ssl_options.certfile = /certs/server_rabbitmq_certificate.pem
15+
ssl_options.keyfile = /certs/server_rabbitmq_key.pem
16+
ssl_options.verify = verify_peer
17+
ssl_options.password = grapefruit
18+
ssl_options.depth = 1
19+
ssl_options.fail_if_no_peer_cert = false
20+
1221
auth_mechanisms.1 = PLAIN
1322
auth_mechanisms.2 = ANONYMOUS
1423
auth_mechanisms.3 = EXTERNAL

cspell.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
"ackmode",
55
"ampq",
66
"amqpvalue",
7+
"cacertfile",
8+
"certfile",
79
"dste",
810
"dstq",
911
"fanout",

docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ services:
77
ports:
88
- "15672:15672"
99
- "5672:5672"
10+
- "5671:5671"
1011
environment:
1112
RABBITMQ_DEFAULT_USER: "rabbit"
1213
RABBITMQ_DEFAULT_PASS: "rabbit"
1314
volumes:
1415
- ./conf/:/etc/rabbitmq/
16+
- "./tls-gen/basic/result/:/certs"

src/environment.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,21 @@ type OauthParams = {
1515
token: string
1616
}
1717

18+
type TlsParams = {
19+
key?: string
20+
cert?: string
21+
ca?: string
22+
rejectUnauthorized?: boolean
23+
}
24+
1825
export type EnvironmentParams = {
1926
host: string
2027
port: number
2128
username: string
2229
password: string
2330
webSocket?: WebSocketParams
2431
oauth?: OauthParams
32+
tls?: TlsParams
2533
}
2634

2735
export class AmqpEnvironment implements Environment {

src/rhea_wrapper.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ function buildConnectParams(
6060
getOauthPassword?: () => string
6161
): ConnectionOptions {
6262
const reconnectParams = buildReconnectParams(connParams)
63+
const tlsParams = buildTlsParams(envParams)
6364
if (envParams.webSocket) {
6465
const ws = websocket_connect(envParams.webSocket.implementation)
6566
const wsUrl = envParams.webSocket.url ?? `ws://${envParams.host}:${envParams.port}/ws`
@@ -75,6 +76,7 @@ function buildConnectParams(
7576
},
7677
...envParams,
7778
...reconnectParams,
79+
...tlsParams,
7880
}
7981
}
8082

@@ -87,19 +89,22 @@ function buildConnectParams(
8789
username: envParams.username,
8890
password: getOauthPassword ? getOauthPassword() : undefined,
8991
...reconnectParams,
92+
...tlsParams,
9093
}
9194
},
9295
host: envParams.host,
9396
port: envParams.port,
9497
username: envParams.username,
9598
password: envParams.oauth.token,
9699
...reconnectParams,
100+
...tlsParams,
97101
}
98102
}
99103

100104
return {
101105
...envParams,
102106
...reconnectParams,
107+
...tlsParams,
103108
}
104109
}
105110

@@ -118,6 +123,17 @@ function buildReconnectParams(connParams?: ConnectionParams) {
118123
return { reconnect: true }
119124
}
120125

126+
function buildTlsParams(envParams?: EnvironmentParams) {
127+
if (envParams && envParams.tls) {
128+
return {
129+
transport: "tls",
130+
...envParams.tls,
131+
}
132+
}
133+
134+
return {}
135+
}
136+
121137
export type LinkOpenEvents = SenderEvents.senderOpen | ReceiverEvents.receiverOpen
122138
export type LinkErrorEvents = SenderEvents.senderError | ReceiverEvents.receiverError
123139
export type OpenLinkMethods =

test/e2e/tls_connection.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { describe, expect, test } from "vitest"
2+
import { createEnvironment, Environment } from "../../src/environment.js"
3+
import { host, username, eventually, numberOfConnections, password } from "../support/util.js"
4+
import { Connection } from "../../src/connection.js"
5+
import { readFile } from "fs/promises"
6+
7+
describe("TLS Connection", () => {
8+
const LOCAL_TEST_CN = "rabbitmq"
9+
10+
let environment: Environment
11+
let connection: Connection
12+
13+
test("creating a TLS connection", async () => {
14+
const cn = process.env.CN ?? LOCAL_TEST_CN
15+
const tls = {
16+
ca: await readFile("./tls-gen/basic/result/ca_certificate.pem", "utf8"),
17+
cert: await readFile(`./tls-gen/basic/result/client_${cn}_certificate.pem`, "utf8"),
18+
key: await readFile(`./tls-gen/basic/result/client_${cn}_key.pem`, "utf8"),
19+
rejectUnauthorized: true,
20+
}
21+
22+
environment = createEnvironment({ host, port: 5671, username, password, tls })
23+
24+
connection = await environment.createConnection()
25+
26+
await eventually(async () => {
27+
expect(await numberOfConnections()).to.eql(1)
28+
})
29+
await connection.close()
30+
await environment.close()
31+
})
32+
})

0 commit comments

Comments
 (0)