baicai

白菜

一个勤奋的代码搬运工!

WireGuard を使用して VPN を構築し、自宅の内部ネットワークにアクセスする

自宅のネットワークにはパブリック 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 からダウンロード

この設定はアプリストアのスクリーンショットを参考にできます。

注記#

保留アドレス範囲#

保留 IP アドレス

小話#

エラーメッセージが表示された場合:

/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}$に従う限り、問題ありません。

VPN を手動で設定するためにwgコマンドを使用することもできますが、一般的にはwg-quickの使用が推奨されます。これは、より強力でユーザーフレンドリーな設定体験を提供し、設定ファイルを通じて設定を管理できます。

[Interface]#

ローカル VPN 設定を定義します。例えば:

  1. ローカルノードがクライアントの場合、自身のトラフィックのみをルーティングし、1 つの IP のみを公開します。
[Interface]
# Name = phone.example-vpn.dev
Address = 192.0.2.5/32
PrivateKey = <phone.example-vpn.devの秘密鍵>

ローカルノードが中継サーバーの場合、他のピア(peer)にトラフィックを転送し、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

中継サーバー、他のピア(peer)にトラフィックを転送可能:

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
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。