• 搭建属于你自己的 ACME 服务器(拥有完全控制权)

如果你想拥有完全控制权,可以搭建一个属于自己的 ACME 服务器。这将允许你在内部网络或私有系统中自动化签发、管理 SSL/TLS 证书,并实现与 Let's Encrypt 类似的自动证书申请流程。

⚠️ 注意:自建 ACME 服务适合企业级部署、开发测试环境或需要内部 CA 的场景。如果你只是想为公网网站获取免费证书,请使用 Let’s Encrypt 或其他公共 CA。


🧩 一、选择合适的开源 ACME 实现

以下是一些常见的开源 ACME 服务器项目:

项目描述GitHub
BoulderLet's Encrypt 官方使用的 ACME 服务器github.com/letsencrypt/boulder
Smallstep CA轻量级、易用的 CA + ACME 服务器smallstep.com/docs/step-ca
EJBCA功能强大的企业级 PKI 系统,支持 ACME 插件ejbca.org
SimpleAuthority基于 Golang 的轻量 ACME 服务器github.com/irai/simpleauthority

我们以 Smallstep CA 为例进行演示,因为它易于安装、文档完善,适合大多数中小型团队和开发者。


🔧 二、使用 Smallstep CA 搭建 ACME 服务器

✅ 步骤 1:准备环境

  • 操作系统:Linux(推荐 Ubuntu/Debian/CentOS)
  • Docker(可选)或直接运行
  • 域名(用于访问 ACME 服务)
  • 公网 IP 或内网穿透(如需远程访问)

✅ 步骤 2:下载并安装 Step CA

# 下载 step CLI 工具
curl -LO https://github.com/smallstep/cli/releases/latest/download/step-cli_0.28.0_amd64.deb
sudo dpkg -i step-cli_0.28.0_amd64.deb

# 初始化 CA 配置
step ca init \
  --name="My Internal CA" \
  --dns="ca.example.com" \
  --address=":8443"

此命令会生成以下内容:

  • 根证书和中间证书
  • 配置文件 ~/.step/config/ca.json
  • 私钥文件 secrets/...

✅ 步骤 3:启动 Step CA 服务

step-ca $(step path)/config/ca.json

默认监听地址是 https://localhost:8443

你可以通过配置 DNS 解析或反向代理(如 Nginx)将其暴露到公网或局域网。

✅ 步骤 4:配置 HTTPS 访问(可选)

建议使用域名绑定并启用 HTTPS,例如使用 Nginx 反向代理:

server {
    listen 443 ssl;
    server_name ca.example.com;

    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    location / {
        proxy_pass https://localhost:8443;
    }
}

📡 三、配置 ACME 客户端连接你的 ACME 服务器

你可以使用任何支持 ACME 协议的客户端(如 Certbot、acme.sh)来连接你自建的 ACME 服务器。

示例:使用 acme.sh 连接 Smallstep CA

export ACME_DIRECTORY="https://ca.example.com/acme/acme/directory"

~/.acme.sh/acme.sh --issue -d myservice.local \
  --server "$ACME_DIRECTORY" \
  --standalone

注意:你需要将 ca.example.com 的证书添加到操作系统信任链中,否则会出现证书错误。


🔐 四、创建用户账户(用于客户端认证)

Step CA 支持创建一次性凭证或长期凭证:

step ca token myservice.local \
  --kid <your-kid> \
  --kty RSA \
  --ca-url https://ca.example.com \
  --root $(step path)/certs/root_ca.crt

你可以将生成的 token 提供给客户端使用。


📁 五、证书签发和管理

  • 所有签发的证书都保存在 Step CA 的数据库中(默认 SQLite)
  • 可查看所有已颁发证书:
step ca list-certificates
  • 吊销证书:
step ca revoke --serial <serial-number>

🔄 六、自动续期与监控

Step CA 不会自动续期证书,但你可以结合客户端工具(如 acme.sh)设置定时任务:

0 0 * * * "/home/user/.acme.sh"/acme.sh --cron --home "/home/user/.acme.sh"

🧪 七、测试与验证

你可以使用 OpenSSL 或浏览器访问你的证书服务,确保能正常获取和验证证书。

openssl s_client -connect ca.example.com:443

📦 八、持久化与备份

  • 备份根证书和密钥非常重要!一旦丢失,所有签发的证书将无法验证。
  • 使用 MySQL/PostgreSQL 替换默认 SQLite 存储(适用于生产环境)

🧱 九、进阶:多租户、审计日志、LDAP 集成

Step CA 支持:

  • LDAP/AD 用户认证
  • 多个 CA 实例(多租户)
  • 日志审计
  • REST API 管理接口

详情请参考官方文档:https://smallstep.com/docs/step-ca


✅ 总结:关键步骤一览表

步骤内容
1选择合适的 ACME 服务器项目(如 Smallstep CA)
2安装并初始化 CA 服务
3启动服务并配置 HTTPS 访问
4使用客户端(Certbot/acme.sh)连接你的 ACME 地址
5创建用户 Token 并授权客户端
6自动化签发、续期、吊销证书
7定期备份根证书和数据库
8(可选)集成 LDAP、数据库、审计等高级功能

❓常见问题 FAQ

Q: 我的客户端提示“证书不受信任”?

A: 你需要将你的 CA 根证书添加到客户端系统的信任链中。

sudo cp root_ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

Q: 如何让多个部门共享同一个 CA?

A: 可以使用 Step CA 的“provisioner”机制,为不同团队创建不同的认证方式和策略。

    • 🚀 一键部署 ACME 服务器(使用 Smallstep CA)

以下是一个一键部署脚本,用于在 Ubuntu/Debian 系统上自动安装并配置 Smallstep CA,搭建一个完整的 ACME 证书服务

✅ 支持 HTTPS、域名绑定、自签名根证书信任
⚠️ 需要你有一个公网 IP 或域名


🧩 脚本功能一览:

功能描述
自动下载 step CLI 工具安装最新版本
初始化 CA 证书包括根证书和中间证书
启动 Step CA 服务默认监听 :8443
反向代理 Nginx 配置支持 HTTPS 访问
添加根证书到系统信任链避免客户端提示“证书不受信任”
提供示例客户端命令用于 acme.sh 或 Certbot 连接测试

📋 使用前准备

  1. 一台 Ubuntu/Debian 服务器
  2. 域名(如 ca.example.com)并解析到服务器 IP
  3. 已安装 curl, sudo

📦 一键部署脚本(保存为 deploy-acme.sh

#!/bin/bash

set -e

echo "🚀 开始部署 Smallstep CA ACME 服务..."

# === 用户输入部分 ===
read -p "请输入你的域名(例如 ca.example.com): " DOMAIN
read -p "是否启用 HTTPS 反向代理?(y/n): " USE_HTTPS

# === 安装依赖 ===
echo "🔧 安装依赖..."
sudo apt update
sudo apt install -y curl wget gnupg nginx software-properties-common

# === 下载并安装 step CLI ===
STEP_VERSION="0.28.0"
echo "📥 正在下载 step CLI v${STEP_VERSION}..."
cd /tmp
wget -q https://github.com/smallstep/cli/releases/download/v${STEP_VERSION}/step-cli_${STEP_VERSION}_amd64.deb
sudo dpkg -i step-cli_${STEP_VERSION}_amd64.deb

# === 初始化 CA ===
echo "🔐 初始化 CA 服务..."
step path > /dev/null 2>&1 || true
step ca init \
  --name="My Internal CA" \
  --dns="$DOMAIN" \
  --address=":8443"

# === 设置开机启动 ===
cat <<EOF | sudo tee /etc/systemd/system/step-ca.service
[Unit]
Description=Step Certificate Authority
After=network.target

[Service]
ExecStart=/usr/bin/step-ca $(step path)/config/ca.json
Restart=always
User=$(whoami)

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable step-ca --now

# === 配置反向代理(可选 HTTPS)===
if [[ "$USE_HTTPS" == "y" || "$USE_HTTPS" == "Y" ]]; then
    echo "🌐 配置 HTTPS 反向代理..."

    sudo apt install -y certbot python3-certbot-nginx

    cat <<EOF | sudo tee /etc/nginx/sites-available/step-ca
server {
    listen 80;
    server_name $DOMAIN;

    location /.well-known/acme-challenge/ {
        root /var/www/html;
        try_files \$uri =404;
    }

    location / {
        return 301 https://\$host\$request_uri;
    }
}
EOF

    sudo ln -sf /etc/nginx/sites-available/step-ca /etc/nginx/sites-enabled/
    sudo nginx -t && sudo systemctl reload nginx

    echo "🔒 获取免费 SSL 证书..."
    sudo certbot --nginx -d $DOMAIN --noninteractive --agree-tos -m admin@$DOMAIN

    cat <<EOF | sudo tee /etc/nginx/sites-available/step-ca
server {
    listen 443 ssl;
    server_name $DOMAIN;

    ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;

    location / {
        proxy_pass https://localhost:8443;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_ssl_verify off;
    }
}

server {
    listen 80;
    server_name $DOMAIN;
    return 301 https://\$host\$request_uri;
}
EOF

    sudo nginx -t && sudo systemctl reload nginx
fi

# === 导出根证书并加入信任 ===
echo "✅ 将根证书添加到系统信任链..."
sudo cp $(step path)/certs/root_ca.crt /usr/local/share/ca-certificates/root_ca.crt
sudo update-ca-certificates > /dev/null 2>&1

# === 显示信息 ===
echo ""
echo "🎉 部署完成!以下是相关信息:"
echo "---------------------------------------------"
echo "ACME 地址: https://$DOMAIN/acme/acme/directory"
echo "CA 根证书路径: $(step path)/certs/root_ca.crt"
echo "服务状态: sudo systemctl status step-ca"
echo ""
echo "📘 示例客户端命令(acme.sh):"
echo "export ACME_DIRECTORY='https://$DOMAIN/acme/acme/directory'"
echo "~/.acme.sh/acme.sh --issue -d yourdomain.local --server \"\$ACME_DIRECTORY\" --standalone"
echo ""
echo "💡 提示:你需要将根证书导入浏览器或客户端以避免证书警告。"

▶️ 如何运行脚本

chmod +x deploy-acme.sh
./deploy-acme.sh

📝 示例输出(运行后)

🎉 部署完成!以下是相关信息:
---------------------------------------------
ACME 地址: https://ca.example.com/acme/acme/directory
CA 根证书路径: /home/user/.step/certs/root_ca.crt
服务状态: sudo systemctl status step-ca

📘 示例客户端命令(acme.sh):
export ACME_DIRECTORY='https://ca.example.com/acme/acme/directory'
~/.acme.sh/acme.sh --issue -d yourdomain.local --server "$ACME_DIRECTORY" --standalone

📌 后续操作建议

  • /home/youruser/.step/certs/root_ca.crt 分发给所有需要连接的客户端设备,并导入信任。
  • 可通过访问 https://ca.example.com 查看 CA 欢迎页面。
  • 所有签发的证书可通过 step certificate inspect <cert.pem> 查看。

🛡️ 安全建议

  • 不要把你的 CA 私钥泄露出去(位于 ~/.step/secrets
  • 建议定期备份整个 .step 目录
  • 生产环境应使用 PostgreSQL 替代默认 SQLite 数据库