サーバーレスの可観測性、モニタリング、セキュリティを強化する方法
2019年7月15日
0 分で読めます関数は実行時間が短く、大量にデプロイされることが多いうえ、規模の拡大に伴って呼び出し頻度も高まります。そのため、イベントの流れを追跡したり、特定のエラーの根本原因を突き止めたりするのが難しくなりがちです。
さらに、組織でのサーバーレスの導入が進むにつれて、安全でない処理フローや、関数を危険なコードパスへ誘導しようとする攻撃者の悪意ある試みを監視することも、より複雑になります。
関数をデプロイしながらセキュリティを維持するために、次のことをお勧めします。
以前の投稿サーバーレスセキュリティのベストプラクティス10選で、サーバーレスセキュリティに関する知見をさらに共有しました。後で読むためにブックマークしておくとよいでしょう。ここでは、クラウドベースのサーバーレスプロジェクトに適用できる、以下のモニタリングとログ記録の実践方法を見ていきましょう。
関数が属する環境の可視性を高める
関数は呼び出されたときにのみ費用が発生するため、実質的に無料であり、その結果、数多くデプロイすることになります。しかし時間が経つにつれ、それぞれの関数がネットワークやデータへのアクセスを許すセキュリティ上のリスクとなる可能性があります。さらに、関数で使用されるライブラリは古くなり、脆弱性を抱えることがあります。一方、一度デプロイした関数は削除しにくく、所有者や組織内での責任の所在が不明確だったり、定義されていなかったりすることもあります。
関数、その目的、対応する環境を見失わないように、次のことを定めましょう。
デプロイする関数について厳格なルールを設け、長期運用する本番用、実験用、バックオフィス用などを簡単に把握できるようにする
関数を削除すべきタイミングに関する明確なガイドライン
AWSは最近、Lambda関数にタグを付ける機能を導入しました。これにより、関数を簡単に追跡し、グループ化できます。Serverless frameworkを使うと、yamlファイルで関数にタグを付けられます。serverless.ymlファイル内のすべての関数にグローバルに適用することも、個々の関数に適用することもできます。
上記のコードは、AWSのLambda関数で利用できる2種類のタグを示しています。
10行目は、
serverless.ymlのデプロイで定義され、すべての関数に適用されるグローバルタグを示しています。18行目は、
helloWorld関数のみに適用されるfooタグを示しています。
セキュリティ上の脆弱性について関数を監視する
関数のデプロイ方法はさまざまで、デプロイされる関数の数は簡単に手に負えなくなります。保守の取り組みが薄れ、他のプロジェクトに注力するようになると、時間の経過とともに関数内のコードや依存関係が古くなり、脆弱性を抱える可能性があります。
デプロイ済みの関数を監視し、状態を適切に保つために、Function as a Service(FaaS)プロバイダーと連携するソリューションを活用しましょう。これにより、関数やオープンソース依存関係の利用に関連して、ソフトウェア開発ライフサイクル全体にわたる既知のセキュリティ脆弱性に対処できます。
次の画像は、スキャン後のGitHubプロジェクトlirantal/bazz-serverlessです。このプロジェクトには、重大度が高・中・低の脆弱性が複数含まれています。これは、複数の関数をデプロイする私のサーバーレスプロジェクトのソースコードです。GitHubプロジェクトのリポジトリの下には、デプロイしたAWS Lambda関数が6つ表示されています。これらはAWSによって実際にデプロイされ、実行される関数です。
Snykは、既知のセキュリティ脆弱性がないか、これらの個々の関数をすべてスキャンしました。それぞれが同じ依存関係ツリーを使用しているため、すべてに脆弱なライブラリが含まれてデプロイされていることがわかります。
興味深いことに、プロジェクトのリポジトリでは重大度の低い脆弱性が4件見つかっていますが、個々の関数には表示されていません。これは、デプロイ済みのバージョンがGitリポジトリに保存されているバージョンとは異なり、特にデプロイ済みの関数が古く、ソースコードに追加したライブラリが含まれていないためです。
プロジェクトのセキュリティを追跡していなければ、脆弱なライブラリをさらに本番環境にデプロイし、開発中のアプリの攻撃対象領域を広げていたかもしれません。

リソースアクセスを監視する
攻撃者がNode.js関数の脆弱性を悪用し、CPU負荷の高い処理に長時間を費やさせてイベントループをブロックする状況を想像してみてください。関数を必要に応じて起動して新しいリクエストに対応するという、Function as a Serviceの仕組み上、これを検知するのは簡単ではないかもしれません。これは優れた機能に思えますし、実際にそうした側面もありますが、その代償として、関数の使用ごとに課金されるため、クラウド料金が急増します。
モニタリング戦略を策定しましょう。意図しない関数の呼び出しを特定してブロックするために、ポリシー、アラート、適用の仕組みを整えます。監視対象となるリソースの例を以下に示します。
CPU
メモリ
入出力の消費量と操作
読み取りや書き込みなどのファイルアクセス
関数の実行時間
関数の呼び出しフローと、想定される呼び出し元からの逸脱
子プロセスの実行
クラウドプロバイダーは多くの場合、アプリケーションや関数のリソースを監視し、こうした情報を把握するための機能を標準で提供しています。MicrosoftはAzure Monitoring、AmazonはAWS X-Rayを提供しています。後者を例にすると、AWSの公式ドキュメントにはAWS X-Rayコンソールの画像が掲載されており、関数やその他のクラウドリソースを通過するデータフローと、実行時間などのメトリクスを確認できます。

モニタリングを実現したら、関数に関する上限を設定し、金銭的なリソースの枯渇をさらに防ぎましょう。
関数のログ記録
ログは関数のまとまりごとに論理的にグループ化され、有益な知見をもたらします。しかし、適切に扱わなければ、新たなセキュリティ上の問題を引き起こすおそれもあります。
ログの価値を最大限に引き出すには、次のことを実践しましょう。
イベント、そのコンテキスト、障害情報を詳細に記録する
クラウドのログ機能を活用する
チームがイベントを簡単にデバッグして見つけられるよう、ログを一元管理するシステムを導入する
ログや特別なイベントにしきい値とアラートを設定する。監査証跡としてだけでなく、問題への即時対応が必要なときに通知を行う手段としてもログを活用する
一方で、認証情報などの機密情報や、環境変数データなどの過剰な情報をログに記録しないよう注意してください。また、個人を特定できる情報が記録されないよう、各地域のGDPR要件への準拠も徹底しましょう。
まとめ
サーバーレス関数の構築とデプロイにおけるセキュリティ上の懸念について、詳しく知りたい方はサーバーレスセキュリティのベストプラクティス10選をご覧ください。