💭

OCIの潤沢な無料枠でIPv6対応のWireGuard VPNをたてる

2023/01/15に公開

目的

  • 自宅インターネット回線のセキュリティ強度を上げる
  • なるべく安くやる
  • なるべくインターネット回線速度を落とさない

上記をやりたい。

OCIの無料枠

Oracle Cloud Infrastructure(OCI)は無料枠がすごく多い。
https://www.oracle.com/jp/cloud/free/

特筆すべきは、

  • ARMベースのAmpere A1 Computeインスタンスが4 ocpuまで無料
  • ブロックストレージが200GB/月まで無料
  • インターネット方向のトラフィックが1TB/月まで無料
  • NATゲートウェイやサービスゲートウェイ、Site to Site VPN等のネットワークサービスの多くが無料でも使える

などなど、AWSとは比較にならないくらい無料枠が潤沢です。
なるべく安くやるという目的のために、今回はOCIを利用します。

WireGuard

https://www.wireguard.com/
WireGuardは、次世代VPNのプロトコルとして注目されている新しいプロトコル及び実装です。
OpenVPNよりも実装コード量が少なく、高速であることがメリットとしてよく謳われます。
先人の記事を共有します
https://zenn.dev/hiroe_orz17/articles/f8f35075dea4cf
自宅インターネット回線のセキュリティ強度を上げるなるべくインターネット回線速度を落とさないという目的のためにWireGuardを導入します。

IPv6

なるべくインターネット回線速度を落とさないという目的のために、
とりあえず、IPv4よりIPv6のほうが早そうなので、IPv6でE2E通信をします。

OCI環境構築


ごくシンプルな構成にします。
Load Balancerは今回使用しません。
IPv6のE2Eな通信をするために、Dockerも使用しません。(Docker Networkは基本はIPv4で構成されており、wireguardコンテナがIPv6でインターネット通信することが難しかったので。)

OCI構築

VM構築まで

ここは割愛。
OSは、OracleLinux7.9を利用しました。
VM.Standard.A1.Flexで、4 ocpu/24GB Memory/200GB ストレージで構築します(無料枠の最大)。
NSGは、安全のために自宅のIPアドレスのみ開けています。
また、サブネットのDefault Security ListのIngress/Egressのルールはすべて削除しておきましょう。
参考
https://iret.media/51648
https://ひとりでできるもん.com/2022/05/19/ociのファイアウォール機能について調べてみまし/
(この仕様、フェイルセーフの考え方に反している気がする…)

IPv6対応


VCNのCIDR Blocks/Prefixesメニューから、新しいCIDRを追加します。
IPv6のアドレスは、OCIが管理しているものを利用します。

こんな風にIPv6グローバルユニキャストアドレスの範囲でCIDRが払い出され、VCNに割り当てられます。


VCNのルートテーブルにもIPv6のルーティング情報を追記しましょう。

VCNがIPv6対応したので、VMのVNICにもIPv6を割り当てます。
上記で作成したVMの詳細メニューから、左側にある「IPv6 Addresses」をクリックし、「Assign IPv6 Address」ボタンから、VNICにIPv6を割り当てます。

VNICにもIPv6が割あたったので、OSに反映します。
sshなどでシェルに接続します。
とりあえず自己責任のもと、FirewallとSELinuxは無効化します。

systemctl stop firewalld
systemctl disable firewalld
/etc/selinux/config
SELINUX=permissive
reboot

OSがIPv6ルーティングをするようにsysctlパラメータを変更します。

/etc/sysctl.d/99-wireguard.conf
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.all.accept_ra=2
net.ipv6.conf.default.accept_ra=2

sysctlパラメータを修正したら、再起動するか、現在のカーネルに反映させます

sysctl --system

現在のOSのNICにIPv6グローバルユニキャストアドレスをDHCPで取得します。NIC名は、OCI Oracle Linuxデフォルトのenp0s3としてここでは書いていますが、適宜変更します。

dhclient -6 enp0s3

最後に、OSのルーティングテーブルに、IPv6でインターネットゲートウェイに通信をするようにルート情報を追記します。
インターネットゲートウェイまでの通信は、リンクローカルアドレスで行います。
IPv6のリンクローカルアドレスの値は、MACアドレスから算出されます。
VCNのPublic Subnetの詳細メニューを確認するとVirtual Router Mac Addressがあります。これがサブネット内のデフォルトゲートウェイのMACアドレスです。

下記サイトなどで、MACアドレスからIPv6のリンクローカルアドレスを算出できます。
https://pg.kdtk.net/1865
ここで得られた値を利用して、ルート情報を設定します。

ip -6 route add default via "ここに得られたIPv6リンクローカルアドレスアドレスを記載" dev "enp0s3"

(この辺はDHCPでいい感じにやってくれそうな気もしますが…自分の場合はうまく行きませんでした…)

WireGuard構築

WireGuardはP2P方式なのですが、便宜上OCI上のWireGuard VMはサーバ側、自分のPCをクライアント側と表記します。

サーバ側

https://www.wireguard.com/install/#oracle-linux-7-uek6-tools

yumでWireGuardをインストールします。
utilityも一緒にインストールされるので、cliでサーバ側の秘密鍵と公開鍵を生成します。

mkdir -p /etc/wireguard/key
wg genkey > /etc/wireguard/key/privatekey
chmod 600 /etc/wireguard/key/privatekey
wg pubkey < /etc/wireguard/key/privatekey > /etc/wireguard/key/publickey

秘密鍵はセキュリティの根幹を担うため、絶対の外部サーバに持ち出してはいけません。
WireGuardの設定ファイルを作成します。
InterfaceのIPはVPN内で用いるCIDRです。VCNの範囲や、クライアント側のCIDRと重複しない範囲を利用します。
Peerとは、WireGuardでVPN接続をする相手のことです。今回だとクライアント側です。
また、VPN接続をすると、パケットがカプセリングされるため、全体のパケットサイズが大きくなります。そのため、自宅ルーターのMTU設定によっては通信が著しく遅くなるため、意図的にMTUの値を小さくします。
WireGuardのデフォルトポートは51820/udpです。

/etc/wireguard/wg0.conf
[Interface]
Address = 10.10.0.1/32, fd86:0000:1111::1
ListenPort = 51820
PrivateKey = "ここに上記で作成した秘密鍵の中身を直接記載する"
MTU = 1350

PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -A FORWARD -o wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o enp0s3 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -D FORWARD -o wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o enp0s3 -j MASQUERADE

[Peer]
PublicKey = "ここに、後述するクライアント側で生成した公開鍵の中身を直接記載する"
AllowedIPs = 10.10.0.2/32, fd86:0000:1111::2

準備ができたらWireGuardを起動します。

wg-quick up wg0

クライアント側

今回のクライアントは、Windows10を想定しています。
https://www.wireguard.com/install/#windows-7-81-10-11-2008r2-2012r2-2016-2019-2022
公式サイトからインストーラをダウンロードし、インストールします。

WireGuardを起動し、空のトンネルを追加します。

このとき表示される公開鍵は、上記のサーバ側/etc/wireguard/wg0.confに追記しましょう。
間違っても秘密鍵を外部に漏洩させてはいけません。

また、クライアント側のWireGuardの設定を修正するために、WireGuardを起動し右下にある「編集」ボタンをクリックして出てくるポップアップに下記を記載します。
ここでのPeerは逆にサーバ側のことですね。また、AllowedIPsには、VPN通信をする際の宛先CIDRを記載します。IPv4のグローバルIPアドレスの範囲や、IPv6のグローバルユニキャストアドレスのみを記載することで、自宅ネットワーク内の通信ではVPN接続をしないように制御することができます。すべてWireGuard経由のVPN通信にしたい場合は0.0.0.0/0, ::/0としましょう。
MTUのサイズはもちろんサーバ側と合わせましょう。
Endpointには、OCIにあるWireGuard VMのIPv6グローバルユニキャストアドレスを設定します。

[Interface]
PrivateKey = "秘密"
ListenPort = 51820
Address = 10.10.0.2/32, fd86:0000:1111:2/128
DNS = 8.8.8.8
MTU = 1350

[Peer]
PublicKey = "サーバ側の公開鍵の値を直接記載します"
AllowedIPs = 0.0.0.0/5, 8.0.0.0/7, 11.0.0.0/8, 12.0.0.0/6, 16.0.0.0/4, 32.0.0.0/3, 64.0.0.0/2, 128.0.0.0/3, 160.0.0.0/5, 168.0.0.0/6, 172.0.0.0/12, 172.32.0.0/11, 172.64.0.0/10, 172.128.0.0/9, 173.0.0.0/8, 174.0.0.0/7, 176.0.0.0/4, 192.0.0.0/9, 192.128.0.0/11, 192.160.0.0/13, 192.169.0.0/16, 192.170.0.0/15, 192.172.0.0/14, 192.176.0.0/12, 192.192.0.0/10, 193.0.0.0/8, 194.0.0.0/7, 196.0.0.0/6, 200.0.0.0/5, 208.0.0.0/4, 224.0.0.0/3, 2000::/3
Endpoint = "サーバ側のVMのIPv6グローバルユニキャストアドレス":51820



最後にVPN接続を有効にして、うまくインターネットにアクセスができれば成功です。

性能計測(参考)

日曜日お昼すぎのインターネットスピードテストをやってみました。
1Gbpsの光回線をマンションタイプで契約していて、PCとルーターのLANは1Gbps帯になってます。(たぶん)
参考情報です。
下記サイトで計測しました。
https://inonius.net/speedtest/

WireGuardの場合

VPN無しの場合

そこそこ出てますね🙂
OCIのインターネット向き通信量が1TB/月を超えない限り無料のはずです。

以上。

Discussion