NginxProxyManagerとDDNSで宅内LANをHTTPS化したかった
概要
困っていること
自宅内のサーバーにアクセスする場合でもHTTPSが求められることが多くなってきました(Vaultwardenとか)。そうすると出てくるのがこれです。
LAN内だから許してくれよと思わないでもないですが、このいちいち出てくる警告画面をスキップするには証明書を用意してHTTPS化するしかありません。
いわゆるオレオレ認証局を作って証明書を配ってもいいのですが、各ブラウザで設定しなければいけないのでこれまた面倒くさい。
そこでサーバーの前段にリバースプロキシを置いて、ワイルドカード証明書を取得することで無限にサブドメインをHTTPS化するという方法を採ることにします。
リバースプロキシとは
リバースプロキシとは、クライアントから見てサーバーの前段に用意されたプロキシで、負荷分散とか色々な効用があるらしい。今回重要なのは、例えばhoge.example.comは192.168.1.10、fuga.example.comは192.168.1.20のように、サブドメインを投げると実際のサーバーに振り分けて繋いでくれるという機能です。さらにSSL暗号化もリバースプロキシに任せることができます。
https://www.cloudflare.com/ja-jp/learning/cdn/glossary/reverse-proxy/
使うソフトウェア
今回はリバースプロキシとしてNginxProxyManagerを使います。
NginxProxyManagerはNginxをリバースプロキシとして利用するのをGUIで設定できる便利なソフトウェアです。
Let’sEncryptの証明書も対応しているDNSならGUIでポチポチするだけで取得できてしまいます。
NginxProxyManagerのデプロイ
DockerとDocker-composeの環境が整っていれば、docker-compose.ymlを書いてupするだけです。
mkdir nginxproxymanager
cd nginxproxymanager
mkdir data
mkdir letsencrypt
nano docker-compose.yml
# docker-compose.ymlの内容
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
# environment:
# PUID: 1000
# PGID: 1000
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- /home/<username>/nginxproxymanager/data:/data
- /home/<username>/nginxproxymanager/letsencrypt:/etc/letsencrypt
# ここまで
sudo docker-compose up -d
ブラウザで127.0.0.1:81にアクセスするとログインを求められます。
Email: admin@example.com
Password: changeme
でログインします。
変更を求められるので、メールアドレスとパスワードを変更します。
DDNSでドメイン名を用意する
Let'sEncryptで証明書を取るためのドメインを用意します。ワイルドカード証明書を取るためにDNS-01チャレンジを行うので、NginxProxyManagerが対応しているDNSプロバイダーでドメインを取るのが楽だと思います。
YouTubeなんかを見るとDDNSサービスのDuckDNSで取得していることが多いのですが、我が家ではDuckDNSがブロックリスト入りしているので(フィッシングに使われまくってるからね…)同じくDDNSのDynuを使ってドメインを取得します。
DynuでAPIキーを取得する
サインアップを済ませましてコントロールパネルからDDNS Servicesでドメインを登録します。
外部に公開するわけではないのでIPアドレスにはNginxProxyManagerのローカルIPアドレスでも指定しておきましょう。
次にコントロールパネルのAPI CredentialsからAPIキーを取得します。双眼鏡アイコンで見ることができます。
NginxProxyManagerでSSL証明書を取得する
Let’sEncryptの証明書の取得にはHTTP-01チャレンジかDNS-01チャレンジに成功する必要があります。HTTP-01チャレンジは証明書を取得するサーバーの80番ポートを開けておく必要があり、またサブドメインごとに一つ一つ取得しなくてはなりません。そこで今回はDNS-01チャレンジでワイルドカード証明書を取得することにします。
NginxProxyManagerにAPIキーを登録してチャレンジする
NginxProxyManagerの上部のタブからSSL Certificatesを選択し、Add Certificatesボタンをクリックします。
Domain Nameはドメイン名とワイルドカードを利用したサブドメインを入力します。例:hoge.mywire.orgと*.hoge.mywire.org
DNS Providerで適当なものを選択します。今回はDynuです。
Credentials File ContentにAPIキーを登録します。
エラーが出ることがありますが、正しく設定されていれば少し待ってもう一度チャレンジすると通ると思います。
私は遭遇しませんでしたが、特定のエラーの回避方法らしきものがあったので置いておきます。
NginxProxyManagerにホストを登録する
HostタブからProxy Hostsを選択し、Add Proxy Hostボタンを押してホストを登録する。
手始めにNginxProxyManagerの管理画面をホストとして登録する。
hoge.mywire.orgへアクセスすると、以下のようにHTTPS化されたログイン画面が表示される。
他のホストを追加すると502BadGatewayになる
ここまでは上手くいったのだが、他のホスト(NASなど)を追加してアクセスすると502BadGatewayになったりならなかったりする。
よくわからない。
うまくいったパターンでもChromeでアクセスすると危険なサイトという警告が出てしまう。Dynuもよくフィッシングに使われているのかもしれない。
警告画面をスキップしようとして別の警告画面がでるなら意味ないんだよなぁ。今回の試みは失敗かもしれない。