X
    Categories: その他

リバースプロキシで、複数のサービスでポートを共有しながら自宅サーバーを安全に公開する(1)

我が家の自宅サーバーは、Windows Server Essentialsが未だに活躍してくれています。
手放せない理由は、記憶域スペースを用いたファイルサーバーとSSTP VPNサーバーとしての用途です。たまに自宅の外で公衆無線LANを用いてPCを利用する場合、広告ブロックの目的で導入したPi-holeをDNSとして利用する目的とセキュリティ面で、自宅にVPN接続して利用するようにしています。

自宅内にはもう1台Raspberry Pi上に導入したUbuntuサーバーで、

  • Pi-hole(広告ブロック用のDNS)
  • Samba(Active Directoryの2台目のドメインコントローラー)
  • NextCloud(スマホからWindows Server Essentialsのファイルサーバーにアクセスするためのフロントエンド)
  • 自宅プライベートDNS(DNS over HTTPS/DNS over TLS)
  • IPSec(IKEv2/IPSec RSA) VPNサーバー

が稼働しています。

このRaspberry Pi上のNextCloudや自宅プライベートDNSも自宅外からのアクセスを可能にしており、Windows ServerとRaspberry PiでTCP 80/443を共用しています。同じポートを共有して外部に複数のサーバーのサービスを公開する方法はいくつかありますが、SSTPはWindows Serverに、その他のWebサービスはRaspbery Piに振り分けするために、自宅ではHAProxyというフリーのリバースプロキシを利用しています。

なぜHAProxyを選択したのか

以下のような理由から、Windowsサーバーのリバースプロキシ機能ではなく、Ubuntu上にHAProxyを導入することにしました。ほかの選択肢もあると思いますが、自分が調べられた範囲ではこれが一番楽でした。

GeoIPでのアクセスコントロールを手軽に実現したい

自宅サーバーを公開する場合、外部からの攻撃が心配になると思います。
自宅では、アクセス元のIPアドレスの国を判定し、日本国内からのアクセスに限定していますが、Windows Serverのリバースプロキシ機能を用いる場合、このアクセス元のIPアドレスを自動メンテするのは割と面倒だったりします。

このあたりはLinuxベースのほうが事例も多く公開されており、CLIを利用した自動化も便利です。
Ubuntu上のWebサーバーはNGINXを利用しています。もちろんNGINXでもGeoIPでのアクセスコントロールは可能ですが、次の理由でNGINX以外の手段を探ることのなりました。

HTTP/HTTPS以外のポートもリバプロを利用したい

GeoIPを利用して海外からのアクセスを遮断したい対象はWebサービスだけではありません。
自宅で立てたPi-holeを自宅外でもスマートフォンからセキュアDNS/プライベートDNSとして利用して広告ブロックを実現しており、DNS over HTTPS(DoH:TCP 443を利用)/DNS over TLS(DoT:TCP 853を利用)を利用しています。AndroidのプライベートDNSではDoTを利用するため、TCP 853へのアクセスもGeoIPをベースに国内からのアクセスに限定しています。

自分が海外に行った際はプライベートDNSにアクセスできなくなってしまいますが、その場合はIKEv2/IPsec RSAのVPNで接続できるようにしており、証明書を事前にインストールしたクライアントからしか接続できないようにしてセキュリティを担保しています。
余談ですが、Windows以外のスマホを公衆Wi-Fiで利用する場合もIKEv2/IPsec RSAのVPNを利用しています。

SNIベースの振り分けを実現したい

自宅用にはドメインを取得していますが、用途に応じてサブドメインを利用しています。たとえばWindows Serverへのアクセスには[aaa.hogehoge.com]、Raspberry Pi上にホストしたサービスは[bbb.hogehoge.com]のようなサブドメインを割り当て、これらのサブドメインに応じてHAProxyから振り分け先のバックエンドのサーバーを切り分けるようにしています。

QUICを利用したい

NextCloudを利用する際に、QUICを利用してアクセスを少しでも高速化したいのも理由の1つです。NextCloudは少し重いので、気休めかもしれませんがQUICを利用することで快適なアクセスを実現したい(している気になりたい)ため、QUICをサポートしているHAProxy(HAProxy 2.8以降が必要)を採用しています。

従来と見直し後の環境構成図

従来

これまでの環境は以下の通りです。
Windows Server EssentialsにTCP 80/443をNATすることで、リモートWebアクセス(RWA)やSSTP VPNを活かしつつ、Ubuntu上に展開したNextCloudや予備用のVPNサーバー(IPsec/L2TP,IKEv2)を入れていました。
Ubuntu上でホストしているNextCloudには、IISのリバースプロキシ機能を使い、URL書き換えをしてきました。が、Windows Server 2016のIIS 10では、残念ながらTLS v1.3やQUICには対応できません。また、GeoIPのでのアクセス制御もできなくはありませんが、IPアドレスのDBの更新含めて考えるとメンテナンスがやや面倒です。

Linuxのコンテナが利用できる新しいWindows Serverであればもっと楽だとは思うのですが…。図には入れていませんが、Ubuntu上でSambaを動かしており、2台目のドメインコントローラーとしての物理的なバックアップの役割もあるので、Ubuntuマシンを活かすことを考えました。

見直し後

見直し後は以下のように、Ubuntuに導入したHAProxyの80/443ポートを、Ubuntuのアプリケーションを利用する場合のSNI(aaa.hogehoge.com)とWindows Server上のアプリケーションを利用する際のSNI(bbb.hogehoge.com)に応じて、HAProxyで振り分けするようにしました。

また、Ubuntu上でセキュアDNS/プライベートDNS用途でDoT/DoHを動かしており、この用途用に割り当てたccc.homehoge.comへのHTTPS(443)/TLS(853)へのアクセスをBind9(その裏でPi-holeにフォワード)に仕向けるようにしています。

HAProxy/Nginxの構成にすることでTLS v1.3やQUICにも対応でき、加えてHAProxyにGeoIPを読ませることで、手軽に海外からのアクセスを遮断することにも成功しました。

これにより、従来Windows Serverでは敷居の高かった海外IPからのSSTPへのアクセス制御も手前のHAProxyで一体的に可能になり、トータルのセキュリティが大きく向上しました。

具体的な設定

HAProxyの具体的な設定は次回に。

ださっち: