OpenVPN は別のミドルウェアやロードバランサを追加しなくても、標準機能だけでサーバの負荷分散+冗長化を実現できるように作られています。
ところが不適切な設定のために正常にフェールオーバーしないという失敗をしてしまいました。この件に関する情報が見つからなかったので、恥ずかしながら今回の記事にしました。
基本設定
以下すべて、クライアント側の設定ファイルの内容です。
参考: https://www.openvpn.jp/document/how-to/#LoadBalancing
冗長構成
remote
で複数の OpenVPN サーバを設定するだけで冗長化が実現します。接続の試行はリスト順なので、以下の例ではまず server1 に、失敗したら server2 に接続を試みます。つまり全クライアントの設定ファイルが共通なら、server1 が正常に稼働していれば接続は server1 に集中します。
remote
でさらに多くのサーバを設定することもでき、上限数は明記されていません。
remote server1 1194 # 最初に接続を試みるサーバ
remote server2 1194
負荷分散+冗長構成
さらにラウンドロビンによる負荷分散を実現するには、remote-random
を追加します。これで接続を試みるサーバの順序がリスト順ではなくランダムに選択されるので、各サーバへの接続数の平準化が期待されます。
remote server1 1194
remote server2 1194
remote-random # remoteで指定されたサーバにランダムに接続する
以上が負荷分散+冗長構成のための基本的な設定です。
不適切な設定と修正
修正前の設定
以下はクライアント側の設定ファイルの一部です。デフォルトのクライアント設定に、セキュリティを考慮してuser nobody
とgroup nobody
を追加(アンコメント)しました。
参考: https://www.openvpn.jp/document/how-to/#Security
client
dev tun
proto udp
remote server1 1194
remote server2 1194
remote-random
resolv-retry infinite
nobind
user nobody
group nobody
persist-key
persist-tun
問題点
接続中のサーバを停止してもフェールオーバーせず、切断状態のままになりました。
修正後の設定
user nobody
とgroup nobody
を削除(コメントアウト)しました。
# user nobody
# group nobody
結果
接続中のサーバを停止すると自動的にフェールオーバーし、15秒後に他方のサーバに接続しました。
原因
user nobody
とgroup nobody
は初期化完了後に実行ユーザーを降格する設定なので、接続中は問題が発生しません。しかし切断が発生して別のサーバに接続しようとしても、新しい tun デバイスをオープンする権限がないためにフェールオーバーができなくなっていました。
反省
悪かった点
デフォルトでコメントアウトされていた設定をアンコメントして有効化する際に、影響への考慮が足りていませんでした。
良かった点
フェールオーバーのテストをしたのでリリース前に問題に気付くことができました。
また問題の発生がなければスルーしていた内部処理について調査したので、少しですが理解が深まりました。