Monitoring SSL Banyak Subdomain dengan Bash dan OpenSSL

Dipublikasikan pada

Kalau hanya punya satu atau dua website, mengecek SSL secara manual tentu bukan masalah. Masalahnya mulai terasa ketika jumlah domain dan subdomain yang harus dikelola sudah cukup banyak.

Yang ingin saya lihat sebenarnya sederhana: apakah SSL masih valid, kapan expired, dan berapa hari lagi masa berlakunya.

Daripada membuka satu per satu lewat browser, pengecekan bisa dilakukan dari server menggunakan openssl.

Mengecek SSL Satu Domain

Untuk melihat informasi sertifikat SSL sebuah domain dari command line, bisa menggunakan:

echo | openssl s_client -servername example.go.id -connect example.go.id:443 2>/dev/null | openssl x509 -noout -dates

Jika SSL bisa dibaca, hasilnya kurang lebih:

notBefore=Aug  1 00:00:00 2026 GMT
notAfter=Oct 20 23:59:59 2026 GMT

Bagian yang paling penting adalah notAfter, karena itu merupakan tanggal expired sertifikat.

Mengambil Tanggal Expired Saja

Kalau hanya membutuhkan tanggal expired:

echo | openssl s_client -servername example.go.id -connect example.go.id:443 2>/dev/null | openssl x509 -noout -enddate

Hasilnya:

notAfter=Oct 20 23:59:59 2026 GMT

Supaya bagian notAfter= tidak ikut ditampilkan, hasilnya bisa dipotong menggunakan cut:

echo | openssl s_client -servername example.go.id -connect example.go.id:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2

Hasil:

Oct 20 23:59:59 2026 GMT

Mengecek Banyak Domain

Daripada menuliskan domain langsung di script, saya lebih suka membuat file daftar domain.

Misalnya buat file:

domains.txt

Isinya:

example.go.id
app.example.go.id
api.example.go.id
portal.example.go.id
data.example.go.id

Kemudian script membaca file tersebut satu per satu.

#!/bin/bash

while read DOMAIN
do
    [ -z "$DOMAIN" ] && continue

    EXPIRY=$(echo | openssl s_client \
        -servername "$DOMAIN" \
        -connect "$DOMAIN:443" 2>/dev/null \
        | openssl x509 -noout -enddate 2>/dev/null \
        | cut -d= -f2)

    echo "$DOMAIN : $EXPIRY"

done < domains.txt

Hasilnya:

example.go.id : Oct 20 23:59:59 2026 GMT
app.example.go.id : Nov 15 23:59:59 2026 GMT
api.example.go.id : Sep 30 23:59:59 2026 GMT
portal.example.go.id : Dec 10 23:59:59 2026 GMT
data.example.go.id : Jan 20 23:59:59 2027 GMT

Menghitung Sisa Hari

Tanggal expired saja belum terlalu praktis. Lebih berguna kalau script langsung menghitung berapa hari lagi sertifikat tersebut expired.

Karena tanggal dari OpenSSL bisa dikonversi menjadi Unix timestamp, kita bisa membandingkannya dengan tanggal hari ini.

#!/bin/bash

while read DOMAIN
do
    [ -z "$DOMAIN" ] && continue

    EXPIRY=$(echo | openssl s_client \
        -servername "$DOMAIN" \
        -connect "$DOMAIN:443" 2>/dev/null \
        | openssl x509 -noout -enddate 2>/dev/null \
        | cut -d= -f2)

    if [ -z "$EXPIRY" ]; then
        echo "$DOMAIN : SSL ERROR"
        continue
    fi

    EXPIRY_DATE=$(date -d "$EXPIRY" +%s)
    TODAY=$(date +%s)

    REMAINING=$(( (EXPIRY_DATE - TODAY) / 86400 ))

    echo "$DOMAIN : $REMAINING hari"

done < domains.txt

Contohnya:

example.go.id : 43 hari
app.example.go.id : 69 hari
api.example.go.id : 23 hari
portal.example.go.id : 94 hari
data.example.go.id : 132 hari

Memberikan Warning untuk SSL yang Hampir Expired

Kalau jumlah domain banyak, saya tidak terlalu membutuhkan daftar domain yang masih memiliki masa berlaku panjang. Yang lebih penting justru domain yang harus segera ditangani.

Misalnya kita menentukan batas warning 30 hari.

if [ "$REMAINING" -lt 30 ]; then
    echo "WARNING: $DOMAIN hanya tersisa $REMAINING hari"
fi

Script lengkapnya menjadi:

#!/bin/bash

THRESHOLD=30

while read DOMAIN
do
    [ -z "$DOMAIN" ] && continue

    EXPIRY=$(echo | openssl s_client \
        -servername "$DOMAIN" \
        -connect "$DOMAIN:443" 2>/dev/null \
        | openssl x509 -noout -enddate 2>/dev/null \
        | cut -d= -f2)

    if [ -z "$EXPIRY" ]; then
        echo "ERROR   : $DOMAIN - SSL tidak dapat dibaca"
        continue
    fi

    EXPIRY_DATE=$(date -d "$EXPIRY" +%s)
    TODAY=$(date +%s)

    REMAINING=$(( (EXPIRY_DATE - TODAY) / 86400 ))

    if [ "$REMAINING" -lt 0 ]; then
        echo "EXPIRED : $DOMAIN - expired $(( REMAINING * -1 )) hari yang lalu"
    elif [ "$REMAINING" -lt "$THRESHOLD" ]; then
        echo "WARNING : $DOMAIN - tersisa $REMAINING hari"
    else
        echo "OK      : $DOMAIN - tersisa $REMAINING hari"
    fi

done < domains.txt

Hasilnya bisa seperti:

OK      : example.go.id - tersisa 43 hari
OK      : app.example.go.id - tersisa 69 hari
WARNING : api.example.go.id - tersisa 23 hari
OK      : portal.example.go.id - tersisa 94 hari
EXPIRED : old.example.go.id - expired 5 hari yang lalu

Menampilkan Tanggal Expired Sekaligus Sisa Hari

Kalau ingin hasil yang lebih informatif, tanggal expired bisa ditampilkan bersama jumlah hari.

#!/bin/bash

THRESHOLD=30

while read DOMAIN
do
    [ -z "$DOMAIN" ] && continue

    EXPIRY=$(echo | openssl s_client \
        -servername "$DOMAIN" \
        -connect "$DOMAIN:443" 2>/dev/null \
        | openssl x509 -noout -enddate 2>/dev/null \
        | cut -d= -f2)

    if [ -z "$EXPIRY" ]; then
        printf "%-35s %s\n" "$DOMAIN" "SSL ERROR"
        continue
    fi

    EXPIRY_DATE=$(date -d "$EXPIRY" +%s)
    TODAY=$(date +%s)

    REMAINING=$(( (EXPIRY_DATE - TODAY) / 86400 ))

    if [ "$REMAINING" -lt 0 ]; then
        STATUS="EXPIRED"
    elif [ "$REMAINING" -lt "$THRESHOLD" ]; then
        STATUS="WARNING"
    else
        STATUS="OK"
    fi

    printf "%-35s %-25s %5s hari  %s\n" \
        "$DOMAIN" "$EXPIRY" "$REMAINING" "$STATUS"

done < domains.txt

Contoh output:

example.go.id                     Oct 20 23:59:59 2026 GMT    43 hari  OK
app.example.go.id                 Nov 15 23:59:59 2026 GMT    69 hari  OK
api.example.go.id                 Sep 30 23:59:59 2026 GMT    23 hari  WARNING
portal.example.go.id              Dec 10 23:59:59 2026 GMT    94 hari  OK
old.example.go.id                 Aug 30 23:59:59 2026 GMT    -8 hari  EXPIRED

Mengatasi Domain yang Tidak Bisa Diakses

Tidak semua domain dalam daftar pasti bisa dicek dengan normal.

Misalnya DNS tidak resolve, port 443 tidak terbuka, server mati, atau sertifikatnya memang bermasalah.

Karena itu bagian pengecekan hasil dari OpenSSL sebaiknya tetap dilakukan:

if [ -z "$EXPIRY" ]; then
    echo "$DOMAIN : SSL ERROR"
    continue
fi

Dengan begitu satu domain yang bermasalah tidak menghentikan proses pengecekan seluruh domain.

Mengecek Issuer Sertifikat

Selain tanggal expired, kadang saya juga perlu mengetahui siapa penerbit sertifikatnya.

Untuk melihat issuer:

echo | openssl s_client \
    -servername example.go.id \
    -connect example.go.id:443 2>/dev/null \
    | openssl x509 -noout -issuer

Contoh:

issuer=C=GB, O=Sectigo Limited, CN=Sectigo RSA Domain Validation Secure Server CA

Subject sertifikat bisa dilihat dengan:

echo | openssl s_client \
    -servername example.go.id \
    -connect example.go.id:443 2>/dev/null \
    | openssl x509 -noout -subject

Mengecek SAN pada Sertifikat

Hal lain yang cukup berguna ketika troubleshooting SSL adalah melihat Subject Alternative Name (SAN).

echo | openssl s_client \
    -servername example.go.id \
    -connect example.go.id:443 2>/dev/null \
    | openssl x509 -noout -text | grep -A1 "Subject Alternative Name"

Ini berguna ketika ingin memastikan sebuah hostname memang tercantum di dalam sertifikat.

Membuat Script Menjadi File

Misalnya script disimpan sebagai:

/root/check-ssl.sh

Berikan permission executable:

chmod +x /root/check-ssl.sh

Kemudian jalankan:

/root/check-ssl.sh

Menjalankan Otomatis dengan Cron

Kalau script ini digunakan untuk monitoring, tidak perlu dijalankan manual setiap hari.

Bisa menggunakan cron.

Buka crontab:

crontab -e

Misalnya dijalankan setiap hari pukul 07.00:

0 7 * * * /root/check-ssl.sh

Kalau ingin menyimpan hasil pengecekan ke file log:

0 7 * * * /root/check-ssl.sh >> /var/log/check-ssl.log 2>&1

Kalau Ingin Dibuat Lebih Lanjut

Script sederhana seperti ini sebenarnya sudah cukup untuk kebutuhan pengecekan dasar. Tetapi kalau jumlah domain semakin banyak, script bisa dikembangkan lagi.

  • Mengirim email jika SSL kurang dari 30 hari.
  • Mengirim notifikasi Telegram.
  • Menyimpan hasil ke CSV.
  • Membuat dashboard monitoring.
  • Mengecek HTTP response code.
  • Mengecek apakah domain masih resolve ke IP yang benar.
  • Mengecek masa berlaku sertifikat secara berkala.
  • Membuat laporan seluruh domain dan subdomain.

Untuk kebutuhan sederhana, kombinasi openssl, Bash, dan cron sebenarnya sudah cukup untuk menghilangkan pekerjaan pengecekan SSL secara manual.

Yang paling penting bukan script-nya harus rumit, tetapi jangan sampai kita baru mengetahui sertifikat expired setelah pengguna lebih dulu mengabarkannya.

Tinggalkan Komentar

Your email address will not be published. Required fields are marked *