如何在Ubuntu18.04上使用Caddy托管网站

来自菜鸟教程
跳转至:导航、​搜索

作为 Write for DOnations 计划的一部分,作者选择了 Free and Open Source Fund 来接受捐赠。

介绍

Caddy 是一个围绕简单性和安全性而设计的 Web 服务器,它具有许多对托管网站有用的功能。 例如,它可以自动从 Let's Encrypt 获取和管理 TLS 证书以启用 HTTPS,并包括对 HTTP/2 的支持。 HTTPS 是一种用于保护您的用户和服务器之间的流量的系统,并且正在迅速成为任何在生产中运行的网站的基本期望——没有它,如果用户尝试提交登录,Chrome 和 Firefox 会警告您的网站“不安全”信息。

在本教程中,您将使用自定义 Caddy 构建器工具 xcaddy 从源代码构建 Caddy,并使用它来托管使用 HTTPS 保护的网站。 这需要编译它,使用 Caddyfile 配置它并安装插件。 最后,您的域将提供静态页面,同时使用 Let's Encrypt 的免费 TLS 证书进行保护。

先决条件

  • 具有 root 权限和辅助非 root 帐户的 Ubuntu 18.04 服务器。 您可以按照我们的 Initial Server Setup Guide for Ubuntu 18.04 进行设置。 对于本教程,非 root 用户是 sammy
  • 完全注册的域名。 本教程将自始至终使用 your_domain。 您可以在 Namecheap 上购买一个域名,在 Freenom 上免费获得一个域名,或者使用您选择的域名注册商。
  • your_domain 的 A DNS 记录指向您服务器的公共 IP 地址。 您可以关注这个DigitalOcean DNS的介绍,详细了解如何添加它们。
  • 安装在您的服务器上的 Go 语言 工具链,版本 1.14 及更高版本。 按照我们关于 如何在 Ubuntu 18.04 上安装 Go 和设置本地编程环境的指南来设置最新的 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

现在您已经验证您能够构建和运行 Caddy,是时候配置一个 systemd 服务,以便可以在系统启动时自动启动 Caddy。 要了解有关 systemd 的更多信息,请访问我们的 Systemd Essentials 教程

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 用户将创建自己的主目录。 无法以 caddy 身份登录,因为它的外壳设置为 nologin

将 Caddy 二进制文件的所有权更改为 root 用户:

sudo chown root:root /usr/bin/caddy

这将防止其他帐户修改可执行文件。 然而,即使 root 用户将拥有 Caddy,建议仅使用系统上存在的其他非 root 帐户来执行它——就像 systemd 服务的情况一样。 这确保了在 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's Encrypt 启用自动 TLS 证书配置。 为此,创建一个目录来存储 Caddy 将获得的任何 TLS 证书,并为其赋予与 /etc/caddy 目录相同的所有权规则:

sudo mkdir /etc/ssl/caddy
sudo chown -R root:caddy /etc/ssl/caddy

Caddy 必须能够将证书写入此目录并从中读取以加密请求。 为此,修改 /etc/ssl/caddy 目录的权限,使其只能由 rootcaddy 访问:

sudo chmod 0770 /etc/ssl/caddy

接下来,创建一个目录来存储 Caddy 将托管的文件:

sudo mkdir /var/www

然后,将目录的所有者和组设置为 caddy

sudo chown caddy:caddy /var/www

Caddy 从一个名为 Caddyfile 的文件中读取其配置,该文件存储在 /etc/caddy 下。 通过运行在磁盘上创建文件:

sudo touch /etc/caddy/Caddyfile

要安装 Caddy 服务,请通过运行以下命令将 systemd 单元文件从 Caddy GitHub 存储库下载到 /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 安装现已完成,但尚未配置为提供任何服务。 在下一步中,您将配置 Caddy 以提供来自 /var/www 目录的文件。

第 3 步 — 配置 Caddy

在本节中,您将编写用于从服务器提供静态文件的基本 Caddy 配置。

首先在 /var/www 中创建一个基本的 HTML 文件,称为 index.html

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 浏览器中显示时,该文件将显示带有文本 This page is being serving via Caddy 的标题。 保存并关闭文件。

打开之前创建的 Caddyfile 配置文件进行编辑:

sudo nano /etc/caddy/Caddyfile

添加以下行:

/etc/caddy/Caddy 文件

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。 您的示例网页将显示:

您现在已将 Caddy 配置为从您的服务器提供静态文件。 在下一步中,您将通过使用插件来扩展 Caddy 的功能。

第 4 步 — 使用 Let's Encrypt 启用自动 TLS

插件提供了一种改变和扩展 Caddy 行为的方法。 通常,它们会根据您的用例提供更多配置指令供您使用。 在本节中,您将启用自动 Let's Encrypt 证书配置和续订,使用 TXT DNS 记录进行验证。 要验证使用 TXT DNS 记录,您将安装 官方插件 用于与 DigitalOcean DNS API 接口。

注意: 你可能会注意到我们在这一步中使用的官方插件被标记为已弃用。 这是因为它正在被一组基于 libdns 的更新的模块化库所取代。

但是,digitalocean 库目前处于开发状态,存在一些未解决的问题。 在问题得到解决之前,我们将使用早期的插件,尽管它被标记为已过时,但它仍然可以正常工作。


要添加插件,您需要使用 xcaddy 重新编译 Caddy,但指定应该可用的插件存储库。 运行以下命令来编译支持 DigitalOcean DNS 的 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

接下来,您将配置 Caddy 以使用 DigitalOcean 的 API 来设置 DNS 记录。 Caddy 需要读取您的 API 令牌作为环境变量来配置 DigitalOcean 的 DNS,因此您将编辑其 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 看看它是否运行正确:

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 块,指定应使用 DigitalOcean DNS:

/etc/caddy/Caddy 文件

your_domain {
    root * /var/www
    encode gzip
    file_server
    
    tls {
        dns lego_deprecated digitalocean
    }
}

使用域而不仅仅是主机名的协议说明符将导致 Caddy 通过 HTTPS 服务请求。 tls 指令配置 Caddy 在使用 TLS 时的行为,dns 子指令指定 Caddy 应该使用 DigitalOcean DNS 系统,而不是 HTTP。

有了这个,您的网站就可以部署了。 用 systemctl 重新启动 Caddy,然后用 enable 重新启动它,这样它就会在启动时运行:

sudo systemctl restart caddy
sudo systemctl enable caddy

如果您浏览到您的域,您将自动被重定向到 HTTPS,并显示相同的消息。

您的 Caddy 安装现已完成且安全,您可以根据您的用例进一步自定义。

结论

您现在已经在您的服务器上安装和配置了 Caddy,在您想要的域中提供静态页面,并使用免费的 Let's Encrypt TLS 证书进行保护。

一个好的下一步是找到一种在新版本的 Caddy 发布时收到通知的方法。 例如,您可以将 Atom 提要用于 Caddy 版本 ,或专用服务,例如 dependencies.io

您可以浏览 Caddy 的文档 以获取有关配置 Caddy 的更多信息。