Splunk Observability CloudでSSL証明書の有効期限を監視
はじめに
監視要件として、SSL証明書の有効期限をチェックしたいというものがあります。
Splunk Observability Cloud(OpenTelemetry Collector: Otel Collector)ではどのように行うかをまとめました。
※Otel Collectorがベースなので、本記事の内容はSplunk Observability Cloudに限定した内容ではありません。
OpenTelemetry CollectorでSSL証明書のメトリクスは取得できるか
答えは、現在(2023/6/13)はそのようなReceiverは存在しませんので、残念ながらNoです。
じゃあどうするかというとPrometheus Exporterをお借りします。
Prometheus Exporter
Otel CollectorではPrometheus Exporterのメトリクスを取得するためのPrometheus Receiverというものが提供されています(ややこしい)。
詳細は以下記事を参照ください。
Prometheus SSL Certificate Exporter
Prometheus Exporterとして、SSL Certificate Exporterというものがあります。
これは以下の方法で証明書に関するメトリクスを取得できます。
tcp
: 任意のtarget(URL)上の証明書に関するメトリクスを取得
http
: tcp
と同じだが、Proxyを通したい場合に使用
file
: ローカルのPEMファイルを取得
kubernetes
: kubernetesのSecret(kubernetes.io/tls)から証明書を取得
kubeconfig
: kubernetesのkubeconfig内のPEMファイルを取得
今回は外部公開サイトの監視のためtcp
を使ってみたいと思います。
OpenTelemetry CollectorでPrometheus Receiverを使用
適当なホストにSplunk Otel Collectorが既にインストールされているとします。
同ホストにPrometheus SSL Certificate Exporterをインストールします。
※別のホストでもいいです。Otel CollectorからのScrape先を変えるだけです。
Build(Go言語)かDockerが可能なようなので、今回はDockerで起動します。
docker run -d -p 9219:9219 ribbybibby/ssl-exporter:latest
次にOtel Collectorに設定を追加します。
試しにzenn.dev
、prometheus.io
、www.splunk.com
の証明書を監視します。
※これは例なので、実際は自分たちが提供しているサービスのURLをターゲットにします。
#prometheus receiverを追加
receivers:
prometheus/ssl_exporter:
config:
scrape_configs:
- job_name: "ssl"
metrics_path: /probe
scrape_interval: 10s
static_configs:
- targets:
- zenn.dev:443
- prometheus.io:443
- www.splunk.com:443
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 127.0.0.1:9219
#既存のmetrics pipelineのreceiverに追加
service:
pipelines:
metrics:
receivers: [hostmetrics, otlp, signalfx, smartagent/signalfx-forwarder, prometheus/ssl_exporter]
processors: [memory_limiter, batch, resourcedetection]
exporters: [signalfx]
Otel Collectorを再起動します。
sudo systemctl restart splunk-otel-collector
念のためログを見て、問題なく起動できているか確認します。
sudo journalctl | grep otelcol | grep ssl
Splunk Observability Cloudで確認
ダッシュボード化
メトリクスを取得できているか確認し、ダッシュボードに組み込みましょう。
Metric Finderでssl
と検索します。
いくつか取得できています。
各メトリクスの詳細はSSL ExporterのGitHubを確認いただきたいですが、今回は期限切れ日を示すssl_cert_not_after
とSSLポーリングが成功したかを示すssl_probe_success
を使いたいと思います。
ssl_cert_not_after
を開きます。
Data Tableを確認してみると、、、ターゲットにしていた3つのサイトの証明書について取得されていますね。成功です。
気になる点として
・ルート証明書も取得している ⇒ フィルタで除外する。dnsnames
が含まれているものが良さそうです。
・Valueが謎の巨大な数値 ⇒ これは有効期限のEpoch Time(秒)で結果が返ってきているためです。このままでは適切な監視ができないので、「残りx日」に変換してアラート設定を組み込みたいと思います。
「残りx日」にするには以下の計算をすればOKです。
残りx日 = (有効期限のEpoch time - 現時点のEpoch time)/(86400秒)
現時点のEpoch time
を取得するには、残念ながら今のところUI上からは設定できないので、代わりにSignalFlowでtime()を使います。
SignalFlowのEditorはPlot Editorタブから開けます。
現在の設定内容がSignalFlowで表示されました。
time()の解説ページを参考に、以下のように修正します。
A = data('ssl_cert_not_after', filter=filter('service.name', 'ssl')).publish(label='A')
expire_epochtime = data('ssl_cert_not_after', filter=filter('service.name', 'ssl') and filter('dnsnames', '*'))
now_epochtime = time()/1000
days_to_expire = floor((expire_epochtime-now_epochtime)/(24*60*60)).publish(label="days_to_expire")
detect(days_to_expire<60).publish(label="Certificates expiring soon!")
time()
はミリセカンドのEpoch Timeが返されるので、1000で割っています。
days_to_expire
に残りの日数が格納されるようにします。
最後の行のdetectは後続のアラート設定で使うための仕込みです。
60日を切ったらアラートを出すようにしています。この値は要件に合わせてセットしてください。
Data Tableを見てみましょう。それっぽい数値になりました。
prometheus.ioが53となっています。正しいか確かめてみます。
2023/8/5が有効期限です。これを仕込んだのが2023/6/12なので、53日後の期限切れで正しそうです。
後は見やすいように表示方法を色々設定してあげましょう。Listタイプがいいですね。期限切れが近いものを上に来るようにして60日を切っていたら赤くしてあげます。
最後にSave Asから適当なダッシュボードに保存すれば完了です。
次に、Otel CollectorからのSSLプローブが成功したかをチェックするためssl_probe_success
をダッシュボードに組み込みます。成功が1、失敗が0といたってシンプルですので、このまま使います。
見やすくしましょう。Heatmapとかいかがですか。
Dashboardに保存します。
Detector
ダッシュボードを毎日眺めている訳にもいかないので、期限切れが近くなったらアラートを発報するようにします。Splunk Observability Cloudではアラート定義をDetectorと呼んでいます。
チャートの🔔アイコンから定義します。
SignalFlowを使った場合は若干特殊な手順です。
Alert RuleからEditします。
Alert Messageに緊急度や、証明書更新手順が載ったURLなども定義できます。
Alert Recipientsで通知先を設定しましょう。
最後に名前を付けてActivateします。
Saveします。
次に、Incident ID(DetectorのID)を取得します(この手順はSignalFlowを使わなかった場合は不要です)。
Alerts & Detectors > Detectorsから、今作成したDetectorを探します。
Detectorを開き、URLからIDをコピーしておきます。
次にChartにDetectorをLinkさせます。
SignalFlowの最後の行にalert定義がコメントアウト状態で追加されているので、コメントアウトを外し、IDを貼り付けてあげます。
これで完了です。
次にProbe Successの方もDetectorを仕込みます。
同じように🔔アイコンからDetectorを作成します。
Alert ConditionをStatic Thresholdにします。
閾値はBelow 1(1未満)にします。これでProbe Successが0になった場合に通知してくれます。
残りの設定は期限切れ日の時と同じです。
ChartとDetectorのLinkは自動的にされますので対応不要です。
Dashboardを見てみましょう。prometheus.ioが60日未満なのでDetectorが発動し、赤色の枠が表示されていますね。一方Probe Successは問題がないので緑色の枠です。このように、アラート状態かどうかをChartに紐づけて確認できます。
もちろんアラート画面からもLinkされたダッシュボードへの遷移ができます。
追記:Splunk Enterprise / Cloudで確認
上記ではIMでDashboard化、Detector作成しましたが、別の方法としてSplunk Enterprise / Cloud(以降、Splunk Core)でもメトリクスを取得し処理することができます。
Splunk CoreにSplunk Infrastructure Monitoring Add-onをインストールすることでSplunk CoreからObservability CloudにREST通信を行い、IMのメトリクスを取得できます。
一時的な取得、もしくは設定 > データ入力 > Splunk Infrastructure Monitoring Data Streams
からインデックス化ができます。
今回は簡単に一時的な取得でやってみましょう。
まずはAdd-onのセットアップをしておきます。REALMとAccess Tokenを指定することでメトリクス取得ができるようになります。
次にIMのダッシュボードからView SignalFlow
をクリックし、SignalFlowを取得します。フィルターをかけてもいいですが、SPLで処理できるのでとりあえず全取得します。
A = data('ssl_cert_not_after').publish(label='A')
Splunk Coreに戻り、このようにSPLを打ちます。Add-onに含まれる| sim
コマンドによりIMのメトリクスが取得できます。
| sim flow query="A = data('ssl_cert_not_after').publish(label='A')"
ドバドバと値が来ました。
いいですね。
もっと見やすくしつつ残り日数を計算してみましょう。
| sim flow query="A = data('ssl_cert_not_after').publish(label='A')"
| spath
| search dnsnames=* "service.name"=ssl
| eval expire_epochtime=_value
| eval now_epochtime=now()
| eval days_to_expire = floor((expire_epochtime-now_epochtime)/(24*60*60))
| stats values(days_to_expire) as days_to_expire by service.instance.id
OK。
期限切れ間近のものに絞り込みたいので、最後にこんな感じで追加すれば絞り込めます。
...
| eval threshold=60
| where days_to_expire<threshold
名前を付けて保存 > アラート からアラート定義をします。
例えば、毎日9:00にチェックし、値があればSlackに送るようにします。
もちろんメッセージに$result.fieldname$
で処理結果を埋め込むこともできます。
変数の取得方法の詳細はこちらを参照してください。
まとめ
本記事では、たまに監視要件であるSSL証明書期限監視の設定方法を見てきました。
Otel CollectorもSplunk Observability Cloudも拡張性が高くてよいですね。
Discussion