久しぶりの投稿になります。
最近はHackintoshの活動もせず、UnityでClusterのメタバースのワールド作成やら、アバター作成やらVRChatやらをHMD被ったりしながらいろいろと試しております。

OSManiaX的なネタではないのと、調査段階なもの多いのであまりBlogへ投稿できていないのですが、
今回はタイトルの通り、Linuxネタでございます。

WEBサーバを冗長化するとしたら、AWS環境であればもうELB やALBで解決になってしまうのですが、
家庭内WEBサーバだとそう簡単なハナシではありません。

クラウド以前に使われていた技術が有効になってくるわけですね。

そこで、今回はWEBサーバの冗長化にあたってHaproxyを試してみました。

冗長化の目的としてはサーバダウンだけでなく、パッチ適用やファームウェア更新、ディスク交換など、メンテナンス対応でも有効に活用できますので、転ばぬ先の杖、やっておいて損はないわけでございます。


OS選定にあたって

OSはもちろんLinuxとなるわけですが、Linux好きとしてはディストリビューション選定は一番悩みますね、そうして悩んだ結果、今回はUbuntu22.10を選定しました。
ArchLinuxも好みではありますが、実はArchlinuxには安定運用に欠ける面もあり、若干懲りてきております。
というのも直近でもsslのライブラリ更新適用したらphpが起動不可、結果としてWordpressの実行不可とか、ライブラリ更新の影響による依存関係の不具合の解決では、うっかり更新しようものなら深夜対応となり、非常に慌てますので、本番環境での運用にはArchLinuxはお勧めできません。
筆者の場合でも大抵はトラブルの解決はできていますが、その分の対応で寝不足になったりします。

そのため不特定多数の方に外部からアクセス可能とさせるサーバならば、安定のUbuntuが良いかなと考えた次第です。ただ、新し物好きなので、ltsではないものとして、22.10とました。


haproxyのインストール

インストール方法は簡単です、以下のコマンドで完了です。

$ sudo apt install haproxy

インストールのバージョンは以下となります。(2022年11月22日現在)

$ haproxy -v
HAProxy version 2.4.18-1ubuntu1 2022/08/15 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2026.
Known bugs: http://www.haproxy.org/bugs/bugs-2.4.18.html
Running on: Linux 5.19.0-23-generic #24-Ubuntu SMP PREEMPT_DYNAMIC Fri Oct 14 15:39:57 UTC 2022 x86_64

haproxyの設定

インストールが完了したら次は設定となります。
以下が設定ファイルのパスとなります。

$ sudo vi /etc/haproxy/haproxy.cfg

HAProxyの設定はいくつかあり、環境に応じた形で行う必要があります。

1)SSLオフロード

SSLサーバ証明書をHaproxy側に持たせ、WEBサーバ側はhttp(80)で通信する方法。
(User→443→Haproxy(サーバ証明書)→80→WEB)

2)SSLブリッジ

SSLサーバ証明書をHaproxy側とWEBサーバ側に持たせる方法。
(User→443→Haproxy(サーバ証明書)→443→WEB(サーバ証明書))

3)SSLパススルー

SSLサーバ証明書をHaproxyには持たせず、WEBサーバ側に持たせる方法。
(User→Haproxy(透過)→443→WEB(サーバ証明書))

筆者環境の場合、WEBサーバはバーチャルネームホスティング環境(OpenLiteSpeed)で、
複数ドメインを1台のサーバで運用しています。(※SSL証明書はサーバ側でLet’s encryptで取得して、
OpenLiteSpeedの管理画面経由で各バーチャルホストで設定可能にしております。)

そのためSSLの処理はHaproxyでは何もしないパススルー方式として設定する必要があります。
設定変更後は以下コマンドでサービスを再起動させます。

$ sudo systemctl restart haproxy

haproxyの設定内容(SSLパススルー)

今回は調査して筆者環境で動作検証した結果、
デフォルト設定項目に加えて、以下設定内容を追記することでの対応としました。
まず、以下はデフォルトの設定項目です。ここは変更せず。


デフォルトの設定値

global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
        ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http

そして以下が今回追記した項目となります。

frontend haweb
        bind *:80
        mode tcp
        compression algo gzip
        compression type text/html text/plain text/plain text/css text/javascript application/x-javascript application/javascript application/json text/js text/xml application/xml application/xml+rss image/svg+xml
        default_backend back_web
#
frontend haweb_ssl
        bind *:443
        mode tcp
        compression algo gzip
        compression type text/html text/plain text/plain text/css text/javascript application/x-javascript application/javascript application/json text/js text/xml application/xml application/xml+rss image/svg+xml
        option forwardfor
        default_backend back_web_ssl
#
backend back_web
        balance roundrobin
        mode tcp
        server web1 192.168.1.xxx:80 check
        server web2 192.168.1.xxx:80 check
#
backend back_web_ssl
        balance roundrobin
        mode tcp
        server web1 192.168.1.xxx:443 check
        server web2 192.168.1.xxx:443 check

メンテナンスで片方だけの動作にしたい場合

実際にメンテナンスの際にはどのようにメンテナンス対象のサーバをHaproxyから切り離すか、
というと、上記設定ファイルのうち、サーバの片方のメンテしたい方をコメントアウトし、
haproxyのサービスを再起動することで対応可能となります。
メンテ完了後は、逆の手順として、コメントアウトを消して、サービス再起動となります。

       #server web1 192.168.1.xxx:443 check
       server web2 192.168.1.xxx:443 check
$ sudo systemctl restart haproxy

まとめ

今回はHaproxyを試してみた結果の報告となりました。
サーバを運用している方でないとあまりイメージできないかもしれませんが、今日はこの辺で!

尚、mode をtcpとしているのは、mode httpとしたらエラーでhaproxyのサービスが起動できなかったためです。

それでは、何かの役に立てば幸いです。