PK
パーネルカニック研究所
今日もどこかでkernel panic。
root@pk-lab:~#

Linuxネットワーク基礎

連載ナビ

この連載は「Linuxを使えるようになる」ではなく、「Linuxがどう動いているのか」を理解するための実践シリーズです。

今回は Linuxを理解する 〜 LFSで学ぶLinux内部構造 〜 の Part 6 / 第1回として、仕組みのつながりを意識しながら学びます。

—

ネットワークは「インターフェース・経路・ソケット」の3点で読める

Linuxのネットワークは奥が深そうに見えますが、状態把握に必要な視点は実は3つに絞れます。結論から言うと、

  • インターフェース: このマシンはどのネットワークに、どのIPアドレスで参加しているか(ip addr で確認)
  • 経路(ルーティングテーブル): 宛先ごとに、パケットをどこへ送り出すか(ip route で確認)
  • ソケット: どのプロセスが、どのポートで通信を待ち受け・実行しているか(ss で確認)

の3点です。「つながらない」系のトラブルは、ほぼすべてこの3点のどこかに原因があります。逆に言えば、この3つのコマンドの出力が読めれば、疎通調査の最初の一手を迷わず打てるようになります。

アプリはネットワークに直接触れず、すべてカーネルが中継するから

なぜこの3点なのか。理由は、Linuxではアプリケーションがネットワークに直接触れることはなく、通信のすべてをカーネルのネットワークスタックが中継しているからです。

たとえば curl がHTTPリクエストを送るとき、内部では次のことが起きています。

1. curl はカーネルに socket() システムコールを発行し、通信の窓口(ソケット)を作る

2. connect() で宛先IPとポートを指定すると、カーネルがルーティングテーブルを引き、どのインターフェースから送るかを決める

3. カーネルがTCPのコネクション確立、パケットへの分割、IPヘッダの付与を行い、NIC(ネットワークカード)経由で送出する

つまりアプリが見ているのはソケットだけで、経路選択もパケット処理もカーネルの仕事です。だからこそ、調査するときは「アプリのログ」だけでなく、カーネルが持っている情報(インターフェース・経路・ソケットの状態)を直接見る必要があるのです。これはPart 1で見た「ユーザー空間とカーネル空間の分離」が、ネットワークにもそのまま当てはまっているということでもあります。

ip addr と ip route の出力を実際に読んでみる

自分のマシン(またはPart 1で作ったLinux VM)で実行してみましょう。まずインターフェースです。


ip addr

典型的な出力はこうなります(一部抜粋)。


1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 ...
    inet 127.0.0.1/8 scope host lo
2: enp0s1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    inet 192.168.64.5/24 brd 192.168.64.255 scope global dynamic enp0s1

読み方のポイントは3つです。

  • lo はループバックインターフェース。127.0.0.1(localhost)宛の通信は外に出ず、ここで折り返します
  • enp0s1 などが実際のNICで、UP,LOWER_UP は「設定上有効かつリンクも確立している」という状態表示です
  • inet 192.168.64.5/24 がIPアドレスとサブネット。/24 は「先頭24ビットが同じ 192.168.64.0〜255 が同一ネットワーク」という意味です

次に経路です。


ip route

default via 192.168.64.1 dev enp0s1 proto dhcp
192.168.64.0/24 dev enp0s1 proto kernel scope link src 192.168.64.5

2行目は「同一ネットワーク宛は enp0s1 から直接送る」、1行目は「それ以外(default)はすべてゲートウェイ 192.168.64.1 に渡す」という意味です。インターネット宛の通信が成立するかどうかは、この default 行があるかにかかっています。

ss でソケットを見れば「誰が待ち受けているか」が分かる

3点目のソケットは ss コマンドで確認します。


sudo ss -ltnp

オプションは -l(LISTEN中のみ)、-t(TCP)、-n(ポートを数値表示)、-p(プロセス名表示)です。典型的な出力はこうです。


State   Recv-Q  Send-Q  Local Address:Port  Peer Address:Port  Process
LISTEN  0       128           0.0.0.0:22         0.0.0.0:*     users:(("sshd",pid=612,fd=3))
LISTEN  0       511         127.0.0.1:80         0.0.0.0:*     users:(("nginx",pid=845,fd=6))

Local Address:Port の読み方が重要です。0.0.0.0:22 は「すべてのインターフェースの22番で待ち受け」、つまり外部からSSH接続できます。一方 127.0.0.1:80 は「ループバックの80番のみ」なので、同じマシンからしかアクセスできません。「サーバーは起動しているのに外から繋がらない」というトラブルの定番原因が、このbindアドレスの違いです。

疎通しないときの調査は、この3点を下から順に確認するのが定石です。

1. ip addr — そもそもIPアドレスが付いているか、インターフェースが UP か

2. ip route — 宛先への経路(特に default 行)があるか

3. ss -ltnp — 目的のプロセスが意図したアドレス・ポートで待ち受けているか

3つの視点を持てば、疎通調査は手順化できる

Linuxのネットワークは、カーネルがすべての通信を中継しており、その状態は「インターフェース(ip addr)・経路(ip route)・ソケット(ss)」の3点で観測できる——これが今回の結論です。

次回は、このうち ip コマンドをもう一歩掘り下げます。かつての標準だった ifconfig との関係と、ip addr / ip route / ip link の使い分けを整理していきます。

図解テキスト


app -> socket -> kernel net stack -> NIC -> network
       (ss)     (ip routeで経路決定)  (ip addr / ip link)

疎通調査の順序:
1. ip addr   … IPは付いているか / UPか
2. ip route  … defaultルートはあるか
3. ss -ltnp  … 誰がどのポートで待っているか

この回で実行するコマンド

上から順番に実行すれば、この回の内容を体験できます。

まずはそのままコピペして実行し、次に1行ずつ意味を確認してください。


ip addr
ip route
sudo ss -ltnp | head -n 40

ハンズオン手順

1. ターミナルを開いて、上のコマンドを1行ずつ実行する

2. ip addr の出力から、自分のIPアドレスとサブネット(/24 など)をメモする

3. ip route の default via の後ろにあるゲートウェイのIPをメモする

4. ss -ltnp の出力から、待ち受け中のプロセスを1つ選び、bindアドレスが 0.0.0.0 か 127.0.0.1 かを確認する

5. エラーが出たら、そのエラーメッセージをそのまま残す

チェックポイント

  • コマンドが最後まで実行できた
  • 自分のマシンの「IPアドレス・デフォルトゲートウェイ・LISTEN中のポート」を1つずつ言える
  • 0.0.0.0:80 と 127.0.0.1:80 の違いを説明できる
  • 次の回に進む前に、分からない単語を1つ調べた

今回理解できたこと

  • アプリはソケット経由でカーネルに通信を依頼し、経路選択やパケット処理はカーネルが行う
  • ネットワーク状態は「インターフェース・経路・ソケット」の3点で観測できる
  • 疎通調査は ip addr → ip route → ss -ltnp の順で手順化できる