GCEの無料枠で1台動かしているサーバを作り直したのでLets encryptを入れる。
以前はcertbotというのを使ったが、今回はlegoというGo実装のCLIでやってみた。
しかしこれをやった後、ブログ記事として整理しようとあっためてる間にGoogle Domains終了のお知らせが出るとは。
さっさと投稿しろということか…
まずlegoでググるとACMEクライアントのHTTP-01 challengeを使うのがよく出てくるが、設定したいのはdevドメインなのでこのやり方は上手くいきません。httpsの設定をこれからやろうというのにhttpsじゃないとアクセス出来ないドメインなんだから。
そこでDNS-01 challengeを使ってみます。
DNSでTXTレコードに特定の文字列を入れて認証するというもののようです。
私のdevドメインはGoogle Domainsで管理しています。
legoでGoogle Domainsはサポートされているようです。
さっそくやってみます。
まずは GOOGLE_DOMAINS_ACCESS_TOKEN を作ります。
Google Domainsのセキュリティ開いたらACME DNS APIという項目があるの「トークンを作成」から作れます。簡単ですね!
apt でいれたlegoでやってみる。
GOOGLE_DOMAINS_ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx== lego --email foo@example.com --dns googledomains --domains www.example.dev run 2023/06/04 10:26:10 unrecognized DNS provider: googledomains
あれあれ?
# apt info lego Package: lego Version: 4.1.3-3ubuntu1.22.04.1
なるほど。バージョンを満たしてないのか。
Configuration for Google Domains.
- Code: googledomains
- Since: v4.11.0
しかたないソースから入れるか。
要件は以下の通り。
go1.17+ environment variable: GO111MODULE=on
$ sudo apt remove lego $ sudo apt install golang-go $ go version go version go1.18.1 linux/amd64 $ go install github.com/go-acme/lego/v4/cmd/lego@latest (snip) # github.com/go-acme/lego/v4/providers/dns/arvancloud/internal go/pkg/mod/github.com/go-acme/lego/v4@v4.12.0/providers/dns/arvancloud/internal/client.go:59:24: c.baseURL.JoinPath undefined (type *url.URL has no field or method JoinPath) go/pkg/mod/github.com/go-acme/lego/v4@v4.12.0/providers/dns/arvancloud/internal/client.go:84:24: c.baseURL.JoinPath undefined (type *url.URL has no field or method JoinPath) go/pkg/mod/github.com/go-acme/lego/v4@v4.12.0/providers/dns/arvancloud/internal/client.go:103:24: c.baseURL.JoinPath undefined (type *url.URL has no field or method JoinPath) note: module requires Go 1.19 # github.com/go-acme/lego/v4/providers/dns/autodns/internal go/pkg/mod/github.com/go-acme/lego/v4@v4.12.0/providers/dns/autodns/internal/client.go:63:24: c.BaseURL.JoinPath undefined (type *url.URL has no field or method JoinPath) note: module requires Go 1.19 (snip)
最新バージョンだと新しいGoじゃないとダメっぽい。
Goも手動で入れるか。
$ cd /usr/local/src $ sudo wget https://go.dev/dl/go1.20.4.linux-amd64.tar.gz $ sudo tar xvfz go1.20.4.linux-amd64.tar.gz $ sudo mv go .. $ sudo vi /etc/environment PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/go/bin" (/usr/local/go/binを追加) $ go version go version go1.20.4 linux/amd64
もう一度インストール。
$ go install github.com/go-acme/lego/v4/cmd/lego@latest
何回やってもフリーズしてしまう。
2日くらいほっといたらCPU負荷は下がったけど上手くいってなかった…
仕方が無いので、ソースから入れよう。
$ sudo apt install git make $ mkdir ~/go/src/github.com/go-acme $ cd ~/go/src/github.com/go-acme $ git clone https://github.com/go-acme/lego.git $ cd lego $ make
これもダメ。
もーあかん。Macでクロスコンパイルすることにするよ。
Goはこの辺が簡単でいいよね。
一応環境確認。
$ go env GOARCH="amd64" GOOS="linux"
こっからは自分のMacで作業。
クロスコンパイルのために確認した環境変数をセットしてビルドする。
$ git clone git@github.com:go-acme/lego.git $ cd lego $ export GOARCH="amd64" $ export GOOS="linux" $ make BIN_OUTPUT: dist/lego rm -rf dist/ builds/ cover.out go generate ./... go: downloading github.com/go-jose/go-jose/v3 v3.0.0 (snip) fork/exec /var/folders/g_/xzlp1_r95r97tw7bxs1d5vs00000gn/T/go-build1172054503/b001/exe/dnsdocs: exec format error internal/dnsdocs/generator.go:3: running "go": exit status 1 fork/exec /var/folders/g_/xzlp1_r95r97tw7bxs1d5vs00000gn/T/go-build1101727331/b001/exe/cli_help: exec format error internal/dnsdocs/cli_help/generator.go:3: running "go": exit status 1 make: *** [generate-dns] Error 1
ありゃ?ドキュメント作ろうとしてエラーになってる?
Makefile見たら make build
でビルドだけ動くということらしい。
$ make build BIN_OUTPUT: dist/lego rm -rf dist/ builds/ cover.out Version: 60d2b55dd801c7f92c51b1624f348728b014c782 $ go build -trimpath -ldflags '-X "main.version=60d2b55dd801c7f92c51b1624f348728b014c782"' -o dist/lego ./cmd/lego/
とりあえず出来た。
サーバに送りこんで使ってみよう。
$ scp -p dist/lego foo@gce-host:/home/foo/. $ ssh gce-host $ sudo mv lego /usr/local/bin/.
今度は上手くいくかなー?
(※ここからはまたGCEのサーバで作業)
# GOOGLE_DOMAINS_ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx== lego --email foo@example.com --dns googledomains --domains www.example.dev run 2023/06/08 14:22:38 No key found for account foo@example.com. Generating a P256 key. 2023/06/08 14:22:38 Saved key to /home/foo/.lego/accounts/acme-v02.api.letsencrypt.org/foo@example.com/keys/foo@example.com.key 2023/06/08 14:22:39 Please review the TOS at https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf Do you accept the TOS? Y/n Y 2023/06/08 14:22:42 [INFO] acme: Registering account for foo@example.com !!!! HEADS UP !!!! Your account credentials have been saved in your Let's Encrypt configuration directory at "/home/foo/.lego/accounts". You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained from Let's Encrypt so making regular backups of this folder is ideal. 2023/06/08 14:22:43 [INFO] [www.example.dev] acme: Obtaining bundled SAN certificate 2023/06/08 14:22:43 [INFO] [www.example.dev] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/235040568277 2023/06/08 14:22:43 [INFO] [www.example.dev] acme: Could not find solver for: tls-alpn-01 2023/06/08 14:22:43 [INFO] [www.example.dev] acme: Could not find solver for: http-01 2023/06/08 14:22:43 [INFO] [www.example.dev] acme: use dns-01 solver 2023/06/08 14:22:43 [INFO] [www.example.dev] acme: Preparing to solve DNS-01 2023/06/08 14:22:44 [INFO] [www.example.dev] acme: Trying to solve DNS-01 2023/06/08 14:22:44 [INFO] [www.example.dev] acme: Checking DNS record propagation using [127.0.0.53:53] 2023/06/08 14:22:46 [INFO] Wait for propagation [timeout: 2m0s, interval: 2s] 2023/06/08 14:22:53 [INFO] [www.example.dev] The server validated our request 2023/06/08 14:22:53 [INFO] [www.example.dev] acme: Cleaning DNS-01 challenge 2023/06/08 14:22:53 [INFO] [www.example.dev] acme: Validations succeeded; requesting certificates 2023/06/08 14:22:54 [INFO] [www.example.dev] Server responded with a certificate.
なんかそれっぽく出来てる。
nginxに証明書設定して、GCEのコンソールでファイヤーウォールを変更。443を許可。
$ cd /etc/nginx $ sudo vi sites-available/hogehoge ssl on; ssl_certificate /home/foo/.lego/certificates/www.example.dev.crt; ssl_certificate_key /home/foo/.lego/certificates/www.example.dev.key; $ service nginx reload
みえたー!!!