はじめに
こにちは。てねろです。
突然ですが
自宅サーバーをやってみたい!!!!!!
ということで、余っていたノートPCにNixOSを入れて常時稼動させることにしました。
しかし、回線がJ:COMマンションタイプ+備え付けWi-Fiという「ポート開放不可能」な構成で素直に外部公開することは叶わなかったのだ………
最終的にはCloudFlare Tunnelを使うことで、グローバルIPなし・ポート開放なしでもHTTPSでインターネット公開できたので、その手順をまとめます。
筆者はLinuxを触りはじめて3ヶ月の新生児なのでいたらない部分があるかもしれません。
環境/前提
- マシン:ProBook 430 G8
- OS:NixOS
- 用途:自作webフレームワークの本番環境
- デプロイ方法:git pull + systemd
- 回線環境:アパートの共有WiFi←やめたい
- flake
本記事ではcloudflaretunnelを使用します。
ポート開放はしません。
NixOS/nixについて
nixとは純粋関数が使われた宣言的なパッケージマネージャーであり、言語としてのnix、ビルドシステムとしてのnixといった包括的な名称でもあります。
nixを使用する最大にして唯一無二の理由、それは完璧に近い再現性にあります。
通常、自作サーバーではubuntu-serverのような安定したOSが好まれていますがNixOSでのサーバー化は全てが宣言的に為されており、依存関係地獄や不慮の事故に悩まされることはありません。
また、一度configを書いてしまえば別のPCに移行しても
sudo nixos-rebuild switch --flake .dotfiles
してしまえば全く同じ環境で開発を続けることができるというメリットもあります。
本記事ではflakeの説明は省きます。
Cloudflare Tunnelについて
Cloudflare Tunnelとはローカル環境をグローバルipを介さず外部に公開できる仕組みのことです。
自分のPCからCloudflareにつなげることで、登録したトンネルに紐づかれたドメインから逆方向にQUICなどの接続を通してCloudflareがHTTPリクエストをそのまま流し込み、PCが返したレスポンスをCloudflareがHTTPSでユーザーに返すことが可能になります。
つまりサーバーPCがWi-Fiにさえ繋っていればCloudflareが代理で外部公開を可能にし、外部からは自分のPCではなくCloudflareにアクセスされるのでセキュリティ的にもよいといえるでしょう。
しかしデメリットとしてインターネット公開がCloudflare依存になってしまうのでCloudflareに障害が起きたときに繋げなくなってしまうというものがあります。
Cloudflare Tunnel はサーバー側から Cloudflare へのアウトバウンド接続だけで動作するため、サーバーの firewall でポート開放を行う必要はありません。
configuration.nix
systemd
systemd.services.mywebfw = {
description = "My Web Framework Server";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "/home/tener/mywebfw/mywebfw";
Restart = "always";
WorkingDirectory = "/home/tener/mywebfw";
};
};
自身のwebアプリをsystemdサービスとして常駐します。
ここでは私の作成したgoフレームワークのGoバイナリを噛ませています。
Cloudflare Tunnel
services.cloudflared = {
enable = true;
tunnels."mywebfw" = {
credentialsFile = "/var/lib/cloudflared/mywebfw.json";
ingress = {
"tenelol.dev" = "http://localhost:8080";
};
default = "http_status:404";
};
};
CloudflareをNixOSで有効化させます。
environment.systemPackages = with pkgs; [
cloudflared
];
なお先にCloudflareをインストールする必要があります。
Cloudflareで外部公開する流れは後に書いています。
サスペンド無効化
services.logind = {
lidSwitch = "ignore";
lidSwitchExternalPower = "ignore";
lidSwitchDocked = "ignore";
};
systemd.sleep.extraConfig = ''
AllowSuspend=no
AllowHibernation=no
AllowHybridSleep=no
AllowSuspendThenHibernate=no
'';
サスペンドを無効化してラップトップを閉じたままでもサーバーを常時稼動させます。
Cloudflare Tunnelで外部公開する
Cloudflare でやる作業一覧
-
ドメイン登録
Cloudflare ダッシュボード → Add Site → DNS を Cloudflare に向ける -
Tunnel 作成
Zero Trust → Network → Tunnels → Create a Tunnel
→ Tunnel 名を入力 -
Public Hostname を作成
Tunnel 詳細 → Public Hostnames
Hostname:tenelol.dev
Service:http://localhost:8080 -
自動生成された CNAME を確認
DNS → tenelol.dev が .cfargotunnel.com に向いていることを確認
サーバー側の設定
cloudflared tunnel login
cloudflared tunnel create mywebfw
cloudflared tunnel route dns mywebfw tenelol.dev
その後~/.cloudflared/にUUID.jsonができるため、これを /var/lib/cloudflared/mywebfw.json に配置します。
NixOSではconfiguration.nixで設定するので~/.cloudflared/config.ymlを書く必要がありません。
ここまででCloudflare側の設定は終わりです。
実装
sudo nixos-rebuild switch --flake .dotfiles
sudo systemctl restart mywebfw.service
configuration.nixを記入後リビルドしてsystemdを再起動させます。
開発用のPCからデプロイしたあとにも同様に行います。
ここで新しくデプロイする場合、できあがったバイナリを更新するのを忘れないようにしましょう。
まとめ
NixOSによる自作サーバーはサーバー設定をすべてdeclarativeに管理でき、
Cloudflare TunnelはグローバルIPやポート開放に縛られない現代的な選択肢として非常に便利でした。今回はノートPCをサーバー化したのでバッテリーを外して運用していますがとても快適に動作しています。
せっかく自宅サーバーもできあがったことだし、用途考えるか〜〜(クネクネ
おまけ
NixOS/nixに興味を持ったそこの君 !
Nixは学習コストこそ高いですが学ぶ価値はそれ以上にあると考えています。
まずは私もお世話になったNix入門から始めてみてはいかが?
ここで説明したコードもNixOS公式のサイトoption searchから検索することが出来ます。