Linux 3.13 引入 nftables,你可能會(huì)喜歡的幾種理由
Linux 3.13 帶來了很多特性。nftables也是***次正式發(fā)布。nftables是一個(gè)致力于替換現(xiàn)有的{ip,ip6,arp,eb}tables框架(也就是大家熟知的iptables)的項(xiàng)目。然而,Linux3.13中的nftables版本還是不完整的,還缺少一些重要的特性。這些特性會(huì)在后續(xù)的Linux版本中發(fā)布。大多數(shù)場(chǎng)景下nftables已經(jīng)可以使用,但是完整的支持(即,nftables優(yōu)先級(jí)高于iptables)應(yīng)該在Linux 3.15。
nftables引入了一個(gè)新的命令行工具nft。nft是iptables及其衍生指令(ip6tables,arptables)的超集。同時(shí),nft擁有完全不同的語法。是的,如果你習(xí)慣于iptables,這是個(gè)不好的消息。但是有一個(gè)兼容層允許你使用iptables,而過濾是由內(nèi)核中的nftables完成的。
到目前為止,只有非常少的文檔資料。你可以找到我的nftables快速開始,其他的一些初步文檔很快就會(huì)公開。
一些命令行例子
一行多個(gè)目標(biāo)
加入你想用iptables記錄并丟棄一個(gè)包,你必須寫兩條規(guī)則,一條記錄,一條丟棄:
- iptables -A FORWARD -p tcp --dport 22 -j LOG
- iptables -A FORWARD -p tcp --dport 22 -j DROP
使用nft,你可以把兩個(gè)目標(biāo)合并到一起:
- nft add rule filter forward tcp dport 22 log drop
方便創(chuàng)建集合
假如你想針對(duì)不同的端口允許包并且允許不同的icmpv6類型。使用iptables,你需要使用類似如下的規(guī)則:
- ip6tables -A INPUT -p tcp -m multiport --dports 23,80,443 -j ACCEPT
- ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
- ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT
- ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT
- ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
使用nft,集合可以用在規(guī)則中任一元素:
- nft add rule ip6 filter input tcp dport {telnet, http, https} accept
- nft add rule ip6 filter input icmpv6 type { nd-neighbor-solicit, echo-request, nd-router-advert, nd-neighbor-advert } accept
這樣更容易編寫,而且對(duì)于過濾方更加高效,因?yàn)閷?duì)每一種協(xié)議只需要添加一個(gè)規(guī)則。
你也可以給集合命名,以便在其他地方使用:
- # nft -i # use interactive mode
- nft> add set global ipv4_ad { type ipv4_address;}
- nft> add element global ipv4_ad { 192.168.1.4, 192.168.1.5 }
- nft> add rule ip global filter ip saddr @ipv4_ad drop
之后,當(dāng)檢測(cè)到一個(gè)新的破壞者時(shí):
- # nft -i
- nft> add element global ipv4_ad { 192.168.3.4 }
映射
nftables的一個(gè)高級(jí)特性就是映射。可以使用不同類型的數(shù)據(jù)并映射它們。例如,我們可以映射網(wǎng)絡(luò)端口到專用的規(guī)則集合(之前創(chuàng)建的存儲(chǔ)在一個(gè)鏈中)。在這個(gè)例子中,鏈的名稱為low_sec和high_sec:
- # nft -i
- nft> add map filter jump_map { type ifindex : verdict; }
- nft> add element filter jump_map { eth0 : jump low_sec; }
- nft> add element filter jump_map { eth1 : jump high_sec; }
- nft> add rule filter input iif vmap @jump_map
現(xiàn)在,比如說你有一個(gè)新的動(dòng)態(tài)端口ppp1,對(duì)它做過濾非常簡(jiǎn)單,僅僅把它加到j(luò)ump_map映射中就可以了。
- nft> add element filter jump_map { ppp1 : jump low_sec; }
運(yùn)維和內(nèi)核方面(更新速度更快)
在iptables中添加一條規(guī)則,會(huì)隨著規(guī)則數(shù)量增多而變得非常慢,這也就解釋了為什么調(diào)用iptables的腳本需要花很久才完成。這種狀況對(duì)nftables而言就不存在了。nftables使用原子的快速操作來更新規(guī)則集合。
內(nèi)核更新更少
使用iptables,每一個(gè)匹配或投遞都需要內(nèi)核模塊的支持。因此,如果你忘記一些東西或者要添加新的功能時(shí)都需要重新編譯內(nèi)核。nftables就不存在這種狀況了。在nftables中,大部分工作是在用戶態(tài)完成的,內(nèi)核只知道一些基本指令(過濾是用偽狀態(tài)機(jī)實(shí)現(xiàn)的)。例如,icmpv6支持是通過nft工具的一個(gè)簡(jiǎn)單的補(bǔ)丁實(shí)現(xiàn)的。在iptables中這種類型的更改需要內(nèi)核和iptables都升級(jí)才可以。