Notakey Authentication Appliance opisuje się zwykle jako serwer
uwierzytelniania: następuje logowanie, na telefonie pojawia się żądanie push,
użytkownik je zatwierdza. Ten sam kanał dostarczania przyjmuje jednak jeszcze
drugi typ wiadomości, zwykłe powiadomienie, i zamienia appliance w coś
bardziej uniwersalnego: kanał wiadomości push do każdego telefonu
zarejestrowanego w Twojej usłudze, wywoływany z dowolnego skryptu jednym
poleceniem curl.
any script ──HTTPS──▶ appliance API ──push──▶ enrolled phone
(cron, monitoring, /notify Notakey Authenticator
home automation…)
W odróżnieniu od żądania uwierzytelnienia powiadomienie nie prosi o zatwierdzenie: po prostu pojawia się na telefonie, zaadresowane do nazwy użytkownika, i trafia jednocześnie na wszystkie zarejestrowane urządzenia danej osoby. Dzięki temu staje się gotowym zamiennikiem tam, gdzie inaczej podłączałbyś SMS (koszt za wiadomość, łatwy do podrobienia nadawca) lub e-mail (przeczytany dopiero w poniedziałek): monitorowanie zadań, powiadomienia dla dyżurnych, ogłoszenia dla pracowników.
Wymagania
- Działający Notakey Appliance (w chmurze lub on-premise) z usługą i co najmniej jednym użytkownikiem, który zarejestrował telefon. Jeśli już korzystasz z VPN 2FA lub SSO, masz to wszystko: powiadomienia idą przez tę samą usługę co logowania albo przez osobną, jeśli chcesz innego brandingu.
- Dane logowania do API (client ID i client secret), utworzone w panelu w sekcji Access credentials (patrz krok 1 poniżej).
curlijqna czymkolwiek, co ma dostęp do appliance. To cała lista zależności.
Krok 1: Utwórz dane logowania do API
W panelu otwórz Access credentials i utwórz dane logowania dla swoich skryptów. Liczą się tu dwie rzeczy:
- Zakresy (scopes). Przyznaj
urn:notakey:notify. To zakres, którego wymaga ten przewodnik. Istnieje teżurn:notakey:auth, służący do tworzenia żądań uwierzytelnienia (zatwierdź/odrzuć); dodaj go tylko wtedy, gdy te same dane logowania mają robić jedno i drugie. Danych z uprawnieniem wyłącznie do powiadomień nie da się nadużyć do wywoływania zatwierdzeń logowania, więc utrzymuj listę zakresów tak krótką, jak pozwala na to zadanie. - Otrzymasz client ID oraz client secret. Secret uprawnia do wysyłania wiadomości do wszystkich w usłudze, traktuj go więc jak hasło roota.
Krok 2: Wymień dane na token i utrzymuj token świeży
Samo wywołanie notify nie używa client secret. Korzysta z tokena dostępu typu bearer, uzyskanego standardowym grantem OAuth 2.0 typu client-credentials. Tokeny dostępu są celowo krótkotrwałe: zaplanuj odnawianie mniej więcej raz na godzinę, w przeciwnym razie Twoje skrypty w pewnym momencie zaczną kończyć się błędami autoryzacji, akurat wtedy, gdy przez 59 minut działały bez zarzutu.
Odnawianie tokena jest więc zadaniem cron, a nie jednorazowym krokiem konfiguracyjnym:
#!/bin/bash
# /usr/local/bin/ntk-token-renew — cron: 0 * * * *
curl -s -X POST https://ntk.example.com/api/token \
-d 'grant_type=client_credentials&client_id=<client-id>&client_secret=<client-secret>&scope=urn:notakey:notify' \
| jq -r .access_token > /etc/notakey/api.token
Skrypt zawiera client secret i zapisuje token, więc zabezpiecz jedno i drugie:
chmod 700 /usr/local/bin/ntk-token-renew # root-only, holds the secret
install -m 600 /dev/null /etc/notakey/api.token
Jeśli przyznałeś także urn:notakey:auth, poproś o niego jako osobny token
do osobnego pliku (to samo wywołanie, scope=urn:notakey:auth), zamiast
jednego tokena z oboma zakresami; skrypty powiadomień nigdy nie będą wtedy
trzymać tokena, którym dałoby się utworzyć zatwierdzenia logowania.
Krok 3: Jeden skrypt notify wielokrotnego użytku
Wszystko dalej w tym przewodniku wywołuje ten jeden skrypt. Przyjmuje on nazwę użytkownika, tytuł oraz treść wiadomości:
#!/bin/bash
# /usr/local/bin/ntk-notify <username> <title> <description>
token=$(cat /etc/notakey/api.token)
curl -X POST -H "Content-Type: application/json" \
-H "Authorization: Bearer $token" \
-d '{ "username": "'"$1"'", "title": "'"$2"'", "description": "'"$3"'", "type": "notification" }' \
"https://ntk.example.com/api/v3/services/<service-id>/notify"
Zastąp ntk.example.com adresem swojego appliance, a <service-id> – numerem
UUID usługi z panelu. Przetestuj to:
ntk-notify j.doe "Test" "If you can read this on your phone, the channel works."
Push trafia do aplikacji Notakey Authenticator, tej samej, której użytkownik używa już do logowań, więc nie ma niczego nowego do zainstalowania, wytłumaczenia ani przepchnięcia przez system zarządzania urządzeniami mobilnymi.
Krok 4: Wywołuj to skądkolwiek
Gdy kanał sprowadza się do jednej linijki, zastosowania zbierają się same. Kilka takich, które działają dziś produkcyjnie:
Zadanie kopii zapasowej, które melduje o wyniku. Klasyczna cicha awaria: kopie, które przestały działać wiele miesięcy temu i nikt tego nie zauważył. Dwie linijki na końcu zadania rozwiązują problem:
if ! /usr/local/bin/backup-run; then
ntk-notify admin "Backup FAILED" "Nightly backup on $(hostname) exited with an error — check /var/log/backup.log"
fi
Miejsce na dysku, wygasające certyfikaty – wszystko, co potrafi sprawdzić cron:
#!/bin/bash
# cron: 0 8 * * *
used=$(df --output=pcent / | tail -1 | tr -dc '0-9')
if [ "$used" -gt 90 ]; then
ntk-notify admin "Disk warning" "Root filesystem on $(hostname) is at ${used}% — time to clean up."
fi
Ogłoszenie do każdego pracownika. API adresuje jedną nazwę użytkownika na wywołanie, więc wiadomość dla całej firmy to pętla po liście użytkowników (okna serwisowe, zamknięcia biura, powiadomienia o awariach):
while read -r user; do
ntk-notify "$user" "IT maintenance" "VPN unavailable Saturday 06:00–08:00 — planned appliance upgrade."
done < users.txt
Ceny spot energii, dwie ceny co dwie godziny. Nie wszystko, co warto wypchnąć jako push, jest awarią. Ten skrypt uruchamia się z crona i mówi użytkownikowi, ile będzie kosztować prąd w najbliższej godzinie, co przydaje się przy decyzji, kiedy włączyć zmywarkę:
#!/bin/bash
# cron: 5 * * * * — sends on even hours, 06–23 only
hour=$(( $(date +%H) + 1 ))
next=$(( hour + 1 ))
if [ "$hour" -gt 5 ] && [ "$hour" -lt 24 ] && (( $(date +%H) % 2 == 0 )); then
ntk-notify "$1" "Electricity" \
"Next hour: $(spot_price "$hour")€/kWh. After that: $(spot_price "$next")€/kWh."
fi
(spot_price to cokolwiek, co pobiera Twoje dane rynkowe: API giełdy, plik
CSV z pamięci podręcznej. Istotne jest dostarczenie, a nie źródło.)
Dla powtarzających się wiadomości, jak ta powyżej, warto znać dwa
udokumentowane dodatki: dodanie pola fingerprint do ładunku sprawia, że
ponowne wysłanie z tym samym odciskiem aktualizuje istniejącą wiadomość,
zamiast piętrzyć kolejną; dzięki temu ticker cen pozostaje jednym
powiadomieniem, a nie czterdziestoma dziennie. Z kolei "type": "sms" wysyła
tę samą wiadomość jako SMS, o ile użytkownik ma zdefiniowany numer telefonu:
kanał zapasowy dla kogoś, kto stracił aplikację na telefonie.
Pralka skończyła. Inteligentne gniazdko śledzące pobór mocy, automatyzacja w Home Assistant, skrypt odpytujący licznik – cokolwiek wykryje koniec cyklu, powiadomieniem pozostaje ta sama linijka. Błahy przykład, a nawyk prawdziwy: gdy wysłanie pusha nic nie kosztuje, powiadamiasz o wszystkim.
Do czego ten kanał się nadaje (a do czego nie)
W porównaniu z SMS strona odbiorcy jest znacznie mocniejsza: SMS trafia na dowolny aparat, w którym akurat tkwi karta SIM, od nadawcy, którego nazwę każdy może podrobić, podczas gdy powiadomienie Notakey ląduje wyłącznie w aplikacji Authenticator na urządzeniach, które ukończyły kryptograficzną rejestrację w Twojej usłudze. Nikt nie zapisze się sam do Twoich alertów i nikt nie podrobi nadawcy.
Jedno uczciwe ograniczenie, prosto z
dokumentacji API: sama treść
powiadomienia nie jest szyfrowana end-to-end: jak każdy mobilny push,
przechodzi przez usługi push Apple i Google i jest czytelna dla aplikacji
mających na urządzeniu dostęp do powiadomień. Traktuj więc treść wiadomości
jak komunikat na pager, a nie jak zapieczętowaną kopertę: „Kopia zapasowa na
hoście X nie powiodła się” jest w porządku; hasło lub klucz API – już nie. Gdy
musisz dostarczyć coś naprawdę tajnego, użyj zamiast tego żądania
uwierzytelnienia (urn:notakey:auth). Tam push jest jedynie zapukaniem do
drzwi, a właściwy ładunek aplikacja pobiera po reakcji użytkownika własnym
kanałem uwierzytelnianym certyfikatem.
Gdzie to pasuje
Jeśli appliance chroni już Twoje VPN lub aplikacje, powiadomienia to funkcja, którą masz za darmo i z której nie korzystasz: ta sama usługa, ta sama aplikacja, te same dane logowania do API, jeden dodatkowy punkt końcowy. A jeśli do tej pory płaciłeś za bramkę SMS na potrzeby wewnętrznych alertów, ten kanał zastępuje ją dla każdego odbiorcy, który nosi przy sobie zarejestrowany telefon.
Powiązane przewodniki
- VPN 2FA z RADIUS – pełna konfiguracja proxy uwierzytelniania: strona uwierzytelniania tego samego appliance
- Linux SSH 2FA z pam_radius: zatwierdzanie z telefonu dla serwerów, na których działają Twoje skrypty
- Dokumentacja API: pełny interfejs REST, w tym zapytania o urządzenia i żądania uwierzytelnienia