แจ้งเตือนใบรับรอง SSL ใกล้หมดอายุ: ไม่มีใครส่งอีเมลบอกคุณอีกแล้ว

Let's Encrypt เลิกส่งอีเมลแจ้งหมดอายุ และใบรับรองเหลืออายุ 200 วัน นี่คือสคริปต์ openssl ที่ทดสอบแล้ว เกณฑ์ที่ถูกต้อง และการแจ้งเตือนที่ถึงตัวจริง

อัปเดตเมื่อ

สารบัญ

มีสองอย่างที่เปลี่ยนไปใต้ระบบใบรับรองของทุกคน และทีมส่วนใหญ่ยังไม่ได้ปรับตัวกับทั้งสองอย่าง

อย่างแรก ตาข่ายนิรภัยถูกถอดออกไปแล้ว Let's Encrypt ปิดบริการแจ้งเตือนหมดอายุเมื่อ 4 มิถุนายน 2025 — อีเมลที่คอยช่วยเว็บนับพันไว้อย่างเงียบ ๆ ทุกครั้งที่ระบบอัตโนมัติพัง เหตุผลนั้นฟังขึ้น (ผู้ใช้ส่วนใหญ่ต่ออายุอัตโนมัติอยู่แล้ว การเก็บอีเมลนับล้านเป็นภาระด้านความเป็นส่วนตัว และบริการนี้ใช้เงิน "หลายหมื่นดอลลาร์ต่อปี") และประกาศนั้นปิดท้ายด้วยการบอกให้ไปหาบริการมอนิเตอร์จากที่อื่นแทน (Let's Encrypt) หลายคนอ่านถึงตรงนั้น พยักหน้าเห็นด้วย แล้วก็ไม่เคยทำครึ่งหลัง

อย่างที่สอง ระยะเผื่อพังทลาย ตั้งแต่ 15 มีนาคม 2026 ใบรับรอง TLS สาธารณะมีอายุได้สูงสุด 200 วัน ลดเหลือ 100 วันในวันที่ 15 มีนาคม 2027 และ 47 วันในวันที่ 15 มีนาคม 2029 ตาม มติ SC-081v3 ของ CA/Browser Forum ส่วน Let's Encrypt เดินเร็วกว่าเพดานนั้น ใบรับรองอายุ 6 วันเปิดให้ใช้ทั่วไปตั้งแต่ 15 มกราคม 2026 และแผนจะพาโปรไฟล์ค่าเริ่มต้นลงไปที่ 64 วันในเดือนกุมภาพันธ์ 2027 และ 45 วันในเดือนกุมภาพันธ์ 2028 (Let's Encrypt)

ทั้งสองอย่างดันไปทางเดียวกัน การต่ออายุเกิดถี่ขึ้น จึงมีโอกาสพังมากขึ้น และเมื่อพังก็ไม่มีใครส่งจดหมายมาบอก คู่มือนี้คือการตรวจสอบที่ปิดช่องว่างนั้น: สคริปต์เชลล์ที่ทดสอบจริงแล้ว เกณฑ์ที่สมเหตุสมผลสำหรับใบรับรองอายุสั้น และวิธีทำให้กรณีสุดท้ายโทรเข้ามือถือคุณด้วย Echobell

เหตุขัดข้องจากใบรับรองร้ายแรงแค่ไหนจริง ๆ

ร้ายแรงพอที่ปีที่แล้วองค์กรมากกว่าหนึ่งในสามเจอกับตัว ในรายงาน 2026 Global Certificate Management Outlook ของ DigiCert — สำรวจโดย Propeller Insights เมื่อพฤษภาคม 2026 กับผู้มีอำนาจตัดสินใจด้านไอทีและความมั่นคงไซเบอร์ 1,001 คนในสหรัฐฯ สหราชอาณาจักร และออสเตรเลีย — องค์กรมากกว่าหนึ่งในสามรายงานว่ามีบริการหยุดทำงานเพราะใบรับรองหมดอายุในรอบปีที่ผ่านมา เกือบสามในสี่สะสมเวลาดาวน์ที่เกี่ยวกับใบรับรองอย่างน้อยห้าชั่วโมง หนึ่งในห้าถึง 25 ชั่วโมงขึ้นไป และเกือบหนึ่งในสี่บอกว่าเหตุการณ์ใบรับรองที่หนักที่สุดสร้างความเสียหายเกิน 250,000 ดอลลาร์ (DigiCert)

ส่วนที่น่าสนใจของตัวเลขเหล่านี้คือระยะเวลา ห้าชั่วโมงไม่ใช่เวลาที่ใช้ต่ออายุใบรับรอง — การต่ออายุใช้เวลาไม่กี่วินาที ห้าชั่วโมงคือเวลาที่ใครสักคนใช้กว่าจะรู้ตัว

ทำไมการต่ออายุอัตโนมัติจึงยังไม่พอ

เพราะระบบต่ออายุอัตโนมัติล้มเหลวอย่างเงียบ ๆ และ cron ที่หยุดทำงานไปแล้วก็ไม่มีเอาต์พุตอะไรออกมาเลย แต่ละข้อต่อไปนี้เกิดขึ้นจริงและเกิดบ่อย และไม่มีข้อไหนส่งเสียง:

  • ตัวตั้งเวลาไม่ทำงานแล้ว การอัปเกรดดิสโทร การสร้างคอนเทนเนอร์ใหม่ หรือคำสั่ง systemctl disable เมื่อสามเดือนก่อนที่ไม่มีใครจำได้ certbot.timer ที่ไม่ยิงหน้าตาเหมือนกับ certbot.timer ที่ยิงสำเร็จทุกประการ
  • ต่ออายุสำเร็จ แต่บริการไม่เคยรีโหลด ใบรับรองใหม่อยู่บนดิสก์แล้ว แต่ nginx, HAProxy หรือ Postfix ยังถือใบเก่าไว้ในหน่วยความจำ นี่คือทางที่การตั้งค่าแบบ "อัตโนมัติเต็มรูปแบบ" หมดอายุได้บ่อยที่สุด
  • เส้นทาง challenge พัง มีคนใส่ redirect, กฎ WAF หรือ Deny ไว้หน้า /.well-known/acme-challenge/ ทำให้ HTTP-01 ล้มเหลว หรือโทเคน API ของผู้ให้บริการ DNS ที่ใช้กับ DNS-01 หมดอายุ
  • ต่ออายุเกิดขึ้นแค่โหนดเดียว โหลดบาลานเซอร์สองตัว cron ตัวเดียว ตัวที่สองจะเสิร์ฟใบเก่าต่อไปจนกว่าจะเสิร์ฟไม่ได้อีก
  • ใบรับรองนั้นไม่ได้อยู่บนเว็บเซิร์ฟเวอร์เลย ไคลเอนต์ mTLS ภายใน, Kafka broker, เซิร์ฟเวอร์ LDAP, อุปกรณ์ VPN, ใบรับรอง push ของระบบจัดการอุปกรณ์ ไม่มีอะไรบนอินเทอร์เน็ตสาธารณะมองเห็นมัน และไม่มีไคลเอนต์ ACME ตัวไหนดูแลมัน
  • การต่ออายุถูกฮาร์ดโค้ดไว้ที่ช่วงเวลาที่ผิด Let's Encrypt พูดตรง ๆ ว่า เมื่อโปรไฟล์ค่าเริ่มต้นลงไปที่ 64 แล้วเป็น 45 วัน "การต่ออายุด้วยช่วงเวลาตายตัว 60 วันจะไม่เพียงพออีกต่อไป" (Let's Encrypt)

ข้อสุดท้ายควรเน้น เพราะนี่คือความล้มเหลวที่ปฏิทินกำลังผลักทุกคนเข้าไปหา ถ้าจังหวะการต่ออายุของคุณคือตัวเลขที่ใครบางคนพิมพ์ไว้เมื่อปี 2022 ตอนนี้อายุใบรับรองกำลังเดินเข้าหาตัวเลขนั้นเอง

จะตรวจวันหมดอายุของใบรับรองจากบรรทัดคำสั่งอย่างไร

ไปป์ไลน์ openssl เส้นเดียว ไม่ต้องติดตั้งอะไรเพิ่ม สำหรับโฮสต์ที่รันอยู่:

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

สำหรับไฟล์บนดิสก์:

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

บน IP ที่ใช้ร่วมกัน แฟล็ก -servername ไม่ใช่ตัวเลือกเสริม — ถ้าไม่มี SNI คุณจะได้ใบรับรองที่เซิร์ฟเวอร์ถือเป็นค่าเริ่มต้น ซึ่งอาจไม่ใช่ใบที่คุณกังวล

ถ้าต้องการแค่คำตอบว่าใช่หรือไม่ ข้ามการแปลงวันที่ไปได้เลย openssl x509 -checkend <วินาที> จะออกด้วยรหัส 0 ถ้าใบรับรองอยู่รอดพ้นช่วงนั้น และ 1 ถ้าหมดอายุภายในช่วงนั้น (รวมถึงกรณีที่หมดอายุไปแล้ว):

openssl x509 -in fullchain.pem -noout -checkend $((14 * 86400)) \
  || echo "หมดอายุภายใน 14 วัน"

ข้อตกลงเรื่องรหัสออกนี้แหละคือแก่นของการมอนิเตอร์ทั้งหมด ทุกอย่างที่เหลือเป็นแค่ท่อรอบ ๆ มัน

จับกรณี "ต่ออายุแล้วแต่ยังไม่รีโหลด"

เทียบใบที่อยู่บนดิสก์กับใบที่ถูกเสิร์ฟจริง นี่คือการตรวจที่แทบไม่มีใครทำ และมันจับความล้มเหลวที่ระบบต่ออายุอัตโนมัติมองไม่เห็นได้พอดี:

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 "บริการยังเสิร์ฟใบรับรองเก่า — ต้องรีโหลด"

ทั้งสองคำสั่งพิมพ์รูปแบบเดียวกันคือ sha256 Fingerprint=AB:CD:... ดังนั้นเทียบสตริงตรง ๆ ก็พอ ให้รันหลังจากช่วงเวลาที่ตัวตั้งเวลาต่ออายุทำงานสักไม่กี่นาที

การแจ้งเตือนใบรับรองควรใช้เกณฑ์อะไร

ใช้สัดส่วนของอายุใบรับรอง ไม่ใช่จำนวนวันตายตัว กฎ "เตือนล่วงหน้า 30 วัน" เคยสมเหตุสมผลกับใบรับรอง 90 วัน พอมาใช้กับใบ 47 วันมันจะเตือนทั้งที่ใบยังสมบูรณ์ดี และถ้าใช้กับใบ 6 วันมันจะเตือนตลอดเวลา

ให้ยึดบันไดขั้นไว้กับจุดต่ออายุแทน Let's Encrypt แนะนำให้ต่ออายุ "ประมาณสองในสามของอายุใบรับรองปัจจุบัน" ดังนั้น เหลืออายุหนึ่งในสาม คือจุดที่การต่ออายุควรจะเกิดขึ้นไปแล้ว ทุกอย่างหลังจุดนั้นคือหลักฐานว่ามันไม่ได้เกิด:

อายุที่เหลือหมายความว่าอย่างไรประเภทการแจ้งเตือน
1/3หน้าต่างการต่ออายุเปิดแล้วไม่ต้องแจ้ง — นี่คือปกติ
1/6พลาดหน้าต่างไปหนึ่งครั้งPush ปกติ
1/12การต่ออายุกำลังล้มเหลว ไม่ใช่แค่ช้าเร่งด่วน
น้อยกว่า 1/24, หมดอายุ หรือติดต่อไม่ได้เหลืออีกไม่กี่ชั่วโมงก็ล่มสายโทรเข้า

แปลงเป็นตัวเลขจริง สำหรับใบรับรอง 47 วันจะประมาณนี้: เงียบจนถึง 7.8 วัน, push ที่ 3.9 วัน, เร่งด่วนที่ 2 วัน, โทรเมื่อเหลือไม่ถึง 1 วัน สำหรับใบ 90 วัน: 15 วัน, 7.5 วัน, 3.75 วัน ส่วนใบ 6 วันนับกันเป็นชั่วโมง และตรงนั้นบันไดสำหรับมนุษย์ไม่ใช่เครื่องมือที่เหมาะอีกต่อไป — ให้พึ่ง ACME Renewal Information (ARI เผยแพร่เป็น RFC 9773) ซึ่งให้ CA บอกไคลเอนต์เองว่าควรต่ออายุเมื่อไร แล้วแจ้งเตือนเฉพาะตอนที่ไคลเอนต์ล้มเหลวซ้ำ ๆ

การคำนวณสัดส่วนใช้แค่สี่บรรทัด และทำให้สคริปต์เดียวกันถูกต้องกับทุกใบรับรองที่คุณมี ไม่ว่าใครเป็นผู้ออก:

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() {  # อ่าน PEM จาก stdin แล้วพิมพ์เปอร์เซ็นต์ของอายุที่เหลือ
  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) ))
}

รูปแบบ date แรกเป็นของ GNU ส่วนอันที่สองเป็นของ BSD/macOS เครื่องหมาย || จะเลือกอันที่เครื่องคุณมี

จะเปลี่ยนสิ่งนี้ให้เป็นการแจ้งเตือนที่ถึงตัวจริง ๆ ได้อย่างไร

Echobell เปลี่ยน webhook หรืออีเมลให้กลายเป็น push ปกติ การแจ้งเตือนเร่งด่วน หรือสายโทรเข้าจริง ๆ ที่ดังทะลุโหมดโฟกัสและห้ามรบกวน (ดู ทะลุโหมดโฟกัสของ iOS) สำหรับใบรับรอง เรื่องนี้สำคัญ เพราะขั้นสุดท้ายในตารางข้างบนคือขั้นที่คุณจะไปเจอตอนตีสามของวันอาทิตย์

ขั้นที่ 1 — สร้างสองช่อง ไม่ใช่ช่องเดียว

สร้างช่องในแอป ตั้งประเภทการแจ้งเตือนเป็น เร่งด่วน และตั้งชื่อว่า "ใบรับรองใกล้หมดอายุ" แล้วสร้างช่องที่สองเป็นแบบ สายโทรเข้า ตั้งชื่อว่า "ใบรับรองจวนหมดอายุ" คัดลอก URL ของ webhook จากรายละเอียดของแต่ละช่อง หน้าตาจะเป็น https://hook.echobell.one/t/<channel-token> ให้ถือว่าเป็นความลับ — ใครถือ URL ของช่องสายโทรเข้าก็ทำให้มือถือคุณดังได้ (คู่มือ webhook)

เขียนเทมเพลตให้อ่านจากหน้าจอล็อกแล้วลงมือได้เลยโดยไม่ต้องปลดล็อกอะไร:

หัวข้อ: TLS {{state}}: {{host}}
เนื้อหา: เหลือ {{daysLeft}} วัน หมดอายุ {{notAfter}} — ออกโดย {{issuer}}

คีย์ JSON ทุกตัวที่คุณส่งไปจะกลายเป็นตัวแปร (เทมเพลต)

ขั้นที่ 2 — รันการตรวจสอบ

นี่คือสคริปต์จากหัวข้อก่อนหน้า ประกอบรวมและทดสอบตั้งแต่ต้นจนจบแล้ว บันทึกเป็น /usr/local/bin/cert-watch:

#!/usr/bin/env bash
# cert-watch — ส่ง POST ไปยัง Echobell เมื่อใบรับรอง TLS ใกล้หมดอายุ
set -uo pipefail

HOOK="${ECHOBELL_CERT_HOOK:?กำหนด ECHOBELL_CERT_HOOK เป็น URL webhook ของช่องคุณ}"
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

มันรายงานสามสถานะ — expiring, expired และ unreachable — และเงียบเมื่อทุกอย่างปกติ เป้าหมายเขียนเป็น host หรือ host:port ได้ ใบรับรองที่ไม่ใช่เว็บจึงครอบคลุมด้วย:

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

unreachable ถูกตั้งใจให้เป็นการแจ้งเตือน ไม่ใช่การข้ามไปเงียบ ๆ การตรวจที่ถือว่า "ฉันดูไม่ได้" เท่ากับ "ทุกอย่างปกติ" คือต้นเหตุที่ทำให้ใบรับรองหมดอายุตั้งแต่แรก

ขั้นที่ 3 — ตั้งเวลา และแจ้งเตือนเมื่อตัวตั้งเวลาเองล้มเหลว

วันละครั้งพอสำหรับใบรับรอง 45 วันขึ้นไป วันละสองครั้งถ้าคุณใช้ใบ 6 วัน ตัวอย่าง systemd timer:

# /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
# /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 สำคัญ: ถ้าไม่มีมัน เครื่องที่ปิดอยู่ตอนถึงเวลาที่กำหนดจะข้ามรอบนั้นไปเฉย ๆ

จากนั้นปิดวงจรที่ตัวการตรวจสอบเอง ยูนิตแบบ Type=oneshot ที่ออกด้วยรหัสไม่เป็นศูนย์จะทริกเกอร์ OnFailure= ดังนั้น drop-in เดียวก็ทำให้การต่ออายุที่พังประกาศตัวเองได้:

# /etc/systemd/system/certbot.service.d/echobell.conf
[Unit]
OnFailure=echobell-alert@%n.service
# /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

โดย /usr/local/bin/echobell-notify มีแค่สามบรรทัด:

#!/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 จะออกด้วยรหัสไม่เป็นศูนย์เมื่อมีการต่ออายุใดล้มเหลว ซึ่งเป็นสัญญาณที่คุณต้องการพอดี และเป็นสัญญาณที่ตอนนี้ไม่ได้ส่งไปไหนเลยพอดีเช่นกัน โปรดทราบว่า --deploy-hook ของ certbot ทำงานเฉพาะเมื่อสำเร็จ จึงใช้กับเรื่องนี้ไม่ได้ — เส้นทางความล้มเหลวต้องมาจากฝั่งยูนิต

ขั้นที่ 4 — แยกบันไดขั้นด้วยเงื่อนไข

ทั้งสองช่องรับ payload เดียวกัน ส่วนช่องไหนจะทำงานจริงนั้น เงื่อนไข เป็นตัวตัดสิน ที่ช่องเร่งด่วน:

state == "expiring" && daysLeft > 3

ที่ช่องสายโทรเข้า:

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

สังเกตว่า <= จะแปลงทั้งสองฝั่งด้วย Number() ดังนั้นแม้ daysLeft จะถูกส่งมาเป็นสตริงก็ยังเทียบกันแบบตัวเลข เงื่อนไขไม่มีตัวดำเนินการ "มีคำว่า" ซึ่งเป็นเหตุผลที่สคริปต์ส่งฟิลด์ state มาอย่างชัดเจน แทนที่จะเป็นข้อความอิสระที่คุณต้องมาจับรูปแบบเอง

ขั้นที่ 5 — ทดสอบก่อนจะไว้ใจ

ชี้สคริปต์ไปที่โฮสต์ที่รู้อยู่แล้วว่าใบรับรองมีปัญหา แล้วดูว่าการแจ้งเตือนมาถึงไหม:

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

ทำแบบนี้โดยเปิดโหมดห้ามรบกวนบนเครื่องที่จะรับจริง และเปิด โทรซ้ำเมื่อสายไม่สำเร็จ ในแอป เพื่อให้สายที่ถูกโหมดโฟกัสกดไว้ถูกโทรอีกครั้ง เส้นทางยกระดับที่ไม่เคยยิงทดสอบเลยก็เป็นแค่การเดา

ถ้าระบบมอนิเตอร์ของฉันตรวจใบรับรองอยู่แล้วล่ะ

ก็ต่อ webhook ที่มีอยู่แล้วเข้ากับช่อง แล้วข้ามสคริปต์ไปได้เลย ระบบมอนิเตอร์ส่วนใหญ่รู้วันหมดอายุอยู่แล้ว สิ่งที่มักขาดคือเส้นทางที่ผ่านคนที่กำลังหลับไปได้

  • Uptime Kuma มีการแจ้งเตือนใบรับรองหมดอายุในตัวอยู่แล้ว — ชี้ไปที่ช่องได้เลย (คู่มือ Uptime Kuma, ตั้งค่าสายโทรเข้า)
  • Prometheus + Alertmanager คู่กับ blackbox exporter จะให้ probe_ssl_earliest_cert_expiry ตั้งกฎบนเมตริกนั้นแล้วส่งไปยังช่อง (คู่มือ Prometheus, สายโทรเข้าผ่าน Alertmanager)
  • กฎแจ้งเตือนของ Grafana ส่ง POST ตรงไปยังช่องได้ (คู่มือ Grafana)
  • Upptime และ UptimeRobot ครอบคลุมเอนด์พอยต์สาธารณะ (Upptime, UptimeRobot)
  • อะไรก็ตามที่ส่งได้แค่อีเมล — พอร์ทัลของ CA เอง การแจ้งเตือน ACM ของผู้ให้บริการคลาวด์ หรือ PKI ภายใน — ใช้กฎการส่งต่ออีเมลแทน แต่ละช่องมีที่อยู่อีเมลของตัวเอง และใช้ from, to, subject, text, html เป็นตัวแปรได้ (ทริกเกอร์อีเมล)

สิ่งเดียวที่ไม่มีตัวเลือกไหนทดแทนได้คือการให้การตรวจสอบรันจากนอกเครื่องที่เสิร์ฟใบรับรองนั้น ถ้าระบบมอนิเตอร์อยู่บนโฮสต์เดียวกัน เหตุขัดข้องที่ทำให้โฮสต์ล่มก็จะพาการแจ้งเตือนล่มไปด้วย

สิ่งที่ Echobell ไม่ทำ

ตรงนี้ต้องพูดให้ชัด เพราะการจัดการใบรับรองเป็นหมวดที่เต็มไปด้วยผลิตภัณฑ์ที่ทำได้มากกว่านี้เยอะ

Echobell ทำ: เปลี่ยน webhook หรืออีเมลให้เป็น push ปกติ การแจ้งเตือนเร่งด่วน หรือสายโทรเข้าที่ดังจริง กรองด้วยเงื่อนไข จัดรูปแบบด้วยเทมเพลต และส่งทริกเกอร์เดียวไปถึงผู้ติดตามทุกคนของช่องที่แชร์ไว้ โดยแต่ละคนเลือกระดับความเร่งด่วนของตัวเอง

Echobell ไม่ทำ:

  • ค้นหาหรือทำบัญชีใบรับรองให้คุณ มันไม่สแกนเครือข่าย ไม่ไล่อ่านล็อก certificate transparency และจะไม่บอกคุณเรื่องใบรับรองที่ไม่มีใครจำได้ว่าเคยออก สคริปต์ข้างบนตรวจเฉพาะโฮสต์ที่คุณระบุไว้เท่านั้น การมีใบรับรองกระจัดกระจายเป็นปัญหาจริง และนี่ไม่ใช่ทางแก้ของมัน
  • ต่ออายุอะไรให้ ไม่มีไคลเอนต์ ACME และไม่แตะกุญแจของคุณ มันบอกแค่ว่าการต่ออายุพัง ส่วนการซ่อมยังเป็นงานของคุณ
  • ตรวจใบรับรองตามตารางของตัวเอง ไม่มีโพรบแบบโฮสต์ให้ ต้องมีบางอย่างที่คุณรันเอง — ตัวตั้งเวลา งาน CI หรือระบบมอนิเตอร์ที่มีอยู่ — เป็นคนไปดู
  • จัดเวรรับสาย นโยบายยกระดับ หรือการตอบรับ ไม่มี "ถ้าห้านาทีไม่มีใครรับ ให้โทรหาคนถัดไป" ถ้าต้องการแบบนั้น คุณต้องใช้แพลตฟอร์มจัดการเหตุการณ์ — ดู เปรียบเทียบทางเลือกแทน Opsgenie
  • รับประกันการส่งถึง สายโทรขึ้นอยู่กับโครงสร้างพื้นฐาน push เครือข่าย และมือถือที่มีแบตเตอรี่ มันย่นระยะระหว่างตอนที่พังกับตอนที่รู้ ไม่ใช่มาตรการควบคุมที่พึ่งพาได้แบบเด็ดขาด

คำถามที่พบบ่อย

Let's Encrypt เลิกส่งอีเมลแจ้งหมดอายุจริงหรือ

จริง บริการแจ้งเตือนหมดอายุสิ้นสุดเมื่อ 4 มิถุนายน 2025 และ Let's Encrypt ได้ลบที่อยู่อีเมลที่เคยเก็บไว้คู่กับบันทึกการออกใบรับรองทิ้งด้วย ประกาศนั้นแนะนำให้ใช้บริการมอนิเตอร์จากภายนอก และยก Red Sift Certificates Lite ที่ฟรีถึง 250 ใบเป็นหนึ่งในตัวเลือก ถ้าคุณไม่ได้รับคำเตือนหมดอายุจาก Let's Encrypt มากว่าหนึ่งปีแล้ว นี่คือเหตุผล — ไม่ใช่เพราะไม่เคยมีใบไหนใกล้หมดอายุเลย

ปี 2026 ใบรับรอง TLS มีอายุนานแค่ไหน

สูงสุด 200 วันสำหรับใบรับรอง TLS ที่เชื่อถือได้สาธารณะ นับตั้งแต่ 15 มีนาคม 2026 เพดานจะลดเหลือ 100 วันในวันที่ 15 มีนาคม 2027 และ 47 วันในวันที่ 15 มีนาคม 2029 ตามมติ SC-081v3 แต่ละ CA จะออกต่ำกว่าเพดานเพื่อความปลอดภัย เช่น DigiCert ออกใบอายุ 199 วันโดยระบุชัดว่า "เพื่อเลี่ยงการเกินอายุสูงสุดที่อนุญาต" ส่วน Let's Encrypt ไปไกลและเร็วกว่านั้นตามตารางของตัวเอง โดยใบรับรอง 6 วันเปิดใช้ทั่วไปตั้งแต่มกราคม 2026

ถ้าใช้ ARI แล้วยังต้องแจ้งเตือนหมดอายุอีกไหม

ยังต้อง แต่เปลี่ยนเหตุการณ์ที่จับ ARI (RFC 9773) บอกไคลเอนต์ ACME ว่าควรต่ออายุเมื่อไร ซึ่งกำจัดปัญหาช่วงเวลาฮาร์ดโค้ดไปได้หมด แต่ไม่รับประกันว่าการต่ออายุจะสำเร็จ ว่าบริการจะรีโหลด หรือว่าไคลเอนต์ยังทำงานอยู่ ให้แจ้งเตือนเมื่อการต่ออายุล้มเหลวซ้ำ ๆ และเมื่อใบที่เสิร์ฟอยู่ไม่ตรงกับใบบนดิสก์ แทนที่จะแจ้งเตือนจากการนับถอยหลังที่คุณไม่ต้องจัดการเองแล้ว

แล้วใบรับรองที่ไม่ได้อยู่บนเว็บเซิร์ฟเวอร์ล่ะ

พวกนั้นแหละที่หมดอายุบ่อยที่สุด เพราะไม่มีไคลเอนต์ ACME คอยดู และไม่มีเบราว์เซอร์ตัวไหนบ่นจนกว่าจะมีอะไรพัง สคริปต์รับ host:port ดังนั้น IMAP ที่ 993, LDAPS ที่ 636, Kafka broker ที่ 9093 หรือ API ภายในที่ 8443 ใช้ได้เหมือนกันหมด ส่วนใบรับรองที่ไม่เคยแตะซ็อกเก็ตเลย — เซ็นโค้ด ใบรับรองแจ้งเตือน push ใบรับรองไคลเอนต์ในฝูงอุปกรณ์ — ต้องดึงวันที่จากที่ที่มันอยู่ แล้วส่งไปยังช่องเดียวกัน

ตรวจทุกวันจะกลายเป็นเสียงรบกวนไหม

ไม่ ถ้ามันเงียบตอนที่ไม่มีอะไรผิดปกติ ซึ่งเป็นเหตุผลที่สคริปต์ไม่ส่งอะไรเลยเมื่ออยู่เหนือเกณฑ์ แบบที่รบกวนจริง ๆ คือแบบที่รายงาน "ใบรับรองปกติดี" ทุกวัน — สองสัปดาห์ผ่านไปไม่มีใครอ่าน และวันที่มันหยุดมาก็ไม่มีใครสังเกต ถ้าอยากได้สัญญาณชีพ ให้ไปไว้ที่ช่องปกติแยกต่างหาก และอย่าไว้ที่ช่องที่ดังเด็ดขาด ดูเวอร์ชันทั่วไปของข้อโต้แย้งนี้ได้ที่ แก้อาการล้าจากการแจ้งเตือน

ทั้งทีมรับการแจ้งเตือนใบรับรองได้ไหม

ได้ แชร์ช่องแล้วผู้ติดตามทุกคนจะได้รับทริกเกอร์ โดยแต่ละคนเลือกประเภทการแจ้งเตือนของตัวเอง การแบ่งที่ใช้ได้จริง: คนที่เข้าเวรสมัครช่องสายโทรเข้า ที่เหลือสมัครช่องเร่งด่วน แบบนี้ใบหมดอายุตอนตีสามจะปลุกคนเดียว ไม่ใช่หกคน

ใช้บน macOS ได้ไหม

ได้ มีข้อควรระวังอย่างเดียว: date ของ BSD ไม่รับ -d จึงเป็นเหตุผลที่ days_left และ to_epoch ลองรูปแบบ GNU ก่อนแล้วค่อยถอยไปใช้ date -u -j -f ส่วน openssl บน macOS เป็น LibreSSL โดยค่าเริ่มต้น และรองรับ -checkend กับ -fingerprint เหมือนกันทุกประการ ถ้าคุณติดตั้ง OpenSSL จาก Homebrew ก็ไม่มีอะไรเปลี่ยน

ใส่รายละเอียดใบรับรองในการแจ้งเตือนปลอดภัยไหม

ฟิลด์ที่ใช้ตรงนี้ — ชื่อโฮสต์ วันหมดอายุ ผู้ออกใบรับรอง — เป็นข้อมูลสาธารณะ ใครก็อ่านจากเซิร์ฟเวอร์คุณได้ด้วยคำสั่ง openssl เดียวกัน อย่าขยาย payload ด้วยกุญแจส่วนตัว พาธภายใน หรืออะไรก็ตามจากใบรับรองบนโฮสต์ที่ไม่เปิดสาธารณะนอกเหนือจากชื่อโฮสต์ Echobell เก็บเนื้อหาและประวัติการแจ้งเตือนไว้บนเครื่องของคุณเท่านั้น ฝั่งเซิร์ฟเวอร์เก็บแค่บัญชี ช่อง และการติดตาม (โมเดลความเป็นส่วนตัว) ซึ่งเป็นค่าเริ่มต้นที่ดี แต่ไม่ใช่เหตุผลให้ส่งมากเกินจำเป็น


บทความที่เกี่ยวข้อง

บทความที่เกี่ยวข้อง

แจ้งเตือนการชำระเงินล้มเหลวของ Stripe: ข้อโต้แย้ง การถูกปฏิเสธ และเว็บฮุกที่ตายไปแล้ว

Stripe แจ้งเรื่องข้อโต้แย้งและการชำระเงินที่ล้มเหลวทางอีเมล นี่คือวิธีเปลี่ยนเหตุการณ์เว็บฮุกของ Stripe ให้เป็นพุช การแจ้งเตือนเร่งด่วน หรือสายโทรเข้า

อ่านต่อ

ให้แจ้งเตือนเมื่อคำสั่งยาว ๆ ในเทอร์มินัลทำงานเสร็จ

เลิกนั่งเฝ้าบิลด์ที่ใช้เวลาสี่สิบนาที แค่ต่อหนึ่งบรรทัดหลังคำสั่งใด ๆ ผลลัพธ์ก็ส่งถึงมือถือ แม้คุณจะเดินออกไปแล้วก็ตาม

อ่านต่อ

แจ้งเตือนคำสั่งซื้อ Shopify ถึงมือถือภายในไม่กี่วินาที

ส่ง webhook ของ Shopify ตรงเข้ามือถือ: คำสั่งซื้อทั่วไปแจ้งเบา ๆ ตะกร้าใหญ่ดังขึ้นหน่อย ส่วนการคืนเงินหรือยกเลิกให้โทรเข้ามาเมื่อต้องการตัวคุณ

อ่านต่อ