前提
原本是想用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原理
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路徑解釋:http://www.lxweimin.com/p/2a14d69987a4
proxy_cache_use_stale解釋:https://linux.cn/article-5945-1.html