Caddy部署反向代理/镜像(支持自签SSL证书)

Caddy 是一款由 Go 编写的 Web Server 工具, Caddy 能让网站自动支持 HTTPS。同时Caddy可以申请免费的Let’s Encrypt泛域名SSL证书,换成 Nginx 我们就必须手工操作,并且还需要设置三个月更新证书的计划任务。除此之外,Caddy默认还支持 http/2,它的配置文件也比Nginx的要相对简单一些。

部署 Caddy

Caddy 是 Go语言编译好的二进制程序,所以只有一个 Caddy 文件(还需要生成一个配置文件),为了管理方便,所以我做了个一键脚本。

1
wget -N --no-check-certificate https://larix.cc/files/shell/fun/caddy_install.sh && chmod +x caddy_install.sh && bash caddy_install.sh install http.filemanager

安装Caddy成功后,继续下面的步骤。

配置文件

域名反向代理 HTTPS:如果你有SSL证书和密匙的话,把SSL证书(.crt)和密匙(.key)文件放到/root文件夹下(也可以是其他文件夹,自己改下面代码)。
HTTP重定向为HTTPS(仅手动指定SSL证书和密匙):当你是手动指定 SSL证书和密匙 来配置的话,Caddy只会监听 443端口(https),并不会自动设置 80端口(http)的重定向(如果是Caddy自动申请的SSL证书,那么就自动做好了)。
使用说明

1
2
3
4
5
6
7
8
9
/etc/init.d/caddy start #启动
/etc/init.d/caddy stop #停止
/etc/init.d/caddy restart #重启
/etc/init.d/caddy status #查看状态
tail -f /tmp/caddy.log #查看Caddy启动日志
/usr/local/caddy/Caddyfile #Caddy配置文件位置
/.caddy/acme/acme-v01.api.letsencrypt.org/sites/xxx.xxx(域名)/ #Caddy自动申请SSL证书位置
wget -N --no-check-certificate https://larix.cc/files/shell/fun/caddy_install.sh && chmod +x caddy_install.sh && bash caddy_install.sh uninstall
#卸载 Caddy,执行以下代码后,会问你是否确定要卸载 Caddy,输入y即可。 注意:卸载 Caddy 会把Caddy的所有虚拟主机文件夹和配置文件删除,并且不可恢复。

查看启动日志:

1
tail -f /tmp/caddy.log

后台启动

首先我们为 Caddy 创建一个配置目录,这里以 /etc/caddy 为例。同时我们还需要生成一个目录用来给 Caddy 放置网站证书。

1
2
3
4
$ sudo mkdir /etc/caddy
$ sudo mkdir /etc/caddy/conf
$ echo 'import ./conf/*' >> /etc/caddy/Caddyfile
$ sudo mkdir /etc/ssl/caddy

从官方仓库中下载 caddy 的 systemctl 守护脚本并对其挂载启动。

1
2
3
4
sudo curl -s https://raw.githubusercontent.com/mholt/caddy/master/dist/init/linux-systemd/caddy.service -o /etc/systemd/system/caddy.service
$ sudo systemctl daemon-reload
$ sudo systemctl enable caddy
$ sudo systemctl start caddy

这样我们就完成 caddy 后台启动任务,可以使用 status 命令查看 caddy 的状态:

1
sudo systemctl status caddy

Caddyfile

Caddyfile 是 Caddy 的配置文件,刚才我们写入了一条 import ./conf/* 命令,表示将 /etc/caddy/conf/ 下的所有文件都导入到配置文件中。下面我就以几个大家常见的需求列举一下如何编写 Caddfile 配置。

静态资源

静态资源和Nginx一样,Caddy 也有一个 root 配置。静态资源的访问只要设置到对应的 root 即可。同时我们也为资源配置了 gzip 压缩功能。

1
2
3
4
5
6
7
sudo cat << EOF > /etc/caddy/conf/static.example.com
static.example.com {
gzip
root /var/www/static.example.com
}
EOF
sudo systemctl restart caddy

####反向代理

反向代理请求到另外的端口算是我们比较常见的需求了,通过 proxy 指令我们可以非常简单的做到。以 ThinkJS 的配置为例,我们在静态资源配置的基础之上,增加了 proxy 指令将请求反向代理到了 http://127.0.0.1:8360 端口。由于反向代理后丢失了原始请求的 HOST,我们使用 transparent 指令增加 X-* 头。最后我们使用 except 指令排除了 /static 的请求,因为这些请求是静态资源的不需要反代。

1
2
3
4
5
6
7
8
9
10
$ sudo cat << EOF > /etc/caddy/conf/thinkjs.example.com
thinkjs.example.com {
gzip
root /var/www/thinkjs.example.com/www
proxy / http://127.0.0.1:8360 {
transparent
except static
}
}
$ sudo systemctl restart caddy

我们可以对比下 ThinkJS Nginx 的配置文件,以下还仅仅只是 HTTP 的配置,没有加上 HTTPS 以及HTTP/2 的配置。所以 Caddy 的简单性不言而喻。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
server {
listen 80;
server_name example.com www.example.com;
root <%= ROOT_PATH %>;
set $node_port 8360;
index index.js index.html index.htm;
if ( -f $request_filename/index.html ){
rewrite (.*) $1/index.html break;
}
if ( !-f $request_filename ){
rewrite (.*) /index.js;
}
location = /index.js {
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:$node_port$request_uri;
proxy_redirect off;
}
location ~ /static/ {
etag on;
expires max;
}
}

Websocket

Caddy 配置WebSocket也非常简单,使用websocket指令即可。

1
2
3
4
5
6
7
8
9
10
11
$ sudo cat << EOF > /etc/caddy/conf/thinkjs.example.com
ws.example.com {
gzip
root /var/www/ws.example.com/www
proxy / http://127.0.0.1:8360 {
websocket
transparent
except static
}
}
$ sudo systemctl restart caddy

更多的配置指令可以上 https://caddyserver.com/docs 官方文档查看,也可以上 https://github.com/caddyserver/examples 仓库中查看各种程序对应的 Caddy 配置。

或者采用如下方案:

部署Caddy

1
2
3
4
5
apt-get install -y libcap2-bin \
&& curl https://getcaddy.com | bash -s personal dns,http.cache,http.filter,http.git,http.ipfilter,http.realip && chown root:root /usr/local/bin/caddy && chmod 755 /usr/local/bin/caddy && setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy \
&& curl -s https://raw.githubusercontent.com/mholt/caddy/master/dist/init/linux-systemd/caddy.service -o /etc/systemd/system/caddy.service && chmod 644 /etc/systemd/system/caddy.service \
&& mkdir /etc/caddy && chown -R root:www-data /etc/caddy && touch /etc/caddy/Caddyfile && mkdir /etc/ssl/caddy && chown -R www-data:www-data /etc/ssl/caddy && chmod 0770 /etc/ssl/caddy \
&& mkdir /var/log/caddy && chown -R www-data:www-data /var/log/caddy

配置方法

Caddy 支持自动申请 SSL 证书好域名的ssl证书,把下面一段中的mail@gmial.com换成自己的邮箱就好了,脚本会自动申请好Lets encrypt的 SSL 证书。申请 SSL证书前,请务必提前解析好域名记录(可以在使用前 Ping 一下域名看一下是否生效),否则 Caddy 会申请失败。

1
2
3
4
5
6
echo "https://abc.com {
gzip
tls mail@gmail.com
log / /var/log/caddy/abc_com.log "{remote} - {user} [{when}] {when_unix} \"{method} {uri} {proto}\" {status} {size} \"{>Referer}\" \"{>User-Agent}\""
proxy / https://www.google.com.hk
}" > /etc/caddy/Caddyfile

如果一切正常,那么Caddy会自动申请 SSL 证书,且会定时续约 SSL 证书!如果你的网站不想公开分享需要加密码的话可以在邮箱下面一行加上basicauth / user passwd。(user和passwd分别变更成指定的用户名和密码即可)

使用说明

1
2
3
4
5
6
systemctl start caddy #启动
systemctl stop caddy #停止
systemctl restart caddy #重启
systemctl status caddy #查看状态
tail -f /var/log/caddy/abc_com.log #查看Caddy启动日志
/etc/caddy/Caddyfile #Caddy配置文件位置