安装前准备

go安装和环境配置

apt install wget software-properties-common apt-transport-https
wget https://golang.google.cn/dl/go1.20.2.linux-amd64.tar.gz
tar -zxvf go1.20.2.linux-amd64.tar.gz -C /usr/local/

nano ~/.bashrc
export GO_HOME=/usr/local/go/
export GO_PATH=$HOME/go 
export PATH=${GO_HOME}/bin:$GO_PATH/bin:$PATH

source ~/.bashrc
#运行go进行测试
go version
#改为国内加速地址
go env -w GOPROXY=https://goproxy.cn/,direct

安装Caddy

安装xcaddy,编译alidns插件。

apt install -y curl git jq

apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-xcaddy-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-xcaddy.list
apt update
apt install xcaddy

xcaddy --help

xcaddy build  --output ./caddy \
        --with github.com/caddy-dns/alidns

~ ./caddy list-modules

mv ./caddy /usr/bin/

开放端口和权限

服务器部署好之后,可以将 443 和 80 端口打开,443 作为 Web 服务器的访问端口,80 是开放给 Let’s Encrypt 注册的。

apt install ufw
ufw allow ssh
ufw allow 443
ufw allow 80
ufw allow 8888
ufw enable
ufw status numbered
ufw delete *

给caddy设置适当的权限

chown root:root /usr/bin/caddy
chmod +x /usr/bin/caddy

给Caddy二进制文件以非root账户身份绑定到80和443端口

setcap 'cap_net_bind_service=+ep' /usr/bin/caddy
echo $(which caddy)
echo $(readlink -f $(which caddy))
setcap 'cap_net_bind_service=+ep' $(readlink -f $(which caddy)) 

创建caddy群组及用户

groupadd --system caddy
useradd --system \
    --gid caddy \
    --create-home \
    --home-dir /var/lib/caddy \
    --shell /usr/sbin/nologin \
    --comment "Caddy web server" \
    caddy

创建必要目录并为 caddy 用户赋予相关目录权限

# 创建网站文件夹,一般网站的部署路径为 /var/www,在该文件夹下建立多个网站目录
mkdir /var/www
# 赋予权限
chown -R caddy:caddy /var/www
touch /var/log/caddy/caddy.log
touch /etc/caddy/caddy.env
chown caddy:caddy /var/log/caddy/caddy.log
chown -R caddy:caddy /etc/caddy

创建 /etc/systemd/system/caddy.service 文件

nano /etc/systemd/system/caddy.service

caddy.service 文件内容

https://github.com/caddyserver/dist/blob/master/init/caddy.service

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=caddy
Group=caddy

ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile --envfile /etc/caddy/caddy.env
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

让caddy随系统自动启动

systemctl daemon-reload
systemctl enable caddy

配置Caddyfile

找到caddy配置文件目录

cd /
# find / -name Caddyfile
touch /etc/caddy/Caddyfile
nano /etc/caddy/Caddyfile

修改配置如下:

{
    # 测试通过的生产环境中去除该项
    # acme_ca https://acme-staging-v02.api.letsencrypt.org/directory

    acme_dns alidns {
        access_key_id {env.ALIYUN_ACCESS_KEY_ID}
        access_key_secret {env.ALIYUN_ACCESS_KEY_SECRET}
    }
    email techlayman@tech.com
}

(ERROR_HANDLE) {
        handle_errors {
                @404 {
                        expression {http.error.status_code} == 404
                }
                handle @404 {
                        rewrite * /404.html
                        file_server
                }
        }
}

(LOG) {
        log {
                output file "{args.0}" {
                        roll_size 10mb
                        roll_keep 3
                        roll_keep_for 7d
                }
        }
}

(TLS){
        tls {
            protocols tls1.2 tls1.3
            ciphers TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
            curves x25519 
            # 不加打不开网页哦
        }
}

(secure_headers){
        header {
            Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
            Referrer-Policy strict-origin-when-cross-origin
            X-Frame-Options SAMEORIGIN
            X-Content-Type-Options nosniff
            X-XSS-Protection "1; mode=block"
        }
}

techlayman.com www.techlayman.com {  
    # 分隔为空格
    import TLS
    import secure_headers
    root * /var/www/hugo
    encode zstd gzip
    file_server
    import ERROR_HANDLE
    import LOG "/var/log/caddy/caddy.log"
    @v2ray_websocket {
        path /ray
        header Connection *Upgrade*
        header Upgrade websocket
    }
    reverse_proxy @v2ray_websocket localhost:8888
}

配置alidns

nano /etc/caddy/caddy.env
env.ALIYUN_ACCESS_KEY_ID="xxx"
env.ALIYUN_ACCESS_KEY_SECRET="xxx"

相关操作命令

# 重载配置文件
sudo systemctl daemon-reload
# 设置 caddy 开机自启
sudo systemctl enable caddy
# 查看是否启动成功,这里因为没启动应该显示 Active: inactive (dead)
sudo systemctl status caddy
# 启动 caddy
sudo systemctl start caddy
# 过十秒钟左右再次查看 caddy 状态
sudo systemctl status caddy
# 重启命令
sudo systemctl restart caddy
# 停止命令
sudo systemctl stop caddy

上传静态文件至/var/www/hugo,就可以使用域名访问博客了。

测试

直接用浏览器访问这个地址,这里示例域名: yourdomain.com

https://crt.sh/?q=yourdomain.com
sudo caddy run -config /etc/caddy/Caddyfile

相关调试

caddy validate --adapter caddyfile --config /etc/caddy/Caddyfile
caddy run
journalctl -u caddy
journalctl --since "30 min ago"