TT Lab
はじめる
学ぶ 学習パス コース

Linuxネットワーク診断

ソケットとポートの診断

TT Labで続きを見る

目標

リスニングソケットのバインディング範囲を区別し、ssと/proc/net/tcpの2つの経路で、同じ事実を確認します。

なぜ重要なのか

「サーバーの中でcurlはできるのに、外からはできない」という報告の大半は、ファイアウォールではなく、バインディングの問題です。127.0.0.1:8080にバインドされたソケットは、同じホストから来た接続だけを受け付け、外部のパケットは、カーネルがそもそも渡しません。この区別は、セキュリティ設計でもあります。管理用ポートをわざとループバックだけにバインドするのが、標準的な慣行です。そして、リスニングソケットのSend-Qはバックログの最大値、Recv-Qはacceptの待ちキューの現在の長さです。確立された接続での意味と違うので、よく読み違えられます。

ステップ

/root/netディレクトリで作業します。

  1. python3 -m http.server 8080 --bind 127.0.0.1をバックグラウンドで起動して、PIDを/root/net/http_pid.txtに書いてください。
  2. python3 -m http.server 8081 --bind 0.0.0.0をバックグラウンドで起動して、PIDを/root/net/all_pid.txtに書いてください。8080はそのままループバック専用である必要があります。
  3. 2つのポートのバインディング範囲を、/root/net/binding.txtに、次の2行で書いてください。値はloopbackまたはallです(プレースホルダーは値です)。
    • 8080=<값>
    • 8081=<값>
  4. 8081に接続を1つ開いて、閉じずに維持するプロセスを起動し、PIDを/root/net/client_pid.txtに書いてください。
  5. 10進数の8080を、16進数4桁の大文字に変えて、/root/net/hexport.txtに書いてください。
  6. 8080のリスニングソケットのバックログの最大値を、/root/net/backlog.txtに、数字だけで書いてください。
  7. 8080をつかんでいるプロセスのPIDを、ssで確認して、/root/net/owner.txtに書いてください。
  8. /root/net/portcheck.sh <포트>を作ってください。そのポートで待ち受けていれば、port=<포트> state=listen pid=<PID>を出力して終了コード0、誰も待ち受けていなければ、port=<포트> state=freeを出力して終了コード1です。引数がなければ、0以外のコードです(プレースホルダーは、ポート番号とPIDです)。

参考

ループバックだけにバインドしてサーバーを起動する

python3 -m http.server 8080 --bind 127.0.0.1をバックグラウンドで起動して、PIDを/root/net/http_pid.txtに書いてください。

python3 -m http.serverに--bindオプションがあります。バックグラウンドで起動して、PIDを書いてください。

すべてのアドレスにバインドして起動する

python3 -m http.server 8081 --bind 0.0.0.0をバックグラウンドで起動して、PIDを/root/net/all_pid.txtに書いてください。8080はそのままループバック専用である必要があります。

0.0.0.0にバインドすると、どのインターフェースから来ても受け付けます。8080はそのままループバックである必要があります。

バインディング範囲を記録する

2つのポートのバインディング範囲を、/root/net/binding.txtに、次の2行で書いてください。値はloopbackまたはallです(プレースホルダーは値です)。

ss -ltnのLocal Address列を見てください。2つのポートがどう違うかを書きます。

接続をつかんでおく

8081に接続を1つ開いて、閉じずに維持するプロセスを起動し、PIDを/root/net/client_pid.txtに書いてください。

接続を開いたまま、閉じずに維持する必要があります。python3でcreate_connectionした後にsleepすれば十分です。

/proc/net/tcpを直接読む

10進数の8080を、16進数4桁の大文字に変えて、/root/net/hexport.txtに書いてください。

ポートが16進数で書かれています。8080を16進数4桁の大文字に変えてみてください。

バックログの最大値を読む

8080のリスニングソケットのバックログの最大値を、/root/net/backlog.txtに、数字だけで書いてください。

リスニングソケットでは、Send-Qがバックログの最大値です。ss -ltnの2列目です。

ポートの持ち主を探す

8080をつかんでいるプロセスのPIDを、ssで確認して、/root/net/owner.txtに書いてください。

ssにプロセス情報を見せるオプションがあります。出力から、pid=の部分を取り出してください。

ポート占有の確認スクリプト

/root/net/portcheck.sh <포트>を作ってください。そのポートで待ち受けていれば、port=<포트> state=listen pid=<PID>を出力して終了コード0、誰も待ち受けていなければ、port=<포트> state=freeを出力して終了コード1です。引数がなければ、0以外のコードです(プレースホルダーは、ポート番号とPIDです)。

待ち受けていればpidまで知らせて0、空いていればfreeと1を出します。