Notifiche degli avvisi
Il firewall controlla il proprio stato con una serie di avvisi,
ad esempio una WAN non raggiungibile o un disco pieno. Gli avvisi attivi sono
sempre mostrati nella pagina Metrics e nel pannello delle notifiche
dell'interfaccia web.
La destinazione degli avvisi, e chi riceve una mail, dipende dall'abbonamento:
- Abbonamento Enterprise: tutti gli avvisi vengono inoltrati a my.nethesis.it, che invia le notifiche via mail, webhook o Telegram. Consultare il manuale di my.nethesis.it per scegliere i destinatari.
- Abbonamento Community o nessun abbonamento: gli avvisi non vengono inviati da nessuna parte e non viene inviata alcuna mail.
Questa pagina descrive due modi per ricevere le notifiche degli avvisi senza un abbonamento Enterprise:
- Avvisi via mail dal firewall: un piccolo script sul firewall invia una mail quando un avviso inizia o termina. Adatto a un singolo firewall.
- Stack Prometheus esterno: un server Prometheus, Alertmanager e Grafana già esistente raccoglie le metriche del firewall e invia gli avvisi. Adatto quando è già presente un server di monitoraggio, o per molti firewall.
Entrambi i metodi possono essere usati anche insieme a un abbonamento Enterprise.
Avvisi via mail dal firewall
Questa è una configurazione avanzata da riga di comando. Non è gestita dall'interfaccia web.
Il firewall valuta i propri avvisi con vmalert, che pubblica gli avvisi attivi su
un indirizzo locale (http://127.0.0.1:8082/api/v1/alerts). Uno script, eseguito
da cron ogni 5 minuti, legge gli avvisi attivi e li confronta con l'esecuzione
precedente. Quando un avviso inizia o viene risolto, lo script invia una mail
usando il client SMTP del firewall.
Configurare il client SMTP
Il firewall ha bisogno di un server di posta esterno per inviare la mail. Aprire un terminale sul firewall e impostare il server, ad esempio:
echo '{"host": "smtp.example.com", "port": 587, "auth": "on", "user": "myuser", "password": "mypassword", "tls": "on", "tls_starttls": "on", "from": "firewall@example.com", "syslog": "LOG_MAIL"}' | /usr/libexec/rpcd/ns.smtp call set
Questo comando sovrascrive /etc/msmtprc. Inviare poi una mail di prova:
echo '{"to": "admin@example.com"}' | /usr/libexec/rpcd/ns.smtp call test
Non proseguire finché la mail di prova non arriva. Consultare il manuale dello sviluppatore per tutte le opzioni.
Creare lo script
Creare il file /usr/local/sbin/alert-mail:
mkdir -p /usr/local/sbin
vi /usr/local/sbin/alert-mail
Incollare il contenuto seguente e cambiare MAIL_TO con l'indirizzo che deve
ricevere gli avvisi:
#!/bin/sh
#
# Send a mail when a firewall alert starts or stops firing
#
# Recipients, separated by a comma
MAIL_TO="admin@example.com"
# Alert severities to notify: info, warning, critical
SEVERITIES="warning critical"
VMALERT_URL="http://127.0.0.1:8082/api/v1/alerts"
STATE_FILE="/var/run/alert-mail.state"
# Keep the previous state if vmalert does not answer
json=$(curl -sf "$VMALERT_URL") || exit 1
current=$(mktemp)
trap 'rm -f "$current"' EXIT
echo "$json" | jq -r --arg sev "$SEVERITIES" '
.data.alerts[]
| select(.state == "firing")
| select(.labels.severity as $s | $sev | split(" ") | any(. == $s))
| (.labels | del(.alertname, .alertgroup, .severity, .service)
| to_entries | map("\(.key)=\(.value)") | join(", ")) as $labels
| "[\(.labels.severity)] \(.name)\(if $labels != "" then " (\($labels))" else "" end): \(.annotations.summary_en // "")"
' | sort > "$current"
touch "$STATE_FILE"
firing=$(grep -Fxv -f "$STATE_FILE" "$current")
resolved=$(grep -Fxv -f "$current" "$STATE_FILE")
if [ -n "$firing" ] || [ -n "$resolved" ]; then
{
echo "To: $MAIL_TO"
echo "Subject: [$(cat /proc/sys/kernel/hostname)] Firewall alerts"
echo
if [ -n "$firing" ]; then
printf 'New alerts:\n%s\n\n' "$firing"
fi
if [ -n "$resolved" ]; then
printf 'Resolved alerts:\n%s\n\n' "$resolved"
fi
printf 'Alerts still firing: %s\n' "$(wc -l < "$current")"
} | msmtp --read-recipients || exit 1
fi
# Save the state only after the mail has been sent, to retry on failure
mv "$current" "$STATE_FILE"
Rendere lo script eseguibile:
chmod +x /usr/local/sbin/alert-mail
La variabile SEVERITIES sceglie quali avvisi inviare via mail. Per
impostazione predefinita gli avvisi info (HighCpuUsage e HighMemoryUsage)
vengono ignorati perché possono essere frequenti. La gravità di ogni avviso è
indicata nei file delle regole in /etc/vmalert/rules/.
Una mail ha questo aspetto:
Subject: [fw1] Firewall alerts
New alerts:
[critical] WanDown (interface=wan): WAN interface wan is offline
Alerts still firing: 1
Pianificare lo script
Eseguire lo script ogni 5 minuti:
crontab -l | grep -q alert-mail || echo '*/5 * * * * /usr/local/sbin/alert-mail' >> /etc/crontabs/root
/etc/init.d/cron restart
Aggiungere lo script ai file conservati durante gli aggiornamenti e inclusi nel backup. Il crontab è già conservato dal sistema.
echo /usr/local/sbin/alert-mail >> /etc/sysupgrade.conf
Tenere presente che:
- La maggior parte degli avvisi diventa attiva solo dopo che il problema dura da alcuni minuti (5 o 10, a seconda della regola). La mail arriva fino a 5 minuti dopo.
- Lo stato dell'ultima esecuzione è conservato in RAM. Dopo un riavvio, gli avvisi ancora attivi vengono inviati di nuovo.
- Se la mail non può essere inviata, lo script riprova all'esecuzione successiva.
- In un cluster in alta affidabilità, configurare lo script su entrambi i nodi. Le impostazioni SMTP sono già sincronizzate.
Provare lo script
Eseguire lo script a mano. Se funziona, non stampa nulla e restituisce 0:
/usr/local/sbin/alert-mail; echo $?
Per verificare l'intera catena, aggiungere un avviso di prova sempre attivo:
cat > /etc/vmalert/rules/zz-test.yaml <<'EOF'
groups:
- name: test
rules:
- alert: TestAlert
expr: vector(1)
labels:
severity: warning
annotations:
summary_en: Test alert, remove /etc/vmalert/rules/zz-test.yaml
EOF
/etc/init.d/vmalert reload
Dopo circa un minuto, eseguire di nuovo lo script: viene inviata una mail con
TestAlert. Rimuovere poi l'avviso di prova, ricaricare vmalert ed eseguire lo
script ancora una volta: una mail segnala l'avviso come risolto.
rm /etc/vmalert/rules/zz-test.yaml
/etc/init.d/vmalert reload
Rimuovere la configurazione
sed -i '/alert-mail/d' /etc/crontabs/root /etc/sysupgrade.conf
/etc/init.d/cron restart
rm -f /usr/local/sbin/alert-mail /var/run/alert-mail.state
Stack Prometheus esterno
Se nella rete è già attivo uno stack Prometheus, Alertmanager e Grafana, può raccogliere le metriche del firewall e inviare gli avvisi:
- Prometheus legge (scrape) le metriche dal firewall e valuta le regole di avviso.
- Alertmanager invia le notifiche, via mail o con qualsiasi altro canale supportato.
- Grafana mostra le metriche nelle dashboard.
Gli avvisi del firewall non vengono inviati a Prometheus: Prometheus raccoglie le stesse metriche usate dal firewall e valuta una propria copia delle regole.
Preparare il firewall
Abilitare l'esportatore Prometheus di Telegraf come descritto in Esportatore Prometheus di Telegraf. La configurazione consigliata prevede:
- il percorso su reverse proxy,
così le metriche viaggiano in HTTPS e l'esportatore ascolta solo su
127.0.0.1; - una password;
- l'indirizzo del server Prometheus nel campo
Allowed networks.
Verificare dal server Prometheus che le metriche siano leggibili:
curl -sk -u prometheus:'<password>' https://fw1.example.com/telegraf-metrics | head
Configurare Prometheus
Aggiungere un job di scrape a prometheus.yml, con un target per ogni firewall:
scrape_configs:
- job_name: nethsecurity
scheme: https
metrics_path: /telegraf-metrics
basic_auth:
username: prometheus
password: <password>
tls_config:
# Only needed if the firewall uses a self-signed certificate
insecure_skip_verify: true
static_configs:
- targets:
- fw1.example.com
- fw2.example.com
rule_files:
- nethsecurity-rules.yml
I nomi delle metriche sono gli stessi usati sul firewall, ad esempio
cpu_usage_idle, mem_used_percent, disk_used_percent,
mwan_interface_online e procd_service_running. Per elencare tutte le
metriche, eseguire sul firewall:
curl -s http://127.0.0.1:9274/metrics | grep -v '^#' | cut -d '{' -f 1 | cut -d ' ' -f 1 | sort -u
Regole di avviso
Creare nethsecurity-rules.yml accanto a prometheus.yml. L'esempio seguente
invia un avviso quando il firewall non è raggiungibile o una WAN non è attiva:
groups:
- name: nethsecurity
rules:
- alert: FirewallDown
expr: up{job="nethsecurity"} == 0
for: 5m
labels:
severity: critical
annotations:
summary: "Firewall {{ $labels.instance }} cannot be reached"
- alert: WanDown
expr: mwan_interface_online{job="nethsecurity"} == 0
for: 5m
labels:
severity: critical
annotations:
summary: "WAN {{ $labels.interface }} is down on {{ $labels.instance }}"
Le regole usate dal firewall si trovano in /etc/vmalert/rules/ e possono
servire da riferimento per altri avvisi. Ricaricare Prometheus dopo aver
modificato la configurazione.
Configurare Alertmanager
Per inviare gli avvisi via mail, configurare un destinatario mail in
alertmanager.yml:
global:
smtp_smarthost: smtp.example.com:587
smtp_from: alertmanager@example.com
smtp_auth_username: myuser
smtp_auth_password: mypassword
route:
receiver: mail
group_by: ['alertname', 'instance']
receivers:
- name: mail
email_configs:
- to: admin@example.com
send_resolved: true
Consultare la documentazione di Alertmanager per gli altri canali, come applicazioni di chat o webhook.
Dashboard Grafana
Aggiungere Prometheus come sorgente dati in Grafana, quindi creare le dashboard
usando i nomi delle metriche elencati sopra. Filtrare i firewall con l'etichetta
job="nethsecurity".