0. 背景

众所周知的原因,如果想要建设一个新网站,那么最好的方式是购买境外域名+境外节点,随买随用,无需一些繁琐的手续流程。但是境外节点又因为线路质量问题,常常国内访问起来非常缓慢,如果站点希望不只对境外提供服务,还需要对境内提供服务,那么一般来说需要搭建在一个高质量线路的节点上。

但是高质量线路的节点通常价格起飞,对于我这种个人用户来说,并不值得专门购买。有一个比较好的折衷方案是:购买普通线路的配置相对较高的机器作为源站,再购买一个低配的优质线路机器作为反向代理,使用Dnspod将境内外请求分流,如下图所示:

dnspod.png

1. 前置准备

为了实现这样一个结构,本文使用以下方式实现:

  1. 首先需要有一个源站,假设IP是11.11.11.11
  2. 其次需要有一个线路机器,假设IP是22.22.22.22
  3. 需要有一个域名,视需求而定,二级、三级域名等不限,只要可以加入到DNSPOD解析即可,假设域名是example.com

2. DNSPOD分流

DNSPOD分流很简单,新增一个origin解析,在线路选项中,“默认”指向源站,“境内”指向线路机器:
24a5af49-e279-4002-aec2-5193cfab999f.png

然后其它所有需要按照这一规则进行分流的域名,均CNAME指向origin.example.com即可。

解析成功添加后,在境内境外分别ping你的域名,查看分流解析是否成功。

3. HTTPS证书申请

这一段你可能要执行两遍,因此先不着急执行,跳过这一章节到下一章,需要时再回来。

首先你需要有一个自己的证书,个人推荐使用Certbot+DNS验证的方式申请,使用DNS验证的方式,可以实现在多台机器上同时申请同一域名的证书。

对于托管在Dnspod上的域名,有certbot-dnspod插件可用。使用方法如下(python venv中安装的certbot-dnspod插件):

  1. 先在DNSPOD上开通API Key,保存在dnspod.ini文件中

    certbot_dnspod_token_id = xxxxx
    certbot_dnspod_token = xxxxx
  2. 安装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中添加:

  3. 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. 线路机器配置

线路机器有两种配置方式,各有优劣:

  1. Stream TCP流量转发:优点在于简单,只要添加一个nginx配置就算完成,线路机器上无需配置SSL证书;缺点在于这台机器上的Nginx就只能用于转发了,无法根据domain做不同的响应;
  2. 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的目标点不同。因此这里不再重复。

最后修改:2024 年 12 月 22 日
如果觉得我的文章对你有用,请随意赞赏