Ubuntu Weekly Recipe

第614回 WireGuardでVPNサーバーを構築する

この記事を読むのに必要な時間:およそ 4 分

WireGuardの起動

サーバー上で,WireGuardのサービスを起動しましょう。WireGuardの起動や終了には,wg-quickというラッパースクリプトを使用します。systemdのユニット名は,⁠wg-quick@使用するインターフェイス名」となっています。sytemctlコマンドで,サービスを有効化してください。

wg-quick@wg0を有効化し,起動する

$ sudo systemctl enable wg-quick@wg0
$ sudo systemctl start wg-quick@wg0

ipコマンドでインターフェイスが生成されていることを確認しましょう。wg0.confで設定したIPアドレス(10.0.0.1)が割り振られていれば成功です。

ipコマンドでインターフェイスの状態を確認する

$ ip a
(...略...)
4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none 
    inet 10.0.0.1/32 scope global wg0
       valid_lft forever preferred_lft forever

クライアントからVPNへの接続

クライアントからVPNへ接続するには,⁠wg-quick up インターフェイス名」コマンドを実行します。

VPNの接続を確立する

$ sudo wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.0.0.2 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] ip -4 route add 10.0.0.0/24 dev wg0

サーバーと同様に,ipコマンドでクライアントのインターフェイスの状態を確認してみましょう。クライアント上でもwg0が作成され,10.0.0.2のIPアドレスが割り当てられていれば成功です。

クライアントのインターフェイスの状態を確認する

$ ip a
(...略...)
4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none 
    inet 10.0.0.2/32 scope global wg0
       valid_lft forever preferred_lft forever

接続が確立できたら,クライアントからサーバーに対してPingを打って,応答が返ってくることを確認してみましょう。またその状態で,サーバー上でwgコマンドを実行してみてください。現在のコネクションの状態が表示されます。ハンドシェイクが成功し,データの送受信が発生していれば成功です。

wgコマンドでVPN接続の状態を確認する

$ sudo wg
interface: wg0
  public key: (サーバーの公開鍵)
  private key: (hidden)
  listening port: 51820

peer: (クライアントの公開鍵)
  endpoint: クライアントのグローバルIPアドレス:クライアントのポート
  allowed ips: 10.0.0.2/32
  latest handshake: 41 seconds ago
  transfer: 564 B received, 476 B sent

LAN内へのルーティングを行うには

インターネットから家庭内へのVPNの確立には成功しました。しかしこの設定だけですと,WireGuardのネットワーク内でしか通信ができません。通常,VPNはインターネットからローカルネットワークに接続する目的で構築します。つまり,WireGuardのネットワークから家庭内LAN(192.168.1.0/24)へのルーティングができないと,その意味がありません。というわけで,ルーティングを設定します。

Ubuntuはデフォルトで,パケットのフォワードが禁止されています。サーバーの「/etc/sysctl.conf」をエディタで開き,コメントアウトされている「net.ipv4.ip_forward=1」のコメントアウトを解除してください。

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1   ← 行頭の # を消してコメントを解除する

sysctlコマンドを実行し,変更を反映します。

$ sudo sysctl -p

WireGuardのサーバー設定には「PostUp」⁠PostDown」という項目があり,インターフェイスの起動/終了時に任意のコマンドを実行させることができます。ここにiptablesコマンドを指定して,インターフェイスが起動している間だけ,iptablesにIPマスカレードの設定を追加するようにします。⁠/etc/wireguard/wg0.conf」の[Interface]セクションに以下の内容を追記してください。その後,WireGuardを再起動してください。

サーバーのwg0.confにIPマスカレードを行うiptablesのルールを追加する。なおwlan0は実際に使っているNICの名前に置き換えること

PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o wlan0 -j MASQUERADE

WireGuardを再起動すると,iptablesのPOSTROUTINGチェインにルールが追加される

$ sudo systemctl restart wg-quick@wg0

$ sudo iptables -L -n -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  0.0.0.0/0            0.0.0.0/0  

これでサーバー側の設定は完了です。

最後に,クライアントのAllowedIPsにLAN内のIPレンジを追加します。クライアントのPeer設定にあるAllowedIPsは,そのPeerを使ってパケットを送信する宛先IPアドレスのリストです。ここにLAN内のプライベートIPアドレスを追記することで,LAN内へのパケットがWireGuardを経由してルーティングされることになります。

クライアントのwg0.confにAllowedIPsを追記する

AllowedIPs = 10.0.0.0/24, 192.168.1.0/24  ← LAN内で使われているIPアドレスをカンマ区切りで追記する

wg0を一度終了してから,再起動する

$ sudo wg-quick down wg0
$ sudo wg-quick up wg0

LAN内の他のサーバーやPCに,VPN経由で接続できることを確認してみてください。

なおAllowedIPsに0.0.0.0/0と書けば,すべてのパケットをWireGuard経由で送信できます。WebブラウザからインターネットへのアクセスをVPN経由にしたい場合などに有効です。

WireGuardには,Linuxカーネルのメインラインにマージされていること,セットアップの容易さ,高いパフォーマンスといったメリットがあります。また本記事ではLinuxのコマンドラインからの使い方のみを紹介しましたが,Windows,Mac,Androidなどのクライアントも用意されているため,デスクトップPCやスマートフォンからVPNへ接続することも簡単です。今後LinuxでVPNサーバーを構築する際は,WireGuardの利用をぜひ検討してみてください。

著者プロフィール

水野源(みずのはじめ)

Ubuntu Japanese Teamメンバー。理想のフリーデスクトップ環境を求めて東へ西へ……のはずが,気がついたら北の大地で就職していたインフラ寄りのエンジニア。最近レンズ沼にハマる。