はじめに
Raspberry Piのubuntu上で、Pythonを使って外部APIやWebサイトに接続するアプリを開発していたところ、特定の外部サイトにまったく接続できないという不可解な事象に遭遇しました。
- ブラウザは一部サイトが表示できる
sudo apt updateは成功する- しかし Python(requestsなど)からの外部API通信は失敗する
「ネットワークは生きているのに、なぜ?」
調査の結果、原因は以前行った Ubuntuの固定IP設定(Netplan設定変更) にありました。
本記事では、
- なぜ一部の通信だけ成功していたのか
- gateway4削除の何が問題だったのか
- 正しいルート設定の方法
を技術的に深掘りします。
トラブルの原因:gateway4の削除
Ubuntuでは Netplan を使ってネットワーク設定を行います。
以前はこのように gateway4 を書くのが一般的でした。
gateway4: 192.168.1.1
しかし現在は gateway4は非推奨 となり、routes セクションでの明示的な記述が推奨されています。
参考サイトを元に gateway4 を削除したものの、
default route(デフォルトゲートウェイ)をroutesで正しく設定していなかった ため、
外の世界への出口が消えていた
という状態になっていました。
そもそも「デフォルトゲートウェイ」とは?
Linuxで現在のルートを確認するには:
$ ip route
正常な状態では、以下のような表示があります。
default via 192.168.1.1 dev enp0s3
この default via がないと、
- ローカルネットワーク外への通信
- インターネットへの通信
が基本的にできません。
謎:なぜ apt は動いていたのか?
ここが今回一番面白いポイントです。
デフォルトゲートウェイが消えていたのに、
なぜ sudo apt update は成功していたのでしょうか?
考えられる理由は以下です。
1. IPv6が生きていた
IPv4のデフォルトゲートウェイは消えていたが、IPv6のルートは生きていた可能性があります。
多くのUbuntuミラーサイトはIPv6対応しているため、
- apt → IPv6で通信成功
- Pythonアプリ → IPv4で接続しようとして失敗
という差が発生していた可能性があります。
確認方法:
$ ping -4 google.com # IPv4
$ ping -6 google.com # IPv6
実施した結果がこれです。
$ ping -4 google.com
ping: connect: Network is unreachable
$ ping -6 google.com
PING google.com(lcnrta-ba-in-x0e.1e100.net (2404:6800:4004:816::200e)) 56 data bytes
64 bytes from lcnrta-ba-in-x0e.1e100.net (2404:6800:4004:816::200e): icmp_seq=1 ttl=113 time=8.28 ms
^C
やはりIPv6が生きている、が理由のようです。
2. LAN内プロキシの存在
その他考えられる要因として、企業ネットワークなどでは、
- LAN内にHTTPプロキシがある
- そのプロキシへのルートは生きている
というケースがあります。
この場合:
- apt → プロキシ経由で成功
- Pythonアプリ → 直接外部に出ようとして失敗
という挙動になります。
我が家の場合は自宅に置いてあるRaspberry Piですし、プロキシも通していませんので、この可能性はないです。
3. DNSキャッシュの影響
それ以外にも、systemd-resolved やキャッシュの影響で、名前解決だけ成功しているケースも考えられます。
ただし今回は「到達不能」だったため、本質的にはルート欠落が原因でした。
Pythonアプリが失敗した理由
Pythonの requests などは、接続先のDNS結果を元に
- IPv4アドレスへ接続
- OSのルーティングテーブルを参照
して通信します。
このとき、
default route が存在しない
と、IPv4外部通信は即失敗します。
つまり:
| 通信 | 結果 |
|---|---|
| apt | 成功(IPv6またはプロキシ) |
| Python外部API | 失敗(IPv4のみ) |
という差が生まれていました。
正しいNetplan設定(routesでのdefault指定)
gateway4 を削除する場合、必ず routes で default を明示する必要があります。
記述は下記のようになります。
routes:
- to: default
via: 192.168.1.1設定例:
/etc/netplan/99-custom.yaml
network:
version: 2
wifis:
wlan0:
dhcp4: false
optional: true
addresses:
- 192.168.1.30/24
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses: [192.168.1.1]
access-points:
"アクセスポイントのSSID":
password: "アクセスポイントのPSK-AES"
適用:
$ sudo netplan apply
確認:
$ ip route
必ず以下が表示されること:
default via 192.168.1.1 dev wlan0 proto static
Tips: netplan apply でパーミッションの警告が出たら
設定ファイルを編集(または新規作成)すると、権限が 644 などになってしまい、「Permissions are too open」と警告されることがあります。
このワーニングが出ると「何か間違えたか?」と焦りますが、これは「設定ファイルの権限(パーミッション)が緩すぎるよ!」というセキュリティ上の警告です。
ネットワーク設定ファイルは機密情報を含むため、
$ sudo chmod 600 /etc/netplan/*.yaml
で権限を絞っておくのが作法です。
今回の教訓
gateway4を削除するならroutes: - to: defaultをセットで書く- 「一部の通信ができるから大丈夫」は危険
- ネットワーク障害時は必ず
ip routeを確認する - IPv4 / IPv6 の違いを意識する
おわりに
今回の障害は単なる設定ミスですが、
なぜ一部の通信だけ成功していたのか?
を深掘りすることで、LinuxのルーティングやIPv6の挙動理解が一段深まりました。
ネットワーク系の不具合は「なんとなく動いている」が一番怖い。
同じように固定IP設定を触る方の参考になれば幸いです。

コメント