自宅サーバーに複数のサービスを載せたい: 構想編
自分はルーターとしてMinisforum MS-01を使ってます。元々自宅サーバー用に用意した機材で、NICが沢山あって都合がよかったので採用したのですが、i5-12600H + 32GB RAMのマシンをルーターだけに使うのはもったいないですよね。
そもそもサーバー用マシンを使ったので、じゃあサーバーをどうするんだという話にもなりますし。
なので、このマシンをルーターとして使いつつ、各種サービスも同居させてしまえばいい話なのですが、そこで気になるのがセキュリティ。どうしましょうかね。
ホスティングしたいサービス
とりあえず何をこのマシンに載せたいのか列挙していきましょう。
ルーター
現状、このマシンの10G NICがONUに繋がっていて、ここからsystemd-networkdとかnftablesを使ってfirewallだったりXpassへのトンネルやNAT変換、固定IPの運用を行っています。
LAN内向けのDHCP,DNSサーバーとしてdnsmasqとか、宅外から繋ぐためのVPNサーバーとかもここで動いてますね。
このあたり、Minisforum MS-01の拡張性と、Linuxマシンでネットワークをいじる自由度がとてもいいので、他の環境に移行するつもりは現状ありません。
Webサーバー
このサイトを運用しているものです。サイトを作り変える前はWordpressだったのですが、負荷や管理の手間から新しいサイトはSSGにしたため、静的なファイルを配布するだけでよくなりました。
なので、Cloudflare Pagesとかに移行してもいいんですけど、それとは別に全文検索エンジンとか導入できたりしないかとも思っているので、現状そのまま自宅サーバーでのホスティングを継続するかなと考えています。
メトリクス・ログ監視
現状でもcockpitを使って簡単に見たりはしているのですが、もっとちゃんとしたものが欲しいです。あと、開発用のLinuxマシンとかバックアップで稼働しているRaspberry Piとかの情報も一緒に収集できたらいいですね。
なので、Grafanaで一元管理できるようにしたいと思ってます。とはいえバックエンドをどうするか迷ってて、現状の考えだと VictoriaMetrics + VictoriaLogs が有力候補。
NAS
MS-01にはM.2 SSDを3枚挿せます。ここに起動用SSDに加えて4TB SSDを2枚挿してNASにしたいです。(SSDが値上がりする前に買っておいてよかった)
ここにデータを補完しておくsambaサーバーを立てます。あと追加でオブジェクトストレージサービスとしてGarageも立てる予定なのと、sambaがよく不安定になるためnextCloudも立てようか迷ってます。
Home Assistant
HomeKitに対応しているものはiPhoneのホームアプリから、自作したものはブラウザかM5Paperから、みたいな運用をしているので、ここはHome Assistantサーバーを立ててまとめて管理できるようにしたいところです。
懸念点
インターネットに直接面しているルーターと、不特定多数からアクセス可能なWebサーバーと、自分だけがLAN内から使うその他諸々が同居してていいのかって話ですね。
たとえばLAN内からしかアクセスしないNASを、ルーターの内側でLAN内に配置するなら特に考えることはないですよね。ルーターは外部からの接続をブロックするだけでよく、NAS側でfirewallを特別に設定する必要はありません。
一方で、ルーターと同居させるとなると、ルーターはLAN内外の境界にいるので、NASが使うサービス・NIC・ポートごとにnftablesとかで内側からのみアクセスを許可するようなフィルタを設定する必要があります。
これは管理が大変だし、ミスって不要なサービスまでインターネット側からアクセスできるようになってしまうリスクがあるので嫌ですね。
また、Webサーバーは脆弱性が存在しやすい箇所だと思ってるため、サーバー内でnginxユーザーからアクセス可能なファイルはいつサーバーから流出してもおかしくないって思ってます。
それを防ぐためにSELinuxとかAppArmorみたいなのがあるわけですが、あのあたり「やりたいことができないのでとりあえず関係ありそうな権限を付与する」みたいな運用になりがちで、トラブルに遭遇しやすいうえに本当に意味あるの?って感じになるのであまり好きではないです。
というわけで色々同居させる懸念点があるわけですが、これを解消する仕組みがありますよね。仮想マシンで分離しましょう。
Hypervisor何使う?
仮想化の方法にも色々あります。どれがいいでしょうか
コンテナ
Docker, podman, systemd-nspawnとかのことです。HostOSのカーネルを共有しつつ、cgroupやchrootを使って分離した環境を作ります。
OSを起動する環境そのまま再現する必要がないため軽量だし、リソースの制限かけたりネットワークもNamespaceで分離できるので便利なのですが、以下の点で却下でした
- 自動起動・コンテナイメージの更新・定期実行のいい方法がわからない
- Composeは機能不足
- k8sは機能過多
- ルーターをコンテナに載せられない
- 基本的にsystemdはコンテナ上で動かさないし、netfilterをがっつり操作する必要があるためコンテナにHostOSのスーパーユーザーとほぼ同等の権限を与えることになってあんまり意味がない
それこそ、NASに使うSSDはNAS VMにPCIe Passthroughで直接割り当てることでNAS VMだけがSSDにアクセスできる、くらいの分離度が欲しかったのでコンテナは合いませんでした。
Kata Containers
コンテナのエコシステムを使ってコンテナ以上の分離度でセキュリティを強化するやつ。コンテナ1つにつき1個のSystemVM(Linuxカーネル)を起動します。
これも結局OCIコンテナを使うためsystemd-networkdどうする問題があるのと、PCIe Passthroughの対応が微妙だったので却下でした。
Qemu KVM
直接qemu-kvmを実行する形でVMを使います。
実は6月にMS-01をルーターにしてから、しばらくはこの方針で運用していたのですが、
- 新規VMを立ち上げるのに毎回OSのインストールが必要
- 仮想マシンを個別に管理する必要がある
という点でスケールしないなと。一応systemdのサービスとして扱えるようにはしていたものの管理が大変だったのでなんとか改善したい点でした。
Proxmox
元々HostOSにもGuestOSにもNixOSを使ってました。HostOSをProxmoxにしたらどうだろうとは考えたのですが、Nix Flakeでの一元管理ができなくなるのでむしろ悪くなるなと思ってやめました。
microvm.nix
というわけで、最終的な結論がこれです。Nixで宣言的にVMを管理できるやつです。HypervisorにはQemuやCloud Hypervisor, FirecrackerなどのSystemVMを使用します。
NixOSで使うと、nix-configurationにVMの構成を記述してビルドすれば、systemdのサービスとしてVMを起動してくれます。
主な特徴は以下の通り。
- VM上の環境もすべてHostOSのnix-configurationで記述可能
- HostOSでパッケージをアップデートすれば、GuestOS側もアップデートされる
- virtiofsでホストOSの/nix/storeを使用可能
- ストレージが削減できる
- GuestOS側で自由なパッケージのインストールが不可能
- readonlyでマウントするため
- GCなどはHostOS側でのみ考えればいい
- HypervisorにQemuを使うと、QMPでVMのシャットダウンとかの制御をやってくれる
- nix-configurationをrebuildしたときやsystemctlでrestartしたときにVMを再起動してくれる
- HostOSをシャットダウンするときに事前にVMもシャットダウンしてくれる
- PCIeやUSBデバイスのPassthroughに対応
- VM上でNixOSがほぼそのまま動く
- 利点として、NixOSで動くものはそのままVMに載せられる
- 欠点として、VMが重たくて起動・終了に時間がかかる
- コミュニティ規模が小さいため、情報が少なくて、かつ不安定になりがち
- 導入にかかる学習コストが非常に高い
- これはmicrovm.nixに限らずNix全般的な話
HostOSと一緒にGuestOSも管理できるためメンテナンスがすごく楽で、その上で自分が考えているVMの構成を実現できそうだったのでこれに決めました。
次、microvm.nix編に続きます。
そもそもmicrovm.nixの使い方がよくわかんないので、ここをなんとかしないといけません。 GitHub - microvm-nix/microvm.nix: NixOS MicroVMs ...
