Netfilter學(xué)習(xí)之NAT類型動態(tài)配置(二)NAT類型介紹及MASQUERADE
??在上一節(jié)中,我們介紹了iptables和netfilter的基本關(guān)系,在這里我們會進(jìn)一步介紹現(xiàn)有的NAT以及Linux中大多已實(shí)現(xiàn)的MASQUERADE實(shí)現(xiàn)原理。
1. NAT類型介紹
??常用的NAT類型主要有Full Cone NAT(全錐型), Restricted NAT(限制型錐型), Port Restricted NAT(端口限制型錐型), Symmetric NAT(對稱型)四種。
??四種類型的主要區(qū)別在于對外界訪問內(nèi)部IP的控制力度。為方便解釋,我們使用如下的用語來說明四種NAT類型的不同之處。
用語定義
- 內(nèi)部Tuple:指內(nèi)部主機(jī)的私有地址和端口號所構(gòu)成的二元組,即內(nèi)部主機(jī)所發(fā)送報文的源地址、端口所構(gòu)成的二元組
- 外部Tuple:指內(nèi)部Tuple經(jīng)過NAT的源地址/端口轉(zhuǎn)換之后,所獲得的外部地址、端口所構(gòu)成的二元組,即外部主機(jī)收到經(jīng)NAT轉(zhuǎn)換之后的報文時,它所看到的該報文的源地址(通常是NAT設(shè)備的地址)和源端口
- 目標(biāo)Tuple:指外部主機(jī)的地址、端口所構(gòu)成的二元組,即內(nèi)部主機(jī)所發(fā)送報文的目標(biāo)地址、端口所構(gòu)成的二元組
詳細(xì)釋義
Full Cone NAT:所有來自同一 個內(nèi)部Tuple X的請求均被NAT轉(zhuǎn)換至同一個外部Tuple Y,而不管這些請求是不是屬于同一個應(yīng)用或者是多個應(yīng)用的。除此之外,當(dāng)X-Y的轉(zhuǎn)換關(guān)系建立之后,任意外部主機(jī)均可隨時將Y中的地址和端口作為目標(biāo)地址 和目標(biāo)端口,向內(nèi)部主機(jī)發(fā)送UDP報文,由于對外部請求的來源無任何限制,因此這種方式雖然足夠簡單,但卻不那么安全
Restricted Cone NAT: 它是Full Cone的受限版本:所有來自同一個內(nèi)部Tuple X的請求均被NAT轉(zhuǎn)換至同一個外部Tuple Y,這與Full Cone相同,但不同的是,只有當(dāng)內(nèi)部主機(jī)曾經(jīng)發(fā)送過報文給外部主機(jī)(假設(shè)其IP地址為Z)后,外部主機(jī)才能以Y中的信息作為目標(biāo)地址和目標(biāo)端口,向內(nèi)部 主機(jī)發(fā)送UDP請求報文,這意味著,NAT設(shè)備只向內(nèi)轉(zhuǎn)發(fā)(目標(biāo)地址/端口轉(zhuǎn)換)那些來自于當(dāng)前已知的外部主機(jī)的UDP報文,從而保障了外部請求來源的安 全性
Port Restricted Cone NAT:它是Restricted Cone NAT的進(jìn)一步受限版。只有當(dāng)內(nèi)部主機(jī)曾經(jīng)發(fā)送過報文給外部主機(jī)(假設(shè)其IP地址為Z且端口為P)之后,外部主機(jī)才能以Y中的信息作為目標(biāo)地址和目標(biāo)端 口,向內(nèi)部主機(jī)發(fā)送UDP報文,同時,其請求報文的源端口必須為P,這一要求進(jìn)一步強(qiáng)化了對外部報文請求來源的限制,從而較Restrictd Cone更具安全性
Symmetric NAT:這是一種比所有Cone NAT都要更為靈活的轉(zhuǎn)換方式:在Cone NAT中,內(nèi)部主機(jī)的內(nèi)部Tuple與外部Tuple的轉(zhuǎn)換映射關(guān)系是獨(dú)立于內(nèi)部主機(jī)所發(fā)出的UDP報文中的目標(biāo)地址及端口的,即與目標(biāo)Tuple無關(guān); 在Symmetric NAT中,目標(biāo)Tuple則成為了NAT設(shè)備建立轉(zhuǎn)換關(guān)系的一個重要考量:只有來自于同一個內(nèi)部Tuple 、且針對同一目標(biāo)Tuple的請求才被NAT轉(zhuǎn)換至同一個外部Tuple,否則的話,NAT將為之分配一個新的外部Tuple;打個比方,當(dāng)內(nèi)部主機(jī)以相 同的內(nèi)部Tuple對2個不同的目標(biāo)Tuple發(fā)送UDP報文時,此時NAT將會為內(nèi)部主機(jī)分配兩個不同的外部Tuple,并且建立起兩個不同的內(nèi)、外部 Tuple轉(zhuǎn)換關(guān)系。與此同時,只有接收到了內(nèi)部主機(jī)所發(fā)送的數(shù)據(jù)包的外部主機(jī)才能向內(nèi)部主機(jī)返回UDP報文,這里對外部返回報文來源的限制是與Port Restricted Cone一致的。不難看出,如果說Full Cone是要求最寬松NAT UDP轉(zhuǎn)換方式,那么,Symmetric NAT則是要求最嚴(yán)格的NAT方式,其不僅體現(xiàn)在轉(zhuǎn)換關(guān)系的建立上,而且還體現(xiàn)在對外部報文來源的限制方面。
??在Netfilter中,不同NAT的實(shí)現(xiàn)在內(nèi)核中進(jìn)行。而通常情況下,Linux系統(tǒng)自帶的NAT類型多為端口限制型錐型NAT或者對稱型。對此,我們參照著內(nèi)核和用戶層的源碼進(jìn)行說明。這里之所以說為端口限制型錐型NAT或?qū)ΨQ型NAT是因?yàn)橄到y(tǒng)自帶的MASQUERADE部分模塊根據(jù)配置命令行的不同可以實(shí)現(xiàn)上述兩種不同類型的NAT。由上一篇,大家應(yīng)該都知道了iptables和Netfilter的關(guān)系,這里我們先看看在用戶層,Iptables命令中關(guān)于MASQUERADE的實(shí)現(xiàn)。
??源碼名libipt_MASQUERADE.c,位置的話不同版本的linux系統(tǒng)可能不大一樣。該部分主要是實(shí)現(xiàn)對配置masquerade命令的解析以及注冊,注冊之后即可激活內(nèi)核空間中的masquerade相應(yīng)鉤子函數(shù)實(shí)現(xiàn)masquerade功能。關(guān)于鉤子函數(shù),在下一講中將會簡單介紹。
??首先看一下該源碼的大體框架。
<div align=center>
??由圖可見,該部分主要由help, opts, init, parse_ports, parse, final_check, print, save, masq, _init組成。按
各個函數(shù)、結(jié)構(gòu)的名稱大致可以猜測到該函數(shù)做的是什么功能,之后實(shí)現(xiàn)其他幾種NAT均需要模仿該模塊完成。
??首先需要介紹的是masq。源碼如下
static struct iptables_target masq = {
NULL,
.name= "MASQUERADE",
.version= IPTABLES_VERSION,
.size= IPT_ALIGN(sizeof(struct ip_nat_multi_range)),
.userspacesize= IPT_ALIGN(sizeof(struct ip_nat_multi_range)),
.help= &help,
.init= &init,
.parse= &parse,
.final_check= &final_check,
.print= &print,
.save= &save,
.extra_opts= opts
};
??該部分是整個MASQUERADE的注冊,給定了該結(jié)構(gòu)體的各個元素(名稱、版本、函數(shù)實(shí)現(xiàn)等)。所有其他的iptables命令行參數(shù)均以此形式添加。
??help部分即命令行常用的幫助部分,在MASQUERADE中,實(shí)現(xiàn)如下。
/* Function which prints out usage message. */
static void
help(void)
{
printf(
"MASQUERADE v%s options:\n"
" --to-ports <port>[-<port>]\n"
"Port (range) to map to.\n"
" --random\n"
"Randomize source port.\n"
"\n"
,
IPTABLES_VERSION);
}
??這里我們可以很清晰的了解iptables中MASQUERADE如何配置。之前所說的MASQUERADE可以配置兩種不同類型的NAT也來源于此,提供的--random功能即為對稱型NAT,其他兩種形式命令行則為端口限制型錐形NAT的配置。
??另外還需要說明的是這里parse是解析命令行,使用的也是大名鼎鼎的opt, getlongopt系列函數(shù),需要了解的可以自行百度谷歌搜索。parse_ports部分主要是實(shí)現(xiàn)將輸入的" --to-ports <port>[-<port>]"加以識別。其余都是很容易弄懂的一些函數(shù),在此不做過多的介紹,有問題的可以聯(lián)系我。本篇結(jié)束。