カテゴリー
Debian LinuxでもWireGuardで自宅VPNネットワークを構築するやり方
※ 当ページには【広告/PR】を含む場合があります。
2022/03/02

VPN(Virtual Private Network)接続はその名の通りで、ソフトウェア的に特定の人のみが利用できる仮想の専用ネットワークを構築する技術です。
VPNというと一般の個人レベルユーザーにはかなり導入の敷居が高く、専用のルーターを設置したり、管理者として通信のトンネリング・暗号化など、通信セキュリティ面で十分な知識をもって扱わないと不安だったりと、気軽に扱うこともできない代物でした。
近年、注目のVPNオープンソースプロジェクトとして注目を集めてきている
ということで、今回はDebianOS上で、WireGuardサーバーを立ち上げておいて、適当なクライアントでSSH接続させるまでの手順を説明していきましょう。
WireGuardサーバーをDebianOS上に構築する
今回の構成の模式図は以下のようになります。
1011x487

まずは自宅のWireGuardサーバー機のほうからインストールしていきます。
WireGuardアプリケーションのインストール方法はOSごとに違いますので
手元で試したのは以下の環境の通りです。
#👇基本OS情報
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 11 (bullseye)
Release: 11
Codename: bullseye
#👇Debianのマイナーバージョン情報
$ cat /etc/debian_version
11.2
#👇Linuxカーネルの情報
$ uname -srv
Linux 5.10.0-10-amd64 #1 SMP Debian 5.10.84-1 (2021-12-08)
では早速サーバー機にwireGuardをインストールします。
$ sudo apt update
$ sudo apt install wireguard
これでDebianにWireGuardがインストールされました。
$ wg --version
wireguard-tools v1.0.20210223 - https://git.zx2c4.com/wireguard-tools/
インストールしたら設定を反映させるために一度再起動しておいたほうが良いでしょう。
WireGuardのクレデンシャルの設定
次にWireGuardを使うための公開鍵と秘密鍵を生成するステップに移ります。
WireGuardにもSSHと同じように秘密鍵と公開鍵をセットで利用することになります。
ただし、WireGuardの認証形式は、SSHのようにサーバーに公開鍵、クライアントに秘密鍵を持たせて2つを照合するのではなく、サーバとクライアントの双方に以下のようなクレデンシャルを設定する必要があります。
+ wgserver.key サーバ用秘密鍵
+ wgserver.pub サーバ用公開鍵
+ wgclient.key クライアント用秘密鍵
+ wgclient.pub クライアント用公開鍵
これらのクレデンシャルのセットがVPN接続認証に必要になります。 このクレデンシャルは、wgコマンドから作成をすることができます。
クレデンシャルの生成・アクセスには通常のユーザーからは制限されているので、以下の操作はルートユーザー(su)から操作することにします。
$ su
#👇以降ではルートユーザーで操作
># cd /etc/wireguard
#👇サーバー用のキーを生成
># wg genkey > wgserver.key
># wg pubkey < wgserver.key > wgserver.pub
#クライアント用のキーを生成
># wg genkey > wgclient.key
># wg pubkey < wgclient.key > wgclient.pub
#👇ルートユーザー以外の秘密鍵のファイル操作権限を制限
># chmod 600 wgserver.key
># chmod 600 wgclient.key
#suから抜ける
$ sudo ls -la /etc/wireguard/
-rw------- 1 root root 45 2月 28 11:58 wgclient.key
-rw-r--r-- 1 root root 45 2月 28 11:58 wgclient.pub
-rw------- 1 root root 45 2月 28 11:56 wgserver.key
-rw-r--r-- 1 root root 45 2月 28 11:57 wgserver.pub
これでWireGuardクレデンシャルの準備は完了です。
ちなみに、suで管理者ルートモードに入って作業するのがなんだかダサいと思われる方は、
tee
/etc/wireguard/
$ wg genkey | sudo tee /etc/wireguard/wgclient.key
$ sudo cat /etc/wireguard/wgclient.key | wg pubkey | sudo tee /etc/wireguard/wgclient.pub
$ sudo chmod 600 /etc/wireguard/wgclient.key /etc/wireguard/wgclient.pub
またコマンドでクレデンシャルを生成するのが面倒な方は、オンラインツールの
クレデンシャルの生成はお好みの方法を選択できるのですが、その後生成した鍵は失くさないようにきちんと管理を心がけましょう。
【サーバー側】WireGuardのconfファイルを設定する
次にWireGuardサーバー側で内部confファイルを設定していきます。
/etc/wireguard/
wg0.conf
今回は例として、WireGuardサーバー側に
10.0.17.1
10.0.17.2
なお、現在のLANネットワークに競合するようなプライベートIPが無い限りはこのWireGuardネットワークのIP値は自由に割り振ることが可能です。
[Interface]
Address = 10.0.17.1/32
PrivateKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(※wgserver.keyの中身)
MTU = 1420
ListenPort = 51820
[Peer]
PublicKey = yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy(※wgclient.pubの中身)
AllowedIPs = 10.0.17.2/32
WireGuardの設定ファイルの簡単な書式だけ説明しておくと、
[Interface]: 自分側の設定
Address: WireGuardで使用するIPアドレスを指定
MTU: 接続時のMTU値。
デフォルトでは1420が設定される。
環境によってはネットワークが不安定動作 (切断を繰り返す等)
する場合、1400や1380に下げて試す
PrivateKey: 秘密鍵(.key)の中身を貼り付ける
ListenPort: WireGuardのサービスポート番号。
サーバー側のデフォルトでは51820
DNS: 優先するDNSサーバーを指定できる
PostUp: WireGuardの起動時に実行するコマンドを記述。
ここでiptablesを設定することでポートフォワーディングなどを構築する
PostDown: 停止時に実行するコマンドを記述
[Peer]: 相手側の設定
PublicKey: 相手側の秘密鍵(.key)からペアリングした
公開鍵(.pub)の中身を貼り付ける
AllowedIPs: 相手がクライアントならば、VPN接続を許可したい
クライアントのIPリストを記述する。
対向がサーバーの場合にはサーバー側ネットワーク内にある接続機器のうちで
通信を許可するIPリストになる
Endpoint: (クライアントのときのみ使用)サーバーのIPとポートを指定
サーバーのconfファイルを設定し終えたら、一度試しにWireGuardの起動してみましょう。
WireGuardの起動や終了は、
wg-quick
本番前のWireGuardサーバーをデバッグするならwg-quickをコマンドとして利用して起動状態をターミナルから確認できます。
$ sudo wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.0.17.1/32 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] ip -4 route add 10.0.17.2/32 dev wg0
正常にWireGuardが立ち上がりました。
ipコマンドでもWireGuardインターフェースが正常に生成されていることを確認しておきます。
$ ip address
(...略...)
12: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet 10.0.17.1/32 scope global wg0
valid_lft forever preferred_lft forever
wg0.confで指定していたサーバー側のIPアドレス(10.0.17.1)が割り振られていればWireGuardサーバーの起動に成功してます。
WireGuardサーバー落とす場合には、
$ sudo wg-quick down wg0
[#] ip link delete dev wg0
では問題無さそうですので、WireGuardのインターフェースwg0を使って本番サービスとして常駐化させてみます。
ここではシステムデーモンのユニット名は
$ sudo systemctl enable wg-quick@wg0
$ sudo systemctl start wg-quick@wg0
これで設定ファイルに異常がなければ以下のように起動していることが確認できます。
$ systemctl status wg-quick@wg0
● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
Loaded: loaded (/lib/systemd/system/wg-quick@.service; disabled; vendor preset: enabled)
Active: active (exited) since Mon 2022-02-28 13:43:27 JST; 1min 2s ago
Docs: man:wg-quick(8)
man:wg(8)
https://www.wireguard.com/
https://www.wireguard.com/quickstart/
https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8
https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8
Process: 1215 ExecStart=/usr/bin/wg-quick up wg0 (code=exited, status=0/SUCCESS)
Main PID: 1215 (code=exited, status=0/SUCCESS)
CPU: 37ms
サーバーサイドのポートフォワード(IPv4)の設定確認
先程までの内容だと、実はまだ十分なVPN接続が確立できていません。
WireGuardはVPN通信のための仮想IPアドレスとwgインタフェースが内部で作成されて動作します。
素のままだと、インターネットからWireGuard VPNまでの通信は確立できるようになるのですが、肝心のWireGuardから自宅LAN側の他のネットワーク機器と通信ができません。
そこでWireGuard(VPN)ネットワークから自宅LAN(192.168.0.1等)に存在する他の機器へのルーティングを作成しましょう。
まずパケットのポートフォワーディングを有効にしておく必要があります。
そこでサーバー機の
/etc/sysctl.conf
#...中略
#👇コメントアウトを外す
net.ipv4.ip_forward=1
#...以下省略
こうすることで、WireGuardインタフェースとLinuxサーバーの標準インタフェース間で通信が正常に確立されるようになります。
sysctl.confを書き換えたら以下のコマンドで変更を反映させます。
$ sudo sysctl -p
次にWireGuardサーバー機で、起動と終了時にIPマスカレードを行うためのiptablesルールをwg0.confの
PostUp
PostDown
[Interface]
#...中略
#👇追加
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o enp3s0(※) -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o enp3s0(※) -j MASQUERADE
#...略
なお手元の環境では-oオプションに
enp3s0
これでwg0を再起動して、
iptables
$ sudo systemctl restart wg-quick@wg0
$ sudo iptables -L -n -t nat
#...略
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0
#...略
NATを越えるために〜ブロードバンドルータのポート開放
さて、折角WireGuardサーバーがお宅内に立てても、外部から繋げないと意味がありません。
このため外部からのアクセスを遮断するのためにブロードバンドルーターは全てのポートを閉じていると思いますが、WireGuard用にポートを一つ開けておくが必要になります。
最近のブロードバンドルーターには必ずと言っていいほどポートフォワーディング設定を手動で行える機能があると思いますので特にどの機種が良いというのは無いのですが、ここでは手持ちでコストパフォーマンスの良さから
Wi-Fi高効率通信によりたくさん繋いでも安定のWiFi環境 TP-Link Wi-Fi無線LANルーター デュアルバンド ギガビット Archer A10
従来のOpenVPNなどでは、ルーターにもポートフォワーディング設定をする必要がありました(今はどうなのかな....?)。
NAT転送の設定手順の詳細はルーター製品の取扱説明書を良く読んで貰うとして、TP-LINK Archerルーターの場合、ルーターの管理画面にログインをし、
[詳細設定] > [NAT転送] > [仮想サーバー]
そして以下のように新しいNAT転送ルールを追加します。
675x472

これで外部からWireGuardサーバーへアクセスする場合の設定は完了です。
なお、TP-LINKルーターでNAT転送指定するWireGuardサーバー機のプライベートIPは固定する必要があるので、MACアドレスで固定IPをバインドしているかを確認しましょう。
余談〜ラズパイでPiVPNを使ったVPNサーバーの構築
WireGuardサーバーを立ち上げるのに、設定ファイルをアレヤコレヤと手動で設定するのは多少骨が折れます。
ラズパイを持っていて、それをWireGuardサーバーにしたいというかたがいらっしゃるなら、
PiVPNはVPNの設定をCUIからYes/Noでポチポチと設定作業できるようになっているだけで、WireGuardの中身としては今回手動で設定していることと同じことをラズパイ内部で処理しているようです。
WireGuardクライアントを試す
さて、先程のパートでは自宅にWireGuardサーバーを構築しとりあえず起動状態しておくところまで解説してみました。
早速どこか自宅外のネットワークから、自宅のWireGuardに接続してみたい衝動に駆られますが、実はここまでWireGuardを解説しておきながら
折角ここまでWireGuard VPNを構築したのでVPN接続の雰囲気だけでも試してみることにします。
ということでWireGuardクライアントから、自宅外からではなく内部のネットワークからWireGuardサーバーにアクセスし、ローカルでVPN接続が出来ているかを検証していきます。
NAT越えしないローカルでWireGuardを試す場合、以降で説明するクライアント機のconfファイルのEndpointを、
#....
[Peer]
#....
#EndPoint = [グローバルIPアドレス]:51820
#👇ローカルでWireGuardを試す場合
EndPoint = [サーバー機のプライベートIPアドレス]:51820
#....
で指定してあげると、ローカルVPNモードで接続可能です。
別のLinuxOSクライアントで試す
現在、WireGuardクライアントはほぼすべてのOSと言っていいほど充実した対応になっています。
各OSごとのWireGuardのインストール方法は
ここではなにか別のLinuxOSをクライアントにしてからWireGuard VPNに接続してみます。
まずはWireGuardクライアント側にもconfファイルを設定します。
confファイルの書式作法としては
先程のサーバーの設定と同様に
/etc/wireguard/wg0.conf
[Interface]
PrivateKey = vvvvvvvvvvvvvvvvvvvvvv (※wgclient.key)
Address = 10.0.17.2/32 (※クライアントのIPアドレス)
ListenPort = 51820
[Peer]
PublicKey = zzzzzzzzzzzzzzzzzzzzzzz (※wgserver.pub)
#EndPoint = [(自宅の)グローバルIPアドレス]:51820
EndPoint = [WireGuardサーバー機のプライベートIPアドレス]:51820
AllowedIPs = 0.0.0.0/0 (※WireGuardサーバー側にある通信したいIPアドレス)
クライアント側だと、
[Interface]
[Peer]
[Interface]
wgclient.key
そしてサーバー側で許可(
AllowedIPs
10.0.17.2
クライアントの
[Peer]
wgserver.pub
EndPoint
後はサーバー側でアクセスしたいIPのリストを
AllowedIPs
ここでは深く考えず、
0.0.0.0/0
10.0.17.1/32
ではWireGuardクライアントを立ち上げてみましょう。
$ sudo wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.0.17.2/32 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] wg set wg0 fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
...エラーが出なればこれでVPN接続できたようです。
適当にクライアントからサーバー機にpingしてみると、
$ ping 10.0.17.1
PING 10.0.17.1 (10.0.17.1) 56(84) bytes of data.
64 bytes from 10.0.17.1: icmp_seq=1 ttl=64 time=674 ms
64 bytes from 10.0.17.1: icmp_seq=2 ttl=64 time=2.10 ms
64 bytes from 10.0.17.1: icmp_seq=3 ttl=64 time=2.29 ms
#.....
--- 10.0.17.1 ping statistics ---
15 packets transmitted, 15 received, 0% packet loss, time 32ms
rtt min/avg/max/mdev = 1.820/46.805/674.177/167.672 ms
接続が確立できているようです。
他方サーバー側で
wg
$ sudo wg
interface: wg0
public key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
private key: (hidden)
listening port: 51820
peer: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
endpoint: xxx.xxx.xxx.xxx:51820
allowed ips: 10.0.17.2/32
latest handshake: 1 minute, 16 seconds ago
transfer: 11.80 KiB received, 18.87 KiB sent
確かにクライアント(
10.0.17.2
余談〜おらが村のインターネット事情:グローバルIP...じゃない?
VPN接続に欠かせないの要素の一つが、外部から家庭内LANにアクセスするための
著者も数年前に引っ越ししてきた傍ら、現在の周りにほぼ田園しかない集落でインターネットをどうするか町役場に相談したところ、
で、そこからしばらく経ち、自宅VPNを構築しようとしてルーター設定を確認したところ、
331x347

WAN側のIPが、なんだかプライベートIPで割り振られているのに気づきました。
こちらの
契約前に聞いておくべきだったのですが、
この忌まわしき「町内光回線」は3年間契約で、もう少しで契約満期なので、とりあえず契約が終わるのを待ってから別のグローバルIPの使えるインターネット回線への乗り換えを考えております。
当然、ドが付くくらいの田舎ですので、グローバルIPの付くインターネットサービスという選択肢は限られております。
グローバルIPを手頃な値段で利用したいのであれば、モバイル通信回線のキャリア各社の提供する
例えば、
☆家でも外でも利用可能なWi-Fiルーター☆ DTI WiMAX 2+
グローバルIPオプションの付いているWiMax2+プランは他にもあり、料金的に少しだけお得な
☆割安なグローバルIP固定プラン☆
ただし、BIGLOBE WiMAX 2+では
まとめ
今回はWireGuardを使った簡単に構築できるVPN接続の話をまとめてみました。
これまで「ちょっと敷居が高くて自宅VPNをやってみたいけど...」と、ためらっていたかたも、この際WireGuardを試してみるのも一興かと思います。
参考サイト
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー