GCP Packet Mirroringサービスを使ってみたよ！

## はじめに
いつの間にかGCP(Google Cloud Platform)でもGCEのVMインスタンスのネットワーク通信を
フルパケットキャプチャできるサービスがBeta版で公開されていましたので簡単に評価してみました！

Azureは以前よりVMのパケットキャプチャするサービスがあり、パブリッククラウドベンダーの中では
先行している印象でしたが、6月にAWSのTraffic Mirroringが登場しているので
これで大手IaaSベンダーでネイティブにパケットキャプチャができるようになったのは、嬉しい限りです^^

**【参考】**
・[Azure Network Watcherの可変パケットキャプチャの概要][00]
・[AWS VPC Traffic Mirroring][01]

## 利用環境
| VM Name | Zone | Network | Subnetwork | Instance Type | image | 用途 |
|---------|---------|---------|---------|---------|---------|---------|
| ping-vm | us-central1-a | vpc1 | subnetwork1(10.128.0.0/20) | g1-small | centos-7-v20191115 | Ping実行用VM |
| mirrored-vm | us-central1-a | vpc1 | subnetwork1(10.128.0.0/20)  | g1-small | centos-7-v20191115 | ミラー対象VM |
| capture-vm1 | us-central1-a | vpc2 | subnetwork2(10.129.0.0/20)  | n1-standard-1 | windows-server-2016-dc-v20191112 | コレクターVM |
※キャプチャされる側を**ミラー対象VM**、キャプチャする側を**コレクターVM**と呼びます。

・本番利用を想定し、ミラー対象VMとコレクターVMを別VPCとしています。(vpc1とvpc2をVPC Peering接続)
・コレクターVMは、GUIで分かり易く表現するため、WindowsにWiresharkを入れてます。

**【構成図】**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/0a26741c-cb3e-16d7-a24f-171228fc584c.png)
※ミラー対象VMとコレクターVMは**同一リージョン**にある必要があります。(今回は、us-central1)

## GCP Packet Mirroringとは
GCPのVPCネットワーク内のVMインスタンス(GCE)のNICを流れる通信を複製し
別のVMインスタンスに内部ロードバランサ経由で転送するサービスです。
(ミラー対象VMを、①サブネット、②ネットワークタグ、③VMインスタンスのいずれかで指定します)

これまでのオンプレミス環境では、ネットワーク機器のスイッチにミラーポートを設定して
キャプチャ用のマシンや機器を接続して、パケットデータの解析をしていたと思います。
主な用途は、「ネットワークトラブルシューティング」や「IDSやWAFでのセキュリティ監視」だと思います。

GCP Packet Mirroringの主な特徴は、以下だと思います。
・料金は、ミラー対象トラフィックのネットワーク転送料のみです。
・ミラー対象VMのNICには複製される通信も乗るため、性能を考慮し必要な通信のみにフィルタできます。
　(デフォルトは全てのトラフィックがミラー対象となります。)
・同一リージョン内であれば、単一VPCや異なるVPC間、共有VPC内でのパケット複製が転送できます。
・キャプチャ成功と失敗したパケット数やバイト数をモニターできます。(これは嬉しい)

詳細は、以下の公式ドキュメントを参照ください。

**【参考】**
・[パケットミラーリングの概要][02]
・[パケットミラーリングの使用][03]
・[パケットミラーリングの監視][04]

## 実施内容
以下のステップで設定を実施しました。
1. ファイアウォールルールの作成
2. キャプチャ用VMインスタンスの作成 
3. インスタンスグループの作成
4. パケットミラーリングの作成
5. Wiresharkでのパケットキャプチャ

#### 1. ファイアウォールルールの作成
ミラー対象のトラフィックをコレクターVMで受信できるようにファイアウォールルールを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/9b8ebd95-14ca-4ebe-5f14-c7c39b1119e1.png)

今回は、以下のような内容でルールを作成しています。

| 名前 | タイプ | ターゲット | プロトコル/ポート | アクション | 優先度 | ネットワーク| 適用VM | 用途 |
|---------|---------|---------|---------|---------|---------|---------|---------|---------|
| allow-ssh-ingress | 上り | vpc1-ssh | tcp:22 | 許可 | 10 | vpc1 | ping-vm | ping-vmへのログイン用 | 
| allow-icmp-ingree | 上り | vpc | icmp | 許可 | 1000 | vpc1 | mirrored-vm | mirrored-vmへのICMP用 |
| allow-capture-ingress | 上り | capture | all | 許可 | 10 | vpc2 | capture-vm1 | コレクターVMのミラー通信受信 |
| allow-rdp-ingress | 上り | vpc2-rdp | tcp:3389 | 許可 | 10 | vpc2 | capture-vm1 | コレクターVMへのログイン用 |


#### 2. キャプチャ用VMインスタンスの作成
[GCPメニュー] > [Compute Engine] > [VMインスタンス]で`インスタンスを作成`します。
`リージョン:us-central1 (アイオワ)`、`ゾーン:us-central1-a`でインスタンスを
`Windows Server 2016 Datacenter`で構築しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/741fb6c0-e31d-528a-0ac8-89e13ab4afe2.png)

下の[ネットワーキング]タブで`ネットワーク:vpc2`、`サブネットワーク:subnetwork2(10.129.0.0/20)`を
忘れずに指定してください。(指定しないと`defalut`ネットワーク行きになります)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/e22d5544-c422-439c-0011-bcddc7d8f19b.png)


#### 3. インスタンスグループの作成
[GCPメニュー] > [Compute Engine] > [インスタンスグループ]で`インスタンスグループを作成`します。
今回はシンプルに`新しい非マネージドインスタンスグループ`で作成しています。
VMインスタンスに`capture-vm1`を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/434aa71d-20ae-3fa9-0153-564e89e5a944.png)


#### 4. パケットミラーリングの作成
[GCPメニュー] > [VPCネットワーク] > [パケットのミラーリング]で`ポリシーを作成`します。
`ポリシー名:pm-mirror (何でもOK)`、`リージョン:us-central1`で`続行`します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/c0c38209-cfc3-2897-8dd1-4ec4d8eba6bd.png)

今回はVPC間で複製しますので
`ミラーリングされるソースとコレクタの宛先が別々のピアリングされたVPCネットワークにある`
にチェックを入れます。
`ミラーリングされるソースVPCネットワーク:vpc1`、`コレクタの宛先VPCネットワーク:vpc2`で`続行`します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/081737f6-5b61-b02d-312f-218329e4819b.png)

今回は、対象VMを`mirrored-vm`のみとするため、``個々のインスタンスを選択する`をチェックを入れて
`選択`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/fbb400ed-69a2-b271-d29b-3f9f03626830.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/142a827f-5095-73e0-2bfd-407ecf46b9b8.png)

ここで内部ロードバランサを作成します。`create new L4 internal load balancer`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/5cc2f79f-cec6-8cab-cc18-bbb4fb263419.png)

名前は`capture-bs (何でもOK)`とし、`バックエンドの設定`を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/b85ae91f-910b-817c-0f31-e955d87c7353.png)

`リージョン:us-central1`、`ネットワーク:vpc2`、
`インスタンスグループ:collector-ig1 (us-central1-a)`を指定します。
ヘルスチェックは新規に作成して、指定します。今回は`collector-healthchaeck (TCP)`を作成しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/15b25bf6-3f0c-91c1-0ae2-8890ca2ef506.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/1e3acf0b-a7f3-ea10-5259-5737f7de2b75.png)

フロントエンドの設定は、`名前:capture-fr (何でもOK)`、`サブネットワーク:subnetwork2`を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/1926fd73-ec8b-eb42-a2e9-a2d9a5d9fd59.png)

最後にミラーリング対象のトラフィックの絞り込みになりますが
今回は`10.128.0.0/20`内の`ICMP`、`TCP`、`UDP`通信としています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/3f175735-113a-d21d-2eba-46939c66f3c5.png)

これでパケットミラーリングの設定は完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/cc72534e-eec2-5fea-12a0-565303cd940c.png)


#### 5. Wiresharkでのパケットキャプチャ
ping-vmにSSHログインし、pingコマンドを実施します。
(特に意味ないですが、最大サイズの1432バイトで実施しています。)

```
[*********@ping-vm ~]$ ping 10.128.0.3 -s 1432
PING 10.128.0.3 (10.128.0.3) 1432(1460) bytes of data.
1440 bytes from 10.128.0.3: icmp_seq=1 ttl=64 time=1.63 ms
1440 bytes from 10.128.0.3: icmp_seq=2 ttl=64 time=0.361 ms
1440 bytes from 10.128.0.3: icmp_seq=3 ttl=64 time=0.324 ms
1440 bytes from 10.128.0.3: icmp_seq=4 ttl=64 time=0.335 ms
^C
--- 10.128.0.3 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 0.324/0.663/1.634/0.561 ms
[*********@ping-vm ~]$ 
```

capture-vm1にリモートデスクトップ接続します。
Wiresharkを起動し、パケットキャプチャを開始します。(Wiresharkは別途インストール)
`icmp`でフィルタすると`10.128.0.2(ping-vm)`から`10.128.0.3(mirrored-vm)`への
PING通信が絞り込めます。(ちゃんと取れてますね笑)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/21b45b77-d240-ccb0-1387-76407e04ba56.png)

また、GCPコンソール上でもミラーリングの状態が確認することができます。
ミラー対象VMの[VMインスタンスの詳細]で`モニタリング`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/911d1ee9-45da-ef87-5c5e-67cdb877beae.png)
すると成功と失敗のバイト数とパケット数がグラフで追うことができます。(これステキ！)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211371/5d55babe-0f83-bc71-ae91-ee8ec7c58f75.png)


## まとめ
さて、いかがでしたでしょうか？

これでパブリッククラウドにおいてもこれまで以上に多くの情報が
パケットの中から判断できるようになりましたね！

半構造化されたデータからStackdriver loggingで多くのことが自動出来たりしますが
より詳細な情報が必要になるシーンでは大いに役に立つのではないでしょうか ^^/

[00]:https://docs.microsoft.com/ja-jp/azure/network-watcher/network-watcher-packet-capture-overview "Azure Network Watcherの可変パケットキャプチャの概要"
[01]:https://aws.amazon.com/jp/blogs/aws/new-vpc-traffic-mirroring/ "AWS VPC Traffic Mirroring"
[02]:https://cloud.google.com/vpc/docs/packet-mirroring "パケットミラーリングの概要"
[03]:https://cloud.google.com/vpc/docs/using-packet-mirroring "パケットミラーリングの使用"
[04]:https://cloud.google.com/vpc/docs/monitoring-packet-mirroring "パケットミラーリングの監視"