開発者向けのVPN設定では、すべての通信を同じ接続先へ送ればよいとは限りません。GitHubのコード管理は開けても、Docker Hubからのイメージ取得やnpm installだけが遅くなることがあります。これは、サービスごとにサーバーの地域、DNS解決、TLS接続、長時間転送の経路が異なるためです。開発環境では、ブラウザーの表示速度だけで判断せず、リポジトリの取得、コンテナイメージのpull、パッケージのダウンロード、CI/CDの認証と成果物転送を分けて確認する必要があります。
本記事では、Windows、macOS、Linuxなどの公式クライアントに加え、Clash Verge、sing-box、Shadowrocketのような互換クライアントで考え方を共通化します。サブスクリプションURLを取り込んだ後、目的別に接続先を選び、ルール分岐またはスプリットトンネルを使って開発用通信だけを適切な経路へ送る方法を説明します。速度の数値を一時的に比較するのではなく、実際の開発タスクが最後まで完了するかを基準にしてください。
開発者の通信をサービス別に分けて考える
GitHub、Docker Hub、npmレジストリは、同じ海外サービスに見えても通信の性質が違います。GitHubでは、リポジトリの一覧表示、HTTPSによるcloneとfetch、SSH接続、ReleaseやActionsの成果物取得などが発生します。小さなテキストファイルだけなら接続確立とDNSの安定性が目立ちますが、履歴の多いリポジトリや大きなバイナリを扱う場合は、長時間の転送が影響します。
Dockerでは、最初にレジストリのAPIへアクセスし、その後にイメージのマニフェストと複数のレイヤーを取得します。つまり、ブラウザーでDocker Hubのページが開くことだけでは、pullの成否を判断できません。認証、マニフェスト取得、レイヤーの並列ダウンロード、ローカルキャッシュの確認までを一つの作業として確認する必要があります。npm installも、npmjsのレジストリ、依存パッケージが指定する別の配布先、Gitリポジトリ由来の依存関係などへ接続する可能性があります。
90+
対応国・地域
200+
接続回線
不限
同時接続台数
| 作業 | 主な通信 | 優先する確認点 | 分岐の考え方 |
|---|---|---|---|
| GitHubのclone・fetch | HTTPSまたはSSH、API、Release | 名前解決、認証、継続転送 | GitHub向けドメインを同じ経路へまとめる |
| Docker imageのpull | レジストリAPI、マニフェスト、レイヤー | 認証と大容量転送の安定性 | Docker関連ドメインを専用グループへ送る |
| npm install | npmレジストリ、依存先、Git URL | レジストリ設定と依存先の経路 | npmだけでなく依存パッケージの配布先も確認する |
| CI/CD | リポジトリ、Runner、レジストリ、成果物 | 実行環境のプロキシと秘密情報 | Runnerの管理者ポリシーを優先する |
接続先は、自分の所在地だけで決めるのではなく、目的のサービス、認証入口、レジストリの地域を基準に選びます。直結回線は構成が分かりやすい一方、利用中のISPや国際経路の影響を受けます。中継回線は入口と出口を分けて経路を制御する方式で、環境によっては安定性が改善することがあります。IEPLと表示される回線は国際区間の伝送方式を示すもので、Shadowsocks、VMess、Trojan、Hysteria2、WireGuardのようなプロトコルそのものではありません。回線方式とプロトコルを混同せず、実際の作業で確認してください。
クライアントとプロトコルの選び方
公式クライアントは、Windows、macOS、iOS、Android、Linuxで提供される接続手順が整理されており、サブスクリプションURLを一度取り込めば、ノード更新や基本的な切り替えを行いやすい方式です。まず公式クライアントで接続を確認し、その後に高度なルールが必要になった場合だけ互換クライアントへ移行すると、問題の切り分けが簡単になります。
Clash Vergeはルールベースのプロキシ運用を組み立てやすく、ドメインやルールセットによる分岐を確認したいデスクトップ利用に向いています。sing-boxは複数のインバウンド、アウトバウンド、DNS、ルールを細かく構成できますが、設定の記述ミスが接続障害につながりやすいため、変更前にバックアップを作成します。Shadowrocketはモバイル端末でサブスクリプションを管理し、ドメインやIPルールを切り替える用途に便利です。いずれも、サービスが配布する形式とクライアントのコアが対応していることが前提です。
Shadowsocksは比較的単純な暗号化プロキシとして利用されます。VMessやTrojanは、サーバー名、TLS、転送方式などの組み合わせが正しく一致しなければ接続できません。Hysteria2はQUICとUDPを使うため、利用中のネットワークでUDP通信が制限されていないかを確認します。WireGuardはVPNインターフェースとして動作する構成が多く、一般的なHTTPプロキシのルールと同じ考え方で扱えない場合があります。プロトコル名だけで速さを決めず、クライアント、回線、対象サービスの組み合わせで判断しましょう。
- ✅ まず公式クライアントでサブスクリプションの導入と基本接続を確認する
- ✅ 互換クライアントでは、対応コアとサブスクリプション形式を確認する
- ✅ TUNモードを使う場合は、DNSとローカルネットワークの挙動も確認する
- ❌ 複数のVPNクライアントを同時にTUNモードで起動しない
- ❌ プロトコル名だけを理由に、すべての開発通信を同じ経路へ固定しない
GitHub・Docker・npm向けの分割トンネル設計
分割トンネルには、アプリ単位で通信を分ける方法と、ドメイン、IP、プロセス、ポートなどのルールで分ける方法があります。開発環境では、アプリ単位だけに頼ると不十分なことがあります。たとえば、ブラウザーでGitHubを開く通信と、Gitコマンドが使うHTTPS通信は同じアプリではありません。Docker DesktopのバックエンドやLinux上のdockerd、Node.jsのnpmプロセスも別の通信主体として動作します。
最初は目的を絞ったルールから始めます。GitHub関連のホスト名、Dockerレジストリ、npmレジストリをそれぞれ確認し、必要な通信だけをプロキシグループへ送ります。GitHubからGit URLで依存パッケージを取得する場合は、npmだけでなくGitHubの経路も必要です。企業内Git、社内レジストリ、ローカル開発サーバーは、誤って外部プロキシへ送らないよう、プライベートネットワークとローカルアドレスを直接接続にします。
DNSの扱いも重要です。ドメインルールを使っていても、DNSだけが直接経路へ送られると、名前解決の地域や結果が通信ルールと一致しないことがあります。逆に、すべてのDNSを遠隔へ送ると、社内ホストや開発用のローカル名を解決できなくなる場合があります。利用するクライアントのDNSモードを確認し、外部サービス、社内ドメイン、ローカルドメインの解決方針を分けてください。
実際に接続先とルールをテストする手順
設定を変更する前に、現在の環境で開発作業がどこまで進むかを記録します。Gitの認証方式、Dockerのログイン状態、npmのレジストリ設定、社内プロキシの有無を確認し、秘密情報そのものはログに残さないようにします。作業用の小さなテストリポジトリや、既にローカルキャッシュへ保存されているデータだけに依存しない検証対象を用意すると、経路の違いを確認しやすくなります。
- クライアントでサブスクリプションを更新し、複数の接続先を地域と回線タイプで整理します。
- 一つの接続先を選び、GitHubの認証、clone、fetchを順番に確認します。HTTPSとSSHを使う場合は、両方が同じ経路になるとは限らない点に注意します。
- Dockerでレジストリへのログイン、イメージのmanifest取得、pullを確認します。既存のイメージだけで判断せず、別のタグや未取得レイヤーを含む作業で確認します。
- npmのregistry設定、lockfileに記載された依存先、Git URLの依存関係を確認し、installが途中で止まらないかを見ます。
- ログでDNSエラー、TLS証明書エラー、認証失敗、接続タイムアウトを分けて確認し、原因が異なる作業を一度に修正しないようにします。
- ルールを一つずつ追加し、変更後にGit、Docker、npm、社内サービスの順で再確認します。
Docker Desktopを使う場合、画面上のブラウザー通信だけをプロキシに入れても、バックエンドのデーモンが同じ設定を使うとは限りません。Docker Engineのプロキシ設定、daemon.json、組織のネットワークポリシーを確認してください。Linuxでは、シェルのHTTP_PROXYやHTTPS_PROXY、Dockerデーモンの環境変数、systemdの設定が別々に存在することがあります。npmでも、シェルのプロキシ環境変数、npm configのproxy、レジストリのHTTPS設定が競合する場合があります。
# 設定値を確認する例
git config --global --get http.proxy
npm config get registry
docker info
env | grep -E 'HTTP_PROXY|HTTPS_PROXY|ALL_PROXY|NO_PROXY'
上の確認では、表示された認証情報をそのまま共有しないでください。NO_PROXYにはlocalhost、127.0.0.1、社内ドメインなどを含めることがありますが、組織の命名規則に合わせて設定する必要があります。VPNを切り替えた後は、古いDNSキャッシュ、Dockerの接続状態、npmの再試行状態が残る場合があるため、クライアントだけでなく対象アプリも再起動してから結果を比較します。
CI/CDと安全な運用の注意点
ローカル端末で成功した設定が、そのままCI/CDのRunnerで動くとは限りません。Runnerはクラウド、社内サーバー、コンテナ内など異なる環境で実行され、ローカルのVPNクライアントやサブスクリプションを持っていないことがあります。組織の管理者が許可したネットワーク経路、プロキシ環境変数、内部ミラー、レジストリ設定を優先し、個人の接続情報をジョブへコピーしないでください。
GitHub ActionsなどのCIでは、リポジトリ取得、依存パッケージの復元、Dockerイメージの取得、成果物の保存が別々の接続になります。依存関係をキャッシュしても、キャッシュが存在しない実行では外部レジストリへの通信が発生します。Dockerの認証情報やnpmトークンは、環境変数やシークレット管理機能で扱い、コマンドライン、ビルドログ、エラーメッセージへ出力しないようにします。
開発用のVPNは、アクセス制御や秘密情報管理の代わりではありません。SSH鍵は端末の保護領域に保存し、GitHubのトークンには必要最小限の権限だけを与えます。npmパッケージを取得するときは、lockfileの変更を確認し、見覚えのない依存先やインストールスクリプトを無条件に実行しないでください。Dockerイメージも、提供元、タグ、ダイジェスト、更新履歴を確認し、信頼できるレジストリを使います。
- ✅ CI/CDでは管理者が指定したRunnerとプロキシ設定を優先する
- ✅ GitHubトークン、npmトークン、SSH鍵をログやサブスクリプションへ含めない
- ✅ DockerデーモンとDocker Desktopのプロキシ設定を別々に確認する
- ✅ VPNを切り替えた後はDNS、認証、レジストリ、社内サービスを再確認する
- ❌ ローカル端末の設定ファイルをCIへそのままアップロードしない