一、路由轉(zhuǎn)發(fā)與SNAT實(shí)驗(yàn)
環(huán)境說明:
debian機(jī)器位于內(nèi)網(wǎng),有一個(gè)網(wǎng)卡ens38,ip地址172.16.1.2/24,網(wǎng)關(guān)為172.16.1.1(router的eth2)
router機(jī)器位于內(nèi)網(wǎng)和外網(wǎng)的邊界,有2個(gè)網(wǎng)卡eth1和eth2,eth1地址192.168.124.247接外網(wǎng),網(wǎng)關(guān)192.168.124.1;eth2地址172.16.1.1,連接debian
在網(wǎng)卡配置正確的情況下,此時(shí)使用debian機(jī)器是可以直接ping通172.16.1.1,但是無法ping通任何外網(wǎng)地址。但是debian機(jī)器可以ping通router上eth1的ip192.168.124.247。部分同學(xué)可能對(duì)這一現(xiàn)象不太理解,原因簡(jiǎn)單陳述一下:在linux系統(tǒng)中,ip地址是屬于內(nèi)核而非網(wǎng)卡的。在這個(gè)案例中,debian?ping?192.168.124.247時(shí),發(fā)現(xiàn)該ip和自己不是同一網(wǎng)段,因此將數(shù)據(jù)包發(fā)往172.16.1.1,此時(shí)數(shù)據(jù)包的dst?ip為192.168.124.247,dst?mac為eth2的mac。router解開mac發(fā)現(xiàn)是自己的mac(eth2的mac),繼續(xù)解包,再解開ip發(fā)現(xiàn)也是自己的(eth1的ip),所以直接回包,此時(shí)兩者可以通信。
debian機(jī)器無法ping通任何外網(wǎng)地址的原因是,數(shù)據(jù)包到網(wǎng)關(guān)router后,router沒有打開ip_forword參數(shù),因此會(huì)直接丟棄目的地址不屬于自己的包。因此第一步需要打開該參數(shù)。在router上打開路由轉(zhuǎn)發(fā)功能:
echo 1 > /proc/sys/net/ipv4/ip_forward
此時(shí)debian的數(shù)據(jù)包經(jīng)過router時(shí)會(huì)被路由轉(zhuǎn)發(fā),但是仍然無法和外界通信。原因是外界沒有返回172.16.1.2的路由。此時(shí)的解決方案是在router上增加一條snat規(guī)則。這樣debian機(jī)器出網(wǎng)時(shí)被snat成router的eth1上的ip,外網(wǎng)回包時(shí)先回給router機(jī)器,router機(jī)器根據(jù)原來的snat映射修改回包的目的地址,再發(fā)送給debian機(jī)器。
iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -o eth0 -j SNAT --to-source 192.168.124.247
此時(shí)debian即可和外界通信。
二、DNAT映射實(shí)驗(yàn)
環(huán)境說明
拓撲如前,現(xiàn)在有一個(gè)網(wǎng)絡(luò)僅能和router(192.168.124.247)通信,無法和debian(172.16.1.2)通信。但是該網(wǎng)絡(luò)下的用戶想要連接位于內(nèi)網(wǎng)的debian機(jī)器,處于安全考慮不能讓用戶ssh到router后再跳到debian,想在router上開一個(gè)端口32200,映射到debian機(jī)器的22端口
思路與實(shí)現(xiàn):
數(shù)據(jù)包到達(dá)router機(jī)器之后,不能直接流向用戶空間。因為用戶空間并沒有程序監(jiān)聽32200。因此映射的變化應(yīng)該是在路由決策之前,所以應(yīng)該配置在PREROUTING鏈上。在PREROUTING鏈上增加一條dnat規(guī)則,使得ssh?192.168.124.247的32200端口時(shí),把目的地址改為172.16.1.2,端口改為22。
三、出向負(fù)載均衡和nat實(shí)驗(yàn)
環(huán)境說明
debian機(jī)器上配置了4個(gè)ip地址,需要實(shí)現(xiàn)4個(gè)ip輪詢訪問外部網(wǎng)絡(luò)。
為了方便驗(yàn)證,我搭建了一個(gè)nginx。nginx幾行配置即可返回客戶端的ip,配置如下:
location / { return 200 <span data-raw-text="" "="" data-textnode-index-1671119076312="26" data-index-1671119076312="1621" data-textnode-notemoji-index-1671119076312="1621" class="character">"$remote_addr\n<span data-raw-text="" "="" data-textnode-index-1671119076312="28" data-index-1671119076312="1636" data-textnode-notemoji-index-1671119076312="1636" class="character">"; }
我們只需要多次請(qǐng)求nginx,只要nginx輪詢返回不同的ip,就證明我們實(shí)現(xiàn)了這樣的效果。
debian機(jī)器的網(wǎng)卡配置如下:
auto ens38 iface ens38 inet static address 172.16.1.2 netmask 255.255.255.0 gateway 172.16.1.1 auto ens38:1 iface ens38:1 inet static address 172.16.1.3 netmask 255.255.255.0 auto ens38:2 iface ens38:2 inet static address 172.16.1.4 netmask 255.255.255.0 auto ens38:3 iface ens38:3 inet static address 172.16.1.5 netmask 255.255.255.0
思路與實(shí)現(xiàn)
通常來說,機(jī)器和外界通信時(shí),會(huì)默認(rèn)使用第一個(gè)網(wǎng)卡主ip,想要修改這一行為,可以在POSTROUTING鏈中修改源ip。iptables有一個(gè)statistic擴(kuò)展,可以實(shí)現(xiàn)負(fù)載均衡的效果。
statistic擴(kuò)展:
statistic This module matches packets based on some statistic condition. It supports two distinct modes settable with the --mode option. Supported options: 該模塊根據(jù)一些統(tǒng)計(jì)條件匹配報(bào)文。 它支持兩個(gè)不同的模式,可通過--mode選項(xiàng)設(shè)置。 --mode mode Set the matching mode of the matching rule, supported modes are random and nth. 設(shè)置匹配規(guī)則的匹配模式,支持的匹配模式為random和nth。 [!] --probability p Set the probability for a packet to be randomly matched. It only works with the random mode. p must be within 0.0 and 1.0. The supported granularity is in 1/2147483648th increments. 設(shè)置報(bào)文被隨機(jī)匹配的概率。 它只適用于隨機(jī)模式。P必須在0.0和1.0之間。 支持的粒度增量為1/2147483648。 [!] --every n Match one packet every nth packet. It works only with the nth mode (see also the --packet option). 每n個(gè)包匹配一個(gè)包。 它只適用于nth個(gè)模式(同時(shí)請(qǐng)參閱--packet選項(xiàng))。 --packet p Set the initial counter value (0 <= p <= n-1, default 0) for the nth mode. 設(shè)置初始計(jì)數(shù)器。計(jì)數(shù)器=p的時(shí)候,命中規(guī)則。0 <= p <= n-1,p=n-1之后,下一次會(huì)被重置為0。如果不設(shè)置則默認(rèn)是0。只適用于nth模式
以上翻譯自官方文檔https://ipset.netfilter.org/iptables-extensions.man.html
所以進(jìn)行如下設(shè)置。
iptables -A POSTROUTING -t nat -d 192.168.127.247 -m statistic --mode nth --every 4 --packet 0 -j SNAT --to-source 172.16.1.2 iptables -A POSTROUTING -t nat -d 192.168.127.247 -m statistic --mode nth --every 3 --packet 0 -j SNAT --to-source 172.16.1.3 iptables -A POSTROUTING -t nat -d 192.168.127.247 -m statistic --mode nth --every 2 --packet 0 -j SNAT --to-source 172.16.1.4 iptables -A POSTROUTING -t nat -d 192.168.127.247 -m statistic --mode nth --every 1 --packet 0 -j SNAT --to-source 172.16.1.5
計(jì)數(shù)器變化: 第一個(gè)tcp會(huì)話:0 ,第一條命中,對(duì)應(yīng)計(jì)數(shù)器+1,被snat成172.16.1.2 第二個(gè)tcp會(huì)話:10,第二條命中,對(duì)應(yīng)計(jì)數(shù)器+1, 被snat成172.16.1.3 第三個(gè)tcp會(huì)話:210,第三條命中,對(duì)應(yīng)計(jì)數(shù)器清+1, 被snat成172.16.1.4 第四個(gè)tcp會(huì)話:3210,第四條命中,對(duì)應(yīng)計(jì)數(shù)器+1,同時(shí)所有計(jì)數(shù)器都打到every上限,所有計(jì)數(shù)器清0, 被snat成172.16.1.2 。。。。進(jìn)入下一個(gè)循環(huán),以此類推
nat表規(guī)則:
root@debian:~# iptables -nL -t nat Chain PREROUTING (policy ACCEPT) target prot opt source destination Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination SNAT all -- 0.0.0.0/0 192.168.124.247 statistic mode nth every 4 to:172.16.1.2 SNAT all -- 0.0.0.0/0 192.168.124.247 statistic mode nth every 3 to:172.16.1.3 SNAT all -- 0.0.0.0/0 192.168.124.247 statistic mode nth every 2 to:172.16.1.4 SNAT all -- 0.0.0.0/0 192.168.124.247 statistic mode nth every 1 to:172.16.1.5
如此即可實(shí)現(xiàn)出向負(fù)載均衡的效果:
root@debian:~# curl 192.168.124.247 172.16.1.2 root@debian:~# curl 192.168.124.247 172.16.1.3 root@debian:~# curl 192.168.124.247 172.16.1.4 root@debian:~# curl 192.168.124.247 172.16.1.5 root@debian:~# curl 192.168.124.247 172.16.1.2 root@debian:~# curl 192.168.124.247 172.16.1.3 root@debian:~# curl 192.168.124.247 172.16.1.4 root@debian:~# curl 192.168.124.247 172.16.1.5
評(píng)論