著者は、 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に移動します。

  1. cd /tmp

次に、wgetを使用して最新リリースをダウンロードします。

  1. wget https://github.com/caddyserver/xcaddy/releases/download/v0.1.8/xcaddy_0.1.8_linux_amd64.tar.gz

ダウンロードしたら、バイナリのみを抽出します。

  1. tar xvf xcaddy_0.1.8_linux_amd64.tar.gz xcaddy

最後に、xcaddy実行可能ファイルを/usr/binに移動して、システム全体でアクセスできるようにします。

  1. sudo mv xcaddy /usr/bin

xcaddyがインストールされたので、Caddyをビルドします。 そのために、それを保存するための別のディレクトリを作成します。

  1. mkdir ~/caddy

次のコマンドを実行して、そこに移動します。

  1. cd ~/caddy

サードパーティのプラグインを使用せずに最新バージョンのCaddyをビルドするには、次のコマンドを実行します。

  1. xcaddy build

このコマンドは完了するまでに少し時間がかかり、その出力は次のようになります。

Output
2021/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に移動して、インストールします。

  1. sudo mv caddy /usr/bin

caddyを実行して、正しくインストールされていることを確認できます。

  1. caddy version

出力には、コンパイルしたばかりのCaddyのバージョンが含まれます。

Output
v2.3.0 h1:fnrqJLa3G5vfxcxmOH/+kJOcunPLhSBnjgIvjXV/QTA=

これで、Caddyをビルドして実行しました。 次のステップでは、Caddyをサービスとしてインストールして、起動時に自動的に起動するようにします。次に、サーバーのセキュリティを確保するために、所有権とアクセス許可の設定を調整します。

ステップ2—キャディをインストールする

Caddyをビルドして実行できることを確認したので、次にsystemdサービスを構成して、システムの起動時にCaddyを自動的に起動できるようにします。 systemdの詳細については、SystemdEssentialsチュートリアルにアクセスしてください。

Caddyをsystemdサービスとして実行するには、独自のユーザーとグループが必要です。 まず、次のコマンドを実行してグループを作成します。

  1. sudo groupadd --system caddy

次に、caddyグループに属するcaddyという名前の新しいユーザーを作成します。

  1. sudo useradd --system \
  2. --gid caddy \
  3. --create-home \
  4. --home-dir /var/lib/caddy \
  5. --shell /usr/sbin/nologin \
  6. --comment "Caddy web server" \
  7. 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

次に、適切なユーザーとグループの権限を設定します。

  1. 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に設定します。

  1. 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でそれらを許可する必要があります。

  1. sudo ufw allow proto tcp from any to any port 80,443

出力は次のようになります。

Output
Rule added Rule added (v6)

ufw statusを使用して、変更が機能したかどうかを確認します。

sudo ufw status

次の出力が表示されます。

Output
Status: 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/wwwindex.htmlという基本的なHTMLファイルを作成することから始めます。

  1. sudo nano /var/www/index.html

次の行を追加します。

/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

次の行を追加します。

/ etc / caddy / Caddyfile
http:// {
    root * /var/www
    encode gzip
    file_server
}

これは基本的なCaddy構成であり、サーバーへのすべてのHTTPトラフィックが/var/wwwrootとしてマークされている)からのファイル(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ページには次のものが表示されます。

Message from Caddy

これで、サーバーから静的ファイルを提供するようにCaddyを構成しました。 次のステップでは、プラグインを使用してCaddyの機能を拡張します。

ステップ4—Let’sEncryptを使用して自動TLSを有効にする

プラグインは、Caddyの動作を変更および拡張する方法を提供します。 一般に、ユースケースに応じて、より多くの構成ディレクティブを使用できます。 このセクションでは、検証にTXT DNSレコードを使用して、自動Let’sEncrypt証明書のプロビジョニングと更新を有効にします。 TXT DNSレコードを使用して確認するには、DigitalOceanDNSAPIとのインターフェース用に公式プラグインをインストールします。

注:この手順で使用している公式プラグインは非推奨としてマークされていることに気付くかもしれません。 これは、libdnsに基づく新しいモジュラーライブラリのセットに置き換えられる過程にあるためです。

ただし、 digitalocean ライブラリは現在開発段階にあり、いくつかの未解決の問題があります。 問題が解決するまで、以前のプラグインを使用します。このプラグインは、廃止されたとラベル付けされていても正しく機能します。

プラグインを追加するには、xcaddyを使用してCaddyを再コンパイルする必要がありますが、使用可能なプラグインのリポジトリを指定します。 次のコマンドを実行して、DigitalOceanDNSをサポートするCaddyをコンパイルします。

  1. xcaddy build --with github.com/caddy-dns/lego-deprecated

出力は次のようになります。

Output
2021/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に移動します。

  1. sudo mv caddy /usr/bin

次に、適切な権限を設定します。

  1. sudo chown root:root /usr/bin/caddy
  2. 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トークンに置き換えます。

/etc/systemd/system/caddy.service
...
[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を実行して、正しく実行されたかどうかを確認します。

  1. 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を使用する必要があります。

/ etc / caddy / Caddyfile
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のドキュメントを参照してください。