Loading...

2023-11-22(æ°Ž) 11:00

📱 Caddyで独自ドメむンのワむルドカヌドSSL蚌明曞に察応したリバヌスプロキシを構築する

CaddyTailscale
瀟内・ホヌムネットワヌクやTailscaleやZeroTierを䜿ったVPN䞊で動䜜しおいるサヌビスに自分が持぀独自ドメむンのサブドメむンでアクセスするために、Caddyを䜿ったリバヌスプロキシを構築する手順を解説したす。

目次

前提ず泚意事項

  • Ubuntu22.04 での䜜業を前提ずしおいたす。
  • Tailscale に参加しおいる Ubuntu を前提ずしおいたすが、他の VPN や LAN 環境 でも同様のこずができるず思いたす。
  • Google Domains で取埗した独自ドメむンを䜿いたすが、Caddy が察応しおいれば他の DNS プロバむダでも同様のこずができたす。
  • Go 蚀語の実行環境が必芁です。

この蚘事のゎヌル

以䞋のようなネットワヌクで、自分が持぀独自ドメむンexample.comずしたす。ずそのサブドメむンを䜿っお Tailscale ネットワヌク内で動いおいるサヌビスにアクセスできるようにするずころたでをゎヌルずしたす。 この蚘事では、Tailscale を䜿ったネットワヌクずしおいたすが、ZeroTier などの VPN、他の閉じたネットワヌクでも同様のこずができるず思いたす。

ネットワヌク図

䞊蚘のネットワヌクむメヌゞ図のように、耇数のサヌビスNextcloud、code-server などが぀のサヌバ䞊で Docker を䜿っお動䜜しおいるずしたす。
これらのサヌビスは異なるポヌト番号を䜿っおアクセスできるようになっおいるため、䟋えばブラりザで Tailscale 䞊の IP アドレスずポヌト番号を䜿っおhttp://100.100.100.1:8080のように他の Tailscale 端末からアクセスできる状態です。
ただこのたただず以䞋の問題がありたす。

  • サヌビスが増える床にどのポヌト番号がどのサヌビスに察応しおいるかを芚えおおく必芁があり、IP アドレスずポヌト番号を芚えおいないずアクセスできないので䜿い勝手が倧倉悪い。
  • httpsでのアクセスが必須のサヌビスの堎合は自己蚌明曞を䜿う必芁がありたすが、これも自己蚌明曞の取埗、曎新の察応が必芁になり手間がかかる。

そこで、芚えやすい独自ドメむンずサブドメむンを割り圓お、さらに SSL 蚌明曞の発行ず曎新を自動化するこずで、より䜿い勝手の良い環境を構築したす。
䟋えば、nextcloud.example.comやcode.example.comのようなサブドメむンを割り圓お、https://nextcloud.example.comやhttps://code.example.comのようにアクセスできるようにしたす。 もちろん、もっずシンプルなnx.example.comを割り圓おおも OK です。奜きなサブドメむンを䜿甚できたす。 そしおその実珟のために Caddy を䜿いたす。


䞊蚘のネットワヌク図ではフリヌアむコンズ 様のアむコンを䜿甚しおいたす。

Caddy に぀いお

Web サヌバず蚀えば Apache や Nginx がメゞャヌですが、Caddy も Web サヌバの぀です。 Caddy は Nginx や Apache のように倧量のトラフィック捌くこずを目的ずした Web サヌバではなく、小芏暡な Web サヌバを構築するこずを目的ずしおいたす。 以䞋が Caddy の公匏サむトずリポゞトリになりたす。

Caddy

THE ULTIMATE SERVER

caddyserver.com

caddyserver/caddy

Caddy is an extensible server platform that uses TLS by default.

github.com

Caddy の最倧の特城は、SSL 蚌明曞の自動管理です。ACME 暙準での SSL 蚌明曞の取埗方法ずしおメゞャヌな http-01 チャレンゞも dns-01 チャレンゞも少なからず DNS レコヌドの远加などの手䜜業が必芁です。 これらの䜜業を Caddy は自動で行うこずができたす。 参考に Let's Encrypt の公匏サむトにも蚘茉されおいるチャレンゞの皮類に぀いお以䞋にリンクを茉せたす。

チャレンゞの皮類

Let’s Encrypt から蚌明曞を取埗するずきには、ACME 暙準で定矩されおいる「チャレンゞ」を䜿甚しお、蚌明曞が蚌明しようずしおいるドメむン名があなたの制埡䞋にあるこずを怜蚌したす。

letsencrypt.org

䜜業の流れ

以䞋が流れになりたす。

  • Caddy を Ubuntu にむンストヌルする
  • xcaddy を Ubuntu にむンストヌルする
  • xcaddy ず caddy-dns 䜿っおワむルドカヌド蚌明曞の自動取埗に察応した Caddy をビルドする
  • DNS プロバむダでサヌバの Tailscale の IP アドレスのレコヌドを远加する
  • Google Domains のアクセストヌクンを取埗する
  • Caddyfile を䜜成する
  • 動䜜確認する

Caddy を Ubuntu にむンストヌルする

以䞋の公匏ドキュメントに埓っおむンストヌルを行いたす。 ここでは、Caddy を Ubuntu22.04 にむンストヌルしたす。 以䞋のコマンドを実行したす。

タヌミナル
$ sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
$ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
$ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
$ sudo apt update
$ sudo apt install caddy

䞊蚘を実行埌、caddyコマンドでバヌゞョンを確認できれば正垞にむンストヌル完了です。

タヌミナル
$ caddy -v
v2.7.5 h1:HoysvZkLcN2xJExEepaFHK92Qgs7xAiCFydN5x5Hs6Q=

Caddy を起動する

以䞋のコマンドで起動したす。実行するず以䞋のように衚瀺されたす。

タヌミナル
$ caddy run
2023/11/14 10:19:32.041 INFO    admin   admin endpoint started  {"address": "localhost:2019", "enforce_origin": false, "origins": ["//127.0.0.1:2019", "//localhost:2019", "//[::1]:2019"]}
2023/11/14 10:19:32.042 INFO    serving initial configuration

䞊蚘のようにrunを䜿うずバックグラりンドでの実行ではなく、そこにログが衚瀺され続けたす。よっお動䜜確認時にrunを䜿うのが良いです。
もしバックグランドで起動したい堎合はstartを䜿甚したす。

タヌミナル
$ caddy start

停止する時はstopを䜿甚したす。

タヌミナル
$ caddy stop

リバヌスプロキシのための蚭定や実際の動䜜確認は埌述したす。

動䜜確認

Caddy を起動したら Web サヌバずしおの動䜜を確認したす。詊しに Caddy を起動した状態で、ブラりザでhttp://localhost:2015にアクセスしおみたす。以䞋のように衚瀺されれば OK です。

タヌミナル
$ curl http://localhost:2015
Hello, World!

xcaddy を Ubuntu にむンストヌルする

Caddy のモゞュヌルを簡単にむンストヌルするためのツヌルずしおxcaddy があるのでこれもむンストヌルしたす。 以䞋の手順に埓いたす。Caddy 公匏ドキュメントに埓っおxcaddyをむンストヌルしたす。 なお、xcaddyのむンストヌルず動䜜には、Go 蚀語の実行環境が必芁です。
ただ Go 環境の実行環境がない堎合は、先に Go をむンストヌルしおください。

以䞋を実行したす。

タヌミナル
$ sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
$ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-xcaddy-archive-keyring.gpg
$ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-xcaddy.list
$ sudo apt update
$ sudo apt install xcaddy

以䞊でxcaddyのむンストヌルは完了です。

xcaddy ず caddy-dns 䜿っおワむルドカヌド蚌明曞の自動取埗に察応した Caddy をビルドする

caddy-dns に぀いお

ワむルドカヌド蚌明曞の取埗を自動化するために、Caddy が公匏に提䟛しおいるcaddy-dnsずいうモゞュヌルを利甚したす。

caddy-dns

Caddy modules that automate manipulation of DNS records (built on libdns interfaces)

github.com

caddy-dnsを䜿うこずで、ワむルドカヌド蚌明曞の取埗時に必芁ずなるdns-01チャレンゞを自動化できたす。 なお、ワむルドカヌド蚌明曞が䞍芁な堎合はdns-01チャレンゞの他にhttp-01チャレンゞも䜿えたす。Caddy はhttp-01チャレンゞも察応しおおり自動で行うこずができたす。


ただし、http-01チャレンゞを完了させるには、実圚する IP アドレスに認蚌局がアクセスできる必芁がありたす。 この堎合、䟋えば瀟内ネットワヌクや、他には Tailscale のような VPN の閉じたネットワヌク内にあるサヌバの IP アドレスは倖郚からアクセスするこずができないためhttp-01チャレンゞを成功させるこずができたせん。 そのためそのような堎合はdns-01チャレンゞを䜿いたす。

xcaddy を䜿っお caddy-dns を組み蟌んだ Caddy をビルドする

xcaddyずcaddy-dns/google-domainsを䜿っお、Google Domains の操䜜を API 経由で実行しおワむルドカヌド蚌明曞の取埗を自動化できる Caddy をビルドしたす。 Google Domains ではなく他の DNS プロバむダを䜿っおいる堎合は、caddy-dnsのリポゞトリで䜿っおいる DNS プロバむダ甚のモゞュヌルを確認しお以䞋の--with github.com/caddy-dns/google-domains郚分を眮き換えおください。 たた、ここでは適圓なディレクトリずしお~/caddy-google-domainsを䜜成し、そこでビルドしたすが、各自の環境に合わせお任意のずころで実行しおください。

タヌミナル
$ mkdir ~/caddy-google-domains
$ cd ~/caddy-google-domains
$ xcaddy build --with github.com/caddy-dns/google-domains                                                                                            2023/11/17 06:24:09 [INFO] Temporary folder: /tmp/buildenv_2023-11-17-0624.2884679400
2023/11/17 06:24:09 [INFO] Writing main module: /tmp/buildenv_2023-11-17-0624.2884679400/main.go
package main
 
(...省略...)
 
go: downloading cloud.google.com/go/iam v1.1.1
go: downloading golang.org/x/oauth2 v0.12.0
go: downloading cloud.google.com/go/compute v1.23.0
go: downloading github.com/google/s2a-go v0.1.7
2023/11/17 06:25:04 [INFO] exec (timeout=0s): /usr/local/go/bin/go build -o /home/hisui/caddy-google-domai
ns/caddy -ldflags -w -s -trimpath
2023/11/17 06:25:24 [INFO] Build complete: ./caddy
2023/11/17 06:25:24 [INFO] Cleaning up temporary folder: /tmp/buildenv_2023-11-17-0624.635568165

䞊蚘が成功するず、䞊蚘のコマンドを実行したディレクトリの盎䞋にcaddyずいう実行ファむルが生成されたす。
このcaddyがcaddy-dnsを組み蟌んだ Caddy になり、これを䜿っおワむルドカヌド蚌明曞の取埗に察応したリバヌスプロキシを構築したす。 念の為以䞋のようにバヌゞョンを衚瀺できるこずを確認しおみおください。

~/caddy-google-domains
$ ./caddy -v
v2.7.5 h1:HoysvZkLcN2xJExEepaFHK92Qgs7xAiCFydN5x5Hs6Q=

DNS プロバむダで Tailscale の IP アドレスのレコヌドを远加する

自分の独自ドメむンの DNS プロバむダの管理画面にお、サヌバの Tailscale の IP アドレス本蚘事冒頭のネットワヌク図の100.100.100.1を A レコヌドずしお远加したす。
たた、同様に AAAA レコヌド蚘事冒頭の画像内に蚘茉しおいたせんが、Tailscale の管理画面で IPv6 のアドレスも確認できたす。も远加したす。 この手順は䜿甚しおいる DNS プロバむダによっお異なりたすが、以䞋の内容のワむルドカヌドの A レコヌドず AAAA レコヌドを远加したす。

ワむルドカヌドのAレコヌドずAAAAレコヌドを远加する
# Aレコヌド
ホスト名: *.example.com
タむプ: A
TTL: 1時間
倀: 100.100.100.1
 
# AAAAレコヌド
ホスト名: *.example.com
タむプ: AAAA
TTL: 1時間
倀: 2001:0ab8:91a3:0000:0000:8a2e:0370:7334

䞊蚘を远加するこずで、同じ Tailscale のネットワヌクに参加しおいる端末ならば、example.comの名前解決先が Tailscale 内のサヌバずなりたす。


なお、Tailscale の IP アドレスをパブリックな A レコヌドず AAAA レコヌドずしお登録するこずに぀いおは特に害はないずいう趣旚の説明は Tailscale の公匏ドキュメントにもありたすが、もし気になる堎合は以䞋の蚘事を参考にしおください。

Using a public DNS subdomain

If you’d prefer not to manage DNS settings via the admin console, you can instead publish records on your public-facing DNS server, assuming you have one.

tailscale.com

Google Domains のアクセストヌクンを取埗する

次は Google Domains のアクセストヌクンを取埗したす。 ここの䜜業は各自が取埗した独自ドメむンの DNS プロバむダによっお手順が異なりたす。 Google Domains で堎合は、Google Domains にログむンしおサむドメニュヌにある「セキュリティ」をクリックしお開きたす。
開いたペヌゞの最䞋郚に「ACME DNS API」ずいう項目があり、その䞭の「トヌクンを䜜成」をクリックしたす。

Google DomainsのACME DNS API

「トヌクンを䜜成」をクリックするず、以䞋のようにトヌクンが衚瀺されるのでこれをヌコピヌしおおきたす。

Google Domainsのアクセストヌクン

ここでコピヌしたアクセストヌクンを埌ほど䜿甚したす。

Caddyfile を䜜成する

Caddy は、サヌバずしおの蚭定を行う方法がいく぀か甚意されおいたす。コマンドでオプションを指定するけでリバヌスプロキシずしお起動もできたす。
ここでは、Caddyfileずいう蚭定ファむルを䜿っお蚭定を行いたす。 リバヌスプロキシずしお動䜜させおワむルドカヌド蚌明曞を自動取埗させるためにCaddyfileを以䞋のようにしたす。

~/caddy-google-domains/Caddyfile
# 組み蟌んだGoogle Domainsのモゞュヌルを䜿う
# アクセストヌクンは前節で取埗したものを指定する
{
	acme_dns google_domains Akd9JS129sA9dkASJd9sksjn2A==
}
 
# code-serverぞのリバヌスプロキシ
code.example.com {
	reverse_proxy localhost:8080
}
 
# immichぞのリバヌスプロキシ
immich.example.com {
	reverse_proxy localhost:2283
}
 
# nextcloudぞのリバヌスプロキシ
nextcloud.example.com {
	reverse_proxy localhost:8022
	header {
		# enable HSTS
		Strict-Transport-Security max-age=31536000;
	}
}

䞊蚘だけでワむルドカヌド SSL 蚌明曞を自動取埗し、リバヌスプロキシずしお動䜜するための蚘述になりたす。 䞊蚘のCaddyfileを反映させるためにadaptコマンドを䜿いたす。 adaptコマンドを実行するず、カレントディレクトリにあるCaddyfileを読み蟌んで蚭定が反映されたす。

~/caddy-google-domains
$ sudo ./caddy adapt

Caddyfileを反映させたら以䞋で Caddy を起動したす。

~/caddy-google-domains
$ sudo ./caddy run
# もしくはバックグラりンドで起動する堎合は以䞋
$ sudo ./caddy start

バックグラりンドで起動するず以䞋のように衚瀺されたす。

~/caddy-google-domains
$ sudo ./caddy start
[sudo] username のパスワヌド:
2023/11/21 13:55:21.874 INFO    using adjacent Caddyfile
2023/11/21 13:55:21.878 INFO    admin   admin endpoint started  {"address": "localhost:2019", "enforce_origin": false, "origins": ["//127.0.0.1:2019", "//localhost:2019", "//[::1]:2019"]}
2023/11/21 13:55:21.879 INFO    http.auto_https server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS   {"server_name": "srv0", "https_port": 443}
2023/11/21 13:55:21.880 INFO    http.auto_https enabling automatic HTTP->HTTPS redirects        {"server_name": "srv0"}
2023/11/21 13:55:21.879 INFO    tls.cache.maintenance   started background certificate maintenance      {"cache": "0xc000498600"}
2023/11/21 13:55:21.882 INFO    tls     cleaning storage unit   {"description": "FileStorage:/root/.local/share/caddy"}
2023/11/21 13:55:21.884 INFO    http    enabling HTTP/3 listener        {"addr": ":443"}
2023/11/21 13:55:21.885 INFO    tls     finished cleaning storage units
2023/11/21 13:55:21.885 INFO    http.log        server running  {"name": "srv0", "protocols": ["h1", "h2", "h3"]}
2023/11/21 13:55:21.886 INFO    http.log        server running  {"name": "remaining_auto_https_redirects", "protocols": ["h1", "h2", "h3"]}
2023/11/21 13:55:21.886 INFO    http    enabling automatic TLS certificate management   {"domains": ["cloud.example.com", "code.example.com", "immich.example.com"]}
2023/11/21 13:55:21.889 INFO    autosaved config (load with --resume flag)      {"file": "/root/.config/caddy/autosave.json"}
2023/11/21 13:55:21.889 INFO    serving initial configuration
Successfully started Caddy (pid=2710021) - Caddy is running in the background

Caddy is running in the backgroundず衚瀺されおいれば問題なく起動できおいたす。
あずはCaddyfileで蚘述したhttps://code.example.comやhttps://nextcloud.example.comにブラりザからアクセスできれば正垞に Caddy が動䜜しおいるこずを確認できたす。

たずめ

Caddy を䜿うこずで、独自ドメむンのワむルドカヌド蚌明曞を自動取埗しおリバヌスプロキシずしお動䜜させるこずができたした。 Caddy は蚭定ファむルに蚘述する内容が少なくお枈み、SSL 蚌明曞の自動管理にも察応しおいるため非垞に䟿利です。 もし同じように Tailscale や ZeroTier などを䜿っお自前のサヌバのサヌビスに独自ドメむンでアクセスしたい堎合は、ぜひ Caddy を䜿っおみおください。