存取Vagrant(Homestead)虛擬機器時取得真實IP

一直以來都是採用預設設定建立homestead虛擬機器,虛擬機預設的網路介面就是nat和hostonly,這樣的環境基本上開發上也沒什麼問題,只是如果要判別client IP的話,不會是真實主機在區網的ip,而是虛擬機裡的gateway IP,例如如果建立虛擬機有指定192.168.10.10的靜態ip,那麼通常程式抓到的client IP應該會是192.168.10.1。

之前有利用虛擬機架設了一個網站提供服務,最近要開發的功能可能需要判斷使用者的真實ip,陸陸續續花了些時間研究,在混亂的網路知識基礎下終於有了些成果,說明如下。

使用 public_network

homestead的network要設定為public_network,這樣虛擬機就等於是區網裡的一部主機。

networks:
    - type: "public_network"
      ip: "192.168.11.55"

如果要指定ip,請指定為跟區網網段相同的ip。網路上查了某些文章會提到上述設定要再加bridge,但實測不加也正常,那個應該是實體主機有多張網卡時才需要指定,只有一張的話,應該跳過即可。

完成之後,通常在區網裡同網段的的任何主機就可以直接利用ip存取虛擬器了。

設定分享器(或NAT)

這個步驟理論上應該非必要,如果實體主機直接連到網際網路的話,應該也可以跳過這個步驟,不過應該多數架設主機時都會透過分享器連外以避免攻擊,這時因為外部網路沒辦法直接連到內部網站,所以需要透過分享器實作NAT轉譯,完成之後,就可以利用分享器連外的ip存取到內部網路的主機了。具體設定方式請參考分享器的使用說明。

設定分享器的port forward

更新虛擬機的路由表

上述設定分享器的步驟完成之後,實際上外部網路的確可以存取到虛擬器,但因為預設的虛擬機路由導致回傳封包無法傳遞回外部的要求主機,因此當使用外部網路連線時會一直呈現連線中,直到逾時。

這裡有個誤區,如果你是在內部網路經分享器連到網際網路,這時你直接以分享器對外ip連線,是可以正常連線的,不過如果你抓client ip會得到gateway的ip。反過來說的話,如果程式抓到的是gateway ip的話,那就代表連線的使用者是在區網裡連線。

虛擬機路由表

上圖是虛擬機的預設路由。因為外部連線進來時是公開ip,上述路由應該會把回傳封包往eth0介面送,然後封包就石沉大海了,解決方式就是自己重設預設路由往eth2送,因為eth2就是內部區網的網段。

sudo route del default //刪除現有預設路由
sudo route add default gw 192.168.11.1 //新增預設路由,就是分享器ip

到此應該就可以用外部網路連到內部虛擬機,並可以取得真實client IP。

附帶說明,上述路由設定在虛擬機重啟後就會消失,所以應該要把上述設定寫成shell script,然後指定在虛擬機重啟時執行。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *