リモートサーバー接続時の「connect: No route to host」を修正する

intermediate🌐 Networking2026-03-24| Linux (Ubuntu, CentOS, RHEL, Debian) — SSH、curl、wget、TCPクライアントに影響

Error Message

connect: No route to host
#ネットワーキング#ルーティング#ファイアウォール#iptables

何が起きているか

ssh user@192.168.1.50curl http://10.0.0.5:8080 を実行すると、以下のエラーが発生します:

connect: No route to host

このエラーは、よく似た2つのエラーとは異なります。Connection refused はサービスが起動しているものの、接続を能動的に拒否していることを意味します。Connection timed out はどこかでパケットが静かに破棄されていることを意味します。「No route to host」はそれらとは異なり、ネットワークスタックが早い段階で処理を中止しています。これは、宛先へのパスが存在しないか、途中の何かがICMP「host unreachable」メッセージを返してきたことが原因です。

主な原因は4つあります:ファイアウォールのREJECTルール、ルーティングテーブルのエントリが欠落または誤っている、接続先ホストが完全にダウンしている、またはネットワークインターフェースの設定ミスです。

デバッグ手順

ステップ1 — ホストに到達できるか確認する

他の操作をする前に、IPレベルから確認しましょう:

# ICMPピング
ping -c 4 192.168.1.50

# pingがブロックされている場合、既知のオープンポートでTCPを試す
nc -zv 192.168.1.50 22
nc -zv 192.168.1.50 80

pingは成功するがTCPが失敗する場合、問題はポート固有のものです — ステップ3に進んでください。両方失敗する場合、ホストはIPレベルで到達不能です — 読み進めてください。

ステップ2 — ルーティングテーブルを確認する

ip route get 192.168.1.50

正常な出力はこのようになります:

192.168.1.50 via 192.168.1.1 dev eth0 src 192.168.1.100 uid 1000

代わりに RTNETLINK answers: Network is unreachable と表示される場合、そのサブネットへのルートがマシンに存在しません。テーブル全体を表示してみましょう:

ip route show
# または
netstat -rn

デフォルトゲートウェイのエントリ(0.0.0.0/0 または default)を探してください。存在しない場合は追加します:

# 一時的なデフォルトゲートウェイ
ip route add default via 192.168.1.1 dev eth0

# または宛先サブネットへの特定ルートのみ追加
ip route add 10.0.0.0/24 via 192.168.1.1 dev eth0

ステップ3 — 両方のマシンのファイアウォールルールを確認する

十中八九、これが原因です。接続先サーバーで以下を実行します:

# iptables
sudo iptables -L -n -v

# nftables(新しいディストリビューション)
sudo nft list ruleset

# firewalld(CentOS/RHEL)
sudo firewall-cmd --list-all

REJECTルール(DROPではなく)があると、クライアント側で即座に No route to host が発生します。iptablesの出力で次のような行が確認できます:

REJECT  tcp  --  0.0.0.0/0  0.0.0.0/0  tcp dpt:22  reject-with icmp-host-prohibited

ポートを開放するには:

# iptables: SSHを許可
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# firewalld: 永続的に開放
sudo firewall-cmd --permanent --add-port=22/tcp
sudo firewall-cmd --reload

# UFW(Ubuntu)
sudo ufw allow 22/tcp

ステップ4 — インターフェースが起動しているか確認する

ip link show
ip addr show

state DOWN と表示されているインターフェースは、起動させる必要があります:

sudo ip link set eth0 up

割り当てられたIPアドレスとサブネットマスクも再確認してください。プレフィックスの誤り — たとえば /24 のところが /25 になっている場合 — 到達可能な範囲が静かに半分に削られ、ローカルサブネットの半分が到達不能に見えてしまいます。

ステップ5 — tracerouteでどこで切れているか特定する

traceroute 192.168.1.50
# または古いシステムでは
tracert 192.168.1.50

ホップが応答を止める箇所を確認してください。そこが問題の原因です — ルートの断絶か、トラフィックを遮断しているファイアウォールのどちらかです。

よくある解決策

解決策1 — リモートファイアウォールにREJECTルールがある

firewalld を実行しているCentOS/RHELシステム(RHEL 7以降のデフォルト)では、明示的に開放するまですべてのポートがブロックされています。これがデフォルトゾーンのポリシーです:

# 必要なポートを開放する
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

# 開放されていることを確認
sudo firewall-cmd --list-ports

解決策2 — 再起動後にデフォルトゲートウェイが消えた

最小インストールや再設定されたばかりのサーバーでは、再起動時にデフォルトルートが失われることがあります。一時的な ip route add コマンドは再起動後に残りません — 永続化するには以下を実行します:

# Ubuntu/Debian — netplanを編集
sudo nano /etc/netplan/00-installer-config.yaml
# インターフェースの下に追加:
#   routes:
#     - to: default
#       via: 192.168.1.1
sudo netplan apply

# CentOS/RHEL — ifcfgファイルを編集
sudo nano /etc/sysconfig/network-scripts/ifcfg-eth0
# 追加: GATEWAY=192.168.1.1
sudo systemctl restart NetworkManager

解決策3 — サブネットマスクの誤り(CIDRの不一致)

192.168.1.100/25 として設定されたインターフェースは、192.168.1.1〜126 の範囲のホストにしか到達できません。.128 以降は、同じ物理スイッチ上にあるにもかかわらず到達不能に見えます。実際のプレフィックスを確認してください:

ip addr show eth0
# inet 192.168.1.100/25 → 使用可能なホスト: 192.168.1.1 から 192.168.1.126

自分のCIDRがカバーすべき範囲がわからない場合は、IPアドレスとプレフィックスをToolCraftのサブネット計算ツールに入力してみてください — 正確なホスト範囲、ブロードキャストアドレス、ネットワークアドレスがすぐに表示されます。アカウント登録は不要です。

解決策4 — SELinuxが接続をブロックしている

RHEL/CentOSにはもう一つの層があります。SELinuxは明確なエラーを表示せずに静かに干渉することがあります。まず監査ログを確認してください:

sudo ausearch -m avc -ts recent
sudo sealert -a /var/log/audit/audit.log

SELinuxが接続をブロックしている場合は、ラベルまたはポリシーを修正してください。SELinux全体を無効にしたくなるかもしれませんが、それは誤った対処法です — システム全体の保護が失われてしまいます。

修正の確認

# TCP接続が機能することを確認
nc -zv 192.168.1.50 22
# 期待される結果: Connection to 192.168.1.50 22 port [tcp/ssh] succeeded!

# その後、元のコマンドを再試行
ssh user@192.168.1.50
curl -v http://192.168.1.50:8080/health

nc は成功するがアプリが失敗する場合、良いニュースです:ネットワークは問題ありません。問題はアプリケーション層に移りました — 誤った認証情報、TLSの不一致、またはホスト名の誤りが原因です。これははるかに範囲の絞られた問題です。

まとめ

  • 「No route to host」はほぼ常に、ファイアウォールのREJECTルールかルートの欠落を意味します — ホストがダウンしているわけではありません(それはタイムアウトとして現れます)。
  • 両端を確認してください:ローカルのルーティングテーブルリモートサーバーのファイアウォールルールの両方です。
  • CentOS/RHELでは、RHEL 7以降 firewalld がデフォルトですべてをブロックします。新しいポートは firewall-cmd --permanent で明示的に開放する必要があります。
  • 再起動やネットワーク再設定の後は、ip route show を実行してデフォルトゲートウェイが残っているか確認してください。
  • TCPポートの素早い確認には nc -zv host port を使いましょう — アプリケーションのデバッグより速く、ネットワークを原因から排除できます。

Related Error Notes