OCIの潤沢な無料枠でIPv6対応のWireGuard VPNをたてる
目的
- 自宅インターネット回線のセキュリティ強度を上げる
- なるべく安くやる
- なるべくインターネット回線速度を落とさない
上記をやりたい。
OCIの無料枠
Oracle Cloud Infrastructure(OCI)は無料枠がすごく多い。
特筆すべきは、
- ARMベースのAmpere A1 Computeインスタンスが4 ocpuまで無料
- ブロックストレージが200GB/月まで無料
- インターネット方向のトラフィックが1TB/月まで無料
- NATゲートウェイやサービスゲートウェイ、Site to Site VPN等のネットワークサービスの多くが無料でも使える
などなど、AWSとは比較にならないくらい無料枠が潤沢です。
なるべく安くやる
という目的のために、今回はOCIを利用します。
WireGuard
OpenVPNよりも実装コード量が少なく、高速であることがメリットとしてよく謳われます。
先人の記事を共有します
自宅インターネット回線のセキュリティ強度を上げる
となるべくインターネット回線速度を落とさない
という目的のために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のルールはすべて削除しておきましょう。
参考
(この仕様、フェイルセーフの考え方に反している気がする…)
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
SELINUX=permissive
reboot
OSがIPv6ルーティングをするようにsysctlパラメータを変更します。
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のリンクローカルアドレスを算出できます。
ここで得られた値を利用して、ルート情報を設定します。
ip -6 route add default via "ここに得られたIPv6リンクローカルアドレスアドレスを記載" dev "enp0s3"
(この辺はDHCPでいい感じにやってくれそうな気もしますが…自分の場合はうまく行きませんでした…)
WireGuard構築
WireGuardはP2P方式なのですが、便宜上OCI上のWireGuard VMはサーバ側
、自分のPCをクライアント側
と表記します。
サーバ側
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です。
[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を想定しています。
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帯になってます。(たぶん)
参考情報です。
下記サイトで計測しました。
WireGuardの場合
VPN無しの場合
そこそこ出てますね🙂
OCIのインターネット向き通信量が1TB/月を超えない限り無料のはずです。
以上。
Discussion