---
title: "Alerty o wygaśnięciu certyfikatu SSL: nikt już do ciebie nie napisze"
description: "Let's Encrypt nie wysyła już maili o wygaśnięciu, a certyfikaty żyją 200 dni. Sprawdzony skrypt openssl, właściwe progi i alerty, które naprawdę dotrą."
date: 2026-09-18
author: Nooc
authorAvatarLink: /images/avatars/nooc.webp
authorLink: https://nooc.me
tags:
  - wygaśnięcie certyfikatu SSL
  - monitoring TLS
  - certbot
  - alerty o awarii serwera
  - alerty telefoniczne
---

# Alerty o wygaśnięciu certyfikatu SSL: nikt już do ciebie nie napisze

Pod infrastrukturą certyfikatów wszystkich zmieniły się dwie rzeczy, a większość zespołów nie dostosowała się do żadnej z nich.

**Po pierwsze: zdjęto siatkę bezpieczeństwa.** Let's Encrypt zamknął usługę powiadomień o wygaśnięciu **4 czerwca 2025 roku** — te maile, które po cichu uratowały tysiące stron, gdy automatyzacja się psuła. Uzasadnienie było sensowne (większość subskrybentów odnawia automatycznie, przechowywanie milionów adresów e-mail to obciążenie dla prywatności, a usługa kosztowała „dziesiątki tysięcy dolarów rocznie"), a ogłoszenie kończy się radą, by poszukać monitoringu u kogoś innego ([Let's Encrypt](https://letsencrypt.org/2025/06/26/expiration-notification-service-has-ended)). Wielu to przeczytało, przytaknęło i nigdy nie zrobiło drugiej połowy.

**Po drugie: zapas bezpieczeństwa się zawalił.** Od **15 marca 2026 roku** publiczny certyfikat TLS może być ważny najwyżej 200 dni, od 15 marca 2027 — 100 dni, a od 15 marca 2029 — 47 dni, zgodnie z [głosowaniem SC-081v3 w CA/Browser Forum](https://cabforum.org/2025/04/11/ballot-sc081v3-introduce-schedule-of-reducing-validity-and-data-reuse-periods/). Let's Encrypt idzie szybciej niż wymaga limit: certyfikaty 6-dniowe są ogólnie dostępne od 15 stycznia 2026, a plan sprowadza domyślny profil do 64 dni w lutym 2027 i 45 dni w lutym 2028 ([Let's Encrypt](https://letsencrypt.org/2025/12/02/from-90-to-45)).

Obie zmiany pchają w tę samą stronę. Odnowienie zdarza się częściej, więc ma więcej okazji, by się zepsuć — a gdy się psuje, nikt nie wysyła listu. Ten przewodnik to kontrola, która zasypuje tę lukę: sprawdzony skrypt powłoki, progi mające sens dla krótko żyjących certyfikatów i sposób, by ostatni przypadek zadzwonił na twój telefon przez [Echobell](https://apps.apple.com/app/apple-store/id6743597198?pt=128151925&ct=blog-ssl-certificate-expiry-alerts-pl&mt=8).

## Jak poważna jest awaria z powodu certyfikatu?

**Na tyle, że w zeszłym roku przydarzyła się ponad jednej trzeciej organizacji.** W raporcie DigiCert 2026 Global Certificate Management Outlook — badaniu Propeller Insights na 1001 decydentach IT i cyberbezpieczeństwa w USA, Wielkiej Brytanii i Australii, przeprowadzonym w maju 2026 — **ponad jedna trzecia** organizacji zgłosiła w ostatnim roku przerwę w działaniu usługi spowodowaną wygasłym certyfikatem. Prawie **trzy czwarte** uzbierało co najmniej pięć godzin przestoju związanego z certyfikatami, **co piąta** — 25 godzin lub więcej, a prawie **co czwarta** podała, że najpoważniejszy incydent certyfikatowy kosztował ponad **250 000 dolarów** ([DigiCert](https://www.globenewswire.com/news-release/2026/09/09/3358724/0/en/digicert-research-finds-certificate-failures-are-a-six-figure-infrastructure-risk.html)).

Najciekawsza w tych liczbach jest długość. Pięć godzin to nie czas odnowienia certyfikatu — odnowienie trwa sekundy. Pięć godzin to czas, jakiego ktoś potrzebował, żeby się *dowiedzieć*.

## Dlaczego automatyczne odnawianie nie wystarcza?

**Bo automatyzacja odnowień zawodzi po cichu, a cron, który przestał działać, nie produkuje żadnego wyjścia.** Każdy z poniższych przypadków jest realny i częsty, i żaden nie wydaje dźwięku:

- **Timer już nie działa.** Aktualizacja dystrybucji, przebudowany kontener albo `systemctl disable` sprzed trzech miesięcy, o którym nikt nie pamięta. Niewyzwalający się `certbot.timer` wygląda dokładnie tak samo jak ten, który wyzwala się poprawnie.
- **Odnowienie się udało, ale usługa nigdy nie przeładowała konfiguracji.** Nowy certyfikat leży na dysku; nginx, HAProxy albo Postfix trzyma w pamięci stary. To najczęstszy sposób, w jaki „w pełni zautomatyzowana" konfiguracja i tak wygasa.
- **Zepsuła się ścieżka wyzwania.** Ktoś dołożył przekierowanie, regułę WAF albo `Deny` przed `/.well-known/acme-challenge/` i HTTP-01 zawodzi. Albo wygasł token API dostawcy DNS używany do DNS-01.
- **Odnowienie odbyło się na jednym węźle.** Dwa load balancery, jeden cron. Drugi serwuje stary certyfikat do momentu, w którym już nie może.
- **Certyfikat w ogóle nie stoi na serwerze WWW.** Wewnętrzni klienci mTLS, broker Kafki, serwer LDAP, koncentrator VPN, certyfikat push z systemu zarządzania urządzeniami. Nic z publicznego internetu go nie widzi i żaden klient ACME nim nie zarządza.
- **Odnawianie ma zaszyty zły interwał.** Let's Encrypt mówi o tym wprost: „odnawianie w zaszytym na sztywno interwale 60 dni przestanie wystarczać", gdy domyślny profil spadnie do 64, a potem do 45 dni ([Let's Encrypt](https://letsencrypt.org/2025/12/02/from-90-to-45)).

Ten ostatni zasługuje na podkreślenie, bo to awaria, w którą kalendarz wpycha właśnie wszystkich. Jeśli twój rytm odnawiania to liczba wpisana przez kogoś w 2022 roku, to teraz długość życia certyfikatu sama zmierza w stronę tej liczby.

## Jak sprawdzić datę wygaśnięcia certyfikatu z wiersza poleceń?

**Jeden potok `openssl`, bez żadnych zależności.** Dla żywego hosta:

```bash
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -startdate -enddate
```

Dla pliku na dysku:

```bash
openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -enddate
```

Na współdzielonym IP flaga `-servername` nie jest opcjonalna — bez SNI dostaniesz certyfikat, który serwer uznaje za domyślny, a to niekoniecznie ten, o który się martwisz.

Jeśli potrzebujesz odpowiedzi tak/nie, całkowicie pomiń parsowanie dat. `openssl x509 -checkend <sekundy>` kończy się kodem **0**, gdy certyfikat przetrwa to okno, i **1**, gdy wygasa w jego trakcie (również gdy już wygasł):

```bash
openssl x509 -in fullchain.pem -noout -checkend $((14 * 86400)) \
  || echo "wygasa w ciągu 14 dni"
```

Ten kontrakt kodów wyjścia to cały prymityw monitoringu. Wszystko poniżej to tylko hydraulika wokół niego.

### Wyłapanie przypadku „odnowione, ale nie przeładowane"

**Porównaj to, co leży na dysku, z tym, co naprawdę jest serwowane.** To kontrola, której prawie nikt nie uruchamia, a wyłapuje dokładnie tę awarię, której automatyzacja odnowień nie jest w stanie zobaczyć:

```bash
served=$(openssl s_client -connect 127.0.0.1:443 -servername example.com </dev/null 2>/dev/null \
         | openssl x509 -noout -fingerprint -sha256)
ondisk=$(openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -fingerprint -sha256)

[ "$served" = "$ondisk" ] || echo "usługa serwuje stary certyfikat — potrzebny reload"
```

Obie komendy wypisują identyczny format `sha256 Fingerprint=AB:CD:...`, więc wystarczy zwykłe porównanie łańcuchów. Uruchom to kilka minut po oknie twojego timera odnowień.

## Jakich progów powinien używać alert o certyfikacie?

**Ułamków czasu życia certyfikatu, a nie stałej liczby dni.** Reguła „ostrzegaj na 30 dni przed" miała sens dla certyfikatów 90-dniowych. Zastosowana do 47-dniowego odpala się na zupełnie zdrowym certyfikacie; zastosowana do 6-dniowego odpala się bez przerwy.

Zamiast tego zakotwicz drabinę w punkcie odnowienia. Let's Encrypt zaleca odnawianie „mniej więcej po dwóch trzecich czasu życia bieżącego certyfikatu" — a więc **jedna trzecia pozostałego czasu** to moment, w którym odnowienie *powinno już było się wydarzyć*. Wszystko po tym punkcie jest dowodem, że się nie wydarzyło:

| Pozostały czas życia | Co to znaczy | Typ powiadomienia |
| --- | --- | --- |
| 1/3 | Otworzyło się okno odnowienia | Nic — to normalne |
| 1/6 | Okno raz przegapione | Zwykły push |
| 1/12 | Odnowienie nie jest spóźnione, tylko zawodzi | Pilne |
| < 1/24, wygasł lub nieosiągalny | Do awarii zostały godziny | Połączenie |

W konkretnych liczbach dla certyfikatu 47-dniowego to mniej więcej: cisza do 7,8 dnia, push przy 3,9 dnia, pilne przy 2 dniach, telefon poniżej 1 dnia. Dla 90-dniowego: 15 dni, 7,5 dnia, 3,75 dnia. Dla 6-dniowego mówimy o godzinach i wtedy drabina dla człowieka przestaje być właściwym narzędziem — oprzyj się na [ACME Renewal Information](https://letsencrypt.org/2025/09/16/ari-rfc) (ARI, opublikowanym jako RFC 9773), gdzie to urząd certyfikacji mówi klientowi, kiedy odnawiać, a alertuj tylko na powtarzające się porażki klienta.

Policzenie ułamka to cztery linijki i sprawia, że ten sam skrypt jest poprawny dla każdego twojego certyfikatu, niezależnie od wystawcy:

```bash
to_epoch() {
  date -u -d "$1" +%s 2>/dev/null || date -u -j -f '%b %d %T %Y %Z' "$1" +%s 2>/dev/null
}

pct_left() {  # czyta PEM ze stdin, wypisuje procent pozostałego czasu życia
  local pem nb na
  pem=$(cat)
  nb=$(to_epoch "$(printf '%s' "$pem" | openssl x509 -noout -startdate | cut -d= -f2)")
  na=$(to_epoch "$(printf '%s' "$pem" | openssl x509 -noout -enddate | cut -d= -f2)")
  echo $(( (na - $(date -u +%s)) * 100 / (na - nb) ))
}
```

Pierwsza forma `date` to GNU, druga BSD/macOS; `||` wybiera tę, którą masz.

## Jak zmienić to w alert, który naprawdę do mnie dotrze?

Echobell zamienia webhook albo e-mail w zwykły push, pilne powiadomienie lub prawdziwy dzwoniący telefon, który przebija się przez tryb skupienia i Nie przeszkadzać (zobacz [omijanie trybu skupienia w iOS](/blog/how-to-bypass-ios-focus-mode-for-critical-alerts)). Przy certyfikatach to się liczy, bo ostatni szczebel powyższej tabeli to dokładnie ten, na który trafisz o 3 w nocy w niedzielę.

### Krok 1 — Utwórz dwa kanały, nie jeden

Utwórz kanał w aplikacji, ustaw jego typ powiadomienia na **Pilne** i nazwij go „Certyfikaty wygasają". Utwórz drugi z typem **Połączenie** i nazwij go „Certyfikat zaraz wygaśnie". Skopiuj adres webhooka z detali każdego kanału; wygląda tak: `https://hook.echobell.one/t/<channel-token>`. Traktuj je jak sekrety — kto ma ten od Połączenia, może uruchomić dzwonek w twoim telefonie ([przewodnik po webhookach](/docs/webhook)).

Napisz szablony tak, żeby po powiadomieniu dało się działać z ekranu blokady, bez odblokowywania czegokolwiek:

```
Tytuł: TLS {{state}}: {{host}}
Treść: zostało {{daysLeft}} dni, wygasa {{notAfter}} — wystawca {{issuer}}
```

Każdy klucz JSON, który wyślesz, staje się zmienną ([szablony](/docs/template)).

### Krok 2 — Uruchom kontrolę

To skrypt z powyższych sekcji, złożony i przetestowany od początku do końca. Zapisz go jako `/usr/local/bin/cert-watch`:

```bash
#!/usr/bin/env bash
# cert-watch — wysyła POST do Echobell, gdy certyfikat TLS zbliża się do wygaśnięcia.
set -uo pipefail

HOOK="${ECHOBELL_CERT_HOOK:?ustaw ECHOBELL_CERT_HOOK na adres webhooka swojego kanału}"
WARN_DAYS="${WARN_DAYS:-14}"

post() {
  curl -sS -m 10 -X POST "$HOOK" \
    -H 'content-type: application/json' \
    -d "{\"host\":\"$1\",\"daysLeft\":$2,\"notAfter\":\"$3\",\"state\":\"$4\"}" \
    >/dev/null
}

days_left() {
  local end
  end=$(date -u -d "$1" +%s 2>/dev/null) ||
    end=$(date -u -j -f '%b %d %T %Y %Z' "$1" +%s 2>/dev/null) || return 1
  echo $(( (end - $(date -u +%s)) / 86400 ))
}

check() {
  local host="$1" port="$2" pem state not_after days

  pem=$(openssl s_client -connect "$host:$port" -servername "$host" \
        </dev/null 2>/dev/null | openssl x509 2>/dev/null)

  if [ -z "$pem" ]; then
    post "$host" 0 "" "unreachable"
    return
  fi

  if printf '%s' "$pem" | openssl x509 -noout -checkend 0 >/dev/null 2>&1; then
    printf '%s' "$pem" | openssl x509 -noout -checkend $((WARN_DAYS * 86400)) >/dev/null 2>&1 && return 0
    state="expiring"
  else
    state="expired"
  fi

  not_after=$(printf '%s' "$pem" | openssl x509 -noout -enddate | cut -d= -f2)
  days=$(days_left "$not_after") || days=-999
  post "$host" "$days" "$not_after" "$state"
}

for target in "$@"; do
  case "$target" in
    *:*) check "${target%:*}" "${target##*:}" ;;
    *) check "$target" 443 ;;
  esac
done
```

Raportuje trzy stany — `expiring`, `expired` i `unreachable` — i milczy, gdy wszystko jest w porządku. Cele podaje się jako `host` albo `host:port`, więc certyfikaty spoza WWW też są objęte:

```bash
ECHOBELL_CERT_HOOK="https://hook.echobell.one/t/<token>" \
  cert-watch example.com api.example.com mail.example.com:993 ldap.internal:636
```

`unreachable` jest celowo alertem, a nie cichym pominięciem. Kontrola, która traktuje „nie dało się zajrzeć" jak „wszystko gra", jest właśnie powodem, dla którego certyfikaty wygasają.

### Krok 3 — Zaplanuj i alertuj, gdy zawiedzie samo planowanie

Raz dziennie wystarczy dla certyfikatów 45-dniowych i dłuższych; dwa razy dziennie, jeśli używasz 6-dniowych. Timer systemd:

```ini
# /etc/systemd/system/cert-watch.service
[Unit]
Description=TLS certificate expiry check

[Service]
Type=oneshot
EnvironmentFile=/etc/echobell.env
ExecStart=/usr/local/bin/cert-watch example.com api.example.com mail.example.com:993
```

```ini
# /etc/systemd/system/cert-watch.timer
[Unit]
Description=Daily TLS certificate expiry check

[Timer]
OnCalendar=daily
RandomizedDelaySec=1h
Persistent=true

[Install]
WantedBy=timers.target
```

`Persistent=true` ma znaczenie: bez tego maszyna wyłączona o zaplanowanej godzinie po prostu pomija to uruchomienie.

Potem zamknij pętlę na samej kontroli. Jednostka `Type=oneshot`, która kończy się kodem różnym od zera, wyzwala `OnFailure=`, więc jeden drop-in sprawia, że zepsute odnowienie samo się zgłasza:

```ini
# /etc/systemd/system/certbot.service.d/echobell.conf
[Unit]
OnFailure=echobell-alert@%n.service
```

```ini
# /etc/systemd/system/echobell-alert@.service
[Unit]
Description=Echobell alert for %i

[Service]
Type=oneshot
EnvironmentFile=/etc/echobell.env
ExecStart=/usr/local/bin/echobell-notify %i
```

Gdzie `/usr/local/bin/echobell-notify` ma trzy linijki:

```bash
#!/usr/bin/env bash
curl -sS -m 10 -X POST "$ECHOBELL_CERT_HOOK" \
  -H 'content-type: application/json' \
  -d "{\"host\":\"$(hostname -f)\",\"state\":\"renewal-failed\",\"unit\":\"$1\",\"daysLeft\":-1}"
```

`certbot renew` kończy się kodem różnym od zera, gdy którekolwiek odnowienie zawiedzie — to dokładnie ten sygnał, którego chcesz, i dokładnie ten, który dziś nigdzie nie trafia. Uwaga: `--deploy-hook` w certbocie uruchamia się tylko przy *sukcesie*, więc do tego się nie nadaje — ścieżka porażki musi przyjść od strony jednostki.

### Krok 4 — Rozdziel drabinę warunkami

Oba kanały dostają ten sam ładunek; to [warunki](/docs/conditions) decydują, który naprawdę wystrzeli. Na kanale Pilnym:

```
state == "expiring" && daysLeft > 3
```

Na kanale Połączenia:

```
state == "expired" || state == "unreachable" || state == "renewal-failed" || daysLeft <= 3
```

Zwróć uwagę, że `<=` konwertuje obie strony przez `Number()`, więc `daysLeft` wysłany jako tekst i tak porównuje się liczbowo. Warunki nie mają operatora „zawiera" — i właśnie dlatego skrypt wysyła jawne pole `state`, a nie dowolny tekst, który musiałbyś dopasowywać wzorcem.

### Krok 5 — Przetestuj, zanim zaufasz

Skieruj skrypt na host ze znanym zepsutym certyfikatem i zobacz, jak alert przychodzi:

```bash
ECHOBELL_CERT_HOOK="https://hook.echobell.one/t/<token>" cert-watch expired.badssl.com
```

Zrób to z włączonym Nie przeszkadzać na telefonie, który naprawdę to odbierze, i włącz w aplikacji **Ponów nieudane połączenie**, żeby telefon zablokowany przez tryb skupienia został wybrany ponownie. Ścieżka eskalacji, której nigdy nie odpaliłeś, to przypuszczenie.

## A jeśli mój monitoring już sprawdza certyfikaty?

**To podepnij jego istniejący webhook pod kanał i pomiń skrypt.** Większość systemów monitoringu zna już datę wygaśnięcia; brakuje im zwykle ścieżki, która przetrwa śpiącego człowieka.

- **Uptime Kuma** ma wbudowane powiadomienie o wygaśnięciu certyfikatu — skieruj je na kanał ([przewodnik po Uptime Kuma](/docs/developer/uptime-kuma), [konfiguracja połączeń](/blog/uptime-kuma-phone-call-alerts)).
- **Prometheus + Alertmanager** z blackbox exporterem dają `probe_ssl_earliest_cert_expiry`; postaw na tym regułę i przekieruj na kanał ([przewodnik po Prometheusie](/docs/developer/prometheus), [połączenia z Alertmanagera](/blog/alertmanager-phone-call-alerts)).
- Reguły alertów **Grafany** wysyłają POST prosto na kanał ([przewodnik po Grafanie](/docs/developer/grafana)).
- **Upptime** i **UptimeRobot** pokrywają publiczne endpointy ([Upptime](/docs/developer/upptime), [UptimeRobot](/docs/developer/uptimerobot)).
- **Wszystko, co wysyła tylko maile** — portal samego urzędu certyfikacji, powiadomienia ACM u dostawcy chmury, wewnętrzne PKI — załatwia reguła przekierowania. Każdy kanał ma własny adres, a `from`, `to`, `subject`, `text` i `html` są dostępne jako zmienne ([wyzwalacze e-mail](/docs/email-trigger)).

Jedyne, czego żadna z tych opcji nie zastąpi, to kontrola uruchamiana *spoza* maszyny serwującej certyfikat. Jeśli twój monitoring mieszka na tym samym hoście, awaria, która kładzie host, zabiera ze sobą także alert.

## Czego Echobell nie robi

Precyzja ma tu znaczenie, bo zarządzanie certyfikatami to kategoria pełna produktów robiących dużo więcej.

**Echobell robi:** zamienia webhook lub e-mail w zwykły push, pilne powiadomienie albo dzwoniące połączenie; filtruje warunkami; formatuje szablonami; dostarcza jedno wyzwolenie każdemu subskrybentowi współdzielonego kanału, a każdy wybiera własny poziom pilności.

**Echobell nie robi:**

- **Nie odkrywa ani nie inwentaryzuje twoich certyfikatów.** Nie skanuje sieci, nie przeszukuje logów certificate transparency i nie opowie ci o certyfikacie, którego wystawienia nikt nie pamięta. Powyższy skrypt sprawdza tylko hosty, które wymienisz. Rozrost certyfikatów to realny problem i to nie jest jego rozwiązanie.
- **Niczego nie odnawia.** Nie ma klienta ACME ani dostępu do twoich kluczy. Mówi ci, że odnowienie się zepsuło; naprawa dalej należy do ciebie.
- **Nie sprawdza certyfikatów we własnym harmonogramie.** Nie ma hostowanej sondy. Zajrzeć musi coś, co uruchamiasz ty — timer, zadanie CI, twój istniejący monitoring.
- **Nie zapewnia dyżurów, polityk eskalacji ani potwierdzeń.** Nie ma „jeśli nikt nie odbierze w pięć minut, zadzwoń do następnego". Jeśli tego potrzebujesz, potrzebujesz platformy do obsługi incydentów — zobacz [porównanie alternatyw dla Opsgenie](/blog/opsgenie-end-of-life-alternatives).
- **Nie gwarantuje dostarczenia.** Połączenie zależy od infrastruktury push, sieci i naładowanego telefonu. Skraca dystans między awarią a zauważeniem; nie jest zabezpieczeniem, na którym można polegać absolutnie.

## FAQ

### Czy Let's Encrypt naprawdę przestał wysyłać maile o wygaśnięciu?

Tak. Usługa powiadomień zakończyła się 4 czerwca 2025 roku, a Let's Encrypt usunął adresy e-mail przechowywane przy rekordach wystawienia. Ogłoszenie zaleca monitoring firm trzecich i wskazuje jako jedną z opcji Red Sift Certificates Lite, bezpłatny do 250 certyfikatów. Jeśli od ponad roku nie dostałeś ostrzeżenia o wygaśnięciu od Let's Encrypt, to właśnie dlatego — a nie dlatego, że nic nigdy nie było blisko końca ważności.

### Jak długo w 2026 roku ważne są certyfikaty TLS?

Maksymalnie 200 dni dla publicznie zaufanych certyfikatów TLS, od 15 marca 2026. Limit spada do 100 dni 15 marca 2027 i do 47 dni 15 marca 2029 zgodnie z głosowaniem SC-081v3. Poszczególne urzędy wystawiają poniżej limitu dla bezpieczeństwa — DigiCert na przykład wystawia certyfikaty 199-dniowe właśnie „by nie przekroczyć maksymalnej dozwolonej ważności". Let's Encrypt idzie dalej i szybciej we własnym harmonogramie, z certyfikatami 6-dniowymi dostępnymi od stycznia 2026.

### Czy przy ARI w ogóle warto alertować o wygaśnięciu?

Warto, ale na innych zdarzeniach. ARI (RFC 9773) mówi twojemu klientowi ACME, *kiedy* odnowić, co całkowicie usuwa awarię z zaszytym interwałem — ale nie gwarantuje, że odnowienie się powiedzie, że usługa przeładuje konfigurację ani że klient wciąż działa. Alertuj na powtarzające się niepowodzenia odnowienia i na rozjazd między serwowanym certyfikatem a tym na dysku, a nie na odliczanie, którym nie musisz już zarządzać.

### A certyfikaty, które nie stoją na serwerze WWW?

To właśnie one wygasają najczęściej, bo żaden klient ACME ich nie pilnuje, a żadna przeglądarka nie protestuje, dopóki coś się nie zepsuje. Skrypt przyjmuje `host:port`, więc IMAP na 993, LDAPS na 636, broker Kafki na 9093 czy wewnętrzne API na 8443 działają tak samo. Certyfikaty, które nigdy nie dotykają gniazda sieciowego — podpisywanie kodu, certyfikaty powiadomień push, certyfikaty klienckie we flocie urządzeń — wymagają wyciągnięcia daty stamtąd, gdzie mieszkają, i wysłania jej na ten sam kanał.

### Czy codzienna kontrola nie stanie się szumem?

Nie, jeśli milczy, kiedy nic się nie dzieje — i właśnie dlatego skrypt nie wysyła niczego powyżej progu. Hałaśliwy jest ten projekt, który codziennie melduje „certyfikat OK": po dwóch tygodniach nikt tego nie czyta, a w dniu, w którym przestaje przychodzić, nikt tego nie zauważa. Jeśli chcesz heartbeat, wrzuć go na osobny kanał Zwykły i nigdy na ten, który dzwoni. Ogólną wersję tego argumentu znajdziesz w [walce ze zmęczeniem alertami](/blog/fix-alert-fatigue-developer-guide).

### Czy cały zespół może dostać alert o certyfikacie?

Tak. Udostępnij kanał, a każdy subskrybent dostanie wyzwolenie i sam wybierze typ powiadomienia. Sensowny podział: dyżurny subskrybuje kanał Połączenia, reszta kanał Pilny — dzięki temu wygaśnięcie o 3 w nocy budzi jedną osobę, a nie sześć.

### Czy to działa na macOS?

Działa, z jednym zastrzeżeniem: BSD-owy `date` nie przyjmuje `-d`, dlatego `days_left` i `to_epoch` najpierw próbują formy GNU, a potem wracają do `date -u -j -f`. `openssl` na macOS to domyślnie LibreSSL i obsługuje `-checkend` oraz `-fingerprint` identycznie. Jeśli zainstalujesz OpenSSL z Homebrew, nic się nie zmienia.

### Czy bezpiecznie jest wysyłać szczegóły certyfikatu w powiadomieniu?

Użyte tu pola — nazwa hosta, data wygaśnięcia, wystawca — są publiczne; każdy odczyta je z twojego serwera tą samą komendą `openssl`. Nie rozszerzaj ładunku o klucze prywatne, wewnętrzne ścieżki ani nic z certyfikatu na niepublicznym hoście poza nazwą hosta. Echobell przechowuje treść i historię powiadomień wyłącznie na twoim urządzeniu, zostawiając na serwerze tylko konta, kanały i subskrypcje ([model prywatności](/docs/features)) — to dobry domyślny wybór, ale nie powód, by wysyłać więcej, niż trzeba.

---

## Powiązane

- [Alerty telefoniczne przy awariach API](/blog/phone-call-alerts-api-downtime)
- [Alerty telefoniczne z Uptime Kuma](/blog/uptime-kuma-phone-call-alerts)
- [Alerty o nieudanych zadaniach cron](/blog/cron-job-failure-alerts)
- [Jak zwalczyć zmęczenie alertami: przewodnik dla programistów](/blog/fix-alert-fatigue-developer-guide)
- [Jak krytyczne alerty omijają tryb skupienia w iOS](/blog/how-to-bypass-ios-focus-mode-for-critical-alerts)
- [Przewodnik po integracji z webhookami](/docs/webhook)
- [Przewodnik po warunkach](/docs/conditions)
