歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux如何做到將外來數據包DNAT到Loopback

Linux如何做到將外來數據包DNAT到Loopback

日期:2017/2/28 15:47:41   编辑:Linux教程

前面寫了篇文章《使用iptables為何不能將外部進入的包NAT到127.0.0.1》,牽扯到了很多知識,最終的結論就是不能那麼做。這個結論讓人有些不舒服,說了半天就是闡述它為何做不到,如果我非要將包NAT到loopback呢。比如為了不將端口以及地址暴露給外部,我就是想讓代理服務偵聽127.0.0.1這個地址,有沒有什麼辦法做到呢?

因為你用的是Linux,答案無疑是肯定的,所要做的無非就是把路由時候的限制條件給去掉。我們知道,在進和出兩個方向,有兩個路由查找邏輯,一個是

  1. ip_route_input_slow,另一個是ip_route_output_slow,其中前一個函數的限制在:
  2. if (ipv4_is_lbcast(daddr) || ipv4_is_zeronet(daddr) ||
  3. ipv4_is_loopback(daddr))
  4. goto martian_destination;

而後一個函數限制在其調用的__mkroute_output中:

  1. if (ipv4_is_loopback(fl->fl4_src) && !(dev_out->flags&IFF_LOOPBACK))
  2. return -EINVAL;

我們到底應該怎麼繞過去呢?如今我們知道,NAT邏輯已經將目標地址改成了127.0.0.1,而源地址保持不變,這種數據包在進入的時候會被ip_route_input_slow攔截並且由於源地址非loopback而目標為loopback而丟棄,丟棄的時候注意還沒有查找路由呢?現在我們假設這個包已經過去了,那麼返回包能不能順利通過ip_route_output_slow呢?答案無疑也是否定的,由於標准路由是基於目標地址的,對於返回包的目標地址其實就是正向包的源地址,路由查找無疑是可以通過的,但是路由前由於還不知道目標設備,因此不能簡單地丟棄,只有到了路由之後確定目標設備非loopback之後才能丟棄。
以上就是Linux協議棧路由模塊對待“火星地址”的邏輯。總結一下就是:
1.對於進入包,若是loopback發來的包則不通過路由查找邏輯,凡是通過路由查找的,都是外來包,路由前知道源地址和目標地址,可以根據目標地址是否loopback而判斷是否丟棄;
2.對於發出包,無條件(考慮下路由cache,意義是一樣的)都要經過路由查找,路由前不一定知道源地址,即使知道源地址也不能確定目標設備是否是loopback設備,只有通過路由查找(local表命中的目標設備為loopback設備)才可以知道全部信息,因此在路由後,生成路由cache之前判斷源地址是loopback地址而卻是發往非loopback設備而決定丟棄之。

Copyright © Linux教程網 All Rights Reserved