- Работа
- Linux
- Monitoring
- Сервис уведомлений - ntfy.sh
Сервис уведомлений - ntfy.sh
Пока только заметки
Запуск сервиса
docker-compose.yaml
version: '3.3'
services:
ntfy:
image: binwiederhier/ntfy
container_name: ntfy
command:
- serve
environment:
- TZ=Europe/Moscow # optional: set desired timezone
user: 1002:1002 # optional: replace with your own user/group or uid/gid
network_mode: "host"
volumes:
- /srv/data/ntfy:/var/cache/ntfy
- /srv/docker/ntfy/etc:/etc/ntfy
environment:
NTFY_LISTEN_HTTP: "127.0.0.1:9010"
NTFY_BASE_URL: "https://ntfy.myhost.ru"
NTFY_BEHIND_PROXY: "true"
NTFY_AUTH_FILE: "/var/cache/ntfy/auth.db"
NTFY_AUTH_DEFAULT_ACCESS: "deny-all"
NTFY_ENABLE_LOGIN: "true"
NTFY_REQUIRE_LOGIN: "true"
NTFY_ATTACHMENT_CACHE_DIR: "/var/cache/ntfy/attachments"
NTFY_CACHE_FILE: "/var/cache/ntfy/cache.db"
restart: unless-stopped
Nginx
server {
server_name ntfy.myhost.ru;
location / {
proxy_pass http://127.0.0.1:9010;
proxy_http_version 1.1;
proxy_buffering off;
proxy_request_buffering off;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 3m;
proxy_send_timeout 3m;
proxy_read_timeout 3m;
client_max_body_size 0; # Stream request body to backend
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/ntfy.myhost.ru/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/ntfy.myhost.ru/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
listen 80;
server_name ntfy.myhost.ru;
location /.well-known/acme-challenge/ {
root /srv/www/ntfy/well-known;
}
location / {
return 301 https://$host$request_uri;
}
}
Новый пользователь - docker exec -it ntfy ntfy user a user
Права (можно использовать *) - docker exec -it ntfy ntfy access user myChannel wo
Получения токена (для отправки) - docker exec -it ntfy ntfy token a user
Скрипт отправки системных уведомлений
#!/bin/bash
CHANNEL=Channel
HOST=https://ntfy.myhost.ru
TOKEN=wewedfshdjfg7e8rfiqgewhfd
print_help() {
cat <<'EOF'
Usage:
send_notify.sh [-c CHANNEL] [-p PRIORITY] [SUBJECT...]
echo "message body" | send_notify.sh [options] [SUBJECT...]
Options:
-c CHANNEL Ntfy channel/topic (default: myChannel)
-p PRIORITY Ntfy priority (1-5 or min/low/default/high/max)
-h, --help Show this help
-- Stop parsing options; rest goes to SUBJECT
Examples:
echo "Disk is full" | send_notify.sh -p high disk alert
echo "Host down" | send_notify.sh -c alerts -p 5 production host
EOF
}
SUBJECT="Host: `hostname`"
PRIORITY=""
while [[ $# -gt 0 ]]; do
case "$1" in
-c)
if [[ -z "$2" ]]; then
echo "Channel is required" >&2
exit 1
fi
CHANNEL="$2"
shift 2
;;
-p)
if [[ -z "$2" ]]; then
echo "Priority is required" >&2
print_help >&2
exit 1
fi
PRIORITY="$2"
shift 2
;;
-h|--help)
print_help
exit 0
;;
--)
shift
break
;;
-*)
echo "Unknown option: $1" >&2
print_help >&2
exit 1
;;
*)
break
;;
esac
done
if [[ -n "$*" ]]; then
SUBJECT="${SUBJECT}, $*"
fi
TEXT="$(cat)"
if [[ -z "${TEXT}" ]]; then
exit
fi
PRIORITY_HEADER=()
if [[ -n "${PRIORITY}" ]]; then
PRIORITY_HEADER=(-H "Priority: ${PRIORITY}")
fi
/usr/bin/curl --silent --output /dev/null \
-H "Authorization: Bearer ${TOKEN}" \
-H "Title: ${SUBJECT}" \
"${PRIORITY_HEADER[@]}" \
-d "${TEXT}" \
"${HOST}/${CHANNEL}"
Icinga2
ntfy-host-notification.sh
#!/usr/bin/env bash
PROG="`basename $0`"
HOSTNAME="`hostname`"
unset DEBUG
Usage() {
cat << EOF
The following are required:
-4 HOSTADDRESS (\$address$)
-l HOSTALIAS (\$host.name$)
-n HOSTDISPLAYNAME (\$host.display_name$)
-o HOSTOUTPUT (\$host.output$)
-d LONGDATETIME (\$icinga.long_date_time$)
-s HOSTSTATE (\$host.state$)
-t NOTIFICATIONTYPE (\$notification.type$)
-C NTFYCHANNEL (\$ntfy_channel$)
-H NTFYHOST (\$ntfy_host$)
-T NTFYTOKEN (\$ntfy_token$)
And these are optional:
-b NOTIFICATIONAUTHORNAME (\$notification.author$)
-c NOTIFICATIONCOMMENT (\$notification.comment$)
-P NTFYPRIORITY (1-5 or min/low/default/high/max)
EOF
exit 1;
}
while getopts 4:b:c:d:h:l:n:o:s:t:C:H:T:P: opt
do
case "$opt" in
4) HOSTADDRESS=$OPTARG ;;
b) NOTIFICATIONAUTHORNAME=$OPTARG ;;
c) NOTIFICATIONCOMMENT=$OPTARG ;;
d) LONGDATETIME=$OPTARG ;;
h) Usage ;;
l) HOSTALIAS=$OPTARG ;;
n) HOSTDISPLAYNAME=$OPTARG ;;
o) HOSTOUTPUT=$OPTARG ;;
s) HOSTSTATE=$OPTARG ;;
t) NOTIFICATIONTYPE=$OPTARG ;;
C) NTFYCHANNEL=$OPTARG ;;
H) NTFYHOST=$OPTARG ;;
T) NTFYTOKEN=$OPTARG ;;
P) NTFYPRIORITY=$OPTARG ;;
\?) echo "ERROR: Invalid option -$OPTARG" >&2
Usage ;;
:) echo "Missing option argument for -$OPTARG" >&2
Usage ;;
*) echo "Unimplemented option: -$OPTARG" >&2
Usage ;;
esac
done
SUBJECT="[$NOTIFICATIONTYPE] Host $HOSTDISPLAYNAME is $HOSTSTATE!"
## Build the message itself
NOTIFICATION_MESSAGE=$(cat << EOF
When: $LONGDATETIME
Host: $HOSTALIAS ($HOSTADDRESS)
Info: $HOSTOUTPUT
EOF
)
## Are there any comments? Put them into the message!
if [ -n "$NOTIFICATIONCOMMENT" ] ; then
NOTIFICATION_MESSAGE="$NOTIFICATION_MESSAGE
Comment by $NOTIFICATIONAUTHORNAME:
$NOTIFICATIONCOMMENT"
fi
PRIORITY_HEADER=()
if [ -n "$NTFYPRIORITY" ] ; then
PRIORITY_HEADER=(-H "Priority: ${NTFYPRIORITY}")
fi
curl -H "Authorization: Bearer ${NTFYTOKEN}" -H "Title: ${SUBJECT}" "${PRIORITY_HEADER[@]}" -d "${NOTIFICATION_MESSAGE}" {$NTFYHOST}/${NTFYCHANNEL}
set +x
ntfy-service-notification.sh`
#!/usr/bin/env bash
PROG="`basename $0`"
HOSTNAME="`hostname`"
unset DEBUG
Usage() {
cat << EOF
The following are required:
-4 HOSTADDRESS (\$address$)
-d LONGDATETIME (\$icinga.long_date_time$)
-e SERVICENAME (\$service.name$)
-l HOSTALIAS (\$host.name$)
-n HOSTDISPLAYNAME (\$host.display_name$)
-o SERVICEOUTPUT (\$service.output$)
-s SERVICESTATE (\$service.state$)
-t NOTIFICATIONTYPE (\$notification.type$)
-u SERVICEDISPLAYNAME (\$service.display_name$)
-C NTFYCHANNEL (\$ntfy_channel$)
-H NTFYHOST (\$ntfy_host$)
-T NTFYTOKEN (\$ntfy_token$)
And these are optional:
-b NOTIFICATIONAUTHORNAME (\$notification.author$)
-c NOTIFICATIONCOMMENT (\$notification.comment$)
-P NTFYPRIORITY (1-5 or min/low/default/high/max)
EOF
exit 1;
}
while getopts 4:b:c:d:e:l:n:o:s:t:u:C:H:T:P: opt
do
case "$opt" in
4) HOSTADDRESS=$OPTARG ;;
b) NOTIFICATIONAUTHORNAME=$OPTARG ;;
c) NOTIFICATIONCOMMENT=$OPTARG ;;
d) LONGDATETIME=$OPTARG ;;
e) SERVICENAME=$OPTARG ;;
h) Usage ;;
l) HOSTALIAS=$OPTARG ;;
n) HOSTDISPLAYNAME=$OPTARG ;;
o) SERVICEOUTPUT=$OPTARG ;;
s) SERVICESTATE=$OPTARG ;;
t) NOTIFICATIONTYPE=$OPTARG ;;
u) SERVICEDISPLAYNAME=$OPTARG ;;
C) NTFYCHANNEL=$OPTARG ;;
H) NTFYHOST=$OPTARG ;;
T) NTFYTOKEN=$OPTARG ;;
P) NTFYPRIORITY=$OPTARG ;;
\?) echo "ERROR: Invalid option -$OPTARG" >&2
Usage ;;
:) echo "Missing option argument for -$OPTARG" >&2
Usage ;;
*) echo "Unimplemented option: -$OPTARG" >&2
Usage ;;
esac
done
## Build the message's subject
SUBJECT="[$NOTIFICATIONTYPE] $SERVICEDISPLAYNAME on $HOSTDISPLAYNAME is $SERVICESTATE!"
## Build the message itself
NOTIFICATION_MESSAGE=$(cat << EOF
When: $LONGDATETIME
Host: $HOSTALIAS ($HOSTADDRESS)
Info: $SERVICEOUTPUT
EOF
)
## Are there any comments? Put them into the message!
if [ -n "$NOTIFICATIONCOMMENT" ] ; then
NOTIFICATION_MESSAGE="$NOTIFICATION_MESSAGE
Comment by $NOTIFICATIONAUTHORNAME:
$NOTIFICATIONCOMMENT"
fi
PRIORITY_HEADER=()
if [ -n "$NTFYPRIORITY" ] ; then
PRIORITY_HEADER=(-H "Priority: ${NTFYPRIORITY}")
fi
/usr/bin/curl -H "Authorization: Bearer ${NTFYTOKEN}" -H "Title: ${SUBJECT}" "${PRIORITY_HEADER[@]}" -d "${NOTIFICATION_MESSAGE}" {$NTFYHOST}/${NTFYCHANNEL}
set +x
commands.conf
object NotificationCommand "ntfy-host-notifaction" {
import "plugin-notification-command"
command = [
"/data/etc/icinga2/scripts/ntfy-host-notification.sh"
]
timeout = 2m
arguments += {
"-4" = {
required = true
value = "$address$"
}
"-b" = {
required = true
value = "$notification.author$"
}
"-c" = "$notification.comment$"
"-d" = {
required = true
value = "$icinga.long_date_time$"
}
"-l" = "$host.name$"
"-n" = "$host.display_name$"
"-o" = {
required = true
value = "$host.output$"
}
"-C" = {
required = true
value = "$ntfy_channel$"
}
"-T" = {
required = true
value = "$ntfy_token$"
}
"-H" = {
required = true
value = "$ntfy_host$"
}
"-s" = "$host.state$"
"-t" = "$notification.type$"
"-P" = "$ntfy_priority$"
}
}
object NotificationCommand "ntfy-service-notification" {
import "plugin-notification-command"
command = [
"/data/etc/icinga2/scripts/ntfy-service-notification.sh"
]
timeout = 2m
arguments += {
"-4" = {
required = true
value = "$address$"
}
"-b" = {
required = true
value = "$notification.author$"
}
"-c" = "$notification.comment$"
"-d" = {
required = true
value = "$icinga.long_date_time$"
}
"-e" = {
required = true
value = "$service.name$"
}
"-l" = "$host.name$"
"-n" = "$host.display_name$"
"-o" = {
required = true
value = "$service.output$"
}
"-s" = "$service.state$"
"-t" = "$notification.type$"
"-u" = {
required = true
value = "$service.display_name$"
}
"-C" = {
required = true
value = "$ntfy_channel$"
}
"-T" = {
required = true
value = "$ntfy_token$"
}
"-H" = {
required = true
value = "$ntfy_host$"
}
"-P" = "$ntfy_priority$"
}
}
templates.conf
template Notification "ntfy-host-notification" {
command = "ntfy-host-notifaction"
states = [ Up, Down ]
types = [ Problem, Acknowledgement, Recovery, Custom,
FlappingStart, FlappingEnd ]
vars += {
notification_logtosyslog = false
ntfy_token = "weklrhjsdfasdf7qw8eudfasf"
ntfy_host = "https://ntfy.myhost.ru"
ntfy_channel = "Channel"
ntfy_priority = "5"
}
interval = 5h
period = "24x7 local"
}
template Notification "ntfy-service-notification" {
command = "ntfy-service-notification"
states = [ OK, Warning, Critical, Unknown ]
types = [ Problem, Acknowledgement, Recovery, Custom,
FlappingStart, FlappingEnd ]
vars += {
ntfy_token = "shkfwfr8w9erydfidsahfkjq4r"
ntfy_host = "https://ntfy.myhost.ru"
ntfy_channel = "Channel"
ntfy_priority = service.vars.ntfy_priority ? service.vars.ntfy_priority : ""
}
interval = 5h
period = "24x7 local"
}
notifications.conf
apply Notification "ntfy-icingaadmin" to Host {
import "ntfy-host-notification"
users = [ "icingaadmin" ]
assign where host.vars.notification.ntfy && host.vars.nohostalert != true
}
apply Notification "ntfy-icingaadmin" to Service {
import "ntfy-service-notification"
users = [ "icingaadmin" ]
assign where service.vars.notification.ntfy
}
[ Править ]
