WireGuardを利用したVPN構築
はじめに
今回は、簡単にVPNを構築できる 【WireGuard】 を実際に構築してみたいと思います。
WireGuardとは
以下は、公式ホームページからの抜粋です。
WireGuard® is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPsec, while avoiding the massive headache. It intends to be considerably more performant than OpenVPN.
高速・シンプル・高セキュリティを売りにした新しいVPNツールのようです。
確かにIPsecやOpenVPNなどのように、今までメジャーだったものと比較すると、シンプルだなとは思いました。
※理解はまだまだ浅いですが。
今回の構成
自宅では、固定グローバルIPを持っていないので、AWS上に2台のサーバを用意し、VPNで繋いでみたいと思います。
項目 | サーバA | サーバB |
---|---|---|
OS | AmazonLinux2 | AmazonLinux2 |
外部IPアドレス | 13.115.170.181 | 43.207.47.224 |
内部IPアドレス | 192.168.1.244 | 172.16.1.91 |
VPN用IPアドレス | 172.16.12.1 | 172.16.12.2 |
WireGuard利用ポート | 44455 | 55544 |
秘密鍵ファイル名 | serverkey | clientkey |
公開鍵ファイル名 | serverpubkey | clientpubkey |
※外部グローバルIPアドレスは、EC2起動時に自動で払い出されるIPアドレスを利用しています。
図にするとこんな感じです。
事前準備(パッケージのインストール)
WireGuardのパッケージは、デフォルトではインストールされていないため、別途インストールする必要があります。
標準リポジトリではなくて、拡張リポジトリ(EPEL)からインストールすることができるので、インストールします。
以下は、AmazonLinux2の場合の手順です。
$ sudo amazon-linux-extras install epel -y
$ sudo yum install wireguard-tools
WireGuardの設定ファイルが格納されるのは/etc/wireguard/
ディレクトリですが、パッケージをインストールするだけでは何もファイルはありませんでした。
今回は、上記ディレクトリをワークディレクトリとします。
WireGuard の設定
1. 鍵の作成
WireGuardは共通鍵を利用してVPNを張るので、接続元と接続先それぞれで秘密鍵と公開鍵を作成します。
WireGuardでは、wg
コマンドを使って鍵を作成することができます。
# サーバAでの作業
# 秘密鍵の作成
$ wg genkey > serverkey #rootで実行
# 秘密鍵から公開鍵を作成
$ wg pubkey < serverkey > serverpubkey #rootで実行
# 作成したファイルの権限を変更
$ chmod 0600 server* #rootで実行
※サーバBでも同様に鍵を作成します。名前を前述の通り、「clientkey」と「clientpubkey」としています。
2. ネットワークインターフェイスの作成
WireGuardで利用するネットワークインターフェイスを作成します。
# サーバAでの作業
$ ip link add dev wg0 type wireguard #rootで実行
# 以下のように作成されます。
$ ip a #rootで実行
3: wg0: <POINTOPOINT,NOARP> mtu 1420 qdisc noop state DOWN group default qlen 1000
link/none
# 作成したインターフェイスにIPアドレスを設定します。
$ ip addr add dev wg0 172.16.12.1/24 #rootで実行
$ ip a #rootで実行
3: wg0: <POINTOPOINT,NOARP> mtu 1420 qdisc noop state DOWN group default qlen 1000
link/none
inet 172.16.12.1/24 scope global wg0
valid_lft forever preferred_lft forever
※サーバBでも同様に作成します。設定は、前述の通りとします。
3. WireGuardの設定
作成したインターフェイスに、WireGuardの設定をしていきます。
なお、WireGuardがVPNを張る時のプロトコルは、「UDP」 を利用しています。
# サーバAでの作業
# WireGuardで待ち受けるポート番号と使用する秘密鍵を指定します。
$ wg set wg0 listen-port 44455 private-key ./serverkey #rootで実行
#サーバBで作成した公開鍵の情報がこの後必要になるため、以下のコマンドをサーバーBで実行して、その結果をメモします。
$ cat clientpukey #サーバBで実行
BBBBBBBB #公開鍵情報
$ wg set wg0 peer BBBBBBBB persistent-keepalive 25 allowed-ips 172.16.12.2/32 endpoint 43.207.47.224:55544 #rootで実行
※サーバBでも同様に設定します。設定は、前述の通りとします。
【補足】
persistent-keepalive: パーシステントの持続時間の設定(秒)。必須ではなく、デフォルトは「off」。指定した時間間隔で、空のパケットをPeerに送信する。
allowed-ips: この説明は、別記事にしたいと思います。
endpoint: 対向のグローバルIPアドレスとポートを指定
以下のコマンドを実行することで、設定の確認が可能です。
【Interface】が自分自身の設定で、【Peer】が対向の設定になります。
Peerは複数設定することが可能なので、1対多でVPNを張ることが可能です。
$ wg showconf wg0 #rootで実行
[Interface]
ListenPort = 44455
PrivateKey = AAAAAAAA
[Peer]
PublicKey = BBBBBBBB
AllowedIPs = 172.16.12.2/32
Endpoint = 43.207.47.224:55544
PersistentKeepalive = 25
4. インターフェイスの起動
サーバAとBの両方で、以下コマンドを実行してインターフェイスを起動させます。
$ ip link set dev wg0 up
5. 疎通確認
ここまでの手順でVPNは張れたので、疎通確認します。
$ ping 172.16.12.2
PING 172.16.12.2 (172.16.12.2) 56(84) bytes of data.
64 bytes from 172.16.12.2: icmp_seq=1 ttl=255 time=0.626 ms
64 bytes from 172.16.12.2: icmp_seq=2 ttl=255 time=0.838 ms
64 bytes from 172.16.12.2: icmp_seq=3 ttl=255 time=0.715 ms
ping
が通っていることが確認できました。
ちなみに、wg
コマンドを実行する事で、Peerとの通信状況を確認することができます。
$ wg #rootで実行
interface: wg0
public key: AAAAAA
private key: (hidden)
listening port: 44455
peer: BBBBBB
endpoint: 43.207.47.224:55544
allowed ips: 172.16.12.2/32
latest handshake: 2 minutes, 13 seconds ago
transfer: 980 B received, 1.15 KiB sent
persistent keepalive: every 25 seconds
おわりに
取り敢えずWireGuardについて知りたいだけなら十分だと思っていますが、実用を考えた時はこれだけでは不十分です。
もう少し踏み込んだ内容は、別の記事で書きたいと思います。
※ここまで書くだけで疲れました。
ちなみに、今回検証してみてどうしてもわからなかったことがあります。
AWS上に構築したEC2 2台のセキュリティグループは、私のクライアント端末からのSSHのみ許可する設定していたにも関わらず、EC2同士でVPNを張れているように見えます。
本来であれば、UDPのポートに対する通信許可をしてあげないといけないのでは?と思っていたのですが。。。
もしわかる方いらっしゃったらコメントください。
Discussion