13日の金曜日だ！Lambda関数を守るぞIAM Access Analyzer！

# はじめに

なんと今日は**13日の金曜日**です:hockey:
12月13日(金)は実に6年ぶりで、次回は2023年だそうです。
~~こんな日にAdvent Calenderの記事を投稿する人たちは何を考えているんでしょうか？~~

※13日の金曜日を知らない方は以下のWikipediaをご参照ください。
参考: [13日の金曜日](https://ja.wikipedia.org/wiki/13%E6%97%A5%E3%81%AE%E9%87%91%E6%9B%9C%E6%97%A5)

さて、本題に入ります。
今日は**13日の金曜日**です。きっと**Json**がLambda関数を危ない**ジェイソン**でInvokeしようとしてるに違いありません:fearful:
悲劇が起きる前にIAM Access AnalyzerでLambda関数のポリシーをチェックしましょう！


# IAM Access Analyzerとは

先日行われたAWS re:Invent 2019で発表されたポリシーチェックのサービスです。
**追加費用なし**で以下のリソースのアクセスポリシーを監視できます。

* S3 Bucket
* KMS Key
* SQS Queue
* IAM Role
* Lambda関数

参考: [Introducing AWS Identity and Access Management (IAM) Access Analyzer](https://aws.amazon.com/jp/about-aws/whats-new/2019/12/introducing-aws-identity-and-access-management-access-analyzer/)

### 設定方法

IAMの画面に行くと**Access Analyzer**がメニューに追加されています。
画面真ん中の【アナライザーを作成】から設定できます。
![スクリーンショット 2019-12-12 18.03.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352561/897e0389-0b23-4e9c-6c96-8f57f55d1086.png)

設定する項目は**名前**と**タグ**だけです。
適当な名前とタグを設定してアナライザーを作成してください。

注意点として、Access Analyzerはリージョン別になっています。
設定していないリージョンのリソースは監視されないので気をつけてください。

### 設定後

設定が完了するとスキャンが開始され、AWSアカウント外からのアクセスが可能になっているリソース一覧が表示されます。（今回は0件でした）

![スクリーンショット 2019-12-12 18.39.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352561/5a82765f-59e5-390b-963f-60a1fa45ab9e.png)

Access Analyzerの詳細は他の方の記事を参照していただければと思います。

## Lambda関数を検出→修正

Access Analyzerで検出されるLambda関数を作成し、解決までのフローを実際にやってみます。

### Lambda関数の用意

[タグ判別でインスタンスを停止するLambda関数](https://qiita.com/Sunochi/items/3d2087c07403d2f5bca9)を使用します。
デプロイしただけでは検出されません。
なので、他のアカウントからも実行できるように以下のコマンドを叩きます。

```
$ aws lambda add-permission \
    --function-name stop_ec2_instances \
    --action lambda:InvokeFunction \
    --statement-id other-account \
    --principal 012345678999 \
    --profile my-account \
    --region ap-northeast-1
```

```
レスポンス
{
    "Statement": "{\"Sid\":\"other-account\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::012345678999:root\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:ap-northeast-1:000000000000:function:stop_ec2_instances\"}"
}
```

principalで指定したアカウントに、実行権限を付与するコマンドになります。
なお、AWSアカウントIDは以下の通りです。

| アカウントID   | 設定          |
|:-------------|:--------------|
| 000000000000 | Lambda関数のあるアカウント |
| 012345678999 | 他者のアカウント |

## 検出結果

Access Analyzerの画面を開いて確認します。
![スクリーンショット 2019-12-12 19.50.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352561/167ec1b2-4e86-5e9c-3f03-288bc87247a0.png)

アクティブの欄に表示されている通り、自身のアカウント以外からアクセス可能になっていることが検出されています。

## Access Analyzerから修正する

Access Analyzerから修正します。
※リソースの管理画面への遷移が簡単なだけで、直接編集できるわけではないです

#### 1. 【**結果ID**】のリンクを押して詳細画面を開く

![スクリーンショット 2019-12-12 20.00.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352561/21f554fd-5874-408e-4ba6-7a079ccb92e6.png)

#### 2. 画面右下のボタンから設定ページを開く

Lambda関数の設定なのでボタンには「次のページに移動します。Lambda コンソール」と表示されています。
今回はLambda関数のページが開きます。

#### 3. リソースのポリシーを修正する

画面上部の「**設定 | アクセス権限 | モニタリング**」からアクセス権限を選択すると、画面中程にポリシーの設定あります。
今回は下記の通りでした。

```
{
  "Version": "2012-10-17",
  "Id": "default",
  "Statement": [
    {
      "Sid": "other-account",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::012345678999:root"
      },
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:ap-northeast-1:000000000000:function:stop_ec2_instances"
    }
  ]
}
```

残念ながらLambda関数はS3などと異なり、マネジメントコンソール上でポリシーの編集ができません。
CLIで下記コマンドを使用します。

```
$ aws lambda remove-permission \
    --function-name stop_ec2_instances \
    --statement-id other-account \
    --profile my-account \
    --region ap-northeast-1
```

レスポンスはありません。
マネジメントコンソールか`aws lambda get-policy`で削除できていることを確認してください。

#### 4. 再確認

Access Analyzerの画面に戻ります。先ほどの詳細画面を開いて、画面右上の【**再スキャン**】を押してください。
![スクリーンショット 2019-12-12 20.44.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352561/f138bbc2-a1d3-c463-a090-f7a62e8e22e1.png)

正しく設定できていると、ステータスが「**アクティブ**」から「**解決済み**」になり、一覧画面からも消えます。
なお、結果自体は「解決済み」の一覧に残ります。便利ですね:v:
![スクリーンショット 2019-12-12 20.20.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352561/cb5c06e5-48d8-4583-8f31-d47095185e13.png)




# おわりに

Lambda関数の実行権限を外部に付与するパターンはあまりないです。しかし、運用方法次第ではあり得るのも確かです。
その時に設定ミスをしていないか検出するためにも、今回紹介したAccess Analyzerは役立ちそうです。紹介した以上の設定も可能ですので、ぜひ活用してみてください。

ちなみに初めてのAdvent Calenderへの参加でした。描いてて楽しかったので、来年も参加できるよう励みます:metal:

# 参考

* [13日の金曜日](https://ja.wikipedia.org/wiki/13%E6%97%A5%E3%81%AE%E9%87%91%E6%9B%9C%E6%97%A5)
* [Introducing AWS Identity and Access Management (IAM) Access Analyzer](https://aws.amazon.com/jp/about-aws/whats-new/2019/12/introducing-aws-identity-and-access-management-access-analyzer/)
* [AWS Lambda のリソースベースのポリシーを使用する](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/access-control-resource-based.html)
* [AWS CLI Command Reference add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html)
* [AWS CLI Command Reference remove-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/remove-permission.html)