自宅のネットワークにはパブリック IP がないため、WireGuard ネットワークの「サーバー」としてパブリック IP を持つサーバーが必要です。自宅には WireGuard ネットワークのノードとして機器が必要です。私たちはスマートフォンを使用して、4G ネットワーク下で VPN が正常に構築されているかを確認します。
IP アドレスの選択#
WireGuard のネットワーク構築には、あなたのデバイスのネットワークと衝突しない IP アドレス範囲を使用する必要があります。192.0.2.0/24、198.51.100.0/24、203.0.113.0/24 のようなアドレスは、文書や例のために「TEST-NET」として割り当てられており、通常は接続する他のネットワークでは使用されません。
以下の設定では、192.0.2.1、192.0.2.2、192.0.2.3 をそれぞれパブリックサーバー、自宅の Mac、iPhone に割り当てます。
サーバー上での WireGuard の設定#
WireGuard を使用するには、まず Linux カーネルがサポートしていることを確認する必要があります。modinfo wireguard
コマンドを使用して WireGuard が組み込まれているかを確認できます。また、uname -r
を使用してカーネルのバージョンが 5.6 以上であるかを確認できます。
wireguard のインストール#
Debian
apt install wireguard
他のシステムの参考:install
サーバー側の設定を完了する#
wireguard が正しくインストールされた後、以下のコマンドを使用して公開鍵と秘密鍵のペアを迅速に作成できます。
$ wg genkey | tee peer_A.key | wg pubkey > peer_A.pub && cat peer_A.key && cat peer_A.pub
/etc/wireguard/wg0.conf
を作成し、設定を記入します。
[Interface]
PrivateKey = (ここにサーバーの秘密鍵を入力)
Address = 192.0.2.1/24
ListenPort = 51820
[Peer]
# 自宅のMac
PublicKey = (ここにMacの公開鍵を入力)
AllowedIPs = 192.0.2.2/32, 192.168.1.0/24
[Peer]
# iPhone
PublicKey = (ここにiPhoneの公開鍵を入力)
AllowedIPs = 192.0.2.3/32
WireGuard では、各デバイスに手動で IP を割り当てる必要があり、各デバイスが一意の IP を持つことを確認する必要があります。Interface には現在のデバイスの設定が含まれており、「サーバー」にとって ListenPort は必須です。以下の各 Peer セクションは、このデバイスに接続できる他のデバイスを表します。
設定ファイルを保存した後、wg-quick up wg0
を使用して設定ファイルを有効にできます。wg-quick は自動的にルーティングテーブルを設定し、手動での設定は不要です。
51820 UDP ポートを開放することを忘れないでください。
自宅の Mac の設定#
/etc/wireguard/wg0.conf
を作成し、設定を記入します。
[Interface]
PrivateKey = (Macの秘密鍵)
Address = 192.0.2.2/24
DNS = 1.1.1.1
[Peer]
PublicKey = (サーバーの公開鍵)
AllowedIPs = 192.0.2.0/24
Endpoint = (サーバーのIPアドレス):51820
PersistentKeepalive = 10
ここでは、パブリックサーバーを唯一の Peer として設定し、PersistentKeepalive を設定して接続の維持を行います。ここでの AllowedIPs の役割は、WireGuard サブネットからのトラフィックがローカルの WireGuard 仮想ネットワークインターフェースによって処理されることを保証することです。
iPhone の設定#
WireGuard をインストール App Store からダウンロード
この設定はアプリストアのスクリーンショットを参考にできます。
注記#
予約アドレス範囲#
小話#
エラーメッセージが表示された場合:
/usr/bin/wg-quick: line 31: resolvconf: command not found [WireGuard | Debian]
シンボリックリンクを作成して解決できます。
ln -s /usr/bin/resolvectl /usr/local/bin/resolvconf
エラーメッセージが表示された場合:
[SELF-SOLVED] Unit dbus-org.freedesktop.resolve1.service not found
systemd-resolved サービスを起動することで解決できます。
systemctl start systemd-resolved.service
systemctl enable systemd-resolved.service
設定の詳細#
WireGuard は INI 構文を設定ファイル形式として使用します。設定ファイルは任意のパスに置くことができますが、絶対パスで参照する必要があります。デフォルトのパスは/etc/wireguard/wg0.conf
です。
設定ファイルの命名形式は${WireGuardインターフェースの名前}.conf
でなければなりません。通常、WireGuard インターフェース名はwg
で始まり、0
から番号が付けられますが、正規表現^[a-zA-Z0-9_=+.-]{1,15}$
に従う限り、他の名前を使用することもできます。
wg
コマンドを使用して VPN を手動で設定することもできますが、一般的にはwg-quick
を使用することをお勧めします。これは、より強力でユーザーフレンドリーな設定体験を提供し、設定ファイルを通じて管理できます。
[Interface]#
ローカル VPN 設定を定義します。例えば:
- ローカルノードがクライアントであり、自身のトラフィックのみをルーティングし、1 つの IP のみを公開します。
[Interface]
# Name = phone.example-vpn.dev
Address = 192.0.2.5/32
PrivateKey = <phone.example-vpn.devの秘密鍵>
ローカルノードが中継サーバーであり、トラフィックを他のピアに転送し、VPN サブネット全体のルーティングを公開します。
[Interface]
# Name = public-server1.example-vpn.tld
Address = 192.0.2.1/24
ListenPort = 51820
PrivateKey = <public-server1.example-vpn.tldの秘密鍵>
DNS = 1.1.1.1
# Name#
これは INI 構文の標準コメントであり、この設定部分がどのノードに属するかを示します。この部分の設定は WireGuard によって完全に無視され、VPN の動作には影響しません。
Address#
ローカルノードがどのアドレス範囲をルーティングすべきかを定義します。通常のクライアントの場合は、ノード自身の単一の IP に設定します(CIDR を使用して指定、例えば 192.0.2.3/32)。中継サーバーの場合は、ルーティング可能なサブネット範囲に設定します。
例えば:
通常のクライアント、自身のトラフィックのみをルーティング:
Address = 192.0.2.3/32
中継サーバー、他のピアにトラフィックを転送可能:
Address = 192.0.2.1/24
複数のサブネットまたは IPv6 サブネットを指定することもできます:
Address = 192.0.2.1/24,2001:DB8::/64
ListenPort#
ローカルノードが中継サーバーである場合、受信 VPN 接続をリッスンするためのポートを指定する必要があります。デフォルトのポート番号は 51820 です。通常のクライアントにはこのオプションは必要ありません。
PrivateKey#
ローカルノードの秘密鍵であり、すべてのノード(中継サーバーを含む)に設定する必要があります。他のサーバーと共有することはできません。
秘密鍵はwg genkey > example.key
コマンドを使用して生成できます。
DNS#
DHCP を通じてクライアントに DNS サーバーを宣言します。クライアントはここで指定された DNS サーバーを使用して VPN サブネット内の DNS リクエストを処理しますが、システム内でこのオプションを上書きすることもできます。例えば:
# 設定しない場合はシステムのデフォルトDNSを使用
# 単一のDNSを指定できます:
DNS = 1.1.1.1
# 複数のDNSを指定することもできます:
DNS = 1.1.1.1,8.8.8.8
Table#
VPN サブネットが使用するルーティングテーブルを定義します。デフォルトでは設定する必要はありません。このパラメータには注意が必要な 2 つの特別な値があります:
Table = off : ルートの作成を禁止
Table = auto(デフォルト値) : ルートをシステムのデフォルトテーブルに追加し、デフォルトルートに対する特別な処理を有効にします。
例えば:Table = 1234
MTU#
対等ノード(peer)への MTU(最大伝送単位)を定義します。デフォルトでは設定する必要はなく、一般的にはシステムが自動的に決定します。
PreUp#
VPN インターフェースを起動する前に実行されるコマンド。このオプションは複数回指定でき、順番に実行されます。
例えば:
ルートを追加:
PreUp = ip rule add ipproto tcp dport 22 table 1234
PostUp#
VPN インターフェースを起動した後に実行されるコマンド。このオプションは複数回指定でき、順番に実行されます。
例えば:
ファイルまたはコマンドの出力から設定値を読み取る:
PostUp = wg set %i private-key /etc/wireguard/wg0.key <(some command here)
ファイルにログを追加:
PostUp = echo "$(date +%s) WireGuard Started" >> /var/log/wireguard.log
WebHookを呼び出す:
PostUp = curl https://events.example.dev/wireguard/started
ルートを追加:
PostUp = ip rule add ipproto tcp dport 22 table 1234
iptablesルールを追加し、パケット転送を有効にする:
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
WireGuardに対等ノードのドメイン名のIPアドレスを再解析させる:
PostUp = resolvectl domain %i "~."; resolvectl dns %i 192.0.2.1; resolvectl dnssec %i yes
PreDown#
VPN インターフェースを停止する前に実行されるコマンド。このオプションは複数回指定でき、順番に実行されます。
例えば:
ファイルにログを追加:
PreDown = echo "$(date +%s) WireGuard Going Down" >> /var/log/wireguard.log
PostDown#
VPN インターフェースを停止した後に実行されるコマンド。このオプションは複数回指定でき、順番に実行されます。
例えば:
ファイルにログを追加:
PostDown = echo "$(date +%s) WireGuard Down" >> /var/log/wireguard.log
[Peer]#
1 つまたは複数のアドレスにトラフィックをルーティングできる対等ノード(peer)の VPN 設定を定義します。対等ノード(peer)は、トラフィックを他の対等ノード(peer)に転送する中継サーバーである場合もあれば、パブリックまたは内部ネットワークに直接接続されるクライアントである場合もあります。
中継サーバーは、すべてのクライアントを対等ノード(peer)として定義する必要があります。中継サーバー以外の他のクライアントは、NAT の背後にあるノードを対等ノード(peer)として定義することはできません。なぜなら、ルーティングが到達不可能だからです。自身のトラフィックのみをルーティングするクライアントは、中継サーバーを対等ノード(peer)として、直接アクセスが必要な他のノードを定義するだけで済みます。
設定例:
対等ノード(peer)がルーティング可能なクライアントであり、自身のトラフィックのみをルーティングします。
[Peer]
# Name = public-server2.example-vpn.dev
Endpoint = public-server2.example-vpn.dev:51820
PublicKey = <public key for public-server2.example-vpn.dev>
AllowedIPs = 192.0.2.2/32
対等ノード(peer)が NAT の背後にあるクライアントであり、自身のトラフィックのみをルーティングします。
[Peer]
# Name = home-server.example-vpn.dev
Endpoint = home-server.example-vpn.dev:51820
PublicKey = <public key for home-server.example-vpn.dev>
AllowedIPs = 192.0.2.3/32
対等ノード(peer)が中継サーバーであり、トラフィックを他の対等ノード(peer)に転送します。
[Peer]
# Name = public-server1.example-vpn.tld
Endpoint = public-server1.example-vpn.tld:51820
PublicKey = <public key for public-server1.example-vpn.tld>
# VPNサブネット全体のトラフィックをルーティング
AllowedIPs = 192.0.2.1/24
PersistentKeepalive = 25
Endpoint#
遠隔対等ノード(peer)のパブリックアドレスを指定します。対等ノード(peer)が NAT の背後にある場合や安定したパブリックアクセスアドレスがない場合は、このフィールドを無視します。通常は中継サーバーの Endpoint のみを指定すればよく、安定したパブリック IP を持つノードも指定できます。例えば:
IP で指定:
Endpoint = 123.124.125.126:51820
ドメイン名で指定:
Endpoint = public-server1.example-vpn.tld:51820
AllowedIPs#
この対等ノード(peer)が送信する VPN トラフィックのソースアドレス範囲を許可します。また、このフィールドはローカルのルーティングテーブルにおける wg0 にバインドされた IP アドレス範囲としても機能します。対等ノード(peer)が通常のクライアントの場合は、ノード自身の単一の IP に設定します。対等ノード(peer)が中継サーバーの場合は、ルーティング可能なサブネット範囲に設定します。カンマ(,)を使用して複数の IP またはサブネット範囲を指定できます。このフィールドは複数回指定することもできます。
データパケットのルーティング方法を決定する際、システムは最も具体的なルートを最初に選択し、一致しない場合はより広範なルートを選択します。例えば、192.0.2.3 宛てのデータパケットに対して、システムは最初に 192.0.2.3/32 の対等ノード(peer)を探し、次に 192.0.2.1/24 の対等ノード(peer)を探します。
例えば:
対等ノード(peer)が通常のクライアントであり、自身のトラフィックのみをルーティングします:
AllowedIPs = 192.0.2.3/32
対等ノード(peer)が中継サーバーであり、他の対等ノード(peer)にトラフィックを転送可能:
AllowedIPs = 192.0.2.1/24
対等ノード(peer)が中継サーバーであり、外部トラフィックと VPN トラフィックの両方を転送可能:
AllowedIPs = 0.0.0.0/0,::/0
対等ノード(peer)が中継サーバーであり、自身と他の対等ノード(peer)のトラフィックをルーティング可能:
AllowedIPs = 192.0.2.3/32,192.0.2.4/32
対等ノード(peer)が中継サーバーであり、自身のトラフィックとその所在する内部ネットワークのトラフィックをルーティング可能:
AllowedIPs = 192.0.2.3/32,192.168.1.1/24
PublicKey#
対等ノード(peer)の公開鍵であり、すべてのノード(中継サーバーを含む)に設定する必要があります。他の対等ノード(peer)と同じ公開鍵を共有することができます。
公開鍵は、wg pubkey < example.key > example.key.pub
コマンドを使用して生成できます。ここで example.key は上記で生成した秘密鍵です。
PersistentKeepalive#
接続が NAT の背後にある対等ノード(peer)からパブリックに到達可能な対等ノード(peer)に向かう場合、NAT の背後にある対等ノード(peer)は定期的に出力 ping パケットを送信して接続性を確認する必要があります。IP が変更された場合、Endpoint が自動的に更新されます。
例えば:
ローカルノードと対等ノード(peer)が直接接続可能:このフィールドは指定する必要はありません。接続確認は不要です。
対等ノード(peer)が NAT の背後にある:このフィールドは指定する必要はありません。接続の維持はクライアント(接続の発起者)の責任です。
ローカルノードが NAT の背後にあり、対等ノード(peer)がパブリックに到達可能:このフィールド PersistentKeepalive = 25 を指定する必要があります。これは 25 秒ごとに ping を送信して接続を確認することを意味します。
peers.conf ファイルを共有する#
ある peer の公開鍵がローカルインターフェースの秘密鍵とペアリングできる場合、WireGuard はそのpeer
を無視します。この特性を利用して、すべてのノードで同じpeer
リストを共有できます。各ノードは単独で[Interface]
を定義するだけで済みます。リストに本ノードが含まれていても無視されます。具体的な方法は以下の通りです:
各対等ノード(peer)には、[Interface]
部分の設定のみを含む独自の/etc/wireguard/wg0.conf
ファイルがあります。
各対等ノード(peer)は、すべての peer を含む同じ/etc/wireguard/peers.conf
ファイルを共有します。
wg0.conf ファイルには、以下の内容の PostUp フックを設定する必要があります。
PostUp = wg addconf /etc/wireguard/peers.conf