会社のネットワーク内でWSL2を開発環境としてセットアップするのに苦労した話

家の自前PCでは一発で動くのに、会社支給のPCで設定しようとすると失敗する
家で自前のPCのWindows環境でセットアップしたWSLの中で apt install や npm install を打つとき、私は特に何も考えていません。だいたい動くからです。
ところが会社ネットワーク内で会社支給のWindowsPCでWSLにUbuntuを入れて、同じコマンドを打つと…失敗します。Could not resolve host、証明書検証エラー、タイムアウト……。
この記事は、そういう環境でWSL2の開発環境を立ち上げようとしてつまずいた記録です。結論だけ知りたい人は最後のチェックリストへ、経緯も含めて知りたい人はこのまま読み進めてください。
前提環境
- Windows 11 25H2(ビルド26xxx系)
- WSL2 Ubuntu Linux 24.04
- 社内からインターネットに出る経路にプロキシが存在する/社内環境にアクセスするためのVPN接続あり
- SSLフォワーダー(Netskopeなどのプロキシ型セキュリティ製品)によるインスペクションあり
※執筆時点(2026年7月)の情報です。WSLのネットワーク機能は現在も活発に更新されているため、バージョンによって挙動が変わる可能性があります。
症状:ネットワークは繋がっているのに環境セットアップできない
当初こんな状態でした。
- ブラウザ(ホストのWindows側)は社内サイトにも外部サイトにも普通に繋がる
- WSL内から
pingは通る - しかし
curl https://example.comは証明書エラー sudo apt updateはタイムアウトHTTP_PROXYを設定しても、一部のツールだけは相変わらず失敗する
以降、ポイント別に切り分けていきます。
ポイント1 ネットワークモードをNATモードからミラーモードに
WSL2のネットワークモードには NATモード(既定) と ミラーモード(mirrored) の2つがあります。
| NATモード | ミラーモード | |
|---|---|---|
| ネットワーク構成 | Hyper-Vの仮想ルーター配下に独立したサブネット | ホストWindowsのNICをそのままWSL側にミラー |
| VPNとの相性 | ルーティングが競合しやすい | ホストの経路をそのまま使うので安定 |
| セキュリティ境界 | 仮想ルーターで分離される | ホストとファイアウォールを共有する(=隔離はやや弱い) |
| 位置づけ | 従来からの既定 | 新しい方式。企業環境向けの機能が揃っている |
NATモードは仮想ルーター越しに独自のサブネットを持つ方式で、これはこれで合理的な設計です。ホストから隔離したいという要件がある場合はむしろ好都合でしょう。ただ、VPN接続時にWSL内から社内リソースに到達できない・DNSが引けないという事象が発生したのであります。
VPNを日常的に使うなら、迷わずミラーモードにしてください。NATモードのまま「なぜかVPN経由だけ繋がらない」を数時間追いかけた経験があります。
設定方法:ポイント1への対応
ホスト側のWindowsで%USERPROFILE%\.wslconfig に以下を書いて wsl --shutdown します。再度ターミナルを開くと新しい設定で起動します。
[wsl2]
networkingMode=mirrored
dnsTunneling=true
autoProxy=true
firewall=true
- dnsTunneling:WSL側のDNS解決をホストWindows経由で行う仕組みです。VPN接続時の社内DNS設定もそのまま共有できるので、VPN環境ではほぼ必須だと感じています。
- autoProxy:ホストWindowsのプロキシ設定をWSL側の環境変数(
HTTP_PROXY/HTTPS_PROXYなど)に自動反映してくれる機能です。
WSL Settings という GUIでも設定できます。

ポイント2 autoProxyを入れても、見てくれないツールがいる
autoProxyを有効にすればWSL内のシェルに HTTP_PROXY などの環境変数は確かに入ります。しかし、その環境変数を見てくれないツールがあります。 「環境変数は入っているのに apt update が固まる」の正体はこれでした。
- 環境変数を見ないツール(独自の設定ファイルを持つ)
- root権限で動くと環境変数が引き継がれないツール(
sudo経由) - Node.jsやPython本体が直接HTTPSを叩くケース(npm config / pip.confでは拾えない)
つまり「autoProxyを設定したから終わり」ではなく、ツールの数だけ設定箇所があるという印象です。これは次章のSSL証明書とセットで対応する必要があります。 まあ、Windowsでもアプリごとに独立したプロキシの設定入れる箇所あったりしますものね…
ポイント3 SSLフォワーダーが証明書を差し替えている
Netskopeのようなプロキシ型セキュリティ製品を通る場合、TLS通信は途中で復号・再暗号化されています。WSLから見ると、サーバー証明書の発行者が社内のCAに置き換わっているということです。
Windows側にはそのCA証明書が配布済みでも、WSLのLinux側には入っていません。 結果としてあらゆるHTTPSアクセスが証明書検証エラーで落ちます。私の環境では、プロキシ設定より先にこれをやらないと何も動きませんでした。
# 社内CA証明書(.crt / PEM形式)を配置
sudo cp corp-ca.crt /usr/local/share/ca-certificates/corp-ca.crt
sudo update-ca-certificates
証明書はWindows側の証明書ストア(certmgr.msc)からBase64エンコードX.509でエクスポートするか、情シスから配布されているものを使います。
ファイル拡張子は .crt、中身はPEM形式である必要があります。DER形式のまま置いても update-ca-certificates が黙って無視するので、「コマンドはエラーなく終わったのに証明書エラーが直らない」というハマり方をします(実際に1回やりました)。
これで curl https://example.com が通るようになれば、ようやく土台が整った状態です。
ツール別の対応:それぞれ独自のルールで動いている
ポイント1で土台ができたら、次はツールごとのポイント2・3に対する個別対応です。
| ツール | 症状 | 対応 |
|---|---|---|
| sudo | curl は通るのに sudo apt update が失敗 |
環境変数の引き継ぎ設定 |
| apt | 環境変数はあるが不安定 | 設定ファイルに直書き |
| git | コマンドがタイムアウトする | プロキシ設定 |
| npm | Node本体が直接叩く処理だけ失敗 | config+環境変数の二重設定 |
| pip | requestsベースのツール全般 | pip.conf+環境変数 |
sudo:環境変数が引き継がれない
sudo apt update が失敗するのに curl は通る、という場合の典型がこれです。sudoは既定でセキュリティのため環境変数をリセットするので、プロキシ変数が消えます。
sudo visudo で以下を追加します。
Defaults env_keep += "http_proxy https_proxy ftp_proxy no_proxy HTTP_PROXY HTTPS_PROXY NO_PROXY"
大文字・小文字の両方を書いておくのが安全です。ツールによって参照する変数名の大小文字が違うため、片方だけ書いて「なぜか効かない」を経験しました。
apt:独自の設定ファイルを持つ
aptは環境変数も見ますが、sudo経由で落ちる問題を避けるためにも設定ファイルに書いてしまうのが確実です。
sudo tee /etc/apt/apt.conf.d/95proxy <<'EOF'
Acquire::http::Proxy "http://proxy.example.co.jp:8080";
Acquire::https::Proxy "http://proxy.example.co.jp:8080";
EOF
/etc/apt/apt.conf に直接書いてもよいですが、apt.conf.d/ に分けておいた方が後から見直しやすいです。
git:プロキシ設定と証明書の両方
git config --global http.proxy http://proxy.example.co.jp:8080
git config --global https.proxy http://proxy.example.co.jp:8080
# システムのCAストアを使う場合(前出の設定を実施済みなら通常はこれで足りる)
git config --global http.sslCAInfo /etc/ssl/certs/ca-certificates.crt
なお、SSHプロトコル(git@github.com:)は多くの企業で設定されているプロキシでは通らないのではないかと推測します。もちろん、弊社の環境でも通らなかったので、HTTPSに統一しました。
http.sslVerify=false は使わないでください。通るようにはなりますが、インスペンション以外の中間者も素通しになります。動かないことに苛立って一瞬手が伸びかけましたが、ここは踏みとどまるべきところです。
npm:プロキシ設定と証明書の両方
npm config set proxy http://proxy.example.co.jp:8080
npm config set https-proxy http://proxy.example.co.jp:8080
npm config set cafile /etc/ssl/certs/ca-certificates.crt
Node.js本体が直接HTTPSを叩くツール(各種CLI、ビルド時のダウンロードなど)はnpm configを見ないので、環境変数も併せて設定しておく必要があります。
echo 'export NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt' >> ~/.bashrc
pip:プロキシ設定と証明書の両方
mkdir -p ~/.config/pip
cat > ~/.config/pip/pip.conf <<'EOF'
[global]
proxy = http://proxy.example.co.jp:8080
cert = /etc/ssl/certs/ca-certificates.crt
EOF
pipに限らず、Pythonのrequestsを使うツール全般は REQUESTS_CA_BUNDLE を見ます。こちらも設定しておくと後々の手戻りが減ります。
echo 'export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt' >> ~/.bashrc
番外 Docker:もう一度同じことをDockerfileに設定するのです
WSL上でDockerを動かす場合、ホストWSLの設定はコンテナ内には一切引き継がれません。ビルド中に apt install や pip install を走らせた瞬間、また同じ壁にぶつかります。
Dockerfileの中で証明書を入れてしまうのが素直です。
FROM ubuntu:24.04
# ビルド時のプロキシ(--build-arg で渡す)
ARG HTTP_PROXY
ARG HTTPS_PROXY
ARG NO_PROXY
# 社内CA証明書をイメージに取り込む
COPY corp-ca.crt /usr/local/share/ca-certificates/corp-ca.crt
RUN update-ca-certificates
ENV REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
ENV NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
ARG で渡したプロキシはビルド時のみ有効なので、実行時にもプロキシが要る場合は ~/.docker/config.json の proxies に書くか、docker run -e で渡します。
証明書は入れてよいですが、プロキシのURLをDockerfileに ENV でハードコードしないでください。イメージを社外や別ネットワークに持ち出したときに動かなくなりますし、社内ネットワーク構成の情報がイメージに焼き付いてしまいます。ARG で外から渡すのが正解です。
まとめ:詰まったときのチェック順
.wslconfigでミラーモード+dnsTunneling+autoProxyになっているかcurl https://example.comが通るか(=CA証明書が入っているか)env | grep -i proxyでプロキシ変数が見えるかsudo env | grep -i proxyでsudo経由でも見えるか- 失敗しているツールが、環境変数ではなく独自設定ファイルを見ていないか
- コンテナの中で同じことを全部やり直していないか
一般化すると、インターネットの出口をプロキシ等で守られた企業ネットワーク配下でのWSL構築は「1.ネットワークモードで土台を合わせる → 2.証明書を設定する → 3.ツールごとにプロキシと証明書の設定方法がないか疑い個別対応する → 4.コンテナは1.から3.をもう一度設定するものとして扱う」という4段構えで切り分けると迷いにくい、というのが今回の学びです。
注意事項
本文中に登場する、プロキシのURLやCA証明書の入手方法は組織ごとに異なるため、内容は自組織のセキュリティポリシーやネットワーク構成を確認のうえ実施してください。
参考資料
公式ドキュメント
- WSL Networking documentation — ミラーモード・autoProxy・dnsTunnelingの仕様
- update-ca-certificates - Debian Manpages
- Docker docs - Configure the daemon to use a proxy

