在部署hy2协议时由于服务器ip使用了域名,那么获得证书是很有必要的,当然也可以使用自签证书,客户端就要设置忽略证书验证。

记录一下我使用ACME协议获得免费证书

ACME 证书获取流程与注意事项

核心流程与常用工具

  • ACME 协议 (Automatic Certificate Management Environment) 用于自动化获取免费的 TLS/SSL 证书(例如来自 Let’s Encrypt)。
  • 常用客户端:
    • acme.sh: 轻量、易于自动化和脚本化,广泛用于服务器端部署。
    • Certbot: 官方推荐,对 Apache/Nginx 等 Web 服务器集成度高。
  • 基本步骤: 安装客户端 ,验证域名,获取证书,自动部署/续期。

关键验证模式及选择

验证模式说明适用场景
DNS 验证 (dns-01)通过在域名 DNS 中添加 TXT 记录来验证所有权。强烈推荐:适用于所有场景,特别需要隐藏服务或端口(如 VLESS、Hysteria 2)时。支持泛域名证书(*.domain.com)。
HTTP 验证 (http-01)通过在服务器的 80 端口上放置临时文件来验证。适用于传统的 Web 服务器(Nginx/Apache),但需要确保 80 端口开放且未被占用。

文件权限和安全设置(极重要

  • 路径安全: 证书和私钥文件(尤其是 .key 文件)默认存储在客户端目录(如 ~/.acme.sh/)下,必须严格保护。
  • 服务用户权限: 运行您代理服务(如 sing-box)的非特权用户,必须拥有读取证书 (.cerfullchain.cer)私钥 (.key) 文件的权限。
  • 权限链修复: 确保从根目录到证书文件的所有父目录,运行服务的用户都拥有 进入 (x) 权限
  • 推荐方法: 使用 ACL (Access Control Lists) 精确授予 sing-box 用户对证书路径的读取权限,避免开放整个用户家目录的权限给“其他人”。

自动化和续期注意事项

  • 证书有效期: ACME 证书通常只有 90 天有效期。
  • 自动化: 必须配置 Cron JobSystemd Timer,确保客户端(如 acme.sh)能每隔 60 天左右自动运行续期命令。
  • Hook 脚本: 续期成功后,客户端必须自动执行 Hook 命令:
    • 将新证书复制到目标配置目录(例如 /etc/sing-box/)。
    • 重启或重新加载 使用该证书的服务,使新证书生效。

您好!安装 acme.sh 客户端非常简单,因为它是一个纯 Shell 脚本,不依赖于复杂的软件包管理器。

以下是安装 acme.sh 的两种主要方法及推荐步骤:


安装 acme.sh

安装完成后,acme.sh 会自动在您的用户目录下创建必要的文件夹(通常是 ~/.acme.sh/)并设置定时任务(Cron Job)以进行证书的自动续期。

  • 方法一:通过 cURL (最常用)

这是最常用的安装方式,它会自动将 acme.sh 安装到您的用户主目录,并自动设置一个 Cron Job 来进行续期。

1
curl https://get.acme.sh | sh
  • 方法二:
1
wget -O - https://get.acme.sh | sh

安装脚本会自动执行以下操作:

  1. 创建目录: 在主目录 (~) 下创建 .acme.sh 文件夹 (~/.acme.sh/)。
  2. 复制脚本: 将脚本文件复制到该目录下。
  3. 设置别名: 在 Shell 配置文件(如 ~/.bashrc~/.zshrc)中添加一个别名 alias acme.sh=~/.acme.sh/acme.sh,这样就可以直接使用 acme.sh 命令。
  4. 设置定时任务(Cron): 自动添加一个 Cron Job 或 Systemd Timer,用于在证书到期前自动续期。

为了让 acme.sh 的别名立即生效,需要重新加载Shell 配置文件:

1
2
3
source ~/.bashrc
# 或者
source ~/.zshrc

(具体取决于使用的 Shell)

通过运行以下命令来确认安装是否成功:

1
acme.sh --version

如果成功,它会输出当前 acme.sh 的版本号。

好的,我将以最常用的 Cloudflare 为例,提供使用 acme.sh 配置 DNS API 的具体步骤和命令。如果您使用的是其他 DNS 服务商(如阿里云/DNSPod/GoDaddy 等),步骤类似,只是环境变量名不同。


使用DNS API

使用 Cloudflare API 或其它dns api 来自动添加和删除 TXT 记录,无需任何手动干预。以cloudflare api 为例:

步骤 1: 获取 Cloudflare API 密钥

  1. 登录您的 Cloudflare 账户
  2. 进入 “我的个人资料” (My Profile) 、**“API 令牌” (API Tokens)**。
  3. 建议创建一个新的 API 令牌,而不是使用全局 API Key(更安全)。
    • 权限设置:
      • 区域 (Zone): Zone:DNS编辑 (Edit)
      • 区域 (Zone): Zone:Zone只读 (Read)
    • 区域资源: 选择 **“特定区域” (Specific zone)**,并选择您的域名。
  4. 保存生成的 API Token

步骤 2: 配置 acme.sh 环境变量

在服务器上(使用 acme.sh 的用户环境),将获取到的 API Key 设置为环境变量。

1
2
3
4
5
# 请将 'YOUR_CLOUDFLARE_API_TOKEN' 替换为您在步骤 1 中获取的真实 API 密钥
export CF_Token="YOUR_CLOUDFLARE_API_TOKEN"

# 请将 'YOUR_CLOUDFLARE_ACCOUNT_EMAIL' 替换为您的 Cloudflare 账户邮箱
export CF_Email="YOUR_CLOUDFLARE_ACCOUNT_EMAIL"

注意: 如果您使用的是 acme.shroot 用户,请将这些命令添加到 ~/.bashrc~/.profile 文件中,以便永久保存。

步骤 3: 签发泛域名证书

使用 acme.shissue 命令并指定 dns 模式和 cf(Cloudflare)插件。

1
2
3
4
5
6
# 假设您的域名是 example.com
# --issue: 签发证书
# -d: 主域名
# -d: 泛域名 (使用 DNS 模式才能签发泛域名)
# --dns dns_cf: 指定使用 Cloudflare 插件
acme.sh --issue --server letsencrypt -d example.com -d '*.example.com' --dns dns_cf

步骤 4: 自动部署证书(Hook 命令)

证书签发成功后,您需要设置 Hook 部署命令,以便在证书续期时自动将文件复制到 Sing-box 所需的目录,并重启服务。

1
2
3
4
5
6
7
# 假设您要将证书部署到 /etc/sing-box/certs/ 目录
# 并且您的 sing-box 服务名为 sing-box

acme.sh --install-cert -d example.com \
--key-file /etc/sing-box/certs/example.com.key \
--fullchain-file /etc/sing-box/certs/fullchain.cer \
--reloadcmd "sudo systemctl restart sing-box && sudo chown sing-box:sing-box /etc/sing-box/certs/example.com.key /etc/sing-box/certs/fullchain.cer && sudo chmod 600 /etc/sing-box/certs/example.com.key /etc/sing-box/certs/fullchain.cer"

命令说明:

  • --install-cert: 设置部署路径和部署命令。
  • --key-file: 私钥的最终部署路径。
  • --fullchain-file: 证书链的最终部署路径。
  • --reloadcmd: 证书更新后要执行的命令。 这里我们执行了三个操作:
    1. sudo systemctl restart sing-box: 重启服务以加载新证书。
    2. sudo chown sing-box:sing-box ...: 确保新证书文件的所有者是 sing-box 用户。
    3. sudo chmod 600 ...: 确保只有 sing-box 用户才能读取私钥和证书(防止权限错误)。

步骤 5: 验证自动续期

acme.sh 在安装时会自动添加一个 Cron Job。您可以通过以下命令手动测试续期流程:

1
acme.sh --cron --force

如果使用的是 阿里云/DNSPod/腾讯云 等其他服务商,可查询对应的 export 环境变量名称。

Webroot 模式Standalone 模式 是 ACME 协议客户端(如 acme.sh 和 Certbot)进行 HTTP 验证 (http-01) 的两种主要方式。

这两种模式都需要服务器能够响应来自 ACME 证书颁发机构(CA)对域名 80 端口的访问。

Webroot 模式 vs Standalone 模式

特性Webroot 模式 (推荐用于已运行 Web 服务)Standalone 模式 (推荐用于无 Web 服务)
工作原理客户端(如 acme.sh)在您现有 Web 服务器的 网站根目录 下创建临时验证文件。客户端(如 acme.sh临时停止您的 Web 服务器,然后自己监听 80 端口,响应验证请求。
端口要求80 端口必须由 现有 Web 服务器(Nginx/Apache 等)监听,且该服务器能够将请求导向 Webroot 目录。80 端口必须是 空闲的,由 acme.sh 临时占用。
对现有服务的影响无影响,现有 Web 服务持续运行。有影响,需要临时停止 Nginx/Apache 等服务。
应用场景您的域名已经有 Nginx/Apache 运行在 80 端口上,并指向一个固定的网站根目录。您的服务器上没有运行 Web 服务,或者您只需要临时获取证书。

1. Webroot 模式

您需要指定您的网站根目录 (--webroot)。

1
2
3
4
5
# 假设您的网站根目录是 /var/www/html/
# --issue: 签发证书
# -d: 您的域名
# -w: 指定网站根目录
acme.sh --issue -d yourdomain.com -w /var/www/html/

2. Standalone 模式

需要使用 --standalone 选项。在运行此命令之前,请务必停止您服务器上所有监听 80 端口的 Web 服务(如 Nginx、Apache、Caddy 等)。

1
2
3
4
5
6
7
8
9
10
11
12
# 在运行前,先停止 Nginx 或 Apache
# sudo systemctl stop nginx
# 或
# sudo systemctl stop apache2

# 使用 Standalone 模式签发证书
acme.sh --issue -d yourdomain.com --standalone

# 证书签发完成后,重新启动 Web 服务
# sudo systemctl start nginx
# 或
# sudo systemctl start apache2

⚠️ 注意事项

无论选择哪种模式,记住以下几点:

  1. 端口 80 必须开放: 您的服务器防火墙(如 ufw)必须允许外部访问 TCP 协议的 80 端口
  2. Webroot 路径必须正确: 在 Webroot 模式下,如果路径不正确,验证将失败。
  3. Standalone 模式和自动化: 如果您使用 Standalone 模式,您必须在续期脚本中添加停止和启动 Web 服务的命令,否则自动续期将失败。
  4. 不适用泛域名: 这两种 HTTP 验证模式都不支持泛域名证书*.yourdomain.com)的签发。

如果需要签发泛域名证书,或者服务器上 80 端口被占用的情况很复杂,或者不想暴露 80 端口DNS 验证仍然是更安全、更通用的选择。