仮想マシンの通信を内側から確かめる
手元のPCと仮想マシンのIP設定を比べ、待ち受け、経路、アドレス変換、通信許可を実際の出力から区別します。
このレッスンのメニュー
手元のブラウザから仮想マシンのWebサーバーへ接続するには、ゲストOSの設定、仮想化環境の転送、通信を許可する規則、外部へ公開する設定が必要です。
このページを終えると、次の四つを実際の出力から確認できます。
- 仮想NICに付いたIPアドレス
- 別のネットワークへ渡すデフォルトゲートウェイ
- プロセスが待ち受けるIPアドレスとポート
- 仮想マシン内では接続できるのに、外部からは接続できない理由
ゲストOSから見える範囲
仮想NICは、仮想マシンへ取り付ける仮想的なネットワークインターフェースです。 ゲストOSは仮想NICを通常のNICとして認識し、MACアドレスとIPアドレスを使って通信します。
Linuxの経路表には、「このネットワークは仮想NICへ直接送る」「それ以外はデフォルトゲートウェイへ渡す」という規則が入ります。 ゲストOSはその先にある物理NICやクラウドのルーターを直接操作しません。 まず仮想NICからパケットを出し、仮想化環境へ渡します。
仮想マシンの外側で転送される
仮想NICから出た通信は、仮想スイッチやブリッジを通ります。 別のネットワークへ進む場合はルーターが次の転送先を決めます。
仮想マシンへプライベートIPアドレスを付ける構成では、外へ出るときにNATやNAPTで送信元を置き換えることがあります。 この変換により、仮想マシンから始めた通信の応答を元の仮想マシンへ戻せます。 外部から新しい接続を始める場合は、公開用のIPアドレスやポート転送、経路、ACLなどを別に設定します。
待ち受けと外部公開は別の状態
Webサーバーが 0.0.0.0:8000 で待ち受けると、ゲストOS内のすべてのIPv4インターフェースで接続を受ける状態になります。
インターネットからの接続には、ゲストOSまでパケットを運ぶ経路と許可設定も必要です。
手元のPCの経路を確認する
最初に、普段使っているPCにもIPアドレスとデフォルトゲートウェイがあることを確認します。 利用しているOSの欄だけを実行してください。
macOS
ifconfig | grep 'inet '
route -n get default
scutil --dns | grep 'nameserver\[[0-9]*\]'
Linux
ip -brief address
ip route
cat /etc/resolv.conf
Windows PowerShell
Get-NetIPConfiguration
Get-NetRoute -DestinationPrefix "0.0.0.0/0"
Resolve-DnsName github.com
出力から、利用中のインターフェース、LAN側のIPv4アドレス、デフォルトゲートウェイ、DNSの問い合わせ先を一つずつ探します。
ループバックアドレスの 127.0.0.1 は自分自身を表すため、LANへ接続するインターフェースのIPアドレスとは区別します。
手元のPCとLabの仮想マシンを比べる
60分 Linux Labを開き、次を実行します。
ip -brief address
ip route
ip route get 1.1.1.1
getent ahostsv4 github.com | head
紙やメモへ、次の表に沿って値を記録します。
| 確かめる項目 | 手元のPC | Labの仮想マシン |
|---|---|---|
| 利用中のインターフェース名 | ||
| 付いているIPv4アドレス(ループバック以外) | ||
| デフォルトゲートウェイ | ||
github.com の名前解決結果 |
PCと仮想マシンで値は異なりますが、どちらにも「インターフェースへIPアドレスを付け、別のネットワークはゲートウェイへ渡す」という共通点があります。
次に仮想マシン内でWebサーバーを起動します。
mkdir -p ~/vm-network-lab
printf 'hello from the virtual machine\n' > ~/vm-network-lab/index.html
python3 -m http.server 8000 --bind 0.0.0.0 --directory ~/vm-network-lab >/tmp/vm-network-http.log 2>&1 &
server_pid=$!
ss -lntp | grep ':8000'
curl http://127.0.0.1:8000/
ssに0.0.0.0:8000が表示され、curlにhello from the virtual machineが返れば、Webサーバーは仮想マシン内で待ち受けています。
手元のブラウザへhttp://仮想マシンのIPアドレス:8000/を入力しても、このLabでは開けません。
仮想マシンのIPアドレスは手元のLANから直接たどれず、8000番ポートを外部へ転送する設定もなく、外部からの接続も許可していないためです。
確認後にWebサーバーを止めます。
kill "$server_pid"
接続できない場所を切り分ける
| 確認 | コマンドや設定 | ここでわかること |
|---|---|---|
| プロセス | systemctl、ps | Webサーバーが動いているか |
| 待ち受け | ss -lntp | どのIPアドレスとポートで受けるか |
| 仮想マシン内の接続 | curl 127.0.0.1:8000 | アプリまでTCP接続できるか |
| IPと経路 | ip address、ip route | 仮想NICとゲートウェイの設定 |
| 仮想マシンの外側 | NAT、ポート転送、ルート | 外部と仮想マシンの間をどう運ぶか |
| 通信許可 | ACL、ファイアウォール | その向きとポートを通すか |
| 名前解決 | getent hosts、nslookup | 名前が期待するIPアドレスになるか |
仮想マシン内のcurlが成功して外部から失敗するなら、Webサーバーより外側を調べます。
仮想マシン内のcurlも失敗するなら、まずプロセスと待ち受けを調べます。
確認した結果から範囲を絞る
ssと仮想マシン内のcurlが成功した事実から、Webサーバーは仮想マシン内で利用できると判断できます。
手元のブラウザから接続できない場合は、仮想マシンのIPアドレスへ至る経路、NATやポート転送、ACLを次に確認します。
このレッスンは完了
このページで扱った流れを確認したら、次の内容へ進みます。