前一天試著用 /etc/ppp/ip-up
在連上 VPN 後自動加入 white list routing,目前有兩個缺點:
- 完整性不夠。因為 Facebook 用了 CDN,除了自家的還有 Akamai 的,不論是用
dig
,ping
,nslookup
,traceroute
等等工具,都沒辦法查出完整的 ip 區段,所以常常會發生讀不出資料、破圖的現象。 - 因為網段是寫死在裡頭的,如果哪天這些 CDN 做了修改,或是擴充新的網域,沒辦法去回溯,要除錯也有些困難。
所以還是想要找個方法來解決這些問題。
Google 了一下,雖然有人也整理出 Facebook 在某個國家內的 CDN list,但一樣有完整性不足的問題。另外有人問了 google 的 CDN,結果是透過 BGP AS Prefixes 來查詢註冊在該公司下的網域,所以只要把 Facebook 和 Akamai 的網域都查出來加入就夠完整了。
就 Facebook 公司的區段 (AS32934) 來說是不多(30~40 筆上下),大部分在之前也查得差不多了,但 Akamai 就 多 多 了(800~900 筆),要我每一條都手動加入太耗工程,還是得弄個 script 出來,不只省得加入,還可以解決寫死在裡頭的問題。
查了一下,沒有 BGP 的 API 可以運用,所以只好轉向網站去擷取,一開始鎖定的是 Hurricane Electric BGP Toolkit,不過因為一開始沒發現 wget
不送出 User-Agent
,它就不給資料(會傳回 403 Forbidden),所以轉向 dan (看起來像個個人網站),結果沒抓幾次資料,它就說我超過單日 query 上限了。@_@
所以在發現 wget
要送出 User-Agent
後,擷取網頁的 script 如下:
/usr/local/bin/wget -qO- -U Safari http://bgp.he.net/AS32934
為了把資料抓出來,用 grep
搭配 regular expression:
/usr/bin/egrep "/net/[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}/[[:digit:]]{1,2}"
抓出來後還要用 sed
裁切:
/usr/bin/sed 's/^.*">\(.*\)<.*$/\1/'
之後用 xargs
把參數餵給 route
/usr/bin/xargs -I % /sbin/route add % -interface ppp0
因為要放在 /etc/ppp/ip-up
裡面使用,所以把 ppp0
改用 $1
替代。綜合起來:
/usr/local/bin/wget -qO- -U Safari http://bgp.he.net/AS32934 | /usr/bin/egrep "/net/[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}/[[:digit:]]{1,2}" | /usr/bin/sed 's/^.*">\(.*\)<.*$/\1/' | /usr/bin/xargs -I % /sbin/route add % -interface $1
其中的 AS32934 是 Facebook 公司,如果要涵蓋 Akamai 則加入 AS21399 和 AS20940, 同理,也可以把 Yahoo 等等想涵蓋的公司加進去,AS number 就不附上了。
雖然 Facebook 應該只是 Akamai 眾多客戶其中之一,把該公司所有的網域全部涵蓋有點浪費,但這也是寧可錯殺一百也不願放過一個的折衷辦法了。