Ubuntu18.04でCaddyを使用してWebサイトをホストする方法
著者は、 Write for DOnations プログラムの一環として、 Free and Open SourceFundを選択して寄付を受け取りました。
序章
Caddy は、シンプルさとセキュリティを中心に設計されたWebサーバーであり、Webサイトのホスティングに役立つ多くの機能が付属しています。 たとえば、 Let’s Encrypt からTLS証明書を自動的に取得して管理し、HTTPSを有効にすることができます。HTTP/2のサポートも含まれています。 HTTPSは、ユーザーとサーバー間のトラフィックを保護するためのシステムであり、本番環境で実行されているWebサイトの基本的な期待に急速になりつつあります。HTTPSがないと、ユーザーがログインを送信しようとすると、ChromeとFirefoxはWebサイトが「安全ではない」と警告します。情報。
このチュートリアルでは、カスタムCaddyビルダーツールである xcaddy を使用してソースからCaddyをビルドし、それを使用してHTTPSで保護されたWebサイトをホストします。 これには、コンパイル、Caddyfile
を使用した構成、およびプラグインのインストールが含まれます。 最終的に、ドメインは静的ページを提供し、Let’sEncryptからの無料のTLS証明書で保護されます。
前提条件
- ルート権限を持つUbuntu18.04サーバー、およびセカンダリの非ルートアカウント。 これを設定するには、
Ubuntu18.04[X84Xの初期サーバー設定ガイド]に従ってください。 このチュートリアルでは、root以外のユーザーは sammy
です。 - 完全に登録されたドメイン名。 このチュートリアルでは、全体を通して
your_domain
を使用します。 Namecheap でドメイン名を購入するか、 Freenom で無料でドメイン名を取得するか、選択したドメイン登録事業者を使用できます。 - サーバーのパブリックIPアドレスを指す
your_domain
を含むDNSレコード。 それらを追加する方法の詳細については、このDigitalOceanDNSの紹介に従ってください。 - サーバーにインストールされているGo言語ツールチェーン、バージョン1.14以降。 Goのインストール方法とUbuntu18.04でのローカルプログラミング環境のセットアップ方法に関するガイドに従って、最新のGoをセットアップします。 サンプルプロジェクトを作成する必要はありません。
- DigitalOceanアカウントの読み取りおよび書き込み権限を持つ個人用アクセストークン(APIキー)。 パーソナルアクセストークンの作成方法にアクセスして作成してください。
ステップ1—キャディを構築する
このステップでは、Caddyのソースコードを変更せずに、後でプラグインを追加できるように、ソースからCaddyをビルドします。 これは、xcaddy
を使用して実行します。これにより、必要に応じてCaddyとそのプラグインがダウンロードおよびビルドされます。
リリースページにアクセスし、linux_amd64
プラットフォームの最新リリースのリンクをコピーします。 ダウンロードする前に、次のコマンドを実行して/tmp
に移動します。
- cd /tmp
次に、wget
を使用して最新リリースをダウンロードします。
- wget https://github.com/caddyserver/xcaddy/releases/download/v0.1.8/xcaddy_0.1.8_linux_amd64.tar.gz
ダウンロードしたら、バイナリのみを抽出します。
- tar xvf xcaddy_0.1.8_linux_amd64.tar.gz xcaddy
最後に、xcaddy
実行可能ファイルを/usr/bin
に移動して、システム全体でアクセスできるようにします。
- sudo mv xcaddy /usr/bin
xcaddy
がインストールされたので、Caddyをビルドします。 そのために、それを保存するための別のディレクトリを作成します。
- mkdir ~/caddy
次のコマンドを実行して、そこに移動します。
- cd ~/caddy
サードパーティのプラグインを使用せずに最新バージョンのCaddyをビルドするには、次のコマンドを実行します。
- xcaddy build
このコマンドは完了するまでに少し時間がかかり、その出力は次のようになります。
Output2021/02/23 21:12:07 [INFO] Temporary folder: /tmp/buildenv_2021-02-23-2112.542119152
2021/02/23 21:12:07 [INFO] Writing main module: /tmp/buildenv_2021-02-23-2112.542119152/main.go
2021/02/23 21:12:07 [INFO] Initializing Go module
2021/02/23 21:12:07 [INFO] exec (timeout=10s): /usr/local/go/bin/go mod init caddy
go: creating new go.mod: module caddy
go: to add module requirements and sums:
go mod tidy
2021/02/23 21:12:07 [INFO] Pinning versions
2021/02/23 21:12:07 [INFO] exec (timeout=0s): /usr/local/go/bin/go get -d -v github.com/caddyserver/caddy/v2
...
2021/02/23 21:12:34 [INFO] Build environment ready
2021/02/23 21:12:34 [INFO] Building Caddy
2021/02/23 21:12:34 [INFO] exec (timeout=0s): /usr/local/go/bin/go mod tidy
...
2021/02/23 21:12:51 [INFO] exec (timeout=0s): /usr/local/go/bin/go build -o /home/sammy/caddy/caddy -ldflags -w -s -trimpath
2021/02/23 21:14:26 [INFO] Build complete: ./caddy
2021/02/23 21:14:26 [INFO] Cleaning up temporary folder: /tmp/buildenv_2021-02-23-2112.542119152
完了すると、caddy
実行可能ファイルが現在のフォルダーで使用できるようになります。 /usr/bin
に移動して、インストールします。
- sudo mv caddy /usr/bin
caddy
を実行して、正しくインストールされていることを確認できます。
- caddy version
出力には、コンパイルしたばかりのCaddyのバージョンが含まれます。
Outputv2.3.0 h1:fnrqJLa3G5vfxcxmOH/+kJOcunPLhSBnjgIvjXV/QTA=
これで、Caddyをビルドして実行しました。 次のステップでは、Caddyをサービスとしてインストールして、起動時に自動的に起動するようにします。次に、サーバーのセキュリティを確保するために、所有権とアクセス許可の設定を調整します。
ステップ2—キャディをインストールする
Caddyをビルドして実行できることを確認したので、次にsystemdサービスを構成して、システムの起動時にCaddyを自動的に起動できるようにします。 systemdの詳細については、SystemdEssentialsチュートリアルにアクセスしてください。
Caddyをsystemdサービスとして実行するには、独自のユーザーとグループが必要です。 まず、次のコマンドを実行してグループを作成します。
- sudo groupadd --system caddy
次に、caddy
グループに属するcaddy
という名前の新しいユーザーを作成します。
- sudo useradd --system \
- --gid caddy \
- --create-home \
- --home-dir /var/lib/caddy \
- --shell /usr/sbin/nologin \
- --comment "Caddy web server" \
- caddy
新しいcaddy
ユーザーには、独自のホームディレクトリが作成されます。 シェルがnologin
に設定されているため、caddy
としてログインすることはできません。
Caddyバイナリの所有権をrootユーザーに変更します。
sudo chown root:root /usr/bin/caddy
これにより、他のアカウントが実行可能ファイルを変更できなくなります。 ただし、 root ユーザーがCaddyを所有している場合でも、systemdサービスの場合と同様に、システムに存在する他の非rootアカウントのみを使用して実行することをお勧めします。 これにより、Caddy(または別のプログラム)が危険にさらされた場合に、攻撃者がバイナリを変更したり、rootとしてコマンドを実行したりすることができなくなります。
次に、バイナリファイルのアクセス許可を755
に設定します。これにより、 root にファイルの完全な読み取り/書き込み/実行のアクセス許可が与えられますが、他のユーザーはファイルの読み取りと実行のみが可能です。
sudo chmod 755 /usr/bin/caddy
これでCaddyバイナリの設定が完了し、Caddy構成の記述を開始する準備が整いました。
次のコマンドを実行して、Caddyの構成ファイルを保存するディレクトリを作成します。
sudo mkdir /etc/caddy
次に、適切なユーザーとグループの権限を設定します。
- sudo chown -R root:caddy /etc/caddy
ユーザーをrootとして設定し、グループを caddy として設定すると、Caddyは( caddy グループを介して)フォルダーへの読み取りおよび書き込みアクセス権を持ち、スーパーユーザーアカウントには、読み取りと変更を行うための同じ権限があります。
後のステップで、Let’sEncryptからの自動TLS証明書プロビジョニングを有効にします。 その準備として、Caddyが取得するTLS証明書を格納するディレクトリを作成し、/etc/caddy
ディレクトリと同じ所有権ルールを付与します。
sudo mkdir /etc/ssl/caddy
sudo chown -R root:caddy /etc/ssl/caddy
キャディは、要求を暗号化するために、このディレクトリに証明書を書き込み、そこから読み取ることができる必要があります。 このため、/etc/ssl/caddy
ディレクトリの権限を変更して、rootおよびcaddyからのみアクセスできるようにします。
sudo chmod 0770 /etc/ssl/caddy
次に、Caddyがホストするファイルを保存するディレクトリを作成します。
sudo mkdir /var/www
次に、ディレクトリの所有者とグループをcaddyに設定します。
- sudo chown caddy:caddy /var/www
キャディは、/etc/caddy
の下に保存されているCaddyfile
というファイルから構成を読み取ります。 次のコマンドを実行して、ディスク上にファイルを作成します。
sudo touch /etc/caddy/Caddyfile
Caddyサービスをインストールするには、次のコマンドを実行して、systemdユニットファイルをCaddyGitHubリポジトリから/etc/systemd/system
にダウンロードします。
sudo sh -c 'curl https://raw.githubusercontent.com/caddyserver/dist/master/init/caddy.service > /etc/systemd/system/caddy.service'
サービスファイルのアクセス許可を変更して、所有者rootのみが変更できるようにします。
sudo chmod 644 /etc/systemd/system/caddy.service
次に、systemdをリロードして、Caddyサービスを検出します。
sudo systemctl daemon-reload
systemctl status
を実行して、systemdがCaddyサービスを検出したかどうかを確認します。
sudo systemctl status caddy
次のような出力が表示されます。
Output● caddy.service - Caddy
Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: https://caddyserver.com/docs/
これと同じ出力が表示される場合は、新しいサービスがsystemdによって正しく検出されています。
サーバーの初期設定の前提条件の一部として、ufw
、複雑でないファイアウォールを有効にし、SSH接続を許可しました。 CaddyがサーバーからのHTTPおよびHTTPSトラフィックを処理できるようにするには、次のコマンドを実行してufw
でそれらを許可する必要があります。
- sudo ufw allow proto tcp from any to any port 80,443
出力は次のようになります。
OutputRule added
Rule added (v6)
ufw status
を使用して、変更が機能したかどうかを確認します。
sudo ufw status
次の出力が表示されます。
OutputStatus: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
80,443/tcp ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
80,443/tcp (v6) ALLOW Anywhere (v6)
これでCaddyのインストールは完了しましたが、何も提供するように構成されていません。 次のステップでは、/var/www
ディレクトリからファイルを提供するようにCaddyを構成します。
ステップ3—キャディの設定
このセクションでは、サーバーから静的ファイルを提供するための基本的なCaddy構成を記述します。
/var/www
にindex.html
という基本的なHTMLファイルを作成することから始めます。
- sudo nano /var/www/index.html
次の行を追加します。
<!DOCTYPE html>
<html>
<head>
<title>Hello from Caddy!</title>
</head>
<body>
<h1 style="font-family: sans-serif">This page is being served via Caddy</h1>
</body>
</html>
このファイルをWebブラウザーに表示すると、というテキストの見出しが表示されます。このページはCaddyを介して提供されています。 ファイルを保存して閉じます。
以前に作成したCaddyfile
構成ファイルを開いて編集します。
sudo nano /etc/caddy/Caddyfile
次の行を追加します。
http:// {
root * /var/www
encode gzip
file_server
}
これは基本的なCaddy構成であり、サーバーへのすべてのHTTPトラフィックが/var/www
(root
としてマークされている)からのファイル(file_server
)で提供され、圧縮される必要があることを宣言しますgzip
を使用して、クライアント側でのページの読み込み時間を短縮します。
完了したら、ファイルを保存して閉じます。
Caddyには、多くのユースケースに対応する膨大な数の異なるディレクティブがあります。 たとえば、 php_fastcgi ディレクティブは、PHPを有効にするのに役立ちます。
すべてが正しく機能していることをテストするには、Caddyサービスを開始します。
sudo systemctl start caddy
次に、systemctl status
を実行して、Caddyサービスのステータスに関する情報を検索します。
sudo systemctl status caddy
次のように表示されます。
Output● caddy.service - Caddy
Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: enabled)
Active: active (running) since Tue 2020-12-08 11:19:47 UTC; 34s ago
Docs: https://caddyserver.com/docs/
Main PID: 4631 (caddy)
Tasks: 6 (limit: 1137)
Memory: 10.4M
CGroup: /system.slice/caddy.service
└─4631 /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
Dec 08 11:19:47 ubuntu-s-1vcpu-1gb-fra1-01 caddy[4631]: USER=caddy
Dec 08 11:19:47 ubuntu-s-1vcpu-1gb-fra1-01 caddy[4631]: INVOCATION_ID=45713fb36abe48ecaf4aa72a12542658
Dec 08 11:19:47 ubuntu-s-1vcpu-1gb-fra1-01 caddy[4631]: JOURNAL_STREAM=9:33053
Dec 08 11:19:47 ubuntu-s-1vcpu-1gb-fra1-01 caddy[4631]: {"level":"info","ts":1607426387.425965,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":""}
Dec 08 11:19:47 ubuntu-s-1vcpu-1gb-fra1-01 caddy[4631]: {"level":"info","ts":1607426387.4281814,"logger":"admin","msg":"admin endpoint started","address":"tcp/localhost:2019","enforce_origin":false,"origins":["127.0.0.1:2019","localhost:2019","[::1]:2019"]}
Dec 08 11:19:47 ubuntu-s-1vcpu-1gb-fra1-01 caddy[4631]: {"level":"info","ts":1607426387.4285417,"logger":"http","msg":"server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server","server_name":"srv0","http_port":80}
Dec 08 11:19:47 ubuntu-s-1vcpu-1gb-fra1-01 caddy[4631]: {"level":"info","ts":1607426387.430661,"msg":"autosaved config","file":"/var/lib/caddy/.config/caddy/autosave.json"}
Dec 08 11:19:47 ubuntu-s-1vcpu-1gb-fra1-01 caddy[4631]: {"level":"info","ts":1607426387.430849,"msg":"serving initial configuration"}
Dec 08 11:19:47 ubuntu-s-1vcpu-1gb-fra1-01 caddy[4631]: {"level":"info","ts":1607426387.4311824,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc00021f0a0"}
Dec 08 11:19:47 ubuntu-s-1vcpu-1gb-fra1-01 caddy[4631]: {"level":"info","ts":1607426387.4313655,"logger":"tls","msg":"cleaned up storage units"}
これで、WebブラウザでサーバーのIPを参照できます。 サンプルWebページには次のものが表示されます。
これで、サーバーから静的ファイルを提供するようにCaddyを構成しました。 次のステップでは、プラグインを使用してCaddyの機能を拡張します。
ステップ4—Let’sEncryptを使用して自動TLSを有効にする
プラグインは、Caddyの動作を変更および拡張する方法を提供します。 一般に、ユースケースに応じて、より多くの構成ディレクティブを使用できます。 このセクションでは、検証にTXT DNSレコードを使用して、自動Let’sEncrypt証明書のプロビジョニングと更新を有効にします。 TXT DNSレコードを使用して確認するには、DigitalOceanDNSAPIとのインターフェース用に公式プラグインをインストールします。
注:この手順で使用している公式プラグインは非推奨としてマークされていることに気付くかもしれません。 これは、libdnsに基づく新しいモジュラーライブラリのセットに置き換えられる過程にあるためです。
ただし、 digitalocean ライブラリは現在開発段階にあり、いくつかの未解決の問題があります。 問題が解決するまで、以前のプラグインを使用します。このプラグインは、廃止されたとラベル付けされていても正しく機能します。
プラグインを追加するには、xcaddy
を使用してCaddyを再コンパイルする必要がありますが、使用可能なプラグインのリポジトリを指定します。 次のコマンドを実行して、DigitalOceanDNSをサポートするCaddyをコンパイルします。
- xcaddy build --with github.com/caddy-dns/lego-deprecated
出力は次のようになります。
Output2021/02/23 21:18:46 [INFO] Temporary folder: /tmp/buildenv_2021-02-23-2118.769615504
2021/02/23 21:18:46 [INFO] Writing main module: /tmp/buildenv_2021-02-23-2118.769615504/main.go
2021/02/23 21:18:46 [INFO] Initializing Go module
2021/02/23 21:18:46 [INFO] exec (timeout=10s): /usr/local/go/bin/go mod init caddy
go: creating new go.mod: module caddy
go: to add module requirements and sums:
go mod tidy
2021/02/23 21:18:46 [INFO] Pinning versions
2021/02/23 21:18:46 [INFO] exec (timeout=0s): /usr/local/go/bin/go get -d -v github.com/caddyserver/caddy/v2
go get: added github.com/caddyserver/caddy/v2 v2.3.0
2021/02/23 21:18:49 [INFO] exec (timeout=0s): /usr/local/go/bin/go get -d -v github.com/caddy-dns/lego-deprecated
...
2021/02/23 21:19:17 [INFO] Build environment ready
2021/02/23 21:19:17 [INFO] Building Caddy
2021/02/23 21:19:17 [INFO] exec (timeout=0s): /usr/local/go/bin/go mod tidy
...
2021/02/23 21:19:20 [INFO] exec (timeout=0s): /usr/local/go/bin/go build -o /home/sammy/caddy/caddy -ldflags -w -s -trimpath
2021/02/23 21:20:09 [INFO] Build complete: ./caddy
2021/02/23 21:20:09 [INFO] Cleaning up temporary folder: /tmp/buildenv_2021-02-23-2118.769615504
コンパイルが終了したら、次のコマンドを実行して、結果のバイナリを/usr/bin
に移動します。
- sudo mv caddy /usr/bin
次に、適切な権限を設定します。
- sudo chown root:root /usr/bin/caddy
- sudo chmod 755 /usr/bin/caddy
次に、DigitalOceanのAPIと連携してDNSレコードを設定するようにCaddyを構成します。 Caddyは、DigitalOceanのDNSを構成するために、APIトークンを環境変数として読み取る必要があるため、systemdユニットファイルを編集します。
sudo nano /etc/systemd/system/caddy.service
[Service]
セクションに強調表示された行を追加し、your_token_here
をAPIトークンに置き換えます。
...
[Service]
User=caddy
Group=caddy
Environment=DO_AUTH_TOKEN=your_token_here
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
...
このファイルを保存して閉じてから、前に行ったようにsystemdデーモンをリロードして、構成が更新されていることを確認します。
sudo systemctl daemon-reload
systemctl restart
を実行して、構成の変更に問題がないことを確認します。
sudo systemctl restart caddy
次に、systemctl status
を実行して、正しく実行されたかどうかを確認します。
- sudo systemctl status caddy
出力は次のようになります。
Output● caddy.service - Caddy
Loaded: loaded (/etc/systemd/system/caddy.service; disabled; vendor preset: enabled)
Active: active (running) since Tue 2020-12-08 13:39:17 UTC; 1s ago
Docs: https://caddyserver.com/docs/
Main PID: 5440 (caddy)
Tasks: 5 (limit: 1137)
Memory: 9.8M
CGroup: /system.slice/caddy.service
└─5440 /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
...
Caddyfile
にいくつかのわずかな変更を加える必要があるので、編集のために開きます。
sudo nano /etc/caddy/Caddyfile
強調表示された行をCaddyfile
に追加し、your_domain
を(http://
だけでなく)ドメインに置き換え、tls
ブロックを追加して次のように指定します。 DigitalOceanDNSを使用する必要があります。
your_domain {
root * /var/www
encode gzip
file_server
tls {
dns lego_deprecated digitalocean
}
}
ホスト名にプロトコル指定子だけでなくドメインを使用すると、CaddyはHTTPS経由でリクエストを処理します。 tls
ディレクティブは、TLS
を使用するときのCaddyの動作を構成し、dns
サブディレクティブは、CaddyがHTTPではなくDigitalOceanDNSシステムを使用するように指定します。
これで、Webサイトを展開する準備が整いました。 systemctl
でCaddyを再起動してからenable
で再起動すると、起動時に実行されます。
sudo systemctl restart caddy
sudo systemctl enable caddy
ドメインを参照すると、同じメッセージが表示された状態で、HTTPSに自動的にリダイレクトされます。
これでCaddyのインストールが完了し、保護されました。ユースケースに応じてさらにカスタマイズできます。
結論
これで、Caddyがサーバーにインストールおよび構成され、目的のドメインで静的ページを提供し、無料のLet’sEncryptTLS証明書で保護されました。
次の良いステップは、Caddyの新しいバージョンがリリースされたときに通知を受ける方法を見つけることです。 たとえば、Caddyリリース用の Atomフィード、またはdependencies.ioなどの専用サービスを使用できます。
Caddyの構成の詳細については、Caddyのドキュメントを参照してください。