これは「フィヨルドブートキャンプAdvent Calendar 2024」の19日目の記事です。
- Part 1
フィヨルドブートキャンプ Part 1 Advent Calendar 2024 - Adventar
昨日はayu-0505さんの「「分からないので教えてください」と言うホスト 〜輪読会を主催して〜」でした。
- Part 2
フィヨルドブートキャンプ Part 2 Advent Calendar 2024 - Adventar
昨日はtogoさんの「2024年に開催したミートアップを振り返って」でした。
自己紹介
こんにちは、ユージと申します。フィヨルドブートキャンプ(以下、FBC)に参加し、約2ヶ月の期間が経とうとしている一現役生です。
下記の記事も是非ご覧下さい。
要約
- 自分のMacBook*1からDockerとTINETとMultipassにより作成したUbuntuを活用して、疑似的なネットワークおよびサーバー検証環境を構築しました。
- その結果、検証環境で生成されたパケットを元にパケットキャプチャを行うことに成功しました。
テーマ選定理由
- 自身はAdvent Calendarにおいて、テック系記事を書きたいと考えていました。
- とはいえ、自身がRubyなどの開発系プラクティスを未だ実施できてないので、執筆できるテーマは限定されるだろう、と思いました。*2
- 自身は通信系のSEとして、ネットワークやサーバ構築(主に仮想サーバ)などのインフラ経験が少しだけありました。
- そのため、Rubyとも親和性のあるDockerやLinux、TCP/IPを利用できるTINETなどをテーマにする事で、自身の経験や学習を元に、より学びを深められると考えました。
- また自身は、SSL/TLSに苦手意識があるため、その学びを深めていきたいと考え、今回の検証環境のテーマとしました。
参考書籍
本記事で参考にした書籍をご紹介します。
ネットワーク検証を行う際はパケット解析が非常に重要となります。しかし、検証環境を構築するためには、ルーターやFWなどのハードウェア機器やLANケーブルなど多くの機材が必要となり、これが大きなハードルとなっています。
本書では「速く・軽く・安く」をコンセプトに、PC1台で主要なネットワーク技術を一通り体験できる設計がなされています。そのためのカラクリとして、「WSL2」*3「Docker」「TINET」の3つのツール(本書では「3種の神器」と呼称しています)を活用する事で、検証内容に応じたルーターやFW機器などの環境を簡単に構築できるため、今後のネットワーク検証において、非常に参考となる一冊となるだろう、と考えております。
全体構成
全体構成は下記のとおりです。
本記事ではMacBookで検証を行うために、参考書籍内で紹介されているWSL2(Windows上でLinuxを動かす仕組み)の代わりに、Multipassを使用してMac上にUbuntu環境を構築をしました。
基本的なアプリケーションの設定はtinet
コマンドを使ってYAML
形式の設定ファイル(機器を擬似的に再現した設定ファイル)を読み込み、Dockerの起動や機器の接続などのネットワーク環境を自動で構築できます。
検証環境にログイン後、tcpdump
などのパケットキャプチャツールを使用してファイルを出力し、Wiresharkで解析を行います。この一連の流れを確認していきます。
検証構成
検証構成は下記のとおりです。今回はSSL/TLSの学びを深めることをテーマに、以下の構成でパケット通信を検証していきます。*4
■Firewall(fw1)
■負荷分散装置(lb1)
■Webサーバ(sv1)
使用する技術の紹介
ここからは本記事において利用する技術を紹介します。
Docker
Dockerは、1台のサーバで複数のアプリケーションを動作させるコンテナ型仮想環境プラットフォームです。
よく、ハイパーバイザー型(例えばVMware、Hyper-Vなど)と比較されますが、ハイパーバイザーの場合は、物理サーバに複数の「仮想マシン(VM)」を立ち上げることで、物理サーバを効率よく活用でき、ホストOSを分離してインフラの一元管理に適していると感じています。
コンテナ型は、ホストOSのカーネルを共有するため、仮想マシンよりも軽量で、起動時間が速いことが特徴です。また、コンテナはアプリケーションとその依存関係をパッケージ化しており、環境の違いに左右されずに動作するため、開発から本番環境へのデプロイが容易になります。
そのため、ハイパーバイザー型は主にインフラの分野で、コンテナ型は主に開発環境の分野において活用されているという点で、利用用途や分野の違いがあります。
TINET
TINETは苫小牧高専情報工学科において開発された、 ITRON TCP/IP API仕様に準拠したコンパクトな TCP/IP プロトコルスタックです。GitHub上でYAMLファイルが公開されており、設定ファイルを読み込むことで検証環境を自動で構築できます。
Multipass
Multipassは、Ubuntuの仮想マシンを手軽に作成・管理できるツールで、特にMacユーザーにとって便利な仮想環境構築手段です。
全体構成構築
ここからは実際に検証環境を構築していきます。
multipass shell
コマンドで仮想マシンにログインします。
% multipass shell UBUNTU
仮想マシンでセットアップスクリプトsetup_mac.sh
で設定を行います。
root@UBUNTU:/home/ubuntu# bash /mnt/c/tinet/setup_mac.sh
仮想マシンでチェックスクリプトcheck_mac.sh
で確認を行います。
root@UBUNTU:/home/ubuntu# bash /mnt/c/tinet/check_mac.sh
tinet up
コマンドでネットワークを構築します。
root@UBUNTU:/home/ubuntu# tinet up -c /mnt/c/tinet/spec_05.yaml | sh -x
tinet conf
コマンドでコンテナを設定・実行でき、YAML形式の設定ファイルを読み込むことで、検証環境を作成できます。
root@UBUNTU:/home/ubuntu# tinet conf -c /mnt/c/tinet/spec_05.yaml | sh -x
検証構成構築
では下記より検証構成を再現していきます。
sv1にログインします
root@UBUNTU:/home/ubuntu# docker exec -it sv1 /bin/bash
tcpdump
を使用し、NICのnet0
で送受信されるHTTPS(ポート443)通信のうち、IPアドレス172.16.1.254
に関わるパケットをキャプチャし、/tmp/https.pcap
ファイルに保存します。
root@sv1:/# tcpdump -i net0 port 443 and host 172.16.1.254 -w /tmp/https.pcap tcpdump: listening on net0, link-type EN10MB (Ethernet), capture size 262144 bytes
fw1にログインします
root@UBUNTU:/home/ubuntu# docker exec -it fw1 /bin/bash
curl
コマンドを使用して、指定されたURLhttps://sv1.example.com/
に対してHTTPリクエスト(HTTP/2)をTLS 1.2を使用し、以下の指定された暗号スイートDHE-RSA-AES256-GCM-SHA384
を使ってリクエストを送信します。
root@fw1:/# SSLKEYLOGFILE=/tmp/key.log curl -vk https://sv1.example.com/ --tls-max 1.2 --http2 --ciphers DHE-RSA-AES256-GCM-SHA384 * Trying 172.16.2.1:443... * TCP_NODELAY set * Connected to sv1.example.com (172.16.2.1) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * Cipher selection: DHE-RSA-AES256-GCM-SHA384 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / DHE-RSA-AES256-GCM-SHA384 * ALPN, server accepted to use h2 * Server certificate: * subject: CN=sv1.example.com; C=JP * start date: Dec 15 05:38:16 2024 GMT * expire date: Nov 21 05:38:16 2124 GMT * issuer: CN=sv1.example.com; C=JP * SSL certificate verify result: self signed certificate (18), continuing anyway. * Using HTTP2, server supports multi-use * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x564a291682f0) > GET / HTTP/2 > Host: sv1.example.com > user-agent: curl/7.68.0 > accept: */* > * Connection state changed (MAX_CONCURRENT_STREAMS == 128)! < HTTP/2 200 < server: nginx/1.18.0 (Ubuntu) < date: Sun, 15 Dec 2024 06:23:40 GMT < content-type: text/html < content-length: 16 < last-modified: Sun, 15 Dec 2024 05:38:45 GMT < etag: "675e6b65-10" < accept-ranges: bytes < sv1.example.com * Connection #0 to host sv1.example.com left intact
キャプチャの結果
WiresharkにてSSL/TLS通信のパケットをキャプチャする事に成功しました。
下記の画像では、WiresharkにてTLS1.2のハンドシェイクの流れをフロー図示したものを示しております。また一般的なTLS1.2のハンドシェイクのフローも参考に載せておきます。
TLS1.2のハンドシェイクのフロー Client Server ClientHello --------> ServerHello Certificate* ServerKeyExchange* CertificateRequest* <-------- ServerHelloDone Certificate* ClientKeyExchange CertificateVerify* [ChangeCipherSpec] Finished --------> [ChangeCipherSpec] <-------- Finished Application Data <-------> Application Data
結論
今回の検証では、MacBookを使用して検証環境を構築し、TLSのパケットキャプチャを成功させることができました。今後はパケット分析などさらに深堀りしていき、引き続きアウトプットを行っていきたいと考えています。
まとめ
全体通しての感想としては、こうした簡単に、そして斬新な方法でネットワークを実践的に学べることに驚き、楽しんで取り組むことができました。また、参考書籍には他にも多くの検証パターンが紹介されているので、さらに興味のある方はぜひ購入し、より詳しく学んでみることをお勧めします。
最後までお読みいただき、ありがとうございました!