前言:Linux主機可以作為路由器使用,利用路由轉發功能實現不同網絡內的主機能夠相互通信,利用iptables的SNAT功能來實現企業內網主機訪問互聯網,下面做個小的實驗。
實驗環境:VM
(1)路由器Linux主機router:
一般來說需要兩塊網卡:eth0 192.168.31.168 eth1 172.16.100.1 其中eth0使用橋接,eth1使用僅主機模式,這里我想你有必要了解VM三種網絡模式的區別。
(2)企業內網主機host1:
僅主機模式,eth0 172.16.100.6
(3)其他網段主機host2:
橋接模式:eth0 192.168.31.167
(4)真正能夠訪問互聯網的路由器MI_router,地址:192.168.31.1和一個撥號得來的公網地址xxx.xxx.xxx.xxx。
1、首先實現hosts1和host2能夠互相訪問
(1)host1添加默認路由:
# route add default gw 172.16.100.1
使其指向router eth1
(2)host2添加默認路由:
# route add default gw 192.168.31.168
使其指向router eth0,方法同上
(3)router打開路由轉發功能:
查看路由轉發功能是否打開:# cat /proc/sys/net/ipv4/ip_forward 結果是0,則沒有打開
臨時打開方法:echo 1 > /proc/sys/net/ipv4/ip_forward
永久打開方法:修改/etc/sysctl.conf文件,net.ipv4.ip_forward = 1,然后執行sysctl -p
(4)檢驗是否能夠互相訪問:
這里我們就實現了內部不同網絡內主機的通信。
2、實現host1訪問互聯網:
因為實驗環境router默認網關指向了MI_router 192.168.31.1,所以router可以訪問互聯網,host2本身是橋接模式,網關指向router,router打開了路由轉發功能,所以host2也可以訪問互聯網。
雖然host1網關也指向router,可以訪問到MI_router網關,但是host1確無法訪問互聯網;
host1的請求能出去,但是不能接收到報文,MI_router無法將互聯網返回的報文送達host1,原因如下:
源地址172.16.100.6經過router轉發,到達MI_router,MI_router進行SNAT,使得請求報文能夠在互聯網傳送;
被請求主機返回數據,MI_router再自動進行DNAT,發現源地址是172.16.100.6,MI_router就蒙圈了,他找不到這台主機;
所以要解決的問題是怎么讓MI_router返回數據給host1;
(1)MI_router我們無法修改其網關使其指向router,但MI_router能訪問router這台主機,那能不能讓MI_router認為源地址請求是從router發出的呢,答案是可以的;
這就涉及到我們真正看的見得SNAT,當然,MI_router本身就已經實現了SNAT,這里我們自己手動實現,將host1的請求轉化為router的請求,發送給MI_router
(2)在router上添加一條規則就可以搞定:
# iptables -t nat -A POSTROUTING -s 172.16.0.0/16 -j SNAT --to 192.168.31.168
在nat表的POSTROUTING鏈上添加規則,所有來自172.16.0.0/16網絡的主機請求,地址都被轉換為192.168.31.168,192.168.31.168能訪問互聯網,數據報文返回到router時,它會自動進行DNAT,最終將數據返回給host1主機。
其實這個環境內,host1訪問互聯網經過了兩次SNAT,到這里我們就實現了:內網地址通過SNAT實現訪問互聯網。
但是,你會發現,host1訪問host2也會進行源地址轉換,這不是我們想要的,ping請求為例:
host1:ping 192.168.31.167
在host2抓包會發現,是192.168.31.168在進行ICMP請求:
那么怎么調整呢,修改我們的SNAT規則即可:
# iptables -t nat -R POSTROUTING 1 -s 172.16.0.0/16 ! -d 192.168.31.0/24 -j SNAT --to 192.168.31.168
再次ping,抓包,OK,正常。
我們可以根據自己的需求更加精准的進行SNAT。
總結:Linux主機實現路由器部分功能
(1)路由轉發:需打開路由轉發功能/proc/sys/net/ipv4/ip_forward為1
(2)SNAT(源網絡地址轉換):iptables -t nat -A POSTROUTING -s 172.16.0.0/16 -j SNAT --to 192.168.31.168: