はじめに
AI事業本部 Dynalystのエンジニアの黒金です。
2019年4月にサイバーエージェントに入社し、バックエンドエンジニアとして主にScalaなどを用いて開発業務に携わっています。
今回のブログでは2019年6月に発表されたVPC Traffic mirroringを使ってみたかったので、この機能を使って普段行っている業務を楽にできないかを検討した事についてお伝えできればいいなと思います。
前提
新しいロジックをリリースする際には最終確認として実際に正しいレスポンスを返してくれるリクエストのサンプルを取得したり、
不具合が起こった際には該当のリクエストのサンプルを取得したりするためにtcpdumpと呼ばれるソフトウェアをよく使っています。
tcpdumpを使用すればアプリケーションコードを変更する事なく、実際のリクエストやレスポンスをみる事ができるので重宝しています。
ですが、毎回sshをしてtcpdumpを使用するのは億劫なのである程度リクエスト/レスポンスをサンプリングして結果ををS3にアウトプットする機構を作ってもいいなと考えていました。
上記の方法だと本番で動いている1つのインスタンスのリソースを使用してしまい、リクエストのロードバランシングにも影響を与えてしまうと思ったため、他の方法を探していました。
そこで見つけたのが VPC Trafic Mirroringというトラフィックを複製してくれるという機能です。本来ならばこれはネットワークおよびセキュリティ上の異常を検出するための物ですが、今回の用途に合っていそうなので調査をしてみました。
セットアップ
インスタンスの作成
VPC Traffic MirroringはNitro世代のEC2にアタッチされるENIに流れてくるトラフィックを複製して別のENIなどに流す物なのです。
なのでまずはNitro世代のインスタンスを二つ作成して一つのインスタンスには複製されたトラフィックを待ち受けるためのENIを追加で一つ作ります。その時のENIをメモしておきます。
- この時、sourceは送信元、targetは送信先になります
- sourceのトラフィックが複製されてtargetに流れるようになります
複製されるトラフィックはVXLAN (Virtual eXtensible Local Area Network)と呼ばれる技術を使って運ばれて来ます。VXLANはでは実際のパケットに「このパケットはどこから来てどこへ行く」という情報をつける事によって今回のようなパケットを複製して違うENIに運ぶ事ができるようです。
上記の事から、VXLANを待ち受けるためにセキュリティグループの設定も必要になります
VPC Traffic Mirroring の設定
Targetを作成
複製される先のENIを選択します。
Filterを作成
どのプロトコルでどのIPから来たかなどをフィルタリングできます。
今回はHTTP(TCP:80)のものだけを許可するようにします。
Sourceを作成
最後に上記で設定をしたTargetとFilterを使用して送信元の設定をします。
上記のTarget, Filter, Sourceを設定すると下記のような流れでトラフィックが複製されるようになります。
動作確認
sourceとtargetにsshしてパケットをキャプチャしてみます。
sourceに向けてJSONを送ってみると
source$ sudo tcpdump -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
実際にVXLANでカプセル化されたパケットが飛んでくる事が確認できました。
カプセル化された状態だと中身がわからないのでwiresharkのCUI版であるtsharkでVXLANのカプセル化を解除して見てみます。
target$ sudo tcpdump -n -i eth1 -w - | tshark -r - -d udp.port==4789,vxlan -w - >&1
上記のようにsourceとtargetでほぼ同じ出力が見れる事を確認できました。
終わりに
上記のようにほぼ同じ出力が見れたものの、このままだとsshした先を本番環境から検証環境に変更できただけになってしまうので、複製されたトラフィックからリクエスト/レスポンスだけを取得して保存するような仕組みを別途作ってあげる必要があると思います。
上記のような課題はあるもののVPC Traffic Mirroringによってパケットを分析、可視化できる事がわかったので今後も何かの機会に使えたらと思っています。