應用場景:
客戶端(client)與服務器A在同一個運營商網絡,應用部署在服務器B,服務器A 、B之間建立tunnel,A設置dnat,client通過訪問A的8000端口來訪問服務器B,B返回的響應通過tunnel到達A,A再返回給client。在dnat之上使用tunnel的原因是通過tunnel后,B接收到的請求源IP為client,而不是A。
client -----》 A 《=======tunnel=======》B
ip:192.168.1.1 ip:192.168.2.2
tunnel_ip:10.111.111.1 tunnel_ip:10.111.111.2
在A(linux) 搭建 gre tunnel過程:
1、創建gre tunnel:
/sbin/iptunnel add tun0 mode gre remote 192.168.2.2 local 192.168.1.1
/sbin/ifconfig tun0 10.111.111.1
/sbin/route add 10.111.111.2 tun0
2、設置iptables規則:
/sbin/iptables -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
# 到apache端口的映射
/sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 8000 -j DNAT --to-destination 10.111.111.2:8000
# SNAT規則
/sbin/iptables -t nat -A POSTROUTING -o eth0 -p tcp -j SNAT --to-source 192.168.1.1
當B是bsd時,在B搭建 gre tunnel過程:
1、BSD 6.2的默認內核不支持ipfw的forward功能,需要重編一下kernel。找一個默認的SMP配置文件,在最后加上
options IPDIVERT
options IPFIREWALL_DEFAULT_TO_ACCEPT
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=10
options IPFIREWALL_FORWARD
options DUMMYNET
編譯內核重啟(或者直接找一個編譯好的來用)
2、做一個到napt服務器的tunnel。在BSD 4.x下,ipip tunnel工作良好,但在6.2下會有一些古怪的問題,小包通訊正常,大包就無法通過,因此要改用gre tunnel。通過下面的命令來創建tunnel,同時可以把這些命令寫到/etc/rc.local,服務器啟動的時候自動創建:
/sbin/ifconfig gre0 tunnel 192.168.2.2 192.168.1.1
/sbin/ifconfig gre0 10.111.111.2/32 10.111.111.1
3、做轉發規則。實現類似linux下ip route的功能,將從10.111.111.2發出的包,都轉發給tunnel另一端的napt服務器。
也可以使用ipf來實現源地址路由的功能(不用重新編譯內核)
1、創建tunnel跟上面的第2步一樣
2、在ipf的rule文件添加規則:
/etc/rc.d/ipfilter restart即可
當B是linux時,在B搭建 gre tunnel過程:
1、裝一個iproute的包,修改/etc/iproute2/rt_tables,添加自定義的table
2、做一條tunnel,步驟不再重復,假設得到tun0
3、添加ip route規則
/sbin/ip route add default dev tun0 table mytunnel mtu 1400
#添加一個規則,讓所有從10.111.111.2發出的包都到mytunnel表里面去找路由
/sbin/ip rule add from 10.111.111.2 table mytunnel