iptables 還能這么玩,厲害了

在學(xué)習(xí)docker和k8s時(shí)大量的用到了iptables况脆,那么iptables到底怎么玩饭宾,這篇文章告訴你答案。提起iptables/netfilter格了,我們應(yīng)該聽說過但在日常的工作中用到的機(jī)會(huì)并不多看铆,那平時(shí)用不到是不是就不需要了解了呢,那肯定不是的盛末,做技術(shù)嘛肯定是要有所追求的弹惦,當(dāng)你越過每座山峰之后,你就能看到遠(yuǎn)處美好的風(fēng)景[圖片上傳失敗...(image-fa5084-1591493797514)]

那么iptables到底是個(gè)什么東西呢悄但?說白了iptables就是一個(gè)用戶態(tài)的命令行工具來操作內(nèi)核態(tài)的netfilter棠隐,對(duì)進(jìn)入本機(jī)的網(wǎng)絡(luò)包進(jìn)行一系列操作,比如 accept檐嚣、reject助泽、drop等等。下圖說明了iptables的數(shù)據(jù)流向嚎京。

image

傳說中的iptables由四表五鏈構(gòu)成嗡贺,那就看看這是個(gè)什么東西吧~

四表

  • raw表:主要用來決定是否對(duì)數(shù)據(jù)包進(jìn)行狀態(tài)跟蹤(用的不多)

  • mangle表:修改數(shù)據(jù)包的服務(wù)類型鞍帝、TTL诫睬、并且可以配置路由實(shí)現(xiàn)QOS內(nèi)核模塊(用的不多)

  • nat表:主要用來做網(wǎng)絡(luò)地址轉(zhuǎn)換SNAT帕涌、DNAT摄凡。

  • filter表:主要對(duì)數(shù)據(jù)包進(jìn)行過濾,比如禁止某個(gè)ip數(shù)據(jù)包訪問蚓曼。

五鏈

  • PREROUTING鏈:在對(duì)數(shù)據(jù)包進(jìn)行路由之前經(jīng)過此鏈的處理亲澡,比如常見的做DNAT轉(zhuǎn)換。

  • INPUT鏈:收到訪問本機(jī)ip地址時(shí)經(jīng)過此鏈處理辟躏,比如常見的在filter表上設(shè)置input鏈谷扣,拒絕或只允許某個(gè)ip訪問。

  • FORWARD鏈:轉(zhuǎn)發(fā)數(shù)據(jù)包時(shí)應(yīng)用此鏈上的規(guī)則捎琐。

  • OUTPUT鏈:數(shù)據(jù)流出方向應(yīng)用此鏈上的規(guī)則会涎。

  • POSTROUTING鏈:對(duì)數(shù)據(jù)路由后應(yīng)用此鏈上的規(guī)則,比如常見的做SNAT轉(zhuǎn)換瑞凑。

由上圖可知末秃,當(dāng)一個(gè)數(shù)據(jù)包進(jìn)入宿主機(jī)的某張網(wǎng)卡時(shí),在四張表中的順序如下:raw -> manager -> nat -> filter 籽御。

image

數(shù)據(jù)如何在五條鏈中流轉(zhuǎn)练慕,根據(jù)目標(biāo)ip是否是本機(jī)某張網(wǎng)卡的ip來判斷惰匙。①:是本機(jī)數(shù)據(jù)包:prerouting -> input -> 本機(jī)進(jìn)程處理數(shù)據(jù) -> output -> postrouting 發(fā)送到網(wǎng)絡(luò)中。
②:不是本機(jī)數(shù)據(jù)包:prerouting -> forward -> postrouting 發(fā)送到網(wǎng)絡(luò)中铃将。每條鏈中可以添加多條規(guī)則项鬼,執(zhí)行時(shí)按照順序執(zhí)行,匹配到相應(yīng)的規(guī)則后執(zhí)行相應(yīng)的動(dòng)作劲阎,由于是順序執(zhí)行當(dāng)鏈中的規(guī)則數(shù)量過多時(shí)绘盟,性能會(huì)有明顯的損耗。
簡單介紹了iptables的四表五鏈后悯仙,是時(shí)候具體來操作一波iptables看看效果了龄毡。iptables基本語法
iptables [-t 表名] 命令選項(xiàng) [鏈名] [條件匹配] [-j 目標(biāo)動(dòng)作或跳轉(zhuǎn)]-t 表名 不寫的話默認(rèn)是filter表 命令選項(xiàng)

  • -A 在指定鏈的末尾添加一條規(guī)則

  • -D 刪除指定鏈的第幾條規(guī)則,后面加上具體數(shù)字

  • -I 默認(rèn)在鏈的頭部插入一條規(guī)則锡垄,也可以指定插入第幾條前面(-I chain num)

  • -F 刪除鏈中所有的規(guī)則

  • -L 列出現(xiàn)有鏈中的全部規(guī)則

通用參數(shù)

  • -p 協(xié)議沦零,tcp、udp货岭、icmp等

  • -s 源地址

  • -d 目的地址

  • --sport 源地址端口

  • --dport 目的地址端口

  • -i 指定入口網(wǎng)卡

  • -o 指定出口網(wǎng)卡

處理動(dòng)作

  • ACCEPT 允許數(shù)據(jù)包通過

  • DROP 丟棄數(shù)據(jù)包路操,數(shù)據(jù)發(fā)送方無法接受響應(yīng),直到過了超時(shí)時(shí)間

  • REJECT 拒絕此數(shù)據(jù)包茴她,數(shù)據(jù)發(fā)送方能感知到被拒絕

  • SNAT 做源地址轉(zhuǎn)換寻拂,如內(nèi)網(wǎng)下訪問外網(wǎng),把源地址ip修改成路由器的公網(wǎng)ip

  • DNAT 做目標(biāo)地址轉(zhuǎn)換

  • MASQUERADE SNAT的另一種模式丈牢,適用于ip地址不固定的情況下

iptables 的語法大致就是以上內(nèi)容,接下來搞幾個(gè)簡單的例子來測(cè)試一下瞄沙,我在本地搭了3臺(tái)虛擬機(jī)己沛,ip 地址分別為 192.168.113.99、192.168.113.100距境、192.168.113.101申尼。所有的iptables規(guī)則都在192.168.113.101這臺(tái)機(jī)器上設(shè)置。
只允許192.168.113.100ping操作

iptables -t filter -A INPUT -p icmp ! 192.168.113.100 -j REJECT

這里在filter 表的INPUT鏈上添加了一條記錄垫桂, 非 192.168.113.100 ip的ping 包直接拒絕掉师幕,只有 192.168.113.100 可以ping通。

發(fā)往192.168.113.100 的imcp包全部丟棄

iptables -t filter -A OUTPUT -p icmp -d 192.168.113.100 -j DROP

這里在filter 表的OUTPUT鏈上添加了一條記錄诬滩,丟棄了192.168.113.100 ping的響應(yīng)包霹粥。只允許特定的端口放開

iptables -t filter -A INPUT -p tcp -m multiport --dport 22,80,8080 -j ACCEPT

查看filter 表上的具體規(guī)則

iptables -t filter -nvL
image

如圖所示,操作filter 表的INPUT鏈疼鸟,開放了9000:10000之間的tcp端口后控,同時(shí)也開放了22、80空镜、8080端口浩淘,過input鏈時(shí)會(huì)從上往下順序執(zhí)行捌朴,當(dāng)匹配到在這個(gè)范圍內(nèi)的端口時(shí),把數(shù)據(jù)包傳給用戶態(tài)進(jìn)程张抄。最終沒有匹配砂蔽,會(huì)執(zhí)行最后一條DROP掉。注意:如果第三條規(guī)則放到最前面署惯,那就跪了察皇,那ssh客戶端直接斷開連接了,就表示禁止訪問所有tcp端口了泽台。

接下來操作nat表什荣,做nat地址的相關(guān)轉(zhuǎn)換。當(dāng)然怀酷,想要開啟forward數(shù)據(jù)轉(zhuǎn)發(fā)的話稻爬,需要如下操作,linux內(nèi)核默認(rèn)是關(guān)閉forward轉(zhuǎn)發(fā)的蜕依。

echo 1 > /proc/sys/net/ipv4/ip_forward

把192.168.113.101:12000轉(zhuǎn)發(fā)到192.168.113.100:8080

iptables -t nat -I PREROUTING -p tcp --dport 12000 -j DNAT --to-destination 192.168.113.100:8080

首先-t 操作nat表桅锄,在PREROUTING鏈上針對(duì)tcp協(xié)議,當(dāng)發(fā)現(xiàn)訪問本機(jī)是12000端口時(shí)样眠,做DNAT協(xié)議轉(zhuǎn)換友瘤,--to-destination 也可以簡寫成--to ,修改dst ip地址為 192.168.113.100檐束。最后在POSTROUTING做SNAT轉(zhuǎn)換辫秧,判斷發(fā)往目標(biāo)ip : port 為192.168.113.100 : 8080,修改源 ip 為192.168.113.101被丧。

// SNAT 也可以這樣寫盟戏,適用于ip不固定的情況下
iptables -t nat -I POSTROUTING -p tcp -d 192.168.113.100 --dport 8080 -j MASQUERADE

iptables lb負(fù)載均衡

k8s里面service的實(shí)現(xiàn)有3種方式,當(dāng)閱讀官方文檔發(fā)現(xiàn)有一種是根據(jù)iptables實(shí)現(xiàn)的甥桂,當(dāng)集群中的pod數(shù)量比較多時(shí)柿究,基于iptables做流量轉(zhuǎn)發(fā)和lb策略性能會(huì)有所損耗(鏈表形式)

)。所以后續(xù)k8s默認(rèn)使用ipvs實(shí)現(xiàn)了黄选。之后再寫k8sservice的實(shí)現(xiàn)時(shí)會(huì)說明ipvs的實(shí)現(xiàn)蝇摸。接下來看看iptables如何做lb

分別在192.168.113.99、192.168.113.100 使用docker 啟動(dòng)兩個(gè)nginx容器办陷,占用虛擬機(jī)的8080端口貌夕,在192.168.101上設(shè)置iptables規(guī)則,如下圖所示:

docker run -it --rm -p 8080:80 nginx
image

iptables兩種負(fù)載均衡策略

隨機(jī):random

// DNAT 轉(zhuǎn)換
iptables -A PREROUTING -t nat -p tcp  --dport 12000 -m statistic --mode random --probability 0.5 -j DNAT --to-destination 192.168.113.100:8080
iptables -A PREROUTING -t nat -p tcp  --dport 12000 -j DNAT --to-destination 192.168.113.99:8080
// SNAT 轉(zhuǎn)換
iptables -t nat -I POSTROUTING -p tcp -d 192.168.113.100 --dport 8080 -j SNAT --to-source 192.168.113.101
iptables -t nat -I POSTROUTING -p tcp -d 192.168.113.99 --dport 8080 -j SNAT --to-source 192.168.113.101

由于有兩個(gè)后端服務(wù)懂诗,做DNAT時(shí)第一個(gè)ip --probability 0.5 指定了50%的命中概率蜂嗽,沒有命中第一條的概率也是50%,當(dāng)沒有命中第一條時(shí)就走到了第二條殃恒,所以兩個(gè)服務(wù)被訪問的概率都是50%植旧。

輪訓(xùn):nth

// DNAT 轉(zhuǎn)換
iptables -A PREROUTING -t nat -p tcp  --dport 12000 -m statistic --mode nth --every 2 --packet 0 -j DNAT --to-destination 192.168.113.100:8080
iptables -A PREROUTING -t nat -p tcp  --dport 12000  -j DNAT --to-destination 192.168.113.99:8080
// SNAT 轉(zhuǎn)換
iptables -t nat -I POSTROUTING -p tcp -d 192.168.113.100 --dport 8080 -j SNAT --to-source 192.168.113.101
iptables -t nat -I POSTROUTING -p tcp -d 192.168.113.99 --dport 8080 -j SNAT --to-source 192.168.113.101

輪訓(xùn)算法中有兩個(gè)參數(shù) :n 指每n個(gè)包辱揭,p 指第p個(gè)包。第一條規(guī)則指每2個(gè)包病附,第一個(gè)包走第一條規(guī)則问窃,那第二個(gè)包就走第二條規(guī)則了。

總結(jié):基于iptables的這兩種方式完沪,很容易實(shí)現(xiàn)四層網(wǎng)絡(luò)代理轉(zhuǎn)發(fā)域庇,但是基于iptables做四層轉(zhuǎn)發(fā)是單點(diǎn)的,掛了就GG了覆积,所以業(yè)界最主流的玩法是lvs+keepalived做四層代理轉(zhuǎn)發(fā)听皿。而且lvs的性能比iptables更高。

前面我們對(duì)iptables做的操作都是直接在默認(rèn)的5個(gè)鏈上操作的宽档,一臺(tái)服務(wù)器上可能有很多個(gè)iptables規(guī)則尉姨,如果全部放一塊修改一處可能會(huì)對(duì)其他的有影響,而iptables支持自定義鏈吗冤,這時(shí)候我們把相同類型的規(guī)則全部放到同一個(gè)鏈中又厉,便于維護(hù)。k8s和docker中就定義了好幾個(gè)鏈椎瘟。

// 創(chuàng)建一個(gè)mysql的自定義鏈
iptables -t filter -N MYSQL
// mysql 的鏈中只允許 192.168.113.99 的ip訪問覆致,其余全部reject掉
iptables -t filter -I MYSQL -s 192.168.113.99 -j ACCEPT
iptables -t filter -A MYSQL -j REJECT
// 將mysql的鏈添加到filter表的INPUT鏈中
iptables -t filter -I INPUT -p tcp --dport 3306 -j MYSQL

自定義鏈規(guī)則如下:

image

參考文檔:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市肺蔚,隨后出現(xiàn)的幾起案子煌妈,更是在濱河造成了極大的恐慌,老刑警劉巖婆排,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件声旺,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡段只,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門鉴扫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赞枕,“玉大人,你說我怎么就攤上這事坪创】簧簦” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵莱预,是天一觀的道長柠掂。 經(jīng)常有香客問我,道長依沮,這世上最難降的妖魔是什么涯贞? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任枪狂,我火速辦了婚禮笨觅,結(jié)果婚禮上铸磅,老公的妹妹穿的比我還像新娘旅挤。我一直安慰自己樱报,他們只是感情好骂际,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布焦影。 她就那樣靜靜地躺著鳞绕,像睡著了一般饥努。 火紅的嫁衣襯著肌膚如雪氧急。 梳的紋絲不亂的頭發(fā)上颗胡,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音吩坝,去河邊找鬼毒姨。 笑死,一個(gè)胖子當(dāng)著我的面吹牛钾恢,可吹牛的內(nèi)容都是我干的手素。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼瘩蚪,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼泉懦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起疹瘦,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤崩哩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后言沐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體邓嘹,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年险胰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汹押。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡起便,死狀恐怖棚贾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情榆综,我是刑警寧澤妙痹,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站鼻疮,受9級(jí)特大地震影響怯伊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜判沟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一耿芹、第九天 我趴在偏房一處隱蔽的房頂上張望崭篡。 院中可真熱鬧,春花似錦猩系、人聲如沸媚送。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽塘偎。三九已至,卻和暖如春拿霉,著一層夾襖步出監(jiān)牢的瞬間吟秩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來泰國打工绽淘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涵防,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓沪铭,卻偏偏與公主長得像壮池,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子杀怠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361