TECHSTEP

ITインフラ関連の記事を公開してます。

Prometheusを利用する際のセキュリティモデル ~公式ドキュメントを読む~

はじめに

これまでPrometheusやExporterを設定し、監視対象のサーバからメトリクスが取得することができました。しかし、これまではセキュリティについて何も気にしておらず、あまり安全な監視体制とは言えない状態でした。

一方でPrometheusのコンフィグを眺めてみても、セキュリティに関わりそうな項目が存在せず、果たしてどうやってセキュアな通信を実現しているのだろう?と言うことが気になりました。

Prometheusの公式ドキュメントの中を見るとこちらのページにてPrometheusのSecurity Modelに関する紹介が載っていたので、ここに内容をまとめておきます。和訳+一部意訳+一部別記事から追加した内容です。

------記事内容はここから------

セキュリティモデル

Prometheusは多くのコンポーネントや他の多くのシステムと統合された洗練されたシステムであり、様々な環境にデプロイすることが可能です。

このページではPrometheusで一般的に想定されているセキュリティについて、そして幾つかの可能性のある攻撃因子について紹介します。

どんなシステムでも、バグが存在しないことを保証することはできません。もしもセキュリティ面のバグを発見した場合は、MAINTAINERS.mdにリストで書かれている管理者に報告してください。

Prometheus

想定されることとして、信頼できないユーザがPrometheusのHTTPエンドポイントやログにアクセスする状況があります。アクセスする情報には、データベースに収められているすべての時系列情報や、加えて様々な運用/デバッグの情報も含まれます。

また別の想定として、信頼できるユーザだけが、Prometheusや他のコンポーネントのランタイム環境に関する情報(コマンドライン・コンフィグファイル・ルールファイルなど)にアクセスできるような状況もあります。

どのターゲットから、どれくらいの頻度でPrometheusがスクレイプするか、あるいはそれ以外の設定は、すべてコンフィグファイルで決定されます。管理者はService Discoveryから得られた情報を使うことも出来ますが、Service Discoveryで得られた情報にはラベルを付け替えられたものも含まれることがあり、それらを参考とするかは考慮が必要です。

スクレイプされるターゲットは、信頼できないユーザによって起動されたものかもしれません。異なるターゲットのふりをするようなデータをさらすことは、ターゲットに対してデフォルトで許可されるべきではありません。honor_labelsオプションは、ラベルを再定義するよう設定するのと同様に、このような事態を防ぐことができます。

Prometheus 2.0から、--web.enable-admin-apiというフラグを使うことができます。これは、例えば時系列を削除するような役割を持つ、管理APIへのアクセスを制御することができます(デフォルトで無効化されています)。有効化すると、管理的・設定変更的な機能は/api/*/admin/パスからアクセスできるようになります。 また--web.enable-lifecycleフラグはPrometheusのHTTPリロードとシャットダウンをコントロールします。このフラグもデフォルトで無効化されており、有効化すると/-/reload/-/quitパスからアクセスできるようになります。

Prometheus 1.xでは、/-/reloadパスへのアクセスと/api/v1/series上でDELETEを実行することは、HTTP APIにアクセスすることで誰にでも可能です。/-/quitエンドポイントはデフォルトで無効化されていますが、-web.enable-remote-shutdownフラグとともに有効化することができます。

Remote Read機能は、HTTPにアクセスするすべてのユーザに対して、Readエンドポイントに向けてクエリを送ることを許可します。例えばPromQLクエリをrelational databaseに送り、起動終了することが可能であれば、クエリを送ることのできるユーザ全員が、好きなSQLをデータベースに対して起動することができることを意味します。

※Remote Read機能とは、Prometheusの持つRemote Storage機能(取得したメトリクスデータを別のマシン上のストレージに格納する)を実現するために用意されたHTTPエンドポイントのことです。

公式ページのこちらから

Alertmanager

AlertmanagerのHTTPエンドポイントにアクセスできるユーザは、Alertmanagerのデータにアクセスすることができます。そのようなユーザはアラートを作成・解除することもできるし、サイレンスを作成・削除することもできます。

※アラート、サイレンスはどちらもAlertmanagerでの設定項目です。

どこに通知を送るかはコンフィグファイルによって決定されます。特定のテンプレート設定をすると、アラート定義の宛先に通知することも可能です。例えばアラートラベルを宛先メールアドレスとして使えば、Alertmanagerにアラートを送ることのできるユーザは、メールアドレス宛に通知を送ることができます。またアラート定義の宛先がテンプレート化可能なsecret fieldであれば、PrometheusやAlertmanagerにアクセスできるすべてのユーザがsecretを閲覧することができます。

※secret fieldはAlertmanagerのコンフィグファイルで設定するsecret placeholderのことを指します。文字列を入力する領域であり、パスワードなどの情報を入力します。

公式ページのこちらから

上記のケースでは、テンプレート化可能なsecret fieldを使うことはrouteでの通知を想定しており、コンフィグファイルからsecretが取り出されるようなことは想定されていません。Alertmanagerのコンフィグファイルを編集し、通知の受け手を指定することのできるユーザは、テンプレートファイルに保存されたsecretを抽出することができます。 例えば大きなシステムの場合、各チームでフルアクセス権限を持ったAlertmanagerコンフィグファイルを別々に持っており、それらは最終的なコンフィグファイルに混在されることもあります。

※上記のrouteは、Alertmanagerのコンフィグファイルで設定できるブロックの一つ。

公式ページのこちらから

Exporters

Exporterは一般的には設定された対象と設定済みのコマンド/リクエストでしか会話しません。それはExporterのHTTPエンドポイントから情報が拡散されないことを意味します。

ExporterにはSNMP ExporterやBlackbox Exporterのような、URLパラメータからターゲットを取得するものもあります。そのため、そのようなExporterにアクセスするユーザは、好きなエンドポイントにリクエストを送ることができます。これらのEndpointはクライアントサイドの認証機能をサポートしており、これらはHTTP認証パスワードなどの機密情報をリークすることにつながる可能性があります。TLSのようなチャレンジレスポンス認証メカニズムはこれらの影響を受けません。

Authentication, Authorization, and Encryption

Prometheusとそのコンポーネントは、サーバーサイドでの認証・認可・暗号化機能は提供しません。もしそれを求めるなら、リバースproxyを利用することを推奨します

管理・変更エンドポイントではcURLのようなシンプルなツールでアクセスされることを想定しており、そのためCSRF (Cross-Site Request Forgery)に対する防御はされていません。したがって、あなたがリバースproxyを利用する際は、CSRFを防ぐためにそのようなパスをブロックしたいと望むでしょう。

変更なしのエンドポイントでは、XSS (Cross-Site Scripting)を防ぐため、リバースproxyにCORS headerをセットすることを望むでしょう。

もしあなたが信頼できないユーザからのインプットデータを含むPromQLクエリを構成している場合、injection攻撃を防ぐため、何らかの信頼できないインプットを適切に防ぐことができます。例えば<user_input>が"} or some_metric{zzz="の場合、up{job="<user_input>"}up{job=""} or some_metric{zzz=""}にすることができます。

Grafanaを利用する場合、dashboard permissionはdata source permissionではないので、proxyモードの際にクエリを投げるユーザの権限は制限しません。

Prometheusコンポーネントでは、クライアントサイドでの認証と暗号化の機能を提供します。TLSのクライアントサポートが求められた場合、insecure_skip_verifyと言うSSL verificationをスキップするようなフラグもよく利用されます。

------記事内容はここまで------

Prometheusでリバースproxyを利用する方法

上記記事の「Authentication, Authorization, and Encryption」にて、リバースproxyを利用してTKS機能を追加することを推奨しています。具体的な設定についても公式ページにて紹介されています

セキュリティを気にする必要はない?

上記公式ドキュメントを読むと、Prometheusではセキュリティに関する設計は、あまりスコープに含まれないように読めました。一方で、そもそもPrometheusを使う際、セキュリティはそこまで気にしなくても良いのでは、との意見もあります。 こちらのフォーラム(20171105の回答)を読んでみると、以下のように書かれています。

Prometheusを利用するのはプライベートネットワークの後ろであることが多いため、
セキュリティには通常関心はありません。
またExporterはシンプルなread-onlyターゲットのため、それほど情報を搾取されません。
ほとんどのメトリクスはセキュリティ的には関心のない項目ですが、例外もあります。

基本的に私たちは、パブリックインターネットからのアクセスを、シンプルなFWルールでブロックすることを推奨しますが、
TLSや認証機能を追加するため、リバースproxyを利用する方法もあります。
PrometheusサーバはSSL/x509証明書や基本的な認証機能をサポートしていますが、それがどう機能するかが
明らかなため、基本の認証機能を使うことは推奨しません。

まとめ

Prometheusでセキュリティを考慮した際には、リバース proxyを利用したTLS機能の追加が推奨されています。一方でセキュリティはそれほど気にしなくても良いのでは、という意見もあります。Prometheusのセキュリティについては、現状ではベストプラクティスのようなものはなく、利用ケースによって対策を考慮する必要がありそうです。