AWSでSlackへのPOST先を限定する仕組みを構築する話（失敗ルート）

# 0. はじめに

今年の7月にAWSアソシをギリで取得した初心者が、AWSでそれっぽいことをする奮闘記である。
言いたいことは、<font color="Blue">**AWS初心者でも調べる＆触るを繰り返せば、それっぽいこと出来ちゃうよ、やってみよう！**</font>ってこと。

ちなみに、これはうまくいかなかった失敗ルートです。
失敗ルートを歩んだけど、HPが０になってゲームオーバーになったわけじゃないから、そこで得た経験値はありがたく自分のものになったので、セーブしとこう。



# 1. やりたいこと

情報流出を防ぐために、みんなで作るLambdaのPOST先をSlackだけに**システム的に絞りたい**。

![slackAWSPOSTAPI-1-Page-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/b6216ca6-65ca-c60c-0b27-5c7f7f0b47f9.png)


ただし、いくつかの条件がある。（この条件も調べてから知った）
### 条件
- SlackのIPアドレスの範囲は非公開のため、L4レイヤによるIPアドレスのフィルタリングでは難しい。
- 現在、AWSサービスでWebフィルタリングする機能はない。（出口側）





# 2. 絵にする

いきなりこれが出来たわけではないけど、こんな構成図を考えました。

![SlackawsFilter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/1f6b5bcf-89dc-3edd-387f-e75a31ff5c7a.png)






# 3. 歩んだ道

やりたいことと「LambdaをVPCに入れたら出来るんじゃない」っていう話を聞いてから、どんな道を歩んだのか、ってのを絵を交えてダラダラと書きます。

![どんな感じでやっていったか.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/b242117c-f54b-9f67-c213-f74ed293f950.png)



## ① 誕生 : day1

誕生である、さぁ道を進もう、、いえいえ生まれたて。

なんとなく出来そうってのは分かってたけど、概念レベル。
セキュリティグループで簡単に出来るんじゃない？って、生まれたて。ようこそ！
そもそも、LambdaをVPC内に入れて、やりたいことがなんで出来るんだっけ？っていう状態。
上の構成図の**Point1の部分**。

- その時のメモたち：まずLambdaってデフォルトはVPCの外にあるんだ！そんなところから。

```
APIのエンドポイントタイプをリージョン ⇒ プライベートにするのかな？
ん？違う？VPCからアクセスしたいわけではないよな。。。つまり最初はパブリックで良い。で、その連携Lambdaもパブリック。
LambdaもAPIGWもDyanamoも全部VPCの外にいる・・・から？
ん？VPCでの制御云々ではないはず。
https://qiita.com/saitotak/items/d2ede050e7a2224da46d

VPC Lambdaならその名の通り、VPCだけど。。
https://dev.classmethod.jp/articles/dynamodb-vpc-endpoint-lambda/

仮にVPC内にLambdaを配置すると、インターネットへのアクセスには、これが必要。
・プライベートサブネット＆パブリックサブネット用意
　　・プライベートいらなくないか？いや、IP固定にはいるのか？？
・「Amazon VPC NAT gateway」
　・プライベートいらないなら、これもいらない。
・VPC エンドポイントを設定する。（cloudwthchとかDyanamodbとか）
・ENI(Elastic Network Interface)の作成権限をLambdaに与える必要があります
・VPCにインターネットGW
・セキュリティグループのインターネット間とのトラフィックを許可している。
　・これだと出来ない。IP指定しかできないのでは？AWSにプロキシ必要なんじゃね？？
・フォワードプロキシおいて、そこ通すようにする？
　・NATGWではなく、NATインスタンス/プロキシ設定
```



## ② 産声：day2

生まれたので、何しよう。よし、泣こう！おぎゃぁおぎゃぁ。

プロキシサーバってヒントを得たので、そこを中心的に調べてみる。
上の構成図の**Point.2の部分**。ようやくちょっと霧が晴れた。
フィルタリングの仕組みもないか調査したり（Amazon GuardDuty使ってみる？とか）と、
ここまでは、<font color="Blue">**ひたすらググってメモに残してく活動**</font>って感じ。

- 利用してるのは、タスク管理ツールとTypora。

- その時のメモたち：Webフィルタリングをなんとなーく理解

```
疑問点
・プロキシサーバを用意する理由は？
　・NATインスタンスなどでは、L7レイヤのURL制御ができない。
　・プロキシサーバなら…？？？ ← ここが？？
　・⇒ URLフィルタリングはProxyサーバにSquidを用いて実装
・プロキシを設定する方法は？
　・pythonのRequest オブジェクト内でset_proxyやればよさげ。
　　https://maku77.github.io/python/web/http-request.html
・Webフィルタリングしたいけど…
　・AWSサービスでWebフィルタリングする機能はない
　　https://dev.classmethod.jp/articles/web-filtering-on-workspaces/
   > また、AWS が提供する他のサービスでも Web フィルタリングを行うためのサービスはありません 
```

今思うと、ここをもっとちゃんと調べりゃよかったっていう話もあるけど、それは過去の話。



## ③ 絵を書く：day3

さーて、進むべき絵でも描くか。急成長である。

今までの内容を**図にすることで頭の整理と、俯瞰することで気付きを見つけよう**の期間。
頭の整理途中の具体例は、

- エンドポイントって2種類あるけど、なにが違うんだ？（GW型とインターフェース型）→ 調べる。

  - AWSのサービスによって違うのね。DynamoとS3はGW型。

- NATインスタンスの図は置かないでいいのか？ → 調べる。

  - プロキシサーバにパブリックIPを付与するから、不要。

- API-GWはVPC内に入れるのか？外なのか？ → 調べる。

  - 外。

    

利用してるのは、draw.io。
意外とここは<font color="Blue">**draw.ioのおかげだな**</font>って思った。
勿論、AWSのサービスの図があるから、とても楽ちん。ってのはあるけど、
サービスの図を選ぶときに、「え？２つあるけど、どっちを選べば良いんだ？」ってなり、そこから調査して理解するっていう流れが数度あった。

俯瞰してみると、やっぱりSlack側のIPさえ分かれば、別にこの仕組みいらないよなー。
って思い、調べる。が、やはり進むべきは間違ってなさそう、そんな結論になった。

```
https://stackoverflow.com/questions/38759599/slack-webhook-which-ips-should-i-open
> 同じ問題に直面し、IP範囲をホワイトリスト化することしかできませんでした。
残念ながら、Slack APIのこのツイートによると、プラットフォームはAWSにあり、
固定IP範囲を持っていません。何らかのプロキシを使わないと通れないかもしれません。
```



## ④ 実際に進んでみる：day4～6

もう歩いちゃう。さーさー、いざ参らん。

構成もある程度決まったので、構築を始める。きゅきゅっとまとめると3日間くらい？
実際は他のことをやったり、待ちだったりとで、8日間くらいはこの状態かな。

- VPC足りない問題（上限：リージョンあたり5）
- Elastic-IP足りない問題（上限：リージョンあたり5）
- カスタムルートテーブルとか、そもそも何を設定したらいいんだ？

進め方のポイントは、<font color="Blue">**満足ポイントを如何に早め＆定期的に得るかってこと**</font>。
まぁ切り分けをやりやすくなるしね。

- ざっと全体にモノを配置していって、満足ポイントを獲得する。
- 部分的に疎通していって、設定があってそうかってのを確認していく。
  - 例：B-API ⇔ B LambdaやB Lambda ⇔ CloudWatch Logsとか

この期間が**一番スキルとしては収穫デカい**ところ。
VPCのIPアドレス体系どうしようかな…とか基本的なところから、
実際にモノ触って初めて分かること多すぎる。これ、**ググれる環境ないとマジ無理**だ。

こんなところに引っかかった。

### Lambda

- VPCを設定しようとすると、エラー起こる。
  `The provided execution role does not have permissions to call CreateNetworkInterface on EC2`

- https://qiita.com/kapibara-3/items/b3afa27d69502e5b8ab7

  > 実際はEC2ではなくVPCの権限。

- 解決策はこれ。LambdaをVPCにぶち込むときの実行ロールが足りない。
  https://blog.i-tale.jp/2020/06/11/

  > 解決策は公式解説どおりですが、 Lambda の実行ロールに管理ポリシーである AWSLambdaVPCAccessExecutionRole これを付与することです。



### Cloudwatch logs

https://qiita.com/akhkyamada/items/7e2fa8f9f8d4b7e78878

- Cloudwatch logs のエンドポイント設定しようとしたけど、エラー

  ```
  VPC エンドポイントの作成でエラーが発生しました
  Enabling private DNS requires both enableDnsSupport and enableDnsHostnames VPC attributes set to true for vpc-xxxxxxxxxxxxxxxxx
  ```

  はいはい、DNSホスト名を有効化するのね。→ 作れた。
  https://dev.classmethod.jp/articles/rdp-windows-deny-all-inbound-access/



## ⑤ もっと良い道を知る：day7,8

なんとなーく感づいてたけど、行く先に大きな石ころが転がってた！さて、どうしよう。

そう、一番大事な箇所であるWebフィルタリングの部分。（squidのconfファイルのところ）
squidとか初めて触るし、ネットワーク周りは苦手…うまくいかない…これは厳しい…。
でも、きっと、こっちから見たら大きいけど実は薄ーい石なんでしょ？って思いつつ、調査。



ん？httpsでは、URLフィルタリングできない？

```
https://milestone-of-se.nesuke.com/sv-advanced/server-software/https-url-filter/
  > 暗号化によりhttpヘッダの中身を見ることができません。

  やり方はいくつかあるけど、どれも完璧にそのままでは出来なそう。
  > この方式の問題点は、CONNECT と同様サブディレクトリが識別できないことです。

https://xtech.nikkei.com/it/atcl/column/16/052300113/052300008/
  > プロキシーサーバーでは、ドメイン単位（https://www.google.co.jp/）での
    フィルタリングはできたが、ディレクトリー単位（https://www.google.co.jp/intl/ja/drive/）はできなかった。
```



なるほど、、、確かに他のwebフィルタリングの記事を見ると、httpのことしか書いてない。
UTMっていう「ぎんがのつるぎ」※を入手するってのも1つの手だけど、いかんせんそこには色んなハードルがある。

``` ※ ドラクエをまともにやったことがないので、こういう時に大変。 https://game8.jp/dq11/277926```

ということで、相談をして、他の道を推奨。ってことで、そちらの道を歩むことにした。

それはまた、別のお話で。