在家,公司座位,公司會議室,公司的角落,客戶現場,酒店...等所有地方,你都要配置一遍自己的網卡以保證和所處地點的配置一致,這太煩人了!能不能有一種方式免除這種繁瑣配置呢?在這個落後的自給自足的DIY時代,對於男耕女織作坊內的耕耘者來講,答案無疑是肯定的!
sggw模組DIY方案
《OpenVPN以及其它IP層VPN的完全鏈路層處理的實現》中介紹了一種自動將包回複到發起者的一種方法,其實就是“從哪裡來的包在收到其回複包時自動發送到相同的地方”,這個patch module連同ARP代理可以實現即時上網!也就是說,在不啟用DHCP時,再也不用換一個地方配一遍IP了,雖然Macbook可以將這件事映射成“位置”這個配置,但是為了一些不常去的地方保留一個“位置”,也不是很好。注意,我這裡說的是路由器端的實現,而不是筆記本的實現。具體怎麼做呢?
1.路由器開啟ARP代理(周末在家試了下,僅開始代理沒有成功,也沒有查出什麼原因,於是對arp_process函數做了點手腳,簡化了流程)。
2.路由器安裝上述的sggw模組。
3.路由器在WAN口做MASQUERADE地址轉換。
試想一個情境,路由器的LAN口配置為1.1.1.1/24,WAN口為2.2.2.2/24,接入路由器LAN口的筆記本IP為192.168.1.34/24,預設閘道為192.168.1.254,它想訪問WAN,比如IP為128.129.1.1,於是定址預設閘道,因路由器有ARP代理,故而回複了ARP請求,於是資料包發給了路由器,此時sggw模組將這個串連記錄了下來,待回複包到達路由器的時候,sggw模組將其發給筆記本!
也就是說,即使你的筆記本和路由器的LAN不在一個網段,也能正常上網!如果你的所到之處都部署了上面的路由器,那麼你就可以只保留一個“位置”了,我的Macbook設定成了公司的“位置”,基於上述的實現,我在家利用公司的位置配置也能上網!但是有一個問題,還以上述為例,萬一由於巧合,筆記本的IP和路由器LAN在同一網段怎麼辦,這時只要真正的網關不在同一網段,或者說真正的網關離筆記本更近以至於路由器的ARP回複可以覆蓋掉真正的ARP回複就沒有問題,其實這個問題很好解決,解決方式是非技術的,那就是把路由的LAN口地址設定成一些比較奇怪的地址,比如12.32.45.54之類的!注意,它絕不作為目標地址存在,僅僅是一個哨位!
最後說一下我對arp_process做了什麼手腳。不管怎樣,筆記本或者PC在發起對網路的訪問時,肯定要發ARP請求的,我們知道它是廣播的,肯定能到達路由器,既然到了路由器,就能抓到它,從這個ARP請求中,可以得到足夠的資訊,比如最重要的就是筆記本的IP地址,MAC地址之類的。由於我的BOX僅僅做這個用,於是我的arp_process流程成為:
1.解析ARP請求包,得到發起者IP;
2.看看該IP是否是自己的直連IP,即是否跟自己的LAN網卡處於一個網段;
3.若不是,則直接回複自己的LAN口的MAC地址,若是,則跳到;
4.(此步驟是我開始添加後來刪除的)根據發起者的IP添加一條force-onlink路由,網關即該地址;
5.返回;
6.走標準arp_process流程
第4個步驟被我去掉了,因為實在不方便在核心裡面加路由刪路由,太TM容易panic了!還是將event通過netlink傳給使用者態好啊!
其它的方案
實際上想達到這個效果,還有另外兩個DIY方案以及一個常規但不常用方案,DIY方案中一個是修改核心協議棧的ROUTE模組,另一個是基於conntrack工具提供的event監控,我們一個一個說。
修改核心代碼的方案:
我們知道有一種force-onlink路由,即使下一跳不是直連網段也能設定上去,因此它是邏輯上在三層沒有直連,物理上是直連的,在沒有任何裝置開啟ARP代理的情況下,ARP只能在物理直連段傳播,而所謂的force-onlink路由就是直接針對下一跳發送ARP請求的!
方案就是,針對每一個接入的筆記本或者PC都設定一條force-onlink路由,比如筆記本的IP為4.4.4.4/24,那麼就設定下面一條:
ip route add 4.4.4.4/32 via 4.4.4.4 dev LAN onlink;
但是路由器事先不知道有多少機器要接入,更不知道其IP分別是什麼,因此必須使用通配的方式來設定上述的路由,比如:
ip route add autolink via link dev LAN onlink;
注意,上述的autolink和link是需要新支援的標誌,就是說在針對WAN進來的資料包尋找路由時,看下LAN上是否綁定autolink路由,若是,則下一跳直接設定成目標地址。
基於現有的工具的方案:
只要筆記本想發包,ARP代理導致它必定來到路由器,路由器的ip_conntrack會記錄包的源IP地址是多少,這個可以通過以下的命令列來監控:
conntrack -E -e NEW;
既然監控的到,就可以為其設定一條路由,比如監控到源IP為A,那麼就執行下面的命令:
ip route add A/32 via A dev LAN onlink;
使用conntrack工具可能會因為延遲帶來不可預知的錯誤,因此可以使用更好的方案,那就是NFQUEUE target,因為QUEUEU是同步的,可以控制在添加好force-onlink路由之前不把QUEUE上來的資料包INJECT回去,注意,和conntrack event監控一樣,只需要對NEW包QUEUE即可。
既然是動態添加,就涉及到了動態刪除的問題,可以採用最近最不經常使用的演算法,加入GC機制。
常規方案:
落後會帶來DIY,等都能流水化了,就沒人DIY了,大部分人拿到手的東西是來用的,而不是來折騰的,如果花錢能帶來簡單,我就決不DIY,大量供貨的物品,你也不會花很多錢,我知道,生命有限,應該來折騰的是人生本身,所謂DEBUG THE LIFE,而不能玩物喪志!IPv6天生針對葉子角色的終端就有自動設定的功能!然而對於IPv4,其自動設定雖然RFC也有明確的建議文檔,比如Router Advertisement,Router Solicitation,Address XXX等ICMP就是可用的,然而很多主流的系統核心協議棧都沒有實現,也許使用DHCP可以更加靈活地控制分配過程以及安全性原則吧。