- Authors
- Name
- 概要
- 1. TCP 3ウェイハンドシェイクの理解
- 2. よくあるTCP接続の問題
- 3. デバッグツールの活用
- 4. TCPチューニングパラメータ
- 5. 接続追跡(conntrack)
- 6. 実践デバッグシナリオ
- 7. 監視自動化スクリプト
- 8. まとめ: TCPデバッグチェックリスト
概要
サーバー運用やバックエンド開発をしていると、「接続できない」「タイムアウトが発生する」「断続的に切断される」といった問題に必ず遭遇します。 これらの問題のほとんどはTCP/IPレベルで発生しており、正確な原因を特定するにはTCPの動作原理とデバッグツールを正しく理解する必要があります。
この記事では、TCP接続の基本原理から、本番環境ですぐに活用できるデバッグ手法までを段階的に整理します。
1. TCP 3ウェイハンドシェイクの理解
1.1 接続確立プロセス
TCP接続は3ウェイハンドシェイクを通じて確立されます。
Client Server
| |
|--- SYN (seq=x) ------->| (1) クライアントがSYNを送信
| |
|<-- SYN-ACK (seq=y, | (2) サーバーがSYN-ACKで応答
| ack=x+1) ----------|
| |
|--- ACK (ack=y+1) ----->| (3) クライアントがACKを送信
| |
|== 接続確立完了 ===========|
各ステップで問題が発生する可能性があり、どのステップで失敗するかによって原因が異なります。
1.2 TCP接続状態の遷移
TCPソケットはさまざまな状態を持ちます。デバッグ時にこれらの状態を理解することが重要です。
LISTEN → サーバーが接続待ち
SYN_SENT → クライアントがSYN送信後、SYN-ACK待ち
SYN_RECV → サーバーがSYN受信後、SYN-ACK送信、ACK待ち
ESTABLISHED → 接続確立完了
FIN_WAIT_1 → アクティブクローズ開始(FIN送信)
FIN_WAIT_2 → FINに対するACK受信、相手のFIN待ち
CLOSE_WAIT → パッシブクローズ(相手のFIN受信)
TIME_WAIT → 接続終了後の待機(2MSL)
LAST_ACK → 最後のACK待ち
CLOSING → 双方同時クローズ
CLOSED → 接続終了完了
1.3 接続終了(4ウェイハンドシェイク)
Client Server
| |
|--- FIN --------------->| (1) クライアントが終了要求
|<-- ACK ----------------| (2) サーバーがACK
| |
|<-- FIN ----------------| (3) サーバーが終了要求
|--- ACK --------------->| (4) クライアントがACK
| |
|-- TIME_WAIT (2MSL) ----|
2. よくあるTCP接続の問題
2.1 Connection Refused(接続拒否)
対象ポートでリッスンしているプロセスがない場合、サーバーはRSTパケットで応答します。
# 症状の確認
$ curl -v http://192.168.1.100:8080
* Trying 192.168.1.100:8080...
* connect to 192.168.1.100 port 8080 failed: Connection refused
# サーバー側でポートを確認
$ ss -tlnp | grep 8080
# (出力なし = リッスンしているプロセスがない)
# ファイアウォールの確認
$ iptables -L -n | grep 8080
$ firewall-cmd --list-ports
主な原因:
- サービスが起動していない
- サービスが別のポートにバインドされている
- サービスがlocalhost(127.0.0.1)にのみバインドされている
- ファイアウォールがREJECTでブロック
2.2 Connection Timeout(接続タイムアウト)
SYNパケットを送信したが応答がない場合に発生します。
# 症状
$ curl --connect-timeout 5 http://10.0.0.50:3306
curl: (28) Connection timed out after 5001 milliseconds
# SYN再送信の統計を確認
$ netstat -s | grep -i retrans
12345 segments retransmitted
678 SYNs to LISTEN sockets dropped
# カーネルのSYN再試行回数を確認
$ cat /proc/sys/net/ipv4/tcp_syn_retries
6
# 再試行間隔: 1秒 → 2秒 → 4秒 → 8秒 → 16秒 → 32秒(合計約63秒)
主な原因:
- ルーティングの問題(パケットが誤った宛先に送られる)
- ファイアウォールがSYNパケットを静かにDROP(REJECTではなく)
- サーバーが過負荷で応答不能
- 中間ネットワーク機器の障害
2.3 SYNフラッド攻撃
# SYN_RECV状態が異常に多い場合
$ ss -s
Total: 15234
TCP: 12890 (estab 234, closed 45, orphaned 12, timewait 567)
$ ss -tn state syn-recv | wc -l
8923 # 異常に高い値
# SYN Cookiesの有効化を確認
$ cat /proc/sys/net/ipv4/tcp_syncookies
1
# SYNバックログの確認
$ cat /proc/sys/net/ipv4/tcp_max_syn_backlog
1024
# SYNフラッド防御設定
$ sysctl -w net.ipv4.tcp_syncookies=1
$ sysctl -w net.ipv4.tcp_max_syn_backlog=4096
$ sysctl -w net.ipv4.tcp_synack_retries=2
2.4 RST(リセット)パケットの分析
RSTパケットはさまざまな状況で送信されます。
# tcpdumpでRSTパケットをキャプチャ
$ tcpdump -i eth0 'tcp[tcpflags] & (tcp-rst) != 0' -nn
# 出力例
14:23:01.123456 IP 192.168.1.10.45678 > 10.0.0.5.80: Flags [R], seq 0, ack 1234567, win 0, length 0
14:23:01.234567 IP 10.0.0.5.80 > 192.168.1.10.45678: Flags [R.], seq 0, ack 7654321, win 0, length 0
RST発生の原因:
- 閉じたポートへの接続試行
- アプリケーションの強制終了(SO_LINGER設定)
- TCPキープアライブの失敗
- ファイアウォールの接続追跡テーブルのオーバーフロー
2.5 TIME_WAITの過多
# TIME_WAIT状態のカウント
$ ss -s
TCP: 8934 (estab 234, closed 45, orphaned 12, timewait 8123)
# TIME_WAIT状態のソケットの詳細確認
$ ss -tn state time-wait | head -20
Recv-Q Send-Q Local Address:Port Peer Address:Port
0 0 192.168.1.10:45678 10.0.0.5:80
0 0 192.168.1.10:45679 10.0.0.5:80
...
# TIME_WAITソケットの再利用を有効化
$ sysctl -w net.ipv4.tcp_tw_reuse=1
# FINタイムアウトの確認(デフォルト60秒)
$ cat /proc/sys/net/ipv4/tcp_fin_timeout
60
3. デバッグツールの活用
3.1 ss(Socket Statistics)
ssはnetstatの最新の代替ツールで、より高速で詳細な情報を提供します。
# すべてのTCPリスニングソケット + プロセス情報
$ ss -tlnp
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=1234,fd=3))
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=5678,fd=6))
LISTEN 0 128 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=5678,fd=7))
# 特定の状態のソケットのみフィルタリング
$ ss -tn state established '( dport = :443 )'
Recv-Q Send-Q Local Address:Port Peer Address:Port
0 0 192.168.1.10:45678 10.0.0.5:443
0 0 192.168.1.10:45679 10.0.0.5:443
# タイマー情報を含む(再送信、キープアライブなど)
$ ss -tnio
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 192.168.1.10:22 10.0.0.1:54321
cubic wscale:7,7 rto:204 rtt:1.5/0.75 ato:40 mss:1448 pmtu:1500
rcvmss:1448 advmss:1448 cwnd:10 ssthresh:20 bytes_sent:12345
bytes_acked:12345 bytes_received:6789 segs_out:100 segs_in:80
# LISTEN状態でのRecv-Q/Send-Qの意味
# Recv-Q: 現在SYNバックログキューにある接続数
# Send-Q: SYNバックログキューの最大サイズ
3.2 netstat(レガシーだが依然として有用)
# TCP状態別の接続カウント
$ netstat -ant | awk '{print $6}' | sort | uniq -c | sort -rn
234 ESTABLISHED
123 TIME_WAIT
45 CLOSE_WAIT
12 LISTEN
5 SYN_SENT
3 FIN_WAIT2
1 SYN_RECV
# 特定ポートの接続確認
$ netstat -antp | grep :3306
tcp 0 0 192.168.1.10:3306 192.168.1.20:45678 ESTABLISHED 1234/mysqld
tcp 0 0 192.168.1.10:3306 192.168.1.21:34567 ESTABLISHED 1234/mysqld
# ネットワーク統計の要約
$ netstat -s | head -40
Ip:
123456 total packets received
0 forwarded
0 incoming packets discarded
123456 incoming packets delivered
654321 requests sent out
Tcp:
12345 active connection openings
6789 passive connection openings
123 failed connection attempts
45 connection resets received
234 connections established
567890 segments received
678901 segments sent out
1234 segments retransmitted
3.3 tcpdumpパケットキャプチャ
# 基本的なパケットキャプチャ(特定のホストとポート)
$ tcpdump -i eth0 host 10.0.0.5 and port 80 -nn
# 3ウェイハンドシェイクのみキャプチャ
$ tcpdump -i eth0 'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0' -nn
# SYNパケットのみキャプチャ(ACKなしのSYNのみ)
$ tcpdump -i eth0 'tcp[tcpflags] & (tcp-syn) != 0 and tcp[tcpflags] & (tcp-ack) == 0' -nn
# ファイルに保存(Wiresharkでの分析用)
$ tcpdump -i eth0 -w /tmp/capture.pcap -c 10000 host 10.0.0.5
# 保存されたファイルを読み込む
$ tcpdump -r /tmp/capture.pcap -nn
# パケット内容を含む(hex + ASCII)
$ tcpdump -i eth0 -X port 80 -c 5
# 出力例(3ウェイハンドシェイク)
14:30:01.001 IP 192.168.1.10.45678 > 10.0.0.5.80: Flags [S], seq 1234567, win 64240, options [mss 1460,sackOK,TS val 123 ecr 0,nop,wscale 7], length 0
14:30:01.002 IP 10.0.0.5.80 > 192.168.1.10.45678: Flags [S.], seq 7654321, ack 1234568, win 65160, options [mss 1460,sackOK,TS val 456 ecr 123,nop,wscale 7], length 0
14:30:01.002 IP 192.168.1.10.45678 > 10.0.0.5.80: Flags [.], ack 7654322, win 502, options [nop,nop,TS val 123 ecr 456], length 0
# HTTPリクエスト/レスポンス内容のキャプチャ
$ tcpdump -i eth0 -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' -c 20
3.4 Wiresharkのディスプレイフィルタ
tcpdumpでキャプチャしたpcapファイルをWiresharkで分析する際に有用なフィルタです。
# 基本的なディスプレイフィルタ
tcp.port == 80 # 特定のポート
ip.addr == 192.168.1.10 # 特定のIP
tcp.flags.syn == 1 && tcp.flags.ack == 0 # SYNのみ
tcp.flags.reset == 1 # RSTパケット
tcp.analysis.retransmission # 再送信パケット
tcp.analysis.duplicate_ack # 重複ACK
tcp.analysis.zero_window # ゼロウィンドウ
tcp.analysis.window_full # ウィンドウフル
# 特定のTCPストリームの追跡
tcp.stream eq 5
# 時間ベースのフィルタ
frame.time >= "2026-03-08 14:00:00" && frame.time <= "2026-03-08 14:30:00"
# 遅いレスポンスの検出
tcp.time_delta > 1 # 1秒以上遅延したパケット
4. TCPチューニングパラメータ
4.1 バックログ設定
# リスンバックログ(SYNキュー + acceptキュー)
$ cat /proc/sys/net/core/somaxconn
4096
# SYNバックログ(ハーフオープン接続キュー)
$ cat /proc/sys/net/ipv4/tcp_max_syn_backlog
1024
# 高トラフィックサーバーの推奨設定
$ sysctl -w net.core.somaxconn=65535
$ sysctl -w net.ipv4.tcp_max_syn_backlog=65535
# アプリケーション側でもバックログの設定が必要
# Nginxの例:
# listen 80 backlog=65535;
4.2 キープアライブ設定
# 現在の設定を確認
$ cat /proc/sys/net/ipv4/tcp_keepalive_time
7200 # デフォルト: 2時間(アイドル後の最初のプローブまで)
$ cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75 # プローブ間隔(秒)
$ cat /proc/sys/net/ipv4/tcp_keepalive_probes
9 # 最大プローブ回数
# 死んだ接続の早期検出のための設定
$ sysctl -w net.ipv4.tcp_keepalive_time=600 # 10分
$ sysctl -w net.ipv4.tcp_keepalive_intvl=30 # 30秒
$ sysctl -w net.ipv4.tcp_keepalive_probes=5 # 5回
# 合計検出時間: 600 + (30 * 5) = 750秒(12.5分)
4.3 ウィンドウスケーリング
# ウィンドウスケーリングの有効化確認(デフォルト: 1)
$ cat /proc/sys/net/ipv4/tcp_window_scaling
1
# TCPバッファサイズ(最小、デフォルト、最大)
$ cat /proc/sys/net/ipv4/tcp_rmem
4096 131072 6291456
$ cat /proc/sys/net/ipv4/tcp_wmem
4096 16384 4194304
# 高帯域幅環境の最適化
$ sysctl -w net.ipv4.tcp_rmem="4096 262144 16777216"
$ sysctl -w net.ipv4.tcp_wmem="4096 262144 16777216"
$ sysctl -w net.core.rmem_max=16777216
$ sysctl -w net.core.wmem_max=16777216
# BDP(帯域幅遅延積)の計算
# 帯域幅1Gbps、RTT 10msの場合:
# BDP = 1,000,000,000 * 0.01 / 8 = 1,250,000バイト(約1.2MB)
# → tcp_rmem/tcp_wmemのmax値をBDP以上に設定
4.4 その他の重要なパラメータ
# エフェメラルポート範囲
$ cat /proc/sys/net/ipv4/ip_local_port_range
32768 60999
# ポート範囲の拡大
$ sysctl -w net.ipv4.ip_local_port_range="1024 65535"
# FINタイムアウト(TIME_WAIT → CLOSEDへの遷移時間)
$ sysctl -w net.ipv4.tcp_fin_timeout=30
# TCP Fast Openの有効化
$ sysctl -w net.ipv4.tcp_fastopen=3
# 最大ファイルディスクリプタ数(ソケットもfd)
$ cat /proc/sys/fs/file-max
1048576
$ ulimit -n
65535
5. 接続追跡(conntrack)
5.1 conntrackの基本
Linuxのnetfilterはすべての接続を追跡します。iptables/nftablesルールでのステートフルフィルタリングに使用されます。
# conntrackテーブルの確認
$ conntrack -L | head -10
tcp 6 431999 ESTABLISHED src=192.168.1.10 dst=10.0.0.5 sport=45678 dport=80 src=10.0.0.5 dst=192.168.1.10 sport=80 dport=45678 [ASSURED] mark=0 use=1
tcp 6 116 SYN_SENT src=192.168.1.10 dst=10.0.0.50 sport=34567 dport=3306 [UNREPLIED] src=10.0.0.50 dst=192.168.1.10 sport=3306 dport=34567 mark=0 use=1
# conntrackエントリ数の確認
$ conntrack -C
45678
# conntrackテーブルの最大値
$ cat /proc/sys/net/nf_conntrack_max
262144
# conntrackテーブルが満杯になると新しい接続がDROPされる
# dmesgで確認
$ dmesg | grep conntrack
[12345.678] nf_conntrack: table full, dropping packet
5.2 conntrackの最適化
# conntrack最大値の増加
$ sysctl -w net.nf_conntrack_max=1048576
# conntrackハッシュテーブルサイズ
$ cat /proc/sys/net/netfilter/nf_conntrack_buckets
65536
# タイムアウト設定
$ cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
432000 # 5日間(デフォルト)
# より短いタイムアウトに変更
$ sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=86400 # 1日
$ sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30
$ sysctl -w net.netfilter.nf_conntrack_tcp_timeout_close_wait=60
# 特定の接続を削除
$ conntrack -D -s 192.168.1.100
$ conntrack -D -p tcp --dport 80
6. 実践デバッグシナリオ
6.1 シナリオ: Webサーバーの断続的なタイムアウト
# ステップ1: 現在の接続状態の概要を確認
$ ss -s
Total: 15234
TCP: 12890 (estab 8234, closed 45, orphaned 12, timewait 4567)
# ステップ2: CLOSE_WAITの蓄積を確認(ソケットリークの疑い)
$ ss -tn state close-wait | wc -l
2345 # 多すぎる!アプリケーションがソケットを閉じていない
# ステップ3: どのプロセスがCLOSE_WAITソケットを保持しているか特定
$ ss -tnp state close-wait | awk '{print $NF}' | sort | uniq -c | sort -rn
2100 users:(("java",pid=5678,fd=...))
200 users:(("python",pid=1234,fd=...))
# ステップ4: 該当プロセスのfd数を確認
$ ls -la /proc/5678/fd | wc -l
4567 # ファイルディスクリプタのリークを確認
# ステップ5: lsofで詳細確認
$ lsof -p 5678 | grep TCP | grep CLOSE_WAIT | wc -l
2100
6.2 シナリオ: マイクロサービス間の接続障害
# ステップ1: DNS解決の確認
$ dig +short service-b.internal
10.0.0.50
# ステップ2: ポート接続テスト
$ nc -zv -w 3 10.0.0.50 8080
Connection to 10.0.0.50 8080 port [tcp/*] succeeded!
# 失敗時:
$ nc -zv -w 3 10.0.0.50 8080
nc: connect to 10.0.0.50 port 8080 (tcp) failed: Connection timed out
# ステップ3: ネットワーク経路の確認
$ traceroute -T -p 8080 10.0.0.50
traceroute to 10.0.0.50, 30 hops max
1 gateway (10.0.0.1) 0.5 ms 0.4 ms 0.3 ms
2 * * *
3 10.0.0.50 1.2 ms 1.1 ms 1.0 ms
# ステップ4: MTU問題の確認
$ ping -M do -s 1472 10.0.0.50
PING 10.0.0.50 (10.0.0.50) 1472(1500) bytes of data.
ping: local error: message too long, mtu=1400
# MTUの調整
$ ip link set dev eth0 mtu 1400
6.3 シナリオ: 大量トラフィックサーバーのチューニング
# 完全なチューニング設定
cat << 'EOF' > /etc/sysctl.d/99-tcp-tuning.conf
# バックログ設定
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.core.netdev_max_backlog = 65535
# TIME_WAITの最適化
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
# キープアライブ
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
# バッファサイズ
net.ipv4.tcp_rmem = 4096 262144 16777216
net.ipv4.tcp_wmem = 4096 262144 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# ポート範囲
net.ipv4.ip_local_port_range = 1024 65535
# SYNフラッド防御
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_synack_retries = 2
# conntrack
net.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_tcp_timeout_established = 86400
# TCP Fast Open
net.ipv4.tcp_fastopen = 3
# ウィンドウスケーリング
net.ipv4.tcp_window_scaling = 1
EOF
# 設定の適用
$ sysctl -p /etc/sysctl.d/99-tcp-tuning.conf
6.4 シナリオ: tcpdumpによる遅いレスポンスの分析
# 特定サービスとの通信を30秒間キャプチャ
$ timeout 30 tcpdump -i eth0 -w /tmp/slow.pcap host 10.0.0.5 and port 443
# キャプチャファイルの分析 - 再送信の確認
$ tcpdump -r /tmp/slow.pcap 'tcp[tcpflags] & (tcp-syn) != 0' -nn
# SYNの再送信が見られる場合は初期接続の問題
# キャプチャファイルの分析 - データフローのタイミング確認
$ tcpdump -r /tmp/slow.pcap -ttt -nn | head -30
# -ttt: パケット間の時間間隔を表示
00:00:00.000000 IP 192.168.1.10.45678 > 10.0.0.5.443: Flags [S], seq 123
00:00:00.001234 IP 10.0.0.5.443 > 192.168.1.10.45678: Flags [S.], seq 456, ack 124
00:00:00.000100 IP 192.168.1.10.45678 > 10.0.0.5.443: Flags [.], ack 457
00:00:00.000500 IP 192.168.1.10.45678 > 10.0.0.5.443: Flags [P.], seq 124:500
00:00:02.345678 IP 10.0.0.5.443 > 192.168.1.10.45678: Flags [P.], seq 457:1200
# ↑ 2秒以上の間隔 = サーバー側の処理遅延
# tshark(CLI版Wireshark)で詳細分析
$ tshark -r /tmp/slow.pcap -q -z io,stat,1
# 1秒間隔の統計
$ tshark -r /tmp/slow.pcap -q -z conv,tcp
# TCP会話ごとの統計
7. 監視自動化スクリプト
7.1 TCP状態モニタリング
#!/bin/bash
# tcp_monitor.sh - TCP接続状態の監視
LOG_FILE="/var/log/tcp_monitor.log"
ALERT_THRESHOLD_TW=5000 # TIME_WAITの警告閾値
ALERT_THRESHOLD_CW=100 # CLOSE_WAITの警告閾値
ALERT_THRESHOLD_SYNR=500 # SYN_RECVの警告閾値
while true; do
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
# 状態別カウント
ESTABLISHED=$(ss -tn state established | wc -l)
TIME_WAIT=$(ss -tn state time-wait | wc -l)
CLOSE_WAIT=$(ss -tn state close-wait | wc -l)
SYN_RECV=$(ss -tn state syn-recv | wc -l)
LISTEN=$(ss -tn state listening | wc -l)
echo "$TIMESTAMP ESTAB=$ESTABLISHED TW=$TIME_WAIT CW=$CLOSE_WAIT SYNR=$SYN_RECV LISTEN=$LISTEN" >> "$LOG_FILE"
# 警告チェック
if [ "$TIME_WAIT" -gt "$ALERT_THRESHOLD_TW" ]; then
echo "$TIMESTAMP [WARN] TIME_WAIT=$TIME_WAIT が閾値を超過" >> "$LOG_FILE"
fi
if [ "$CLOSE_WAIT" -gt "$ALERT_THRESHOLD_CW" ]; then
echo "$TIMESTAMP [ALERT] CLOSE_WAIT=$CLOSE_WAIT - ソケットリークの可能性!" >> "$LOG_FILE"
fi
if [ "$SYN_RECV" -gt "$ALERT_THRESHOLD_SYNR" ]; then
echo "$TIMESTAMP [ALERT] SYN_RECV=$SYN_RECV - SYNフラッドの可能性!" >> "$LOG_FILE"
fi
sleep 10
done
7.2 conntrackモニタリング
#!/bin/bash
# conntrack_monitor.sh
MAX=$(cat /proc/sys/net/nf_conntrack_max)
CURRENT=$(conntrack -C 2>/dev/null || cat /proc/sys/net/netfilter/nf_conntrack_count)
USAGE=$((CURRENT * 100 / MAX))
echo "Conntrack: $CURRENT / $MAX ($USAGE%)"
if [ "$USAGE" -gt 80 ]; then
echo "[WARN] Conntrackテーブルの使用率が80%を超過!"
echo "トップソースIP:"
conntrack -L 2>/dev/null | awk '{print $5}' | cut -d= -f2 | sort | uniq -c | sort -rn | head -10
fi
8. まとめ: TCPデバッグチェックリスト
問題が発生した場合、以下の手順で体系的に確認します。
1. 基本的な接続確認
□ ping / tracerouteでネットワーク経路を確認
□ nc -zv または telnetでポート接続テスト
□ DNS解決の確認(dig、nslookup)
2. ソケット状態の分析
□ ss -tlnpでリスニングポートを確認
□ ss -sで全体のソケット統計を確認
□ 異常な状態(CLOSE_WAIT、SYN_RECVの過多)をチェック
3. パケットレベルの分析
□ tcpdumpでパケットをキャプチャ
□ RST、再送信、遅延を分析
□ Wiresharkで詳細に検査
4. カーネルパラメータの確認
□ バックログキューのサイズ
□ conntrackテーブルの使用率
□ ファイルディスクリプタの制限
5. アプリケーションレベル
□ コネクションプールの設定
□ タイムアウト設定
□ アプリケーションのエラーログ
TCP/IPの問題は階層的にアプローチすることが重要です。物理層/ネットワーク層から始めて、アプリケーション層に向かって上方向に進みながら、各ステップで原因を絞り込んでいくのが効率的なトラブルシューティングの方法です。