Caddy是一款简单易用的Web Server,不费吹灰之力就可以让你的站点支持HTTPS和HTTP/2,虽然它的名气没有和Apache、Nginx响亮,但它该有的功能一点也不含糊,语言层面使用Golang实现,性能妥妥的,配置方面亦十分简洁,比Nginx友好N倍
背景
HTTPS几乎已经成为主流网站的标配了,但是动辄几千大洋的价格,对个人用户真心不友好,即便有些云厂商提供短期免费的SSL证书,但各种注册、认证等要求,让人不胜其烦。好在有Caddy这个神器,可以不费吹灰之力实现全站https。
文档
友好提醒一下,目前Caddy已经有v2版本了,不过v2正式版发行时间尚短,个人认为其稳定性有待验证,暂时强烈建议使用v1版本,本文内容亦是以Caddy1为准。可以先去官网概览一下其特性
官网: https://caddyserver.com/
Caddy1:https://caddyserver.com/v1
环境
证书服务是针对域名颁发的,所以需要在真实外网环境进行测试,内网是无法使用HTTPS服务的。请读者朋友自备服务器和域名
1. Centos7服务器一台 (其他Linux系统类似)
2. 域名一个
安装
Caddy的安装方式比较多,官网有详细介绍,我这里以常用的Centos服务器为例,说明下安装过程。
yum安装
建议使用yum
安装,安装完成后,将会自动把caddy服务添加到系统服务
$ yum install epel-release
$ yum install caddy
自定义安装
老手建议此方式安装,可以扩展插件。Caddy支持很多插件,可以提供额外的功能,如果需要使用插件扩展,可以在官网选择对应平台、插件,下载软件包或一键安装脚本。后面介绍插件时,再详细说下该方式
快速开始
若使用yum安装,将会在系统自动创建系统服务和初始配置文件,当然了如果使用其它安装方式,也不用慌,Caddy配置文件十分简单。下面内容还是以yum安装方式为前提
服务管理
启动服务
$ systemctl start caddy
服务启动成功后,caddy会开启一个演示站点,默认监听80端口,可以访问查看内容
$ netstat -nltup
$ curl 127.0.0.1
停止服务
$ systemctl stop caddy
配置文件
主配置文件路径 /etc/caddy/caddy.conf
,默认内容大致如下
http:// {
gzip
root /usr/share/caddy
}
import conf.d/*.conf
http: { } 这部分是站点配置,这里是指定了一个站点,监听80端口,
使用gzip压缩网站内容,站点目录位于/usr/share/caddy
在服务器本机执行以下命令,可以看到网站内容
$ cat /usr/share/caddy/index.html
$ curl 127.0.0.1
imprort
是引入其他配置文件,这里引入的是/etc/caddy/conf.d
目录下所有文件名以.conf
结尾的配置文件。如果有多个站点,建议每个站点一个单独配置文件,放在该目录下
站点管理
Caddy最亮眼的功能在于可以自动实现https,它使用的是Let’s Encrypt颁发的ssl证书,虽然是免费证书,但安全级别一点也不差,也完全不用担心证书过期,只需要提供一个邮箱,Caddy会定期检查,自动续期。现在按以下步骤快速体验一把,
假设您的域名为 caddy-test.com
申请证书的邮箱为 email@caddy-test.com
域名解析
Caddy在申请ssl证书时,要对域名解析进行校验,解析到本机的域名才可以成功申请证书,所以DSN解析要预先添加好,注意以下事项
1. 注意服务器防火墙设置,须对外开放80、443端口。
2. 具体解析步骤在域名供应商提供的后台进行操作,这里不做赘述。
如果添加的解析设置为www,可以使用ping命令查看是否解析成功
ping www.caddy-test.com
配置站点
在完成DNS解析之后,仿照默认配置内容,新建一个配置文件
/etc/caddy/conf.d/test.conf
www.caddy-test.com {
gzip
tls email@caddy-test.com
root /usr/share/caddy
}
保存之后,使用systemctl reload caddy
重载配置文件
在浏览器中或使用curl访问http://www.caddy-test.com
, 可以看到状态码为301重定向,该网址将跳转到https://www.caddy-test.com
至此https成功开启,惊不惊喜!拥有一个https站点就是如此简单。
配置文件
Caddy的配置文件,一般称为Caddyfile,遵循较为宽松的语法要求。如果想对站点再做更专业的配置,则需要对此语法有所了解。对于常见的一些Web应用,官方已经提供了一份参考配置文件,参考地址:
https://github.com/caddyserver/examples
Caddyfile
根据前面的案例,举一反三,分析以下Caddyfile的结构
www.caddy-test.com m.caddy-test.com {
gzip
root /usr/share/caddy
}
一个站点配置通常包含网址 、指令块、指令
- 网址,必须声明是哪些网址,不可重复,可以指定http或https,也可以指定端口,多个网址之间可使用空格或逗号隔开
- 指令块,不是必须的,通常在指令较多情况下,使用
{}
包裹,建议尽量使用指令块,这样结构会更清晰,注意{
前面必须是有空格的,否则会导致配置错误 - 指令,
gzip
root
这些都是指令,对应站点的某项配置
指令
标准的Caddy内,已经内置很多常用功能,都是以指令方式使用,本文介绍一些最常用的指令
root
指定站点对应的root目录
gzip
压缩响应内容,可以优化响应速度,默认压缩级别为6,可以使用以下方式覆盖默认参数
gzip {
level 3
}
fastcgi
代理对FastCGI服务器的请求,目前绝大多数都是用于PHP站点,配合php-fpm使用配置如下
fastcgi / 127.0.0.1:9000 php
header
添加或删除某些响应头,比如不在响应header中返回服务器信息
header / {
-Server
}
rewrite
rewrite是比较复杂的指令,通常需要根据网站的设计来设置规则,比如常见的mvc框架,先检查请求的文件或目录是否存在,若不存在则将请求都转到index入口文件
rewrite {
to {path} {path}/ /index.php?{query}
}
这里的{path} {query}是占位符,后面会再介绍
redir
重定向,不要和rewrite混淆,该指令会发生网址跳转,而rewrite不会,比如访问顶级域名时强制跳转到www域名,状态码为301
caddy-test.com {
redir / https://www.caddy-test.com{uri} 301
}
status
返回状态码,比如不允许网站的某些目录被访问,直接返回404
status 404 {
/.git
/secrets
}
log/errors
日志分为请求日志和错误日志,类似nginx中的access.log和error.log ,如果需要记录日志,可以指定日志存储参数,注意日志文件需要有caddy用户写入权限
errors /var/log/caddy/error.log
log / /var/log/caddy/access.log "{combined}" {
rotate_size 50 # 50M以后轮转
rotate_age 90 # 保持轮转文件90天
rotate_keep 5 # 最多保持5个日志文件
}
proxy
反向代理,该指令可以代理其他Web服务,或按某种策略实现负载均衡
proxy /api localhost:8080
proxy / web1.local:80 web2.local:90 web3.local:100 {
policy round_robin
health_check /health
transparent
}
tls
用于配置https连接,如果是指定了域名且没有明确指定使用http,默认会启用https,该项配置仅用于覆盖某些默认配置
出于安全考虑,caddy默认支持的tls协议,最低为tls1.2,这在某些环境中(尤其是一些低端手机上)可能无法正常访问,因此可以采用下面写法设置最低支持tls1.0,最高支持tls1.3。但是除非有明确要求,否则十分不建议修改该配置
tls email@caddy-test.com {
protocols tls1.0 tls1.3
ciphers ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-WITH-CHACHA20-POLY1305 ECDHE-RSA-WITH-CHACHA20-POLY1305 ECDHE-RSA-AES256-CBC-SHA ECDHE-RSA-AES128-CBC-SHA ECDHE-ECDSA-AES256-CBC-SHA ECDHE-ECDSA-AES128-CBC-SHA RSA-AES256-CBC-SHA RSA-AES128-CBC-SHA ECDHE-RSA-3DES-EDE-CBC-SHA RSA-3DES-EDE-CBC-SHA
}
占位符
占位符分请求占位符和响应占位符,通常是指代请求或响应对象的某个属性,是可以被替换的值,不同指令支持不同的占位符,使用过程中需参考文档要求
请求占位符
常用请求占位符
占位符 | 描述 |
---|---|
{uri} | URI(包括路径、查询串、以及锚部分) |
{path} | URI的路径部分(不包含查询字符串(query)以及锚点(fragment)部分) |
{query} | URL链接中的查询参数串,不包含问号? |
{fragment} | URL链接中的锚点内容,URL末尾以 #开始的内容 |
{scheme} | 使用的协议(通常是http或者https) |
{host} | 主机 |
{port} | 端口 |
{proto} | 协议(比如”HTTP/1.1”) |
{remote} | 客户端的IP地址 |
{>Header} | 请求头,”Header”是请求头信息的某个字段名称 |
响应占位符
常用响应占位符
占位符 | 描述 |
---|---|
{status} | 响应的HTTP状态码 |
{<Header} | 响应头,”Header”是响应头信息的某个字段名称 |
插件
Caddy可以基于插件进行扩展。若自行开发,需要有一定Golang基础,目前官方已经提供了很多常用的插件,可以直接使用,相关指令文档在Directives/Middleware部分。
获取插件
前面使用yum安装,是标准安装包,可以使用下面命令查看当前caddy已有的插件
$ caddy -plugins
若要使用官方扩展插件,需要下载caddy软件包使用
地址 https://caddyserver.com/v1/download
依次选择平台(PLATFORM)和所需插件(PLUGINS),点击确认(DONE),可以看到下面有两种安装方式,选择一种你喜欢的方式安装即可。这里假设选择平台Linux 64-bit ,插件为指令/中间键中的http.ipfilter
安装方式有两种,可下载软件安装包,也可以使用安装脚本。
软件安装包
该方式方式是下载安装包,手动部署,可以更清晰的理解caddy安装过程
$ curl -o caddy.tar.gz "https://caddyserver.com/download/linux/amd64?plugins=http.ipfilter&license=personal&telemetry=off"
$ tar zxvf caddy.tag.gz
$ ls
$ ./caddy -plugins |grep ipfilter
执行以上命令,根据输出可以看到,当前下载的caddy中已经包含http.ipfilter插件。
若已经使用yum安装过caddy,可以直接覆盖caddy二进制文件
$ which caddy
$ cp ./caddy /usr/bin/caddy
若未安装过,则需要自行添加系统服务
$ cp init/linux-systemd/caddy.service /usr/lib/systemd/system/caddy.service
$ cat init/linux-systemd/caddy.service
下载的caddy.service可能和yum安装自动创建的稍有不同,根据目前下载的文件内容,需要创建以下几项
1. 用户/组, www-data
2. 配置文件,/etc/caddy/Caddyfile
,参考快速开始部分的配置文件
3. ssl证书目录,/etc/ssl/caddy/
安装脚本
该方式是下载安装脚本,一键安装部署
$ curl https://getcaddy.com | bash -s personal http.ipfilter
耐心等待脚本执行完成,将会自动搞定安装步骤
使用插件
插件也是提供指令操作,语法遵循Caddyfile的要求,以上一步中安装的ipfilter插件为例。
该插件提供提供ip白名单、黑名单功能,使用方式如下
www.caddy-test.com {
gzip
root /usr/share/caddy
ipfilter / {
rule block
prefix_dir /etc/caddy/blacklisted
}
}