This guide explains how to set up mutual TLS (mTLS) security for ServiceRadar, from certificate generation through deployment.
graph TB
subgraph "Agent Node"
AG[Agent<br/>Role: Server<br/>:50051]
SNMPCheck[SNMP Checker<br/>:50054]
DuskCheck[Dusk Checker<br/>:50052]
SweepCheck[Network Sweep]
AG --> SNMPCheck
AG --> DuskCheck
AG --> SweepCheck
end
subgraph "Poller Service"
PL[Poller<br/>Role: Client+Server<br/>:50053]
end
subgraph "Core Service"
CL[Core Service<br/>Role: Server<br/>:50052]
DB[(Database)]
API[HTTP API<br/>:8090]
CL --> DB
CL --> API
end
%% Client connections from Poller
PL -->|mTLS Client| AG
PL -->|mTLS Client| CL
%% Server connections to Poller
HC1[Health Checks] -->|mTLS Client| PL
classDef server fill:#e1f5fe,stroke:#01579b
classDef client fill:#f3e5f5,stroke:#4a148c
classDef dual fill:#fff3e0,stroke:#e65100
class AG,CL server
class PL dual
class SNMPCheck,DuskCheck,SweepCheck client
ServiceRadar uses the following certificate files:
root.pem
- The root CA certificateserver.pem
- Server certificateserver-key.pem
- Server private keyclient.pem
- Client certificateclient-key.pem
- Client private key
First, install the CloudFlare SSL toolkit (cfssl) which we'll use for generating certificates:
go install github.com/cloudflare/cfssl/cmd/...@latest
Create cfssl.json
:
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"rootca": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "8760h",
"ca_constraint": {
"is_ca": true,
"max_path_len": 0
}
},
"server": {
"usages": ["signing", "key encipherment", "server auth"],
"expiry": "8760h"
},
"client": {
"usages": ["signing", "key encipherment", "client auth"],
"expiry": "8760h"
}
}
}
}
Create csr.json
:
{
"hosts": ["localhost", "127.0.0.1"],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [{
"O": "ServiceRadar"
}]
}
Generate the root CA:
cfssl selfsign -config cfssl.json --profile rootca "ServiceRadar CA" csr.json | cfssljson -bare root
Generate server and client keys:
cfssl genkey csr.json | cfssljson -bare server
cfssl genkey csr.json | cfssljson -bare client
Sign the certificates:
cfssl sign -ca root.pem -ca-key root-key.pem -config cfssl.json -profile server server.csr | cfssljson -bare server
cfssl sign -ca root.pem -ca-key root-key.pem -config cfssl.json -profile client client.csr | cfssljson -bare client
ServiceRadar components need different certificates based on their role:
-
Poller (RolePoller)
- Needs all certificates (client + server)
- Acts as both client (connecting to agents/core) and server (health checks)
-
Agent (RoleAgent)
- Needs all certificates (client + server)
- Acts as server (accepting poller connections) and client (connecting to checkers)
-
Core (RoleCore)
- Needs only server certificates
- Acts as server only (accepting connections)
-
Checker (RoleChecker)
- Needs only server certificates
- Acts as server only (accepting connections)
- Create the certificates directory:
sudo mkdir -p /etc/serviceradar/certs
sudo chown serviceradar:serviceradar /etc/serviceradar/certs
sudo chmod 700 /etc/serviceradar/certs
- Install certificates based on role:
For core/checker (server-only):
sudo cp root.pem server*.pem /etc/serviceradar/certs/
For poller/agent (full set):
sudo cp root.pem server*.pem client*.pem /etc/serviceradar/certs/
- Set permissions:
sudo chown serviceradar:serviceradar /etc/serviceradar/certs/*
sudo chmod 644 /etc/serviceradar/certs/*.pem
sudo chmod 600 /etc/serviceradar/certs/*-key.pem
Server-only deployment (Core/Checker):
/etc/serviceradar/certs/
├── root.pem (644)
├── server.pem (644)
└── server-key.pem (600)
Full deployment (Poller/Agent):
/etc/serviceradar/certs/
├── root.pem (644)
├── server.pem (644)
├── server-key.pem (600)
├── client.pem (644)
└── client-key.pem (600)
Verify your installation with:
ls -la /etc/serviceradar/certs/
Example output (Core instance):
total 20
drwx------ 2 serviceradar serviceradar 4096 Feb 21 20:46 .
drwxr-xr-x 3 serviceradar serviceradar 4096 Feb 21 22:35 ..
-rw-r--r-- 1 serviceradar serviceradar 920 Feb 21 04:47 root.pem
-rw------- 1 serviceradar serviceradar 227 Feb 21 20:44 server-key.pem
-rw-r--r-- 1 serviceradar serviceradar 928 Feb 21 20:45 server.pem
Common issues and solutions:
-
Permission denied
- Verify directory permissions:
700
- Verify file permissions:
644
for certificates,600
for keys - Check ownership:
serviceradar:serviceradar
- Verify directory permissions:
-
Certificate not found
- Confirm all required certificates for the role are present
- Double-check file paths in configuration
-
Invalid certificate
- Ensure certificates are properly formatted PEM files
- Verify certificates were generated with correct profiles
-
Connection refused
- Verify server name in config matches certificate CN
- Check that all required certificates are present for the role
- Confirm service has proper read permissions
-
Testing with grpcurl
- Install grpcurl:
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
- Test health check endpoint with mTLS:
grpcurl -cacert root.pem \ -cert client.pem \ -key client-key.pem \ -servername <SERVER_IP> \ <SERVER_IP>:50052 \ grpc.health.v1.Health/Check
- Successful response should show:
{ "status": "SERVING" }
- If this fails but certificates are correct, verify:
- Server is running and listening on specified port
- Firewall rules allow the connection
- The servername matches the certificate's Common Name (CN)
- Install grpcurl: