WireGuard はLinuxなどのホスト上で動作するVPN実装です。AndroidやiOSを含む各種OSのパッケージがあり、手軽にインストールできます。
既存VPNとの違い
ルーターなどに実装する従来型VPNの境界型防御は、VPN機器に接続できた場合に多様なサービスへのアクセス権を獲得できてしまう設計になりがちでした。WireGuardもこの方式で実装することじたいは可能です。
WireGuardはWebサーバーなどのアプリケーションホストで動作させることにより、アプリケーションへのアクセス経路を限定する方式もとれます。
一般的にサーバーアプリケーションにはlistenするIPを設定でき、多くの場合[::]や0.0.0.0といったアドレスを指定します。これは全てのネットワークデバイスからの接続経路を許可する設定です。
WireGuardをセットアップのうえfd00:1や10.0.0.1といった仮想LANのIPをlistenすることにより、アプリケーションへの到達をWireGuard経由に限定できます。
最終的な認証はアプリケーション層で確保する必要がありますが、DoS耐性を強化しやすい構成になります。
ただし、これはWireGuard接続が成立したときにアクセスをWireGuard内に閉じ込めるような機能ではない点には注意が必要です。パケットForwardの制限はWireGuardではなく別のネットワーク設定で実装する必要があります。
config
Linuxのsystemdから呼ぶ形式のセットアップには、wireguard付属のwg-quickを用いる方法が手軽です。慣習としてまずwg0デバイスをconfigで定義し、wg-quick経由で起動します。
具体的には /etc/wireguard/wg0.conf を記述し、sudo systemctl enable --now wg-quick@wg0 を実行することで有効なsystemdユニットに追加できます。
configはこの機器を設定するInterfaceと接続先リストのPeer群の構成になっています。
[Interface]
Address = fd00:1/128, 10.0.0.1/32
PrivateKey = <このホストの秘密鍵>
ListenPort = 51820
[Peer]
Endpoint = <接続先の実アドレス>:<WireGuard port>
PublicKey = <接続先の公開鍵>
AllowedIPs = fd00::2/128, 10.0.0.2/32
Interface.AddressとPeer.AllowedIPsはVPN内のローカルIPを定義して指定する。重複すると動作不良が起きるため、WireGuardネットワークのIPリストを定義しておくことで接続トラブルを減らせるPeer.EndpointはWireGuardが接続初期にアクセスする実アドレスの固定エンドポイント。Peerには接続を受け入れるデバイスも定義する必要があり、IPが定まらないクライアントはEndpointを記述しないAllowedIPsはルーティングに追加される。VPN接続後にここに記述したIPにアクセスすると、トンネルを通って該当Peerネットワークと通信する
仮想ネットワークデバイスをセットアップできるとip addressにリストされます。
鍵生成
公開鍵のセットはwg genkey|pubkeyサブコマンドで生成できます。
$ wg genkey > private.key
$ cat private.key | wg pubkey > pulick.key
接続できない場合
WireGuardは設定が比較的簡素なため、接続できないケースも限定できます。
デバイスが無効
まず、現在の設定はwg showコマンドで確認できます。デバイスが有効でない場合にはsyntax errorによる起動時エラーでしょう。
journalctl -u wg-quick@wg0コマンドでログを表示できます。
実ネットワーク不達
実ネットワークのPeer.Endpointに到達できるかを確認するにはtcpdumpを用いる必要があります。
WireGuardは接続失敗するとパケットをドロップし、ログも残りません。パケットの到着を外から観察する必要があります。
Endpointで接続を受け付けるホストで、次のようにtcpdumpを起動しておき、
$ sudo tcpdump -ni any -vv 'udp port 51820'
PeerからEndpointに記述した実アドレスにpingを送ります。
実ネットワーク経路が到達不能な場合、tcpdumpの出力が出ません。
認証失敗
この例で、:51820に出力があるならおそらく認証失敗です。
認証に失敗している場合には、:51820はパケットを確認できるもののwg0デバイスをtcpdumpすると出力が出ない挙動になります。
$ sudo tcpdump -ni wg0 -vv 'ip or ip6'
認証は鍵設定で挙動が決まるため、適切な鍵を記述します。