はじめに
WireGuardを使って、自宅とOracle Cloudの間で拠点間VPNを構築してみました。
Oracle Cloud上のVMから自宅サーバーのDBにアクセスする際などにセキュアな通信ができ、非常に便利です。
構築した際の手順やハマったポイントなどを記事に残しておこうと思います。
環境
VMのOSはいずれもUbuntu 20.04です。
今回はVM1とVM2の間でVPNを張り、PC1からVM2やVM3へアクセスできるようにしました。
もちろん、VM3からPC1へのアクセスもできます。
WireGuardの設定
インストール
WireGuardはaptでシュッとインストールできます。
$ sudo apt install wireguard
VM2側の設定
VM2はサーバー側です。
WireGuardの設定ファイルである /etc/wireguard/wg0.conf
に以下のような設定を書きます。
基本的にはドキュメントのとおりに設定すればOKです。
[Interface] Address = 192.168.1.1/24 MTU = 8920 SaveConfig = true PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE; iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE; iptables -t nat -D POSTROUTING -s 192.168.1.0/24 -j MASQUERADE ListenPort = 51820 PrivateKey = <Your PrivateKey> [Peer] PublicKey = <Your PublicKey> AllowedIPs = 192.168.1.2/32, 172.16.0.0/23 Endpoint = 125.30.20.110:43297
PeerのAllowedIPsには自宅側のネットワークのセグメントを書いてあげます。
また、MTUを8920に設定してあげます。
設定を記入したら $ sudo wg-quick up client
でWireGuardの設定を反映させます。
VM1側の設定
VM1はクライアント側です。/etc/wireguard/client.conf
に以下のような設定を書きます。
こちらも基本的にはドキュメントのとおりに設定すればOKです。
[Interface] PrivateKey = <Your PrivateKey> Address = 192.168.1.2 DNS = 8.8.8.8 MTU = 1350 [Peer] PublicKey = <Your PublicKey> AllowedIPs = 10.0.0.0/8, 192.168.1.0/24 Endpoint = <VM2 Global IP Address>:51820 PersistentKeepalive = 10
AllowedIPsにはOracle Cloud側のネットワークのセグメントを書いてあげます。
また、DNSとMTUの設定も追記します。
設定を記入したら $ sudo wg-quick up wg0
でWireGuardの設定を反映させます。
ファイアウォール・NATの設定
VM2はOracle CloudのVMでデフォルトで使われているiptablesの設定を変更します。
以下の設定を追記し、WireGuardがlistenしているポートに対してのリクエストを許可します。
-A INPUT -p udp -m state --state NEW -m udp --dport 51820 -j ACCEPT
また、VPN経由でのpingに応答できるようにするため、以下の行をコメントアウトします。
- -A FORWARD -j REJECT --reject-with icmp-host-prohibited+ # -A FORWARD -j REJECT --reject-with icmp-host-prohibited
全て設定したら、 $ sudo systemctl restart iptables.service
で設定を反映させます。
VM1の方は、ufwを使っていたので、以下のコマンドで設定を追加しました。
$ sudo ufw route allow in on eth0 out on client from 172.16.0.0/23
設定を追加したら、 $ sudo ufw reload
で設定を反映させます。
Oracle Cloudのファイアウォールの設定
セキュリティ・リストに 0.0.0.0/0からの51820/UDPへのリクエストを許可する設定を追加します。
また、10.0.0.0/8からのICMPのリクエストも許可するようにします。
ルーターのスタティックルートの設定
Oracle Cloudではルート・ルールに、172.16.0.0/23宛の通信を全て10.0.0.2に向ける設定を追加します。
設定欄には、以下のように入力します。
- ターゲット・タイプ: プライベートIP
- 宛先タイプ: CIDRブロック
- 宛先CIDRブロック: 172.16.0.0/23
- ターゲット選択: 10.0.0.2 (VM2のプライベートIPアドレス)
また、
プライベートIPをターゲットとするルート・ルールの場合は、最初に、プライベートIPが割り当てられているVNICで「ソース/宛先チェックのスキップ」を有効にする必要があります。
とあるように、VM2のVNICの設定で「ソース/宛先チェックのスキップ」を有効に設定しておきます。
一方自宅側は、ルーターにスタティックルートの設定を追加します。
自宅側の各VMやPCに直接スタティックルートの設定をしてもいいですが、ルーターで一括で設定したほうが楽です。
私の家では、NECのIX2105を使っているので、それを例に説明します。
ルーターのコンフィグに以下の設定を追加します。
ip route 10.0.0.0/8 172.16.0.11 (VM1のプライベートIPアドレス)
これで、自宅側のネットワークから10.0.0.0/8宛にパケットを送信した際は、デフォルトゲートウェイであるルーターに到達し、ルーティング設定に基づいてVM1に転送されるようになります。
一通り設定を終えたら、相互にpingを送ったり、Oracle CloudのVMに対して、自宅のネットワークからプライベートアドレスでSSHを繋いだりできるようになっているはずです。
最終的なパケットの流れは、以下の図のようになります。
ハマったポイント
MTUのサイズの設定
最初にWireGuard経由でSSHで接続しようとしたところ、なかなか接続できず、タイムアウトしてしまいました。
sshコマンド実行時に -v
オプションを付けて接続したところ、 expecting SSH2_MSG_KEX_ECDH_REPLY
というメッセージが出たところで止まっていました。
このメッセージで調べたところ、どうやらMTUのサイズが小さい場合に発生するということがわかりました。
また、WireGuardの設定にはMTUのサイズの設定もあることがわかりました。
WireGuardの設定ファイルにMTUサイズの設定も追加したところ、無事にSSHがつながるようになりました。