技術 約5分で読めます

V2Ray(WebSocket+TLS)サーバーの構築メモ

前回の記事「ShadowSocksサーバーの構築メモ」でV2Rayという後継プロトコルがあると書いたが、実はこっちも立ててた。当時のメモが出てきたのでまとめておく。

V2Rayとは

V2Rayは ShadowSocks の後継として開発されたプロキシツール。複数のプロトコルをサポートし、WebSocketやgRPCを使ってHTTPSトラフィックに偽装できる。

ShadowSocksとの違い:

  • ShadowSocks: シンプルで軽量。設定が簡単
  • V2Ray: 多機能で柔軟。WebSocket+TLSで検閲回避能力が高いが、設定が複雑

構成

今回の構成は以下の通り:

クライアント → CloudFlare (CDN) → Caddy (リバースプロキシ) → V2Ray (WebSocket)

CloudFlareを間に挟むことで:

  • サーバーの実IPを隠蔽
  • SSL/TLS証明書の自動管理
  • CDNキャッシュによる高速化

サーバー構築手順

CentOS 7での手順。

事前準備

yum update -y && yum install curl -y

CloudFlareの設定

  1. CloudFlareでサブドメインを追加(例: v2ray.example.com
  2. DNSレコードを作成(Aレコード、サーバーのIPを指定)
  3. プロキシ(オレンジの雲)を有効化
  4. DNS反映を待つ(数分〜数時間)

V2Rayのインストール

233blogのスクリプトを使用する。

bash <(curl -s -L https://git.io/v2ray.sh)

インストーラーの選択肢:

  1. 1 を選択(V2Ray)
  2. 4 を選択(WebSocket+TLS)
  3. ポート番号(デフォルトのままエンター、または443)
  4. サブドメインを入力(例: v2ray.example.com
  5. 以降は基本的に Y または N で進める
    • 自动配置: Y
    • 开启广告拦截: N(好みで)
    • ShadowSocks: N

注意: CloudFlareのDNS反映が完了していないと途中で止まる。nslookup v2ray.example.com で名前が引けることを確認してから実行。

インストール確認

v2ray status

V2RayとCaddyの両方が active (running) になっていればOK。

Caddyの設定

/etc/caddy/Caddyfile を編集:

v2ray.example.com {
  root /var/www/html
  tls your-email@example.com
  log ./access.log
  timeouts none
  proxy / 127.0.0.1:54878 {
    websocket
    header_upstream -Origin
  }
}
import sites/*

ポイント:

  • tls のメールアドレスは必ず自分のものに変更
  • proxy のポート番号(54878)はV2Rayの設定に合わせる

ファイアウォールの無効化

systemctl stop firewalld
systemctl disable firewalld

または必要なポートだけ開ける(443など)。

カーネルパラメータの最適化

ShadowSocksと同じ設定を使用。詳細は前回の記事を参照。

/etc/security/limits.conf:

root soft nofile 51200
root hard nofile 51200

/etc/sysctl.conf は前回の記事と同じ内容を設定し、sysctl -p で反映。

BBRの有効化

v2ray bbr

1 を選択してBBRを有効化。その後再起動が必要:

reboot

タイムゾーンの設定

timedatectl set-timezone Asia/Tokyo
date  # 確認

設定ファイル

V2Rayの設定ファイルは2つある:

  • /etc/v2ray/config.json - メイン設定
  • /etc/v2ray/233blog_v2ray_config.json - 233blogスクリプト用の設定

重要: 両方のファイルにUUIDを設定しないとエラーになる。バックアップを取ってから編集すること:

cp /etc/v2ray/config.json /etc/v2ray/config.json.bak
cp /etc/v2ray/233blog_v2ray_config.json /etc/v2ray/233blog_v2ray_config.json.bak

config.json の構造

{
  "log": {
    "access": "/var/log/v2ray/access.log",
    "error": "/var/log/v2ray/error.log",
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "port": 54878,
      "protocol": "vmess",
      "settings": {
        "clients": [
          {
            "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
            "level": 1,
            "alterId": 233
          }
        ]
      },
      "streamSettings": {
        "network": "ws"
      },
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls"]
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "settings": {}
    },
    {
      "protocol": "blackhole",
      "settings": {},
      "tag": "blocked"
    }
  ],
  "dns": {
    "server": ["1.1.1.1", "1.0.0.1", "8.8.8.8", "8.8.4.4", "localhost"]
  },
  "routing": {
    "domainStrategy": "IPOnDemand",
    "rules": [
      {
        "type": "field",
        "ip": [
          "0.0.0.0/8",
          "10.0.0.0/8",
          "127.0.0.0/8",
          "192.168.0.0/16"
        ],
        "outboundTag": "blocked"
      }
    ]
  },
  "transport": {
    "kcpSettings": {
      "uplinkCapacity": 100,
      "downlinkCapacity": 100,
      "congestion": true
    },
    "sockopt": {
      "tcpFastOpen": true
    }
  }
}

ポイント:

  • inbounds.port はCaddyの proxy で指定したポートと一致させる
  • clients.id はクライアント側でも同じUUIDを使う
  • routing.rules でプライベートIPへのアクセスをブロック

複数ユーザーの設定

clients 配列にユーザーを追加:

"clients": [
  {
    "id": "uuid-for-user1",
    "level": 1,
    "alterId": 233
  },
  {
    "id": "uuid-for-user2",
    "level": 1,
    "alterId": 233
  }
]

ShadowSocksと違い、ポートではなくUUIDでユーザーを区別する。

設定変更後の再起動

v2ray restart
v2ray status

トラブルシューティング

接続できない場合

  1. ポート番号の不一致: config.json のポートとCaddyの proxy ポートが一致しているか確認
  2. DNS未反映: CloudFlareのDNS反映を待つ
  3. 証明書エラー: Caddyのログを確認(/var/log/caddy/ 配下)
  4. UUID不一致: サーバーとクライアントで同じUUIDを使っているか確認

ログの確認

# V2Rayのログ
tail -f /var/log/v2ray/access.log
tail -f /var/log/v2ray/error.log

# Caddyのログ
tail -f /etc/caddy/access.log

2025年現在の推奨設定

上記の設定は当時のもので普通に動いていたが、今ならこうした方がいいっぽい。

alterId は 0 を推奨

// 元の設定
"alterId": 233

// 推奨
"alterId": 0

alterId: 0 にすると AEAD暗号化 が有効になり、より安全。233や4などの値はレガシー認証方式で、現在は非推奨。

Caddy v2 での構文変更

記事のCaddyfileは Caddy v1 の構文だが、Caddy v2 では以下のように変わる:

# Caddy v1(当時)
proxy / 127.0.0.1:54878 {
  websocket
  header_upstream -Origin
}

# Caddy v2(現在)
reverse_proxy 127.0.0.1:54878

Caddy v2 ではWebSocketは自動でサポートされるため、明示的な設定は不要。233blogスクリプトがCaddy v1をインストールしていた場合は当時の構文で動く。

カーネルパラメータ

ShadowSocksと同じ設定を使っていたので、改善点も同様:

  • net.ipv4.tcp_tw_reuse = 1 に変更
  • net.ipv4.tcp_congestion_control = bbr に変更(Linux 4.9以降)

詳細は前回の記事を参照。

2025年現在の状況

  • 233blogのスクリプトはメンテナンスが止まっている可能性がある
  • 今から構築するなら Xray(V2Rayのフォーク)を検討した方がいい
  • VMess より軽量な VLess + XTLS など、より検閲回避に強いプロトコルが登場している

→ 続き: SoftEther VPN サーバーの構築メモ

→ まとめ: 対中国通信 VPN規格によるつながりやすさの比較

参考