前提
原本是想用mac的方法,Proxifier直接通过正向代理,添加一个国内ip的proxy server达到听网易云音乐的目的。但是,Proxifier的win版一直安装不成功,安装过程中说一个网络相关的文件需要修改。
- 点修改之后,安装成功却导致
网易邮箱大师
无法使用。 - 点不修改之后,安装也成功,但是无法使用软件本身报错说缺少winsock
- 一番重启安装卸载折腾后,放弃Proxifier这个软件。
改用修改host的方法:
windows系统下:在C:\Windows\System32\drivers\etc
路径下找到host,笔记本打开,添加反向代理host:
# 网易云音乐服务器反代
(由 [yizhiheng](https://github.com/yizhiheng) 赞助提供; 服务器位于多伦多)
138.197.154.53 music.163.com
# 归属地查询服务器反代
138.197.154.53 ip.ws.126.net
# HTTPS DNS 服务器屏蔽
0.0.0.0 music.httpdns.c.163.com
# m10 服务器
125.39.1.27 m10.music.126.net
以上反代来源: https://jixun.moe/2017/02/24/oversea-netease-cloud-music-by-hosts/
PAC和反向代理
PAC的原理和配置说明
PAC文件实际上是一个Script, 通过PAC我们可以让系统根据情况判断使用哪一个Proxy来访问目标网址, 这样做的好处:
- 分散Proxy的流量,避免Proxy Server负载过高
- 针对个别条件设定, 加快浏览速度
-
设定请求顺序, 自动依次尝试多个Proxy途径
PAC文件是纯文本, 格式和JavaScript一样, 不能包含任何HTML标签, 一定要定义的是Function FindProxyForURL
function FindProxyForURL(url, host) {
...
}
如果使用了PAC, 则浏览器在接受我们要求的网址后会去执行
ret = FindProxyForURL(url, host)
. 其中,
url是所要求网址的完整路径,
host是对方的计算机名称(就是在://和/之中的部份).
return值ret是Proxy的组态. 它的格式有下列三种:
DIRECT
: 直接联机而不透过Proxy
PROXY host:port
: 使用指定的Proxy
SOCKS host:port
: 使用指定的Socks代理
比如说当浏览器得到的是Proxy aa.bb.cc:3128; Proxy bb.cc.dd:3128; DIRECT
的话,那浏览器会先尝试aa.bb.cc:3128
, 如果无法使用, 再尝试bb.cc.dd:3128
, 还是不行的话, 就直接联机.
PAC中的预设函数
在PAC中,除了可以使用一般JavaScript的Function外, 它还定义了一些预设的函数
isPlainHostName(host)
host 由网址取得的主机名称.
此 Function 会判断 host 是否为不包含网域 (Domain). 如果不包含则 return true, 如果包含则 return false.
dnsDomainIs(host, domain)
host 由网址取得的主机名称.
domain 指定的网域.
此 Function 会判断 host 是否属于网域 domain. 如果是则 return true, 否则return false.
localHostOrDomainIs(host, hostdom)
host 由网址取得的主机名称.
hostdom 完整的网域名称.
此 Function 会判断 host 是否为 hostdom,或 host 是否为 hostdom 的主机名称. 如果是则 return true, 否则 return false.
isResolvable(host)
host 由网址取得的主机名称.
此 Function 会尝试透过 DNS 去解析 host,如果解析成功则 return true, 否则return false.
isInNet(host, pattern, mask)
host主机名称,可以是 Domain Name 或 IP. 如果是 Domain Name,则会透过 DNS 查出 IP.
pattern IP.
mask对应于pattern的遮盖.
此 Function 会 host 是否在指定的 IP 范围内,如果是则 return true, 否则 return false.
dnsResolve(host)
host 要透过 DNS 解晰的主机名称.
此 Function 会透过 DNS 去解析 host,return 值即为解析之结果.
myIpAddress()
此 Function 会 return 浏览器所在计算机之 IP 地址.
dnsDomainLevels(host)
host 由网址取得的主机名称.
此 Function 会 return host 的 Domain 层数(点的数目).
shExpMatch(str, shexp)
str 要进行比对的字符串.
shexp 比对的条件.
此 Function 会比对 str 是否符合 shexp 的表示式(此表示式为 shell expression 而非 regular expressions). 如果是则 return true, 否则 return false.
weekdayRange()
, dateRange()
, timeRange()
这三个函数的功用都是检查线在时间是否在指定范围内,可以设定分时段使用代理服务.
根据不同时间选择不同代理
例如:
周一到周五
if (weekdayRange("MON", "FRI")) {
return "PROXY proxy1.example.com:8080";
} else {
return "DIRECT";
}
一月到五月
if (dateRange("JAN", "MAR")) {
return "PROXY proxy1.example.com:8080";
} else {
return "DIRECT";
}
八点到十八点
if (timeRange(8, 18)) {
return "PROXY proxy1.example.com:8080";
} else {
return "DIRECT";
}
- 例子1
var domains = {
"google.com": 1,
"facebook.com": 1,
"bing.com":1
};
var proxy = "SOCKS5 127.0.0.1:1080; SOCKS 127.0.0.1:1080; DIRECT;";
var direct = 'DIRECT;';
function FindProxyForURL(url, host) {
var lastPos;
do {
if (domains.hasOwnProperty(host)) {//判断domains中是否有host这个属性,可以参考http://blog.csdn.net/tenfyguo/article/details/6171666理解
return proxy; //走代理
}
lastPos = host.indexOf('.') + 1; //如果要检索的字符串值没有出现,则该方法返回 -1
host = host.slice(lastPos); //slice(lastPos)表示从lastPos到末尾的所有字符
} while (lastPos >= 1);
return direct;
}
- 例子2
function FindProxyForURL(url, host)
{
url = url.toLowerCase();
host = host.toLowerCase();
if (isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0")
|| isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0")
|| isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0")
|| isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0")
) {//DNS解析出来的ip在内网网段内,直连
return "DIRECT";
}
if (shExpMatch(url,"*twitter*")
|| shExpMatch(url,"*google*")
|| shExpMatch(url,"*facebook*")
|| shExpMatch(url,"*blogspot*")
|| shExpMatch(url,"*youtube*")
|| shExpMatch(url,"*gstatic*")
|| shExpMatch(url,"*ytimg*")
|| shExpMatch(url,"*ggpht*")
|| shExpMatch(url,"*github*")
) {//正则匹配到某些网站就走proxy
return "SOCKS 192.168.1.1:3128";
}
return 'DIRECT';
}
- 例子3
function FindProxyForURL(url, host) {
if (shExpMatch(url,"*.google.com/*")) {
return “PROXY 192.168.1.1:3128”;
}
if (shExpMatch(url, "*.wikipedia.com:*/*")) {
return "SOCKS5 lilinux.net:1080";
}
if (isInNet(host, "10.0.0.0", "255.0.0.0")){
return "DIRECT";
}
return "DIRECT; PROXY 192.168.1.1:3128; SOCKS5 lilinux.net:1080";
}
这个PAC文件中引入了两个新的函数,但从字面意思上,我们也可以猜出代码的大概意思:
当url是*.google.com/*
时,自动使用PROXY代理;
当url是*.wikipedia.cm/*
时,自动使用SOCKS5代理;
当host是10.0.0.0 /255.0.0.0
的子网内时,自动直连;
如果都不匹配,则依次按DIRECT、PROXY、SOCKS5的次序尝试。
shExpMatch函数用来匹配url或者host,匹配的方式和DOS的通配符相似。例如前面用到的*.google.com/*
可以匹配任意包含.google.com/
的字符串。
Chrome/Chromium 的扩展Switchy!创建的pac文件还自定义了一个函数,可以用来匹配正则表达式,不过个人认为在url匹配上通常不需要使用强大的正则表达式。
isInNet函数用来返回请求的host是否在指定的域内。值得注意的是,isInNet的第二个参数必须是 IP,不能是主机名。因此需要把主机名转换成IP。比如”isInNet(host, dnsResolve(www.google.com), “255.255.255.0”)”讲到这里,应该可以解决你的问题了吧。
PAC 示例文件
https://github.com/n0wa11/gfw_whitelist/blob/master/examples/whitelist_socks5_7070.pac
https://github.com/n0wa11/gfw_whitelist/blob/master/examples/whitelist_http_8081.pac
https://github.com/n0wa11/gfw_whitelist/blob/master/whitelist.pac
https://pac.itzmx.com/abc.pac
https://github.com/breakwa11/gfw_whitelist/blob/master/proxy.pac
来源:
http://www.cnblogs.com/milton/p/6263596.html
http://www.truevue.org/p/519
https://blog.huzhifeng.com/2017/07/16/PAC/
反向代理的原理和配置说明
(https://jixun.moe/2017/01/01/ymusic-hosts-fix/)。
反代的原理是搭建一个Nginxf服务器
- 163-uwp.json
{"code":200,"uwp":1}
- ipquery.txt
// 文件需存为 GBK 格式
var lo="广东省", lc="广州市";
var localAddress={city:"广州市", province:"广东省"}
- proxy-163.conf
# /etc/nginx/conf.d/proxy-163.conf
# Cahce缓存路径
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=STATIC:10m inactive=24h max_size=1g;
server {
listen 80;
listen [::]:80;
server_name music.163.com;
location /weapi/feedback/weblog {
add_header Set-Cookie "os=uwp; path=/";
error_page 405 = $uri;
alias /usr/share/nginx/html/163-uwp.json;
}
location / {
proxy_redirect off;
proxy_pass http://music.163.com/;
# Hint: http://bgp.he.net/AS45102#_prefixes
# 这个 IP 已经失效,随便找一个 IP 来代替。
proxy_set_header X-Real-IP 110.76.23.1;
proxy_cache STATIC;//静态的
proxy_cache_valid 200 1d; //200状态缓存1天
proxy_cache_use_stale error timeout invalid_header update http_500 http_502 http_503 http_504;
//proxy_cache_use_stale中的updating参数告知NGINX在客户端请求的项目的更新正在原服务器中下载时发送旧内容,而不是向服务器转发重复的请求。第一个请求陈旧文件的用户不得不等待文件在原服务器中更新完毕。陈旧的文件会返回给随后的请求直到更新后的文件被全部下载。
}
}
server {
listen 80;
listen [::]:80;
server_name ip.ws.126.net;
location /ipquery {
alias /usr/share/nginx/html/163/ipquery.txt;
}
}
cache首行设置参数:
proxy_cache_path
指的是存放cache的位置,如果没有此文件夹,重启nginx会报错
keys_zone=STATIC:200m
表示这个zone名称为STATIC,分配的内存大小为200MB
inactive=24h
表示这个zone中的缓存文件如果在1天内都没有被访问,那么文件会被cache manager进程删除掉
max_size=1g
表示最大缓存大小为1G
对于指定的域名加上cacheproxy_set_header X-Real-IP
其中这个X-real-ip是一个自定义的变量名,名字可以随意取,这样做完之后,用户的真实ip就被放在X-real-ip这个变量里了,然后,在web端可以这样获取:request.getAttribute("X-real-ip")
来源
https://segmentfault.com/a/1190000002797601
location写法:https://segmentfault.com/a/1190000002797606
proxy_set_header X-Real-IP解释: http://gong1208.iteye.com/blog/1559835
缓存cache时间解释:http://blog.51yip.com/apachenginx/1018.html
缓存cache路径解释:https://www.jianshu.com/p/2a14d69987a4
proxy_cache_use_stale解释:https://linux.cn/article-5945-1.html