0. 背景
众所周知的原因,如果想要建设一个新网站,那么最好的方式是购买境外域名+境外节点,随买随用,无需一些繁琐的手续流程。但是境外节点又因为线路质量问题,常常国内访问起来非常缓慢,如果站点希望不只对境外提供服务,还需要对境内提供服务,那么一般来说需要搭建在一个高质量线路的节点上。
但是高质量线路的节点通常价格起飞,对于我这种个人用户来说,并不值得专门购买。有一个比较好的折衷方案是:购买普通线路的配置相对较高的机器作为源站,再购买一个低配的优质线路机器作为反向代理,使用Dnspod将境内外请求分流,如下图所示:
1. 前置准备
为了实现这样一个结构,本文使用以下方式实现:
- 首先需要有一个源站,假设IP是
11.11.11.11
- 其次需要有一个线路机器,假设IP是
22.22.22.22
- 需要有一个域名,视需求而定,二级、三级域名等不限,只要可以加入到DNSPOD解析即可,假设域名是
example.com
。
2. DNSPOD分流
DNSPOD分流很简单,新增一个origin
解析,在线路选项中,“默认”指向源站,“境内”指向线路机器:
然后其它所有需要按照这一规则进行分流的域名,均CNAME指向origin.example.com
即可。
解析成功添加后,在境内境外分别ping
你的域名,查看分流解析是否成功。
3. HTTPS证书申请
这一段你可能要执行两遍,因此先不着急执行,跳过这一章节到下一章,需要时再回来。
首先你需要有一个自己的证书,个人推荐使用Certbot+DNS验证的方式申请,使用DNS验证的方式,可以实现在多台机器上同时申请同一域名的证书。
对于托管在Dnspod上的域名,有certbot-dnspod
插件可用。使用方法如下(python venv中安装的certbot-dnspod
插件):
先在DNSPOD上开通API Key,保存在
dnspod.ini
文件中certbot_dnspod_token_id = xxxxx certbot_dnspod_token = xxxxx
安装certbot和certbot-dnspod插件
我个人不是很喜欢snap的certbot,它仅限于ubuntu生态,在debian上不可用。推荐使用python venv的方式安装:apt install python3 python3-pip python3-venv mkdir /root/certbot/ cd /root/certbot/ python3 -m venv venv ./venv/bin/pip install certbot certbot-dnspod
然后就可以用下面的方式
/root/certbot/venv/bin/certbot certonly --authenticator certbot-dnspod --certbot-dnspod-credentials /root/certbot/dnspod.ini -d example.com -d '*.example.com'
然后就是添加自动更新,
crontab -e
中添加:6 * bash -c 'bash /root/certbot/renewal.sh &> /root/certbot/renewal.log'
然后创建一个`renew.sh`:
/root/certbot/venv/bin/certbot certonly --authenticator certbot-dnspod --certbot-dnspod-credentials /root/certbot/dnspod.ini -d example.com -d '*.example.com' -n
`-n`参数是指定快到期时才更新,不需要更新则跳过。
4. 线路机器配置
线路机器有两种配置方式,各有优劣:
- Stream TCP流量转发:优点在于简单,只要添加一个nginx配置就算完成,线路机器上无需配置SSL证书;缺点在于这台机器上的Nginx就只能用于转发了,无法根据domain做不同的响应;
- Http ProxyPass转发:优点在于Nginx可以正常响应其它服务,缺点就是这台节点上也需要配置SSL证书了。
4.1. Stream TCP流量转发
首先修改/etc/nginx/nginx.conf
,在最外层添加:
stream {
include /etc/nginx/stream.d/*.conf;
}
然后是/etc/nginx/stream.d/proxy.conf
内容如下:
upstream origin_443 {
server 11.11.11.11:443; # <- 将这里替换成源站IP
}
server {
listen 443;
proxy_pass origin_443;
proxy_protocol on; # 开启 PROXY protocol
# 性能优化
proxy_connect_timeout 5s;
proxy_timeout 60s;
# TCP keepalive
proxy_socket_keepalive on;
}
4.2. Http ProxyPass转发
首先参照第3节的内容,先在这台节点上申请好Nginx证书。
然后就可以在/etc/nginx/sites-enabled/example.com
中添加:
server {
listen 80;
server_name example.com *.example.com; # <- 改为你的域名
return 301 https://$host$request_uri;
}
server {
server_name example.com *.example.com; # <- 改为你的域名
location / {
proxy_pass https://11.11.11.11:443; # <- 改为源站IP
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
client_max_body_size 512M;
proxy_ssl_server_name on;
}
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # <- 改为你的证书路径
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # <- 改为你的证书路径
}
5. 源站配置
源站其实也是照常配置即可,先申请好SSL证书,域名也同样是你自己的域名,与4.2.节里的配置几乎一样,无非是proxy_pass
的目标点不同。因此这里不再重复。