APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

【AP Tech Blog Week】AWS環境のEC2にWireGuard + IPv6を用いて接続してみた

本記事はAP Tech Blog Weekのものになります。

目次

はじめに

こんにちは、エーピーコミュニケーションズ iTOC事業部MBS部の岸野です。

今回はAWS環境のEC2にWireGuardとIPv6を用いて接続してみようと思います。 AWS EC2へ外部からのアクセス方法と言えばEC2にElasticIPやグローバルIPの割り当ててアクセスしたり、 DirectConnetcやSite-to-SiteVPN、Client VPNといった物を用いてアクセスするケースが一般的かと思います。

今回はそのSite-to-SiteVPNとしても利用でき、Client VPNとしても利用できるWireGuard使用し、そのWireguardのトンネルをIPv6を使用して構築したいと思います。

WireGuardとは

公式サイトを覗いてみると以下の説明がありました。

WireGuard: fast, modern, secure VPN tunnel

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. WireGuard is designed as a general purpose VPN for running on embedded interfaces and super computers alike, fit for many different circumstances. Initially released for the Linux kernel, it is now cross-platform (Windows, macOS, BSD, iOS, Android) and widely deployable. It is currently under heavy development, but already it might be regarded as the most secure, easiest to use, and simplest VPN solution in the industry.

簡単にまとめると

  • シンプルで無駄のないVPN
  • IPsecやOpenVPNよりもパフォーマンスが良いことを目指している
  • 最初はLinux向けでしたが、今は色んなプラットフォームで使用ができる

とのことです。

今回構築してみる構成図

構成図1
上記図のような構成を構築していきます。 図中の「EC2-WireGuard」にはIPv4でルーティングさせ、別のVPCSubnetとの通信をIPv4で可能にしてみます。

構成図2
しかし、今回は図左側のオフィスIPv6環境が用意できなかったので、こちらもAWSで用意してみます。

VPC IPv6設定

まず、VPCを作成します。

今回は「Amazon 提供の IPv6 CIDR ブロック」を使用します。

IPv4はお好みの値で良いですが、今回は10.0.0.0/16を使用します。

次にサブネットを作成します。

Amazon提供のIPv6CIDRブロックは/56で提供されます。 1つのサブネットに/56を割り当ててもよいのですが、今回は/64で割り当てを行います。

こちらもIPv4はお好みの値で良いですが、今回は10.0.1.0/24を使用します。

インターネットゲートウェイ、ルートテーブルの変更

インターネットゲートウェイをいつも通りVPCにアタッチします。

ルートテーブルに関しては送信先「::/0」をアタッチしたインターネットゲートウェイに向けます。

EC2 起動

次にEC2を起動させます。

今回は以下を選択しました。

  • OS:Ubuntu, 22.04 LTS*1
  • インスタンスタイプ:t3nano*2
  • キーペア:自分の物、もしくは新規作成する
  • VPCとサブネットは先ほど構築した物を設定
  • パブリックIPの自動割り当て:無効化
  • IPv6 IP を自動で割り当てる:無効化
  • セキュリティグループを作成

初回のWireguardセットアップはIPv6でSSHするのでキーペア選択しています。

IPv6は後ほど手動で割り振るので一旦無効化でEC2作成します。

セキュリティグループはSSHを::/0で設定しました。 UDPのカスタムポート51820を「Client-WireGuard」のIPv6アドレスで設定すると接続元を絞れます。

その他はデフォルトです。

EC2 IPv6アドレスの固定

起動できたらIPv6アドレスの固定を行います。

下記画像のアクション>ネットワーキング>IPアドレスの管理からアドレス管理の画面に遷移できます。

サブネットに設定されたIPv6 サブネットCIDR ブロックのアドレスを使用してアドレスを固定します。

値は何でもよいですが、建てるサーバのメイン用途のアドレスで固定するとわかりやすくて良いです。

DNSサーバなら2001:0DB8:1234:1234:1::53

NTPサーバなら2001:0DB8:1234:1234:1::123

というようなやり方を私はよく使用します。

今回はWireguardのデフォルトポートである51820をそのまま使用しようと思うので、下記のようにca6cを設定しました。

対向の「Client-WireGuard」側も同様のやり方で構築しました。

ただ、「Client-WireGuard」側はインバウンドの通信が想定されないのでEgress-only インターネットゲートウェイで構築しました。

設定しましたら固定したIPv6アドレスでSSH接続します。

WireGuard設定

「EC2-WireGuard」の設定をします。

##Wireguard、iptablesのインストール
$sudo apt -y install wireguard-tools iptables

##wireguardの公開鍵と秘密鍵の作成
$umask 077
$wg genkey | tee privatekey-server | wg pubkey > publickey-server


##IPv4 パケット転送を有効にする
$sudo vi /etc/sysctl.conf
##最終行に以下追加
net.ipv4.ip_forward=1

##反映させる
$sudo sysctl -p

「Client-WireGuard」の設定をします。

##Wireguardのインストール
$sudo apt -y install wireguard-tools

##wireguardの公開鍵と秘密鍵の作成
$umask 077
$wg genkey | tee privatekey-client | wg pubkey > publickey-client

「EC2-WireGuard」のWireguardConfファイルの作成

$sudo mkdir wireguard
$sudo vi /etc/wireguard/wg0.conf

「EC2-WireGuard」の/etc/wireguard/wg0.confの内容

[Interface]
PrivateKey = <privatekey-serverの内容>
Address = 192.168.0.1/24
ListenPort = 51820

PostUp = echo 1 > /proc/sys/net/ipv4/ip_forward; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = echo 0 > /proc/sys/net/ipv4/ip_forward; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = <publickey-clientの内容>

AllowedIPs = 192.168.0.0/24, 10.1.1.0/24

AllowedIPsはどこの通信をWireguardにルーティングさせるかを決めることができます。

AllowedIPsに「0.0.0.0/0」設定するとすべての通信をWireguard通過させることもできます。

今回は特定IPレンジのみWireguardを通す設定をさせています。

「Client-WireGuard」のWireguardConfファイルの作成

$sudo mkdir wireguard
$sudo vi /etc/wireguard/wg0.conf

「Client-WireGuard」の/etc/wireguard/wg0.confの内容

[Interface]
PrivateKey = <privatekey-clientの内容>
Address = 192.168.0.2/24

[Peer]
PublicKey = <publickey-serverの内容>
AllowedIPs = 10.0.1.0/24
EndPoint = [「EC2-WireGuard」のIPアドレス::ca6c]:51820

接続確認

wg show コマンドでデータが送受信されているか確認します。

ubuntu@ip-10-0-1-217:~$ sudo wg show
interface: wg0
  public key: h+p8PDUsfiXxeLKoIndNJ7Q6CxZK/DuhfAxcbecxDR4=
  private key: (hidden)
  listening port: 51820

peer: WcTPXuPCMrUPSZQUq/pyNecaZi5N7vUKWgCcyWE9bAI=
  endpoint: [xxxx::x]:36182
  allowed ips:10.1.1.0/24
  latest handshake: 1 minute, 2 seconds ago
  transfer: 59.79 KiB received, 58.62 KiB sent
ubuntu@ip-10-1-1-59:~$ sudo wg show
interface: wg0
  public key: WcTPXuPCMrUPSZQUq/pyNecaZi5N7vUKWgCcyWE9bAI=
  private key: (hidden)
  listening port: 36182

peer: h+p8PDUsfiXxeLKoIndNJ7Q6CxZK/DuhfAxcbecxDR4=
  endpoint: [xxxx::ca6c]:51820
  allowed ips: 10.0.1.0/24
  latest handshake: 2 minutes, 37 seconds ago
  transfer: 1.76 KiB received, 2.55 KiB sent

無事にデータの送受信ができていそうなので問題なさそうです。

別途IPv6アドレスとグローバルIPv4アドレスを持たない「EC2-test」を用意し、Client-Wireguard→EC2-testでPing疎通をしてみます。*3

結果は以下です。 IPv6アドレスとグローバルIPv4アドレスを持たないEC2インスタンスに無事Pingが飛びました。

値も東京大阪間と考えれば問題ないと思います。

ubuntu@ip-10-1-1-59:~$ ping -c 4 10.0.1.130
PING 10.0.1.130 (10.0.1.130) 56(84) bytes of data.
64 bytes from 10.0.1.130: icmp_seq=1 ttl=126 time=17.1 ms
64 bytes from 10.0.1.130: icmp_seq=2 ttl=126 time=8.36 ms
64 bytes from 10.0.1.130: icmp_seq=3 ttl=126 time=8.37 ms
64 bytes from 10.0.1.130: icmp_seq=4 ttl=126 time=8.44 ms

--- 10.0.1.130 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 8.364/10.568/17.102/3.772 ms
ubuntu@ip-10-1-1-59:~$ 

性能的な話

以下がClient-Wireguard→EC2-WireGuardにPingした時の結果です。

Wireguardを通すと若干遅延してることがわかるものの、ソフトウェア的な遅延は少なく感じます。

ubuntu@ip-10-1-1-59:~$ ping -c 4 10.0.1.217
PING 10.0.1.217 (10.0.1.217) 56(84) bytes of data.
64 bytes from 10.0.1.217: icmp_seq=1 ttl=64 time=17.9 ms
64 bytes from 10.0.1.217: icmp_seq=2 ttl=64 time=8.61 ms
64 bytes from 10.0.1.217: icmp_seq=3 ttl=64 time=8.48 ms
64 bytes from 10.0.1.217: icmp_seq=4 ttl=64 time=8.63 ms

--- 10.0.1.217 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 8.484/10.915/17.944/4.058 ms
ubuntu@ip-10-1-1-59:~$ ping -c 4 xxxx::ca6c
PING xxxx::ca6c(xxxx::ca6c) 56 data bytes
64 bytes from xxxx::ca6c: icmp_seq=1 ttl=50 time=7.97 ms
64 bytes from xxxx::ca6c: icmp_seq=2 ttl=50 time=7.98 ms
64 bytes from xxxx::ca6c: icmp_seq=3 ttl=50 time=7.98 ms
64 bytes from xxxx::ca6c: icmp_seq=4 ttl=50 time=7.98 ms

--- xxxx::ca6c ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 7.969/7.975/7.981/0.004 ms
ubuntu@ip-10-1-1-59:~$ 

iperf3もしてみました。 テストポリシーに抵触しているのか、チューニングしていないからなのかわかりませんがフルパワー出せていない気がします。

しかし途切れることなく安定通信してるように見える思います。

ubuntu@ip-10-1-1-59:~$  iperf3 -c 10.0.1.217
Connecting to host 10.0.1.217, port 5201
[  5] local 192.168.0.2 port 40726 connected to 10.0.1.217 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  2.61 MBytes  21.9 Mbits/sec   19   8.66 KBytes       
[  5]   1.00-2.00   sec  1.18 MBytes  9.93 Mbits/sec   11   17.3 KBytes       
[  5]   2.00-3.00   sec  1.24 MBytes  10.4 Mbits/sec   18   17.3 KBytes       
[  5]   3.00-4.00   sec  1.24 MBytes  10.4 Mbits/sec   22   17.3 KBytes       
[  5]   4.00-5.00   sec  1.12 MBytes  9.44 Mbits/sec   22   26.0 KBytes       
[  5]   5.00-6.00   sec  1.18 MBytes  9.93 Mbits/sec   14   26.0 KBytes       
[  5]   6.00-7.00   sec  1.12 MBytes  9.44 Mbits/sec   11   26.0 KBytes       
[  5]   7.00-8.00   sec  1.24 MBytes  10.4 Mbits/sec    9   26.0 KBytes       
[  5]   8.00-9.00   sec  1.18 MBytes  9.93 Mbits/sec   11   26.0 KBytes       
[  5]   9.00-10.00  sec  1.12 MBytes  9.44 Mbits/sec   11   17.3 KBytes       
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  13.3 MBytes  11.1 Mbits/sec  148             sender
[  5]   0.00-10.03  sec  13.1 MBytes  10.9 Mbits/sec                  receiver

iperf Done.
ubuntu@ip-10-1-1-59:~$ 

その他

今回はAWS EC2間の構成になってしまいましたが、最初に簡単にまとめた通りWireguardはほとんどのLinuxディストリビューションやWindows、MacOS、Android/iOS(スマホ)に対応しており、それはすなわち他のクラウド同士やオンプレを混ぜた構成でも使用することができるということです。

また、Armのビルドも標準パッケージで用意されている場合もあり、本文中に記載していませんが「Client-WireGuard」は「t4g.nano」インスタンスで構築しています。

更に、複数のpeerを持つことができ、以下の図のような複数接続も可能です。

また、今回は本文中に明確には記載していませんが、クライアント側はアウトバウンド通信のみの許可で問題ありません。*4

他のプラットフォームのインストール方法は公式サイトに記載がありますので、確認してみてください。 www.wireguard.com

最後に

今回はAWS EC2にIPv6アドレスを割り振りWireguardで接続してみました。

運用や管理の問題でAWSサービスのElasticIPやDirectConnectなどの方が都合が良いケースが大半と思います。

しかしながらサクッと構築でき、持ち物も実機ルータなど物理機器を用意せずに仮想マシン等あれば構築できそうなのが良いですね。

最後まで読んでいただきありがとうございました。次回もよろしくお願いします。

お知らせ

APCはAWS Advanced Tier Services(アドバンストティアサービスパートナー)認定を受けております。

一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

*1:OSは今回の手順はUbuntuで説明します。AmazonLinux等もWireGuard構築できます。

*2:実運用するならもっと速度の出るインスタンスの方が良いと思います。また、WireguardはArmでも動作するのでArmのインスタンスでもよいかもしれません。

*3:IPv4のプライベートアドレスを固定しておらずアドレスがぐちゃぐちゃで申し訳ないです。

*4:企業などでNGFWのアプリケーション制御を行っていると検知されるケースがあるようです。