Profundis Alerting Docker Image
We provide a Docker image that allows you to setup a robust alerting system that receives real-time alerts from Profundis and routes them to your preferred notification channels.
The Profundis Alerting tool is a lightweight client application that connects to the Profundis platform via Server-Sent Events (SSE) and routes security alerts to various notification channels (Discord, email, etc.) based on configurable rules.
Quick Start
We assume
- Docker is installed on your system (doc).
- You have a valid Profundis API key.
- You know the settings / credentials for at least one notification channel (Discord webhook or email).
- You are comfortable with the Docker CLI usage.
Create a config.yaml file with your settings.
token: "your-profundis-api-token"
# Output channels
channels:
discord_main:
type: "discord"
enabled: true
rate_limit_ms: 500
config:
webhook: "https://discord.com/api/webhooks/your-webhook-url"
template: |
**🚨 New alert received!**
**link:** {{.Protocol}}://{{.Host}}:{{.Port}} {{.StatusCode}} ({{.StatusCodeMessage}}) ({{.Resolution}})
**title:** `{{.Title}} `
**content length:** `{{.ContentLength}} bytes `
**technologies:** `{{join .Technologies ", "}} `
**cert subj:** `{{.CertSubj}} `
**cert org:** `{{.CertSubjOrg}} `
------------------------------------------------------------------------------------
# Alert filters (required even if empty)
filters:
- name: "default_fallback"
channels: ["discord_main"]
conditions: [] # Empty conditions = matches everything (fallback)
Run the Docker container.
docker run -d \
--name profundis-alerting \
--restart unless-stopped \
-v $(pwd)/config.yaml:/config.yaml:ro \
profundis/profundis-alerting:latest
Check the container logs to ensure the container is working properly and connected to profundis.io.
docker logs -f profundis-alerting
Supported Channel Types
- Discord
discord_alerts:
type: "discord"
enabled: true
rate_limit_ms: 500
config:
webhook: "https://discord.com/api/webhooks/your-webhook"
template: |
**Alert on {{.Host}}**
Status: {{.StatusCode}}
Resolution: {{.Resolution}}
email_alerts:
type: "email"
enabled: true
rate_limit_ms: 10000
config:
smtp_host: "smtp.gmail.com"
smtp_port: 587
username: "[email protected]"
password: "your-app-password"
from: "[email protected]"
to: ["[email protected]"]
use_starttls: true
template: |
Alert Details:
Host: {{.Host}}
Status: {{.StatusCode}}
Alerts filtering
You can control which alerts go to which channels using filters.
filters:
- name: "errors_status_codes" # Descriptive name for the filter
channels: ["discord_channel_1"] # List of channels to notify when filter matches
stop_on_match: true # Do not process the other filters
conditions: # Array of matching conditions (all must match)
- field: "status_code"
regex: "^5[0-9]{2}$"
- name: "hosts_containing_prod"
channels: ["my_email_channel"]
stop_on_match: false
conditions:
- field: "host"
regex: ".*prod.*"
You can filter on any field from incoming alerts.
host,resolution,port,protocolstatus_code,status_code_messagealert_id,@timestampcert_expired,cert_trustedtechnologies,titleas_name,ip_country_code- And any other field specified here.
Template system
You can customize the notifications content/layout using Go templates. As visible below, conditions can be used.
template: |
**Alert: {{.Host}}**
Status: {{.StatusCode}} ({{.StatusCodeMessage}})
Time: {{.Timestamp}}
{{if .CertExpired}}
Warning: Certificate expired
{{end}}
Technologies: {{join .Technologies ", "}}
You can access any existing field usig the Go template syntax: {{.FieldName}}. Array fields can be joined using the join keyword: {{join .ArrayField ", "}}.
Rate Limiting
You can control the notifications frequency to prevent spam and being rate limited by the output notification system (e.g. Discord, your SMTP, etc).
channels:
discord_main:
rate_limit_ms: 1000 # Max 1 notification per second
email_critical:
rate_limit_ms: 30000 # Max 1 email per 30 seconds
The rate_limit_ms variable can be set the value to 0 for an unlimited rate, but it is not recommended.
Use multiple channels
channels:
default_fallback:
type: "discord"
enabled: true
rate_limit_ms: 1000
config:
webhook: "https://discord.com/api/webhooks/general-channel"
template: |
**Alert: {{.Host}}**
Status: {{.StatusCode}}
discord_critical:
type: "discord"
enabled: true
rate_limit_ms: 2000
config:
webhook: "https://discord.com/api/webhooks/critical-channel"
template: |
@everyone **CRITICAL ALERT**
Host: {{.Host}}
Status: {{.StatusCode}}
filters:
- name: "critical_alerts"
channels: ["discord_critical"]
stop_on_match: true
conditions:
- field: "status_code"
regex: "^5[0-9]{2}$"
- name: "default_fallback"
channels: ["discord_main"]
conditions: [] # Empty conditions = matches everything (fallback)
Troubleshoot common issues
- Verify the config file syntax with
docker run --rm -v $(pwd)/config.yaml:/config.yaml profundis/profundis-alerting:latest --health-check. - Check file permissions on
config.yaml. - Verify the API key validity.
- Review filter rules for confl