一、设计背景
假设你有一个经常去逛的海外网站,但是由于跨洋网络或者某种不可貌似的原因。你需要做一个 海外节点ip的代理,才能访问得到这个网站。但是可能某天发现这个方法也不太好使了,猜测可能原因是流量分析大数据系统可能对你访问的域名做了截获。另外这样访问的流量是需要你在客户端和服务端安装某种网络层代理工具。加上网络层代理软件如果被封了。所以能否绕开搭建天梯的步骤,而且你使用一个安全的域名(你拥有的域名)做网站镜像拷贝。
本文就是通过大家熟知的nginx来解决这个问题。
二、设计工具
这里需要你拥有一个你的一个境外节点(推荐香港节点,连接国内国外最好的桥梁),这个节点可以是任意Linux系统,能跑nginx就行。还需要你有个域名。这个域名的解析ip是这个境外节点。
开始啰!
三、反向代理配置proxy_pass
这里以CentOS7为例,先来安装下nginx。
yum install nginx
vim /etc/nginx/nginx.conf
先新增一个server配置如下,这个配置把所有访问http://[你的域名]的流量通过设置新的请求Host头,然后经过nginx的上游模块[新的域名]。这个新的域名就是你打算访问的网站。因为nginx的upstream模块是在香港节点访问【海外域名】,相当于香港用户访问海外网站,那当然是嗖嗖嗖地快!
server {
listen 80;
listen [::]:80;
server_name [你的域名];
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
#所有路径
location / {
proxy_pass http://[海外域名]/;
proxy_set_header Host [海外域名];
# You may need to uncomment the following line if your redirects are relative, e.g. /foo/ba
#proxy_redirect / /;
}
}
四、重定向到https
问题来了,当前https网站几乎已经普及了(这里强调国外,因为国外的https,ipv6普及率都超级高,相比国内来说)。所以国外很少有网站是通过http访问。但是人家也不限制你从http访问,他会用一个30x响应告诉你,请你访问Location响应头的url,https://[新域名]。
也就是说用第三节的配置,你其实不能访问到真实网站内容。
于是,我们加上了30x截获,重新再来一轮nginx的upstream请求。
server {
listen 80;
listen [::]:80;
server_name [你的域名];
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
#所有路径
location / {
proxy_pass http://[海外域名]/;
proxy_set_header Host [海外域名];
# You may need to uncomment the following line if your redirects are relative, e.g. /foo/ba
#proxy_redirect / /;
# 开始截获30x请求,到handle_redirect流程
proxy_intercept_errors on;
error_page 301 302 307 = @handle_redirect;
}
# 截获的进入这个流程,重新开始新一轮的proxy_pass,到指定的url
location @handle_redirect {
set $saved_redirect_location '$upstream_http_location';
proxy_pass $saved_redirect_location;
proxy_set_header Host [海外域名];
}
}
这里对30x请求进行了截获,并且截获的请求进行新一轮的proxy_pass重定向,这次重定向到Location标头带的URL(也就是https://[新的域名])。
五、内嵌url改写
好了,到这里你基本上可以访问到一个主页,这个主页的内容就是期望的方式得到的。接着你在这个主页挨个点链接。是不是又感觉哪里不对劲呢?是的,这样还有个问题,就是主页里面的内嵌url其实还是用海外那个域名。这里需要改成你自己的域名。
这里的sub_filter对网页内嵌url进行了改写。sub_filter_once 顾名思义就是最多匹配到一次,就结束任务。当然我们这里想要他把全部url都替换掉,所以选择了off。
server {
listen 80;
listen [::]:80;
server_name [你的域名];
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
#所有路径
location / {
proxy_pass http://[海外域名]/;
proxy_set_header Host [海外域名];
# You may need to uncomment the following line if your redirects are relative, e.g. /foo/ba
#proxy_redirect / /;
# 开始截获30x请求,到handle_redirect流程
proxy_intercept_errors on;
error_page 301 302 307 = @handle_redirect;
sub_filter "https://[海外域名]/" "http://[你的域名]";
sub_filter_once off;
}
# 截获的进入这个流程,重新开始新一轮的proxy_pass,到指定的url
location @handle_redirect {
set $saved_redirect_location '$upstream_http_location';
proxy_pass $saved_redirect_location;
proxy_set_header Host [海外域名];
}
}