Chapter 05

構築手順の解説(ネットワーク編:基本)

yutafujii
yutafujii
2021.07.03に更新

この章ではネットワークに関する解説をします.

ネットワークとは

コンピュータの誕生以降,0と1で表されるデータの様々な処理が進化してきました.次第にコンピュータ間でのデータのやりとりが必要となり,それをネットワークと呼ぶようになりました.独自の通信方法が乱立すると,あるサーバーとデータ通信したいと思った時に必要になる通信方法の構築コストが莫大になるため,ISO[1]によってルール(または規約.これをプロトコルと呼ぶ)が定められていきました.

OSI model

ISOが標準化した通信体系が参考にしたのがOSI[2]の作成したOSI参照モデルです.プロトコルをネットワークが果たすべき役割にそって7つに分類しています.

もちろん,OSI参照モデルはプロトコルの階層区分を示す一つの考え方にすぎず,プロトコルの階層区分に対する考え方は他にもあります.本書ではOSI参照モデルの階層名を利用します.

WiFiアクセスポイント構築手順においては,データリンク層,ネットワーク層とアプリケーション層においてプロトコルや処理方法を構築していきました.

操作 レイヤ
ドライバのインストール データリンク層
Hostapdの立ち上げ データリンク層
DNS アプリケーション層
IPパケットのフォワーディング ネットワーク層

なお,普段Webエンジニアとして使うのはアプリケーション層が大半ですが(HTTP, TLS, SSH, SMTP, DNS),ICMPを利用するping, tracerouteコマンドはネットワーク層を使っています.Nginxなどアプリケーション層のプログラムを何も立ち上げていなくてもpingコマンドは何かしら応答するのはこういう背景でもあります.

IPアドレスとNAT

IPアドレスは郵便における住所と例えられることが多いと思います.コンピュータに固有の番号と思われがちですが,厳密にはネットワークインターフェイスごとに固有であり,コンピュータが複数のIPアドレスを持つことの方が普通です.

手持ちのMacbookで確認できるIPアドレスの例:IPv4は1個だけ振られている

$ ifconfig
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	options=400<CHANNEL_IO>
	ether f0:18:98:xx:xx:xx
	inet6 fe80::xxxx:xxxx:xxxx:xxxx%en0 prefixlen 64 secured scopeid 
	inet 192.168.0.20 netmask 0xffffff00 broadcast 192.168.0.255
	nd6 options=201<PERFORMNUD,DAD>
	media: autoselect
	status: active
...	

Raspberry Piでifconfigを実行した例:複数のネットワークインターフェイスにIPアドレスが振られている

└─# ifconfig
eth0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether xx:xx:xx:xx:xx:xx  txqueuelen 1000  (Ethernet)

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 2312
        inet 192.168.1.1  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::xxxx:xxxx:xxxx:xxxx  prefixlen 64  scopeid 0x20<link>
        ether 98:48:27:xx:xx:xx  txqueuelen 1000  (Ethernet)

wlan1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.49  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::xxxx:xxxx:xxxx:xxxx  prefixlen 64  scopeid 0x20<link>
        ether dc:a6:32:xx:xx:xx  txqueuelen 1000  (Ethernet)

wlan2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.41  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::xxxx:xxxx:xxxx:xxxx  prefixlen 64  scopeid 0x20<link>
        ether xx:xx:xx:xx:xx:xx  txqueuelen 1000  (Ethernet)

  • eth0: Piに標準装備されているイーサネットケーブル(接続していないのでIPなし)
  • wlan1: Piに標準装備されているwireless LAN(192.168.0.49
  • wlan0: Piに接続したTP-Linkのwireless LAN(192.168.1.1
  • wlan2: Piに接続した別のネットワークアダプタのwireless LAN(192.168.0.41

なおIPアドレスにはIPv4とIPv6の2種類が存在します.IPv4は123.123.123.123のような3桁数字区切り4ブロックの数字で示されるアドレスで,一般的にはIPv4を使うことが多いです.しかしIPv4にはアドレス数が世界全体で足らないという問題があり[3],NATという仕組みを用いて対処しています.

NAT(Network Address Translator)

会社でも家でも,WiFiにパソコンを接続すると思います.自分のIPを知ろうと思ってifconfig.meなどを開くと確かにIPアドレスが表示されています(222.111.3.12とします).しかしWiFiに接続するのはあなただけではありません.隣の同僚も,何なら自分のiPhoneやiPadや何から何までWiFiに繋げています.当然それらでifconfig.meを開いても全部同じIPアドレスになっています.

それではHTTPリクエストをもらったサーバーがユーザーにレスポンスを返す時,宛先IPアドレスを222.111.3.12にすれば届くかというと,WiFiルーターまでは届きますがそからどのデバイスに送ればいいのかがわかりません.

これを解決しているのがNAT(正確にはNAPT:Network Address Ports Translator)と呼ばれる仕組みです.

IPv4ではグローバルIPアドレスだけでは端末(ネットワークインターフェイス)が1つに特定できないので,ポート番号も組み合わせることで一意に特定できるようにしています.そのためにIPアドレスとポート番号を組み合わせて変換するテーブルを保持・管理する必要があります.一般家庭含めWiFiルーターにはこの機能が備わっているので,複数の端末が同じグローバルIPを共有できるようになっています.

グローバルIPとプライベートIP

単語だけ先に出しておりますが,NATの仕組みを活用することで,IPv4のアドレスは1つにつき1インターフェイスに制約する必要がなくなりました.

そこで,混乱を避けるためにネットワークインターフェイス1つにしか付与しないIPアドレスと,複数のインターフェイスに付いて構わないIPアドレスを明確に分けて取り扱うことになっています.全社をグローバルIPアドレス,後者をプライベートIPアドレスと呼びます.

プライベートアドレス
クラスA:10.0.0.0/8
クラスB:172.16.0.0/12
クラスC:192.168.0.0/16

サブネットマスク長をみてわかるように,クラスAが最もホスト数が多く持つことができます.家のWiFiでは通常クラスCのIPが振られていることが多いと多いますが,AWSのVPCのサブネットではクラスBアドレスがEC2にプライベートIPとして割り振られていたり,カフェやコワーキングスペースなどのWiFiではクラスAのアドレスが接続する各端末に振られていることもあります.

192.168.0.1向けのパケットはなぜ問題なくルーターに届くのか

MACアドレス
これは余談になりますが,ネットワークインターフェイスをIPv4で一意に特定するためにNATを利用していることを述べました.逆に言えば,プライベートIPアドレスは実に様々なインターフェイスに同時に付与されていると言えます.あるカフェでIPが192.168.0.1のWiFiに繋いだとして,隣のカフェのWiFiルーターも192.168.0.1ということはあり得ます.

それでは 192.168.0.1 などプライベートIPアドレスを送信先にするパケットはどうして間違うことなく意図したデバイスに届くのでしょうか.

それは,デバイスごとに固有の識別子が存在しており,IPアドレスと識別子をマッピングしておくことで送信先デバイスを識別子で特定しているためです.

この識別子をMACアドレスと呼びます.フォーマットはxx:xx:xx:yy:yy:yyの16進数12文字で構成され,前半6文字がベンダーID,後半6文字が製品IDを表しています.後半6文字は特に製品のシリアル番号のようなものなので,取り扱いには気をつけましょう.逆に前半6文字はベンダーIDなので,Find MAC Address Vendorsなどに打ち込むとどこのベンダーかすぐにわかります.

一度繋いだWiFiルーターの識別子は arpコマンド[4]で確認できます.

$ arp
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.0.1              ether   xx:xx:xx:xx:xx:xx   C                     wlan1

ここに表示されているMACアドレスをもってして192.168.0.1 へパケットを送っているというのが実際に起きていることです.このMACアドレスを用いた通信はデータリンク層の役目です.

脚注
  1. International Organization for Standatdization.国際標準化機構 ↩︎

  2. Open Systems Interconnection.開放型システム間相互接続 ↩︎

  3. IPv4では各ブロックごとに0-255の数字が入ります.つまり8ビットで表され4ブロック合わせて32ビットで1つのアドレスが表現されます.32ビットで表すことができる数は 2^(32) の43億個程度となり,圧倒的に数が足らないのです. ↩︎

  4. arpはARP(Address Resolution Protocol)の意味で,IPアドレスからMACアドレスの名前解決を行うプロトコル. ↩︎