サーバインフラ担当の porianes です。
この記事では、 pfSense の HAProxy プラグインの使い方について、簡単に説明します。 HAProxy 自体の説明はあまりしないので、 HAProxy マニュアルを見ながら読むと理解が深まるかもしれません。
はじめに
HAProxy とはなにか
HAProxy はリバースプロキシの実装の一つであり、 特にロードバランス (複数のサーバに負荷を適切に分散する) と可用性確保 (サーバが停止しても他のサーバを利用してサービスを継続できる) に焦点を当てたソフトウェアです。 記述方法に少し癖があるものの、設定ファイルの書き方次第でかなり柔軟な制御ができます。
朝日ネットでは Nginx や Apache が動いているウェブサーバにリクエストを振り分けたり、 一部のアクセス制御を行う用途で使用しています。
pfSense とはなにか
pfSense は FreeBSD をベースにした、 WEB GUI を備えたソフトウェアルータです。 FreeBSD の IP 実装を利用したルーティングやフィルタリング、フェイルオーバー等を基本機能として備えている他、 多彩なプラグインによる拡張が可能です。
HAProxy プラグインが存在し、 pfSense の GUI の中で HAProxy の設定ができるようになっています。 朝日ネットで動いている HAProxy は、大部分が pfSense の中で動いています。
導入方法
pfSense のインストールをして、管理画面 (Web) で System > Package Manager を開きます。 Available Packages のタブから haproxy を検索し、インストールします。
HAProxy の Setting で、 Enable HAProxy にチェックを入れて設定を Save して Apply すると、 HAProxy が起動します。
設定方法
HAProxy の設定は Services > HAProxy の中にあります。 Templates の中にいくつか設定例が収録されています。
試しに Serving multiple domains from 1 frontend のテンプレートをロードしてみると、 バックエンドが 3 つ、フロントエンドが 2 つロードされます。
生成された設定の確認
pfSense の HAProxy プラグインの GUI は単純な設定しかしないならとっつきやすいでしょうが、
複雑な設定や後述の pass-through を使い出すと、GUIについてのまともなマニュアルがないこともあり、分かりづらい部分多く感じられます。
そんなときは、GUI上の設定から生成された設定ファイルを確認して、状態を整理する必要が出てくるでしょう。
設定のファイルは /var/etc/haproxy/ に生成されますが、
Services > HAProxy >Settings の画面下部の show automatically generated configuration.
でも確認できます。
こうして設定ファイルの形になってしまえばその読み方は HAProxy の設定と同じですから、
HAProxy のマニュアルを見ながら設定方法を検討できます。
設定を変更したら、この機能を使って意図通りの設定になっているか確認するのが良いでしょう。 特に ACL 周りの自動生成には難があり、GUIの設定から直感的に理解できない挙動をすることが多いように思います。
残念ながら設定の適用 (Apply ボタンの押下) 前にこれを確認する機能はありませんが、
設定にエラーがある (例えば、 Global Advanced pass thru に invalid
などと書き込むことで意図的に発生させられます) と show automatically generated test configuration.
が追加で表示されるようになり、適用前の設定が表示できます。
奇妙なやり方ですが、一応、適用前の設定を確認できます
*1。
Shared フロントエンド
Serving multiple domains from 1 frontend テンプレートの、 example_multipledomains_forum という名前のフロントエンドは Shared Frontend です。この、「Shared Frontend」こそが、私がこの記事を書こうと思った理由であり、このGUIでのHAProxyの設定を難解にしている原因です*2。
これは概念的には「1つのポートで複数のサービスを提供する」ような設定をするための、 「複数のサービス」に対応するものであり、設定の中で「1つのポート」に相当するものを「Primary frontend」として選択するようになっています。 しかし、HAProxy にはそのような概念はありません。 これらの Shared なフロントエンドは、単に1つの frontend に統合されます。
例えば、Serving multiple domains from 1 frontend のフロントエンドはこのように変換されます。
結果1つのフロントエンドにすべて書くのと同じ設定になりますが、 フロントエンド一覧で「On」のカラムを操作するとフロントエンドごとに無効化できる *3 ため、 部分的に無効化したい用事があるときには便利です。
shared なフロントエンドは実際には1つのフロントエンドなので、親で設定したACLを子で使用したり、子で設定したACLを親や兄弟が使ったりできます。 ACLの名前が衝突しないように気をつける必要がありそうです。 すべての ACL を親に設定して、子では Actions のみ設定するというのもありかもしれません。
設定の pass-through
pfSense の HAProxy 設定画面は、 HAProxy の豊富な機能のほんの一部の設定しかできません。 しかし、あちこちに「書いたテキストをそのまま設定ファイルに pass-through する」機能があり、これを使うと色々できるようになります。 例えば、次のような pass-through が可能です
- 設定ファイルのglobalセクション
- Settings の Global Advanced pass thru に書けます
- frontend の bind 行
- フロントエンドの External address の Advanced 欄に書けます
- backend の server 行
- 追加時に Advanced の欄に書けます。また、 [+] ボタンから、後で変更することもできます。 すべての server に同じことを書く場合、 Advanced settings の中の Per server pass thru が使えます。
- frontend/backend の acl
- ACL の Expression のところで `Custom acl:` を選択して書けます
- frontend/backend の Action (http-request, tcp-request, use_backend等)
- Action の種類を Custom にすると custom action の部分に書けます
- frontend の、その他の設定
- Advanced settings の中に Advanced pass thru があります。(shared でないフロントエンドのみ)
- backend の、その他の設定
- Advanced settings の中に Backend pass thruがあります。
listen セクションを作ることはできないようですが、フロントエンドとバックエンドを適切に組み合わせれば、 listen と同じことを実現できるはずです。
pfSense に固有の便利機能
pfSense の HAProxy には、 pfSense 自体の機能と連携する機能があります。
設定の同期
Settings の中の Configuration synchronization のチェックボックスで、2台の pfSense で HAProxy の設定を同期できます。 pfSense 本体の設定で同期設定をしたホストが同期対象です。
IPアドレス
bind するアドレスを pfSense の IF のアドレスから選択できます。
ACL のマッチング条件も、 pfSense 本体の Firewall で設定した Alias を利用できます。 (Source IP matches IP or Alias:
を選択)
おわりに
わたしは正直なところ pfSense はあまり好きではありませんが、 挙動の詳細を知ることができる利点のある、オープンソースであることは好印象です。 クローズドソースでマニュアルもあまり充実していないアプライアンスより、 こういったフリーソフトを使ったファイヤーウォールやロードバランスがもっと流行ればいいと思っています。
Community Edition が無料でダウンロードできるので、興味があれば試してみてください。
HAProxy とは関係ない話になってしまいますが、試しに家のルータを pfSense に置き換えてみる*4などいかがでしょう。 PPPoE を利用しているなら、おそらく置き換えられる家が多いと思います。