🎃

DockerでNordVPNプロキシサーバーを構築する方法

に公開

はじめに

過去にnordvpn proxy dockerについて解説をした。

NordvpnをDocker上で動かしてproxyにする

ただ、このDockerHubやGithubを見たところ4年commitがなく、メンテされていなさそうなので突然使えなくなった時凄い困ることが判明しました。

なので
Docker hub
github
Joentje / nordvpn-proxy
のレポジトリについて細かく解説・分析しました。

主な機能

  • 自動サーバー選択: NordVPN APIを使用して最適なサーバーに自動接続
  • 負荷分散: サーバー負荷が高い場合に自動的に再接続
  • ランダムサーバー選択: 上位N個の推奨サーバーからランダムに選択可能
  • ヘルスチェック機能: 接続の安全性を定期的に確認
  • Privoxyプロキシ: ブラウザなど外部アプリケーションからの利用が可能
  • コンテナ間通信: 他のDockerコンテナをVPN経由で通信させることが可能
  • 自動更新: OpenVPN設定ファイルを毎日自動更新

アーキテクチャ概要

ディレクトリ構造

nordvpn-proxy/
├── Dockerfile          # Alpineベースのコンテナイメージ定義
├── docker-compose.yml  # Docker Compose設定ファイル
├── README.md          # プロジェクトドキュメント
└── app/
    ├── date.sh        # 日付フォーマット用ヘルパー関数
    ├── crond/         # Cronジョブ管理
    │   └── run        # Cronデーモン起動スクリプト
    ├── ovpn/          # OpenVPN関連
    │   ├── get-ovpn-files.sh      # OpenVPN設定ファイルダウンロード
    │   ├── get-status-server.sh   # サーバー負荷チェック
    │   ├── run                    # OpenVPN起動スクリプト
    │   └── servers_recommendations.sh  # 最適サーバー選択
    └── privoxy/       # Privoxyプロキシ
        ├── config     # Privoxy設定ファイル
        └── run        # Privoxy起動スクリプト

動作の仕組み

1. コンテナの起動プロセス

  1. Alpineベースイメージの使用

    • 軽量なAlpine Linux 3.10.1をベースに構築
    • 必要なパッケージ(OpenVPN、Privoxy、runit、jq等)をインストール
  2. runitによるプロセス管理

    • /appディレクトリ内の各サービスをrunitで管理
    • 各サービスはrunスクリプトで起動

2. OpenVPN設定ファイルの管理

get-ovpn-files.shスクリプトの動作:

# NordVPNから最新のOpenVPN設定ファイルをダウンロード
curl -s -o ${OVPN_CONFIG_DIR}/ovpn.zip ${OVPN_FILES}

# ファイルを解凍
unzip -q ${OVPN_CONFIG_DIR}/ovpn.zip -d ${OVPN_CONFIG_DIR}
  • 設定ファイルはREFRESH_TIME(デフォルト120分)経過後に再ダウンロード
  • 毎日自動的に最新の設定ファイルを取得(Cronジョブ)

3. 最適なVPNサーバーの選択

servers_recommendations.shの処理フロー:

  1. サーバー未指定の場合

    • NordVPN APIから推奨サーバーリストを取得
    • 国コードが指定されている場合は、その国のサーバーに限定
    • RANDOM_TOPが設定されている場合、上位N個からランダム選択
  2. APIエンドポイント

    https://api.nordvpn.com/v1/servers/recommendations
    
  3. フィルタリング条件

    • OpenVPNプロトコル(TCP/UDP)対応サーバー
    • 指定国のサーバー(COUNTRY環境変数使用時)

4. VPN接続の確立

runスクリプトでOpenVPN接続を開始:

  1. TUNデバイスの作成

    mknod /dev/net/tun c 10 200
    
  2. 認証情報の設定

    echo "$USERNAME" > auth.conf
    echo "$PASSWORD" >> auth.conf
    
  3. OpenVPN起動

    openvpn --config ${SERVER}.${PROTOCOL}.ovpn --auth-user-pass auth.conf
    

5. Privoxyプロキシサーバー

  • ポート8118でHTTPプロキシを提供
  • VPN接続確立後10秒待機してから起動
  • ローカルネットワークへのルーティング設定

6. ヘルスチェックとメンテナンス

  1. ヘルスチェック(1分間隔)

    curl -x localhost:8118 https://api.nordvpn.com/vpn/check/full
    
    • VPN接続が「Protected」状態であることを確認
  2. 負荷チェック(Cronジョブ)

    • サーバー負荷が設定値(デフォルト75%)を超えた場合、自動的に再接続
    • get-status-server.shが定期的に実行

環境変数の詳細

変数名 必須 デフォルト値 説明
USERNAME - NordVPNアカウントのユーザー名
PASSWORD - NordVPNアカウントのパスワード
LOCAL_NETWORK - ローカルネットワークのCIDR(例: 192.168.1.0/24)
CRON - */15 * * * * サーバー負荷チェックの頻度
LOAD - 75 サーバー負荷の閾値(%)
RANDOM_TOP - - ランダム選択するサーバー数
COUNTRY - - 接続する国の2文字コード(例: JP)
PROTOCOL - tcp 使用するプロトコル(tcp/udp)
SERVER - - 特定のサーバー名(例: jp123.nordvpn.com)
REFRESH_TIME - 120 設定ファイル更新間隔(分)

使用方法

1. 基本的な起動方法

docker run -d \
  --cap-add=NET_ADMIN \
  --name=vpn \
  --dns=103.86.96.100 \
  --dns=103.86.99.100 \
  --restart=always \
  -e "USERNAME=your_nordvpn_username" \
  -e "PASSWORD=your_nordvpn_password" \
  -e "LOCAL_NETWORK=192.168.1.0/24" \
  -v /etc/localtime:/etc/localtime:ro \
  -v ovpn-data:/app/ovpn/config \
  -p 8118:8118 \
  jeroenslot/nordvpn-proxy:latest

2. Docker Composeを使用する場合

version: '3'
services:
  vpn:
    image: jeroenslot/nordvpn-proxy:latest
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
    dns:
      - 103.86.96.100
      - 103.86.99.100
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ovpn-data:/app/ovpn/config
    environment:
      - USERNAME=your_nordvpn_username
      - PASSWORD=your_nordvpn_password
      - LOCAL_NETWORK=192.168.1.0/24
    ports:
      - 8118:8118
    restart: always

volumes:
  ovpn-data:

3. 他のコンテナからVPNを使用

docker run -d \
  --network="container:vpn" \
  your-image-name

4. ブラウザでプロキシを使用

ブラウザのプロキシ設定で以下を指定:

  • プロキシサーバー: Dockerホストのアドレス
  • ポート: 8118

Chrome拡張機能「Proxy SwitchyOmega」の使用を推奨

高度な設定例

日本のサーバーに接続

docker run -d \
  # ... 他の設定 ...
  -e "COUNTRY=JP" \
  jeroenslot/nordvpn-proxy:latest

ランダムサーバー選択を有効化

docker run -d \
  # ... 他の設定 ...
  -e "LOAD=0" \
  -e "RANDOM_TOP=100" \
  jeroenslot/nordvpn-proxy:latest

特定のサーバーを指定

docker run -d \
  # ... 他の設定 ...
  -e "SERVER=jp123.nordvpn.com" \
  jeroenslot/nordvpn-proxy:latest

セキュリティ考慮事項

  1. 認証情報の管理

    • USERNAME/PASSWORDは環境変数で管理
    • Docker Secretsの使用を推奨
  2. ネットワーク権限

    • NET_ADMIN capabilityが必要
    • TUNデバイスへのアクセス権限
  3. DNS設定

    • NordVPNのDNSサーバーを使用(103.86.96.100、103.86.99.100)

トラブルシューティング

VPN接続が確立できない場合

  1. 認証情報を確認
  2. ログを確認: docker logs vpn
  3. OpenVPN設定ファイルの更新を強制実行

プロキシに接続できない場合

  1. コンテナのポートマッピングを確認
  2. LOCAL_NETWORKの設定を確認
  3. ファイアウォール設定を確認

パフォーマンスの問題

  1. LOAD値を調整して頻繁な再接続を防ぐ
  2. 特定のサーバーを指定して安定性を向上
  3. プロトコルをUDPに変更してみる

まとめ

理解したので万が一困っても直せますね
ヤッタ!

宣伝(招待リンク)

お友達紹介リンク を使用した登録は下記の特典が付くので、もし検討している方はご一考ください。

- 1年または2年プランを選ぶと3か月分の無料期間
- 1か月プランを選ぶと1か月分の無料期間
がもらえます。

書いていて思いましたが、結構紹介特典がしょぼいのでハピタス経由でダウンロードしてポイント貰った方がお得かもしれません。

Discussion