Table of Contents
Open Table of Contents
前言
IP+端口如何变成直接域名访问的呢?
假设你在 IP 地址为 1.1.1.1 的服务器上部署了一个 web 服务,它监听 8080 端口,那么你现在可以通过 http://1.1.1.1:8080
访问。
(1) DNS 解析
你再对你持有的域名 example.com
进行 DNS 解析,添加 A 类型记录,名称填 www
,地址填 1.1.1.1
,此时可以通过 http://www.example.com:8080
访问。
(2) 反向代理
输入 http://www.example.com
,其实就是访问的 http://www.example.com:80
,很方便,所以需要复用 80 端口,就需要反向代理。
让反向代理软件先监听 80 端口,进行配置(大致就是如果访问域名是 www.example.com
就反向代理到 1.1.1.1:8080
上),此时可以通过 http://www.example.com
访问。
(3) 配置 SSL 证书
和 HTTP 的默认端口是 80 类似,HTTPS 的默认端口是 443。
HTTPS 相比于直接 HTTP 访问更安全,但需要 SSL 证书,在反向代理那配置好了 SSL 证书之后,此时就可以通过 https://www.example.com
访问。
下面就介绍一种我用的反向代理方案,使用 acme.sh 定期申请泛域名 SSL 证书,配置 Caddy 进行反向代理,实现 HTTPS + 域名访问。
温馨提示,请确保你的服务器放行 80 和 443 端口,否则无法正常访问。国内云服务器需要进行备案才能使用 80 和 443 端口。
Caddy
与常见的 Nginx 反向代理相比,Caddy 的配置更为简单,仅需几行简单的配置即可实现基本的反向代理功能。
虽然很多人推荐新手使用 Nginx Proxy Manager,图形化界面加上能申请泛域名证书,对新手很友好。但它内存占用高,主体加上数据库的大小超过 100MB,而 Caddy 的内存占用则仅仅不到 30MB。
(1) 安装 Caddy
Caddy 的官方文档提供了多种安装方式,详细信息可在 Caddy 官方文档的安装页面找到。
虽然 Caddy 可以使用 Docker 部署,但我试过后并不推荐,使用起来反而更复杂。
我这里就贴一下在 Debian 系统上安装的示例:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
(2) 配置 Caddyfile
Caddy 的配置文件称为 Caddyfile,你需要选择一个存放此文件的地方。我通常将其放置在 ~/Caddy/Caddyfile
。
vim ~/Caddy/Caddyfile
~~~ # 分隔符,表示进入文本编辑界面
www.example.com {
reverse_proxy 127.0.0.1:8080
}
# 英文下键入 :wq,保存并退出
~~~ # 分隔符,表示退出文本编辑界面
关于 Caddyfile 的编写具体请查看 Caddy 官方文档,也可以多问问 ChatGPT,但其实就是把上面这个重复多次即可。
(3) 启动 Caddy
Caddy 需要使用 root 权限启动,否则将无法查看由 acme.sh 申请的泛域名 SSL 证书。
sudo caddy start --config ~/Caddy/Caddyfile
之后,你可以通过 http://www.example.com
进行访问。
(4) 泛域名 SSL 证书
如果你稍微了解一点 Caddy,就会发现它相比于 Nginx 还有一个特点就是会自动申请 SSL 证书。所以,你刚刚访问的 www.example.com
可能已经是 HTTPS 访问。
不过,Caddy 默认申请的 SSL 证书仅适用于 www.example.com
,无法用于其他子域名。
泛域名证书则是能用在 *.example.com
下,所有的二级域名都可以用。
如需泛域名证书,可以使用后文介绍的 acme.sh 脚本进行申请和更新。Caddy 本身申请泛域名证书的流程很麻烦。
acme.sh
acme.sh 是发布在 GitHub 上的一个脚本,可以通过 acme 协议,从 Let’s Encrypt 申请免费的泛域名证书。
PS 不管是 GitHub 还是 Let’s Encrypt 都是境外网站,如果不能正常运行,大概率是网络问题,需要自行解决。
(1) 安装 acme.sh
所谓的安装其实就是从网上拉取一个脚本文件下来,然后执行。
curl https://get.acme.sh | sh -s [email protected]
PS 你可以把这里的邮箱地址改为你的邮箱,在 SSL 证书快到期时会有邮件提醒。不过因为脚本会自动定期更新证书,其实不管也可以。
(2) 申请泛域名证书
这里我们采用 DNS 的方式,通过域名解析商提供的 api 自动添加 txt 记录验证域名的所有权。
支持的域名解析商以及使用说明详见 How to use DNS API,这里以 CloudFlare 为例。
打开 CloudFlare 官网,右上角“我的个人资料”,“API 令牌”点“创建令牌”,“API 令牌模板”-“编辑区域 DNS”-“使用模板”,“区域资源”-“包括特定区域”,选择你的域名。
点击继续,保存给出的 API 令牌。
export CF_Token="<cloudflare-api-token>" # 替换成你的 API 令牌
acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'
等待脚本执行完毕,就成功申请了。
(3) 安装证书
这一步就是把之前生成的证书复制到其他地方。
acme.sh --install-cert -d example.com \
--key-file ~/Caddy/example.com/key.pem \
--fullchain-file ~/Caddy/example.com/cert.pem \
--reloadcmd "caddy reload --config ~/Caddy/Caddyfile"
(4) 编辑 Caddyfile
这里对 Caddyfile 进行编辑,让它用上刚刚申请的泛域名证书来配置 HTTPS。
vim ~/Caddy/Caddyfile
~~~ # 分隔符,表示进入文本编辑界面
www.example.com {
encode gzip
tls ~/Caddy/example.com/cert.pem ~/Caddy/example.com/key.pem
reverse_proxy 127.0.0.1:8080
}
blog.example.com {
encode gzip
tls ~/Caddy/example.com/cert.pem ~/Caddy/example.com/key.pem
reverse_proxy 127.0.0.1:9090
}
# 英文下键入 :wq,保存并退出
~~~ # 分隔符,表示退出文本编辑界面
# 重启 reload 让配置生效
caddy reload --config ~/Caddy/Caddyfile
可以看到,我上面给出了两个子域名的反向代理配置,其实只用改动 reverse_proxy 这个参数。
补充说明
这篇博客主要还是走了一遍配置 Caddy + acme.sh 反向代理的流程走了一遍,主要目的是介绍 Caddy + acme.sh 这一套方案。
实际配置下来可能还会遇到很多问题,请自行查看相应的官方文档,或者把问题放在底下评论区,但我也不能保证我能解决,我也是小白捏。
(1) 快速编辑 Caddyfile
可以用环境变量保存 Caddyfile 文件路径。
vim ~/.bashrc # 其实我更推荐用单独文件保存环境变量和别名
~~~ # 分隔符,表示进入文本编辑界面
export caddyfile=~/Caddy/Caddyfile
# 英文下键入 :wq,保存并退出
~~~ # 分隔符,表示退出文本编辑界面
之后就可以用 $caddyfile
代替。
sudo caddy start --config $caddyfile
caddy reload --config $caddyfile
(2) 部署静态博客
如果你在服务器上部署了静态博客,相应的 Caddyfile 配置如下。
blog.example.com {
encode gzip
root * /path/to/website # 替换为你的博客根目录
file_server
tls ~/Caddy/example.com/cert.pem ~/Caddy/example.com/key.pem
}
不过我挺推荐你把静态博客部署到 CloudFlare Pages 上的,我的博客就是部署到 CloudFlare Pages 上。