NO_PROXYの設定で詰まった話 - プロキシ環境でのハマりポイント
職場で開発環境を構築していた時、外部へのHTTP通信はできるのに、内部サーバーへの通信だけが弾かれるという謎の現象に遭遇した。原因はNO_PROXYの設定漏れ。今回は、この実体験をもとに、プロキシ環境での通信制御とNO_PROXYの重要性について解説していこう。
来春からデータサイエンティストとして働く予定の技術オタク。
『知りたい』気持ちで質問を止められない、好奇心旺盛な学生。
プロキシって何?なんで必要なの?
そもそもプロキシって何?職場で設定しろって言われたけど...
プロキシは、インターネットへの通信を中継するサーバーのことなんだ。職場や学校のネットワークでは、セキュリティのために外部への通信をプロキシサーバー経由にすることが多いんだよ。
中継?なんでわざわざ中継するの?
いくつか理由があるんだけど、主なものはこの3つかな。
- セキュリティ: 怪しいサイトへのアクセスをブロックできる
- ログ管理: どのサイトにアクセスしたか記録できる
- キャッシュ: よく使うデータを保存して通信を高速化できる
なるほど、安全性のためなんだね
そう。企業のネットワークでは、社員が誤って危険なサイトにアクセスしたり、機密情報が漏洩したりしないよう、プロキシで通信を監視・制御してるんだ。
プロキシの設定方法
プロキシってどうやって設定するの?
環境変数で設定することが多いんだ。LinuxやMacなら、こんな感じで設定するよ。
# HTTP通信用のプロキシ
export HTTP_PROXY="http://proxy.company.com:8080"
# HTTPS通信用のプロキシ
export HTTPS_PROXY="http://proxy.company.com:8080"
HTTP_PROXYとHTTPS_PROXY?2つあるの?
HTTPとHTTPSは別々に設定できるんだ。最近はほとんどの通信がHTTPSだから、両方設定するのが一般的だね。
これで外部にアクセスできるようになるんだ?
そう!例えば、curlコマンドで外部のサイトにアクセスする時も、自動的にプロキシ経由で通信してくれるんだよ。
# プロキシ経由でGoogleにアクセス
curl https://www.google.com
問題発生:内部サーバーに繋がらない!
じゃあプロキシ設定すれば全部解決だね!
...と思うじゃない?実は僕も最初そう思って、HTTP_PROXYとHTTPS_PROXYだけ設定したんだ。でも、そこで問題が起きたんだよ。
え、何が起きたの?
外部サイトへの通信は問題なくできるのに、社内の開発サーバーに全く繋がらなくなったんだ。
# 外部サイト → OK
curl https://www.google.com
# → 成功
# 社内サーバー → NG
curl http://dev-server.internal.company.com
# → タイムアウト...
え!?なんで社内サーバーに繋がらないの!?
それが、プロキシ設定をすると、すべてのHTTP/HTTPS通信がプロキシ経由になっちゃうんだ。社内サーバーへの通信もプロキシを通ろうとしてたんだよ。
それの何が問題なの?プロキシ通ればいいじゃん
いい質問だね!実は、多くの企業のプロキシサーバーは、外部への通信だけを中継する設定になってるんだ。内部サーバーへのアクセスは直接通信することを前提にしてるから、プロキシを通ろうとすると弾かれちゃうんだよ。
えー、困るじゃん...外部も内部も両方アクセスしたいのに
NO_PROXYの登場
そこで登場するのがNO_PROXYなんだ!
NO_PROXY?
NO_PROXYは、「この宛先へはプロキシを使わないで!」って指定する環境変数なんだ。
# プロキシの設定
export HTTP_PROXY="http://proxy.company.com:8080"
export HTTPS_PROXY="http://proxy.company.com:8080"
# NO_PROXYの設定
export NO_PROXY="localhost,127.0.0.1,.internal.company.com"
おお!特定の宛先だけプロキシをスキップできるんだ!
そういうこと!NO_PROXYに指定したホストには、プロキシを経由せず直接アクセスするようになるんだ。
それなら外部はプロキシ経由、内部は直接アクセスって使い分けられるね!
NO_PROXYの書き方とルール
NO_PROXYって、どうやって書けばいいの?
カンマ区切りで複数のパターンを指定できるんだ。いくつか書き方のルールがあるから、見ていこう。
1. 特定のホスト名
まず、特定のホスト名を指定する方法。
export NO_PROXY="dev-server.company.com,api.company.com"
これで、dev-server.company.comとapi.company.comへはプロキシを使わなくなるよ。
2. ドメイン全体
会社のサーバー全部をスキップしたい時は?いちいち全部書くの?
それだと大変だよね。ドメイン全体を指定することもできるんだ。先頭にドット(.)をつけるんだよ。
export NO_PROXY=".company.com"
これで、*.company.comのすべてのサブドメインがプロキシをスキップするようになる。例えば、dev.company.comもapi.company.comもtest.company.comも、全部直接アクセスになるんだ。
それは便利!一気に設定できるんだね
3. localhost
あと、ローカルホストも忘れずに設定した方がいいよ。
export NO_PROXY="localhost,127.0.0.1"
自分のPC上で動いてるサービスにアクセスする時も、プロキシを通ろうとすると失敗することがあるんだ。
自分のPCなのにプロキシ通るの?
そう、HTTP_PROXYを設定すると、localhostへのアクセスもプロキシを通ろうとするツールがあるんだ。Docker内のサービスとか、ローカルで開発サーバーを立ててる時とかね。
4. IPアドレス範囲
IPアドレスの範囲も指定できるよ。
export NO_PROXY="192.168.0.0/16,10.0.0.0/8"
これは、社内ネットワークのIPアドレス範囲を指定する時に便利なんだ。
/16とか/8って何?
CIDR表記っていうネットワークの範囲を示す書き方なんだ。例えば、192.168.0.0/16は、192.168.0.0から192.168.255.255までの範囲を表すんだよ。
範囲でまとめて指定できるんだ!
実際の設定例
実際の職場では、こんな感じで設定することが多いよ。
# プロキシの設定
export HTTP_PROXY="http://proxy.company.com:8080"
export HTTPS_PROXY="http://proxy.company.com:8080"
# NO_PROXYの設定
export NO_PROXY="localhost,127.0.0.1,.internal.company.com,192.168.0.0/16,10.0.0.0/8"
これで、以下のようになる。
- localhost(
127.0.0.1)→ プロキシなし - 社内ドメイン(
.internal.company.com)→ プロキシなし - 社内ネットワーク(
192.168.*.*、10.*.*.*)→ プロキシなし - それ以外(外部サイト)→ プロキシ経由
これなら外部と内部を使い分けられるね!
大文字?小文字?環境変数の落とし穴
ところで、HTTP_PROXYって大文字だけど、小文字じゃダメなの?
いい質問だね!実は、ツールによって大文字か小文字かが違うんだ。
え、統一されてないの?
そうなんだ。curlは大文字小文字どちらも認識するけど、一部のツールは小文字しか見ないこともあるんだよ。だから、念のため両方設定しておくのが安全なんだ。
# 大文字
export HTTP_PROXY="http://proxy.company.com:8080"
export HTTPS_PROXY="http://proxy.company.com:8080"
export NO_PROXY="localhost,127.0.0.1,.internal.company.com"
# 小文字も念のため
export http_proxy="http://proxy.company.com:8080"
export https_proxy="http://proxy.company.com:8080"
export no_proxy="localhost,127.0.0.1,.internal.company.com"
面倒くさい!でも確実に動くなら仕方ないか...
そうなんだよ。特にDockerやPythonのrequestsライブラリは小文字を見ることが多いから、両方設定しておくのがおすすめだね。
トラブルシューティング:プロキシ設定の確認方法
設定したけど、ちゃんと動いてるか確認したい時はどうすればいいの?
いくつか確認方法があるから、紹介するね。
環境変数の確認
まず、環境変数がちゃんと設定されてるか確認しよう。
# 環境変数の確認
echo $HTTP_PROXY
echo $HTTPS_PROXY
echo $NO_PROXY
これで、設定した値が表示されれば OK なんだ。
curlで動作確認
次に、実際に通信してみて、プロキシを通ってるか確認できるよ。
# プロキシ経由になってるか確認(外部サイト)
curl -v https://www.google.com
# プロキシをスキップしてるか確認(社内サーバー)
curl -v http://dev-server.internal.company.com
-vオプションをつけると、詳細な通信ログが出るから、プロキシを使ってるかどうかわかるんだ。
詳細ログ?どこを見ればいいの?
プロキシ経由の場合、こんな行が出るよ。
* Trying proxy.company.com:8080...
* Connected to proxy.company.com (192.168.1.100) port 8080
プロキシをスキップしてる場合は、直接ホストに接続する。
* Trying 192.168.10.50...
* Connected to dev-server.internal.company.com (192.168.10.50) port 80
なるほど!接続先を見ればわかるんだね
明示的にプロキシを無効化してテスト
あと、一時的にプロキシを無効にして試すこともできるよ。
# この1回だけプロキシを使わない
curl --noproxy '*' http://dev-server.internal.company.com
これで繋がるなら、プロキシの設定が原因だってわかるんだ。
よくあるハマりポイント
他にハマりやすいポイントってある?
あるある!僕がハマったポイントをいくつか紹介するね。
1. スペースを入れてしまう
NO_PROXYの区切りは、カンマだけで、スペースは入れちゃダメなんだ。
# ❌ ダメな例(スペースが入ってる)
export NO_PROXY="localhost, 127.0.0.1, .company.com"
# ✅ 正しい例
export NO_PROXY="localhost,127.0.0.1,.company.com"
スペースあるだけでダメなの!?
そうなんだ。スペースが入ると、 .company.com(スペース+ドメイン)という文字列として認識されて、マッチしなくなっちゃうんだよ。
2. ドットの付け忘れ
サブドメインをまとめて指定する時、先頭のドット(.)を忘れると、一部のツールで正しく動かないことがあるんだ。
# ❌ 微妙な例(ドメインそのものしかマッチしない可能性)
export NO_PROXY="company.com"
# ✅ 正しい例(すべてのサブドメインにマッチ)
export NO_PROXY=".company.com"
ドットがないとどうなるの?
ツールによって挙動が違うんだけど、company.comだけマッチして、dev.company.comやapi.company.comはマッチしないことがあるんだ。
3. ワイルドカードの罠
*とか使えないの?*.company.comみたいに
ワイルドカード(*)は、一部のツールでは動くけど、動かないツールもあるんだ。だから、先頭のドット(.company.com)を使う方が安全なんだよ。
4. シェルの再起動を忘れる
環境変数を.bashrcや.zshrcに書いた後、シェルを再起動しないと反映されないことも忘れがちだね。
# 設定ファイルを再読み込み
source ~/.bashrc
# または
source ~/.zshrc
あー、それよくやっちゃう...
永続的な設定方法
毎回exportコマンドを打つのは面倒だよね...
そうだね。設定ファイルに書いておけば、シェルを起動するたびに自動で設定されるよ。
Bashの場合
~/.bashrcに書くんだ。
# ~/.bashrc に追記
export HTTP_PROXY="http://proxy.company.com:8080"
export HTTPS_PROXY="http://proxy.company.com:8080"
export NO_PROXY="localhost,127.0.0.1,.internal.company.com"
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export no_proxy="$NO_PROXY"
Zshの場合
Zshを使ってるなら、~/.zshrcに書くよ。
# ~/.zshrc に追記
export HTTP_PROXY="http://proxy.company.com:8080"
export HTTPS_PROXY="http://proxy.company.com:8080"
export NO_PROXY="localhost,127.0.0.1,.internal.company.com"
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export no_proxy="$NO_PROXY"
これで毎回設定しなくて済むね!
まとめ
プロキシ環境での開発は、最初は戸惑うことも多いけど、仕組みを理解すれば怖くないんだ。特にNO_PROXYの設定は、プロキシ環境では必須だよ。
ポイントをまとめると?
こんな感じかな。
- プロキシは外部通信のセキュリティのために使われる
- プロキシを設定すると、すべての通信がプロキシ経由になる
- NO_PROXYで、内部サーバーへの直接通信を許可する
- 大文字小文字の両方を設定しておくと安全
- カンマ区切りでスペースなし、ドメインには先頭にドット
これでプロキシ環境も怖くないね!
そう!僕も最初はNO_PROXYの存在を知らなくて、「なんで社内サーバーに繋がらないんだ!」って何時間も悩んだからね。この記事が同じように詰まってる人の助けになれば嬉しいな。
教えてくれてありがとう!これで職場のプロキシ環境でも困らなくて済みそう!
参考情報
プロキシ設定についてもっと詳しく知りたい場合は、以下のドキュメントも参考にしてみよう。