Linux 2.4 NAT HOWTO
Rusty Russell, mailing list netfilter@lists.samba.org
$Revision: 1.18 $ $Date: 2002/01/14 09:35:13 $
Превод: Николай Пламенов Баръмов (Blady) за http://irchelp.unibg.org
Този документ описва masquerading, transparent proxying,
port forwarding, и други форми на Network Address Translations с
2.4 Линукс кърнълите.
______________________________________________________________________
Съдържание:
1. Въведение
2. Къде са официалния WEB сайт и мейлинг лист?
2.1 Какво е Network Address Translation?
2.2 Защо бих искал да ползвам NAT?
3. Двата вида NAT
4. Бърз Translation от 2.0 и 2.2 Kernels
4.1 Просто искам да masquerading! Помощ!
4.2 А ipmasqadm?
5. Контролирайки какво да NAT
5.1 Проста селекция,използваща iptables
5.2 По-добра преценка,кои пакети да орежем
6. Как точно да "режем".
6.1 Source NAT
6.1.1 Masquerading
6.2 Destination NAT
6.2.1 Пренасочване
6.3 Планиране в дълбочина
6.3.1 Селекция на Multiple Addresses в определен диапазон
6.3.2 Създаване на Null NAT планове
6.3.3 Стандартно поведение на NAT
6.3.4 Implicit Source Port Mapping
6.3.5 Какво става при провал на NAT
6.3.6 Многовариантно планиране, застъпване and различия
6.3.7 Изменяне дестинациите на локалните връзки
7. Специални протоколи
8. Caveats при NAT
9. Сорс NAT и рутиране
10. Дестинации на NAT в рамките на същата мрежа
______________________________________________________________________
1. Въведение
Добре дошъл,любезни читателю,
Ще се поровим в омайващия (и понякога ужасен)свят на NAT:
Network Address Translation, а това HOWTO ще бъде вашият своеобразен
водач в 2.4 Linux Kernel и след него.
В Linux 2.4 беше представена система за филтриране на пакети,наречена
`netfilter'.NAT прдлага едно ниво над това.
(C) 2000 Paul `Rusty' Russell. Licensed under the GNU GPL.
2. Къде са официалният WEB сайт и мейлинг лист?
Има три официални адреса:
o Благодарение на Filewatcher .
o Благодарение наThe Samba Team and SGI .
o Благодарение на Harald Welte .
Можете да достигнете всеки от тях чрез round-robin DNS през
и
За официалния мейлинг лист вижте:
.
2.1. Какво всъщност е Network Address Translation?
Обикновено, пакетите в мрежата "пътуват" от началната си позиция(например
домашния ви компютър) до своята дестинация (например www.gnumonks.org) през
много различни линкове: Около 19 от мен в Австралия. Никой от тези линкове
не променя самите пакети: просто ги препращат нататък.
Ако един от тези линкове правеше NAT, тогава би се променил сорса или
дестинацията на пакета в неговия път през този линк.Както се досещате
не това е замисълът на системата, и от тук нататък NAT просто няма да
работи.Обикновено линкът,който прави NAT "помни" как точно е променил
пакета,и когато отговарящ пакет минава обратно,всичко ще е възстановено
и методът работи.
2.2. Защо бих използвал NAT?
В идеален свят,нямаше да се налага. Основните причини са:
Интернет връзки чрез модем
Повечето интернет доставчици дават едно IP,когато наберете.Можете
да изпращате пакети от всякакви адреси,но ще ви се връщат отговори
единствено съответстващи на вашето IP.Ако изкате да използвате няколко
различни машини(например домашна мрежа),за да се свържете с интернет
по този начин,имате нужда от NAT.
Това е най-широкото приложение на NAT в наши дни, още известно като
`masquerading' в света на Linux.Наричам това SNAT, защото можете да
смените сорс адреса на първия пакет.
Няколко сървъра
Понякога ще искате да контролирате къде отиват пакетите във
вашата мрежа.Често това е защото(както и по-горе), разполагате
само с един IP адрес, но бихте искали хората да могат да достигат
до тези зад реалното IP.Ако пренапишете дестинацията на пристигащите
пакети,ще можете да контролирате това.Този тип NAT се нарича още
port-forwarding при предишните версии на Linux.
Честа вариация на това е т.нар. load-sharing,т.е. планиране на
диапазони при няколко машини, разпределяйки пакетите между тях.
Ако правите това на сериозно ниво,може би е добре да погледнете:
Linux Virtual Server .
Transparent Proxying
Понякога ще искате да заблудите,че всеки пакет,преминал през
Linux box-а ви е предназначен за програма на самия него.
Това се използва,за да направите transparent proxies:Proxy
е програма,която стои между вашата мрежа и външния свят,
разбъркваща комуникацията между тях.Proxy e transparent
защото вашата мрежа дори няма да знае,че комуникира с прокси,
освен разбира се в случаите,когато то не работи.
Squid може да се конфигурира за работа по този начин,и се нарича
redirection или transparent proxying в предишните версии на Linux.
3. Двата вида NAT
NAT се разделя на два основни типа: Source NAT (SNAT) и
Destination NAT (DNAT).
Source NAT е когато променяме сорс адреса на първия пакет:
т.е. ако променяме адреса,от който връзката идва.Source NAT
винаги се прави при пост-рутиране,точно преди да изпратим пакета
по жицата.Masquerading е специален вид SNAT.
Destination NAT е когато променяме дестинацията(крайния адрес) на
първия пакет: т.е. промяна на това къде отива пакета.Destination NAT
винаги се прави преди рутиране,когато пакета се получава по жицата.
Port forwarding, load sharing, и transparent proxying са форми на DNAT.
4. Бърз превод от 2.0 и 2.2 Кернели
Първо,просто можете да използвате ipchains и ipfwadm както досега.
За да го правите,трябва да insmod "ipchains.o" или "ipfwadm.o" кернел
модул,които можете да намерите в новите netfilter дистрибуции.
Не бива обаче да ги използвате в комбинация с други netfilter модули.
Щом ги инсталирате,можете да използвате ipchains и ipfwadm както преди,
със следните разлики:
o Сетване на masquerading timeouts с ipchains -M -S, или ipfwadm
-M -s няма да работи.Тъй като тези timeouts са по-дълги за новата
NAT инфраструктура,това не е от значение.
o Init_seq, delta и previous_delta полета в masquerade листингите
са винаги нули.
o Зануляване и листване на броячите едновременно `-Z -L' вече няма да
работи: броячите няма да са занулени.
o Backward compatibility layer не работи добре при по-голямо количество
връзки: не я използвайте за общия gateway!
Хакерите може би ще забележат,че:
o Можете да ползвате портове 61000-65095 дори когато правите masquerading.
Masquerading кода,използван да присвои всичко в този диапазон е такъв,че
програмите немогат да го ползват.
o Недокументираният `getsockname' хак,който transparent proxy
програми могат да ползват за да открият истинската дестинация
на връзките вече не работи.
o Недокументираният bind-to-foreign-address хак също не работи;
това се използва,за да допълни илюзията за transparent proxying.
4.1. Просто искам да правя masquerading! Помощ!
Това е което искат повечето хора.Ако разполагате с динамично разпределено
IP PPP dialup (ако незнаете,това сте вие), вие просто искате да кажете на
на вашата машина,че всички пакети идващи от вътрешната мрежа трябва да бъдат
направени така,че да изглежда че идват от PPP dialup box.
# Зареждане на NAT модула (отнася се за всички останали).
modprobe iptable_nat
# В NAT table (-t nat), (-A) след рутиране
# (пострутиране) за всички излизащи пакети ppp0 (-o ppp0) което казва да
# MASQUERADE връзката (-j MASQUERADE).
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
# Включване на IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
Забележете,че не се прави никакво филтриране на пакетите:
за повече информация - Packet Filtering HOWTO: `Mixing NAT and Packet Filtering'.
4.2. Ами ipmasqadm?
Това е много по-добра основа за потребителя,затова не се притеснявам
толкова за обратната съвместимост.Просто използвайте `iptables -t nat'
за port forwarding.Например в Linux 2.2 нещата изглеждаха така:
# Linux 2.2
# Forward TCP packets going to port 8080 on 1.2.3.4 to 192.168.1.1's port 80
ipmasqadm portfw -a -P tcp -L 1.2.3.4 8080 -R 192.168.1.1 80
А сега бихте направили:
# Linux 2.4
# Append a rule before routing (-A PREROUTING) to the NAT table (-t nat) that
# TCP packets (-p tcp) going to 1.2.3.4 (-d 1.2.3.4) port 8080 (--dport 8080)
# have their destination mapped (-j DNAT) to 192.168.1.1, port 80
# (--to 192.168.1.1:80).
iptables -A PREROUTING -t nat -p tcp -d 1.2.3.4 --dport 8080 \
-j DNAT --to 192.168.1.1:80
5. Контролирайки какво да NAT
Трябва да създадете NAT правила,които да казват на кернела кои връзки да променя
и как точно да става това.За да направим това използваме изключително гъвкавия
iptables tool,и му казваме да промени NAT table като посочваме опцията "-t NAT".
NAT правилата съдържат три листинга,наречени `chains': изследва се всяко правило
докато някое съвпадне.Два от chains са PREROUTING (за Destination NAT,за влизащи пакети)
и POSTROUTING (за Source NAT, за излизащи пакети).Третия chain (OUTPUT)
няма да разглеждаме тук.
Следната диаграма би трябвало да илюстрира казаното:
_____ _____
/ \ / \
PREROUTING -->[Routing ]----------------->POSTROUTING----->
\D-NAT/ [Decision] \S-NAT/
| ^
| |
| |
| |
| |
| |
| |
--------> Local Process ------
Във всяка от точките,когато пакет минава,проверяваме с кой кънекшън
е свързан.Ако е нов кънекшън,поглеждаме съответния chain в NAT table,
за да преценим какво да го правим.Отговорът който дадем в този момент,
ще е в сила за всички следващи пакети,идващи от този кънекшън.
5.1. Проста селекция,използваща iptables
iptables съдържат редица стандартни опции,показани по-долу.Всички
double-dash могат да бъдат съкращавани,стига iptables da могат
да ги зададат независимо от останалите опции.Ако кернела ви има
iptables съпорт,като модул,ще трябва да заредите ip_tables.o
модула: `insmod ip_tables'.
Най-важната опция тук е тази за избор на таблица, `-t'.
За всички NAT операции,ще използвате `-t nat' за NAT таблицата.
Втората много важна опция е `-A' ,за прибавяне на ново правило,накрая
на всеки chain (например: `-A POSTROUTING'), или `-I' за добавяне на
такова в началото (например: `-I PREROUTING').
Можете да посочите source (`-s' или `--source') и дестинация (`-d'
или `--destination') за пакетите,които искате да NAT.Тези опции
могат да бъдат използвани с единичен IP адрес (например: 192.168.1.1),име
(например www.gnumonks.org), или мрежов адрес (например 192.168.1.0/24 или
192.168.1.0/255.255.255.0).
Можете да посочите пристигащия (`-i' или `--in-interface') или излизащия
(`-o' или `--out-interface') интерфейс за съвпадение,но кой можете да посочите
зависи от това в кой chain добавяте правилото:за PREROUTING можете да посочите
влизащия интерфейс,а за POSTROUTING - излизащия.Ако сгрешите iptables ще ви
даде грешка.
5.2. По-добра преценка,кои пакети да "орежем"
Както по-горе казах,можете да посочите сорс или дестинационен адрес.
Ако не използвате source select опцията,то в сила ще е всеки сорс адрес.
Същото важи и за дестинационния адрес.
Също така,можете да посочите и конкретен протокол(`-p' или `--protocol'),като
TCP или UDP;само пакети от този протокол,ще се засягат от правилото.Главната
причина да правим това е,че посочвйки протокол като tcp или udp
позволява допълнителни възможности:например опциите `--source-port' и
`--destination-port' (съкращавани съответно `--sport' and `--dport').
Така ще можете да декларирате,че само пакети,съвпадащи със source или
destination порта ще се засягат от правилото.Това е полезно за пренасочване
на web заявки(TCP порт 80 или 8080) без това да засяга другите пакети.
Тези опции трябва да бъдат следвани от `-p' (това дава side-effect при
зареждане на споделени библиотеки за този протокол).Можете да използвате
номера на портове,или просто име от файла /etc/services .
Много по-подробни обяснения за това можете да получите с "man iptables".
6. Описвайки как да бъдат орязвани пакетите
Вече знаем как да изберем орязваните пакети.За да довършим правилото
остава само да кажем на кернела,какво точно искаме да направи с тях.
6.1. Source NAT
Искате да правите Source NAT; сменете сорс адреса на кънекшъните на
нещо друго.Това се прави в POSTROUTING chain,точно преди да е окончателно
изпратен;това е важен детайл,тъй като това означава,че всичко друго(routing,
packet filtering) ще вижда пакета сменен.Освен това може да се използва `-o'
(outgoing interface) опцията.
Source NAT се специфицира чрез `-j SNAT', и `--to-source' опцията
показваща IP aдрес,IP рейндж, и по избор порт или набор от портове
(само за протоколите TCP и UDP ).
## Change source addresses to 1.2.3.4.
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4
## Change source addresses to 1.2.3.4, 1.2.3.5 or 1.2.3.6
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6
## Change source addresses to 1.2.3.4, ports 1-1023
# iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023
6.1.1. Masquerading
Това е специален случай на Source NAT наречен masquerading: трябва да се
използва само за динамични IP адреси, като например стандартните dialups
(за статични IP адреси,просто използвайте SNAT).
Не е задължително да включвате пълния сорс адрес,когато правите
masquerading: ще бъде използван сорс адреса на интерфейса,от който
пакета идва.По важното е,ако връзката падне,кънекшъните(които така
или инъче са загубени) са забравени.
## Masquerade everything out ppp0.
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
6.2. Destination NAT
Това се прави в PREROUTING chain, при пристигане на пакета;
което означава че при(routing, packet filtering) ще се вижда неговата `real'
дестинация.Също така можете да използвате опцията `-i' (incoming interface).
Destination NAT се специфицира чрез `-j DNAT', и `--to-destination' опциите
определящи IP address,рейндж от IP addresses,
и по избор набор от портове(това отново е валидно само за TCP и UDP).
## Change destination addresses to 5.6.7.8
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8
## Change destination addresses to 5.6.7.8, 5.6.7.9 or 5.6.7.10.
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8-5.6.7.10
## Change destination addresses of web traffic to 5.6.7.8, port 8080.
# iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 \
-j DNAT --to 5.6.7.8:8080
6.2.1. Пренасочване
Има специален случай на Destination NATнаречен пренасочване: той е просто
удобство абсолютно еквивалентно на DNAT до адреса на входния интерфейс.
## Send incoming port-80 web traffic to our squid (transparent) proxy
# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 \
-j REDIRECT --to-port 3128
6.3. Задълбочено планиране
Има някои тънкости при NAT,с които повечето хора никога няма да се сблъскат.
Документираме ги за любопитните.
6.3.1. Селекция на набор от адреси
Ако е даден набор от адреси,използваното IP се избира на базата на неговата
използваност.Винаги се избира най-слабо натовареното.
6.3.2. Нулеви NAT планове
Можете да използвате `-j ACCEPT' за да допуснете връзка без да я NAT.
6.3.3. Стандартно поведение на NAT
По подразбиране кънекшъна се променя колкото е възможно по-малко,
в рамките на правилата зададени от потребителя.Това означава,че не
се прави нищо допълнително,без то да е необходимо(remap ports например).
6.3.4. Implicit Source Port Mapping
Дори когато даден кънекшън не се MAP,може да се появи промяна на сорс порта,
Ако вече имаме кънекшън,предвиден за този порт.Трябва да се има предвид masquerading,
най често:
1. Web connection e установен от 192.1.1.1 от порт 1024 към www.netscape.com порт 80.
2. Това е masqueraded от masquerading box-а за използване на сорс IP-то
address (1.2.3.4).
3. Мasquerading box-а опитва да отвори web connection към
www.netscape.com порт 80 от 1.2.3.4 (адреса на външния интерфейс) порт 1024.
4. NAT ще промени сорс порта на втория кънекшън на 1025,за да избегне конфликта.
В тези случай портовете се разделят условно на три класа:
o Протове под 512
o Протове между 512 и 1023
o Портове след 1024
NAT никога не прескача от клас в клас.
6.3.5. Какво става при провал на NAT ?
Ако няма начин даден кънекшън да бъде направен според плановете на потребителя,
връзката ще се прекъсне.Това става и с пакети,когато тяхната принадлежност неможе
да бъде определена,като честа причина за това е липсата на памет.
6.3.6. Multiple Mappings, Overlap and Clashes
Можете да имате правила,които разпределят пакети в един и същ диапазон;
NAT кода е достатъчно "умен",за да не допусне конфликти.Следователно,имайки
две правила,които определят сорс адреси 192.168.1.1 и 192.168.1.2 респективно към
1.2.3.4 не е проблем.
Още повече,можете да насочвате към реални,използвани IP адреси,стига те
да минават през mapping box-а.Така че ако имате закачена мрежа (1.2.3.0/24),
но имате и вътрешна,която използва тези адреси и една която използва
Private Internet адреси 192.168.1.0/24, можете просто да NAT 192.168.1.0/24
към 1.2.3.0 мрежата,без опасност от конфликт.
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 \
-j SNAT --to 1.2.3.0/24
Същото важи и за адреси използвани от самия NAT:именно така работи
masquerading (поделя интерфейс адреси между masqueraded пакети и `real'
пакети идващи от NAT).
Освен това можете да разпределяте едни и същи пакети към различни адреси,
и те ще бъдат поделени.Например,ако не искате да слагате нищо на 1.2.3.5:
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 \
-j SNAT --to 1.2.3.0-1.2.3.4 --to 1.2.3.6-1.2.3.254
6.3.7. Променяне дестинацията на Locally-Generated Connections
NAT ви позволява да вмъквате DNAT правила в OUTPUT chain, но това не е
съвсем така във версия 2.4 (може и да е,но е нужна нова опция,тестване,
и малко писане,затова не я очаквам скоро).
Единственото ограничение е че можете да смените дестинацията само на
локалната машина (например: `j DNAT --to 127.0.0.1'), иначе отговорите
няма да бъдат правилно преведени
7. Специални протоколи
Някой протоколи не са податливи на NAT.За всеки от тях трябва да бъдат,
написани по 2 нови продължения;едно за connection tracking на протокола,
и едно за самия NAT.
В netfilter дистрибуцията,в момента има модули за ftp: ip_conntrack_ftp.o
и ip_nat_ftp.o.Ако ги insmod във вашия кернел(или просто ги компилирате),
няма да имате проблем при NAT на ftp.Aко не го направите,все още можете да
използвате пасивно ftp,но дори и то може да не функционира нормално,ако опитате
повече от обикновен source NAT.
8. Недостатъци
Ако правите NAT на даден кънекшън,минаващи в двете посоки трябва да минат
през NAT box-а,в противен случай няма да работи надеждно.
otherwise it won't work reliably.В случая,connection
tracking кода реасемблира фрагментите,а това означава,че не само
connection tracking няма да е надежден, но и пакетите могат изобщо да не минат,
тъй като ще има загуба на фрагменти.
9. Source NAT и рутиране
Ако правите SNAT,ще искате да се уверите че всяка машина до която отива
SNAT пакет ще връща отговор към NAT box-а.
Например,например ако разпределяме няколко заминаващи пакета към source
адрес 1.2.3.4, външния рутер трябва да има информация как да праща отговорите
(с дестинация 1.2.3.4) обратно към NAT box-a.
Това може да стане по следните начини:
1. Ако правите SNAT в собствения адрес на BOX-a(за който рутиране и всичко друго
работи),не трябва да правите нищо.
2. Ако правите SNAT на неизползван адрес в LAN-а (например,пренасочвате към
1.2.3.99, свободно IP на вашата 1.2.3.0/24 мрежа), NAT box-a ще трябва да
отговаря на АRP заявки за този адрес,както и на своите:най-лесният начин да
направите това е да направите IP алайъс:
# ip address add 1.2.3.99 dev eth0
3. Ако правите SNAT на абсолютно различни адреси, ще трябва да се уверите,че
машините към който тези пакети ще отидат,ще рутират отговорите към NAT box-a.
Разбира се всичко е наред,ако това е техния GATEWAY по подразбиране,в противен случай
ще трябва да посочите пътя обратно(ако използвате рутиращ протокол) или ръчно да укажете
пътечките до всички "замесени" машини.
10. Destination NAT в рамките на същата мрежа
Ако правите port forwarding обратно в съшата мрежа,ще трябва да се уверите,че
както вашите така и обратните пакети ще минат през NAT box-a(за да могат да
бъдат променяни).NAT ще блокира излизащо ICMP пренасочване,което се получава
пакет се насочи към изходния си интерфейс,но получаващия сървър ще продължи да
праща отговори към своя клиент(който пък няма да ги разпонава).
Класически случай е когато вашия персонал се опитва да достигне `public'
web server,на който се прави NAT ot public address(1.2.3.4) към вътрешна
машина (192.168.1.1), като:
# iptables -t nat -A PREROUTING -d 1.2.3.4 \
-p tcp --dport 80 -j DNAT --to 192.168.1.1
Единия начин е да стартирате вътрешен DNS server който знае истинския
адрес на въпросния web server,и пренасочва всички заявки.Това означава,че
логинга на вашия web server ще показва вярното вътрешно IP.
Другия начин е да се NAT-ва и сорс IP адреса към собствен за тези връзки,
заблуждавайки сървъра да отговаря през него.В този случай бихме направили следното:
(вътрешния адрес на NAT box-a e 192.168.1.250):
# iptables -t nat -A POSTROUTING -d 192.168.1.1 -s 192.168.1.0/24 \
-p tcp --dport 80 -j SNAT --to 192.168.1.250
Тъй като PREROUTING правилото стартира първо,пакетите вече ще са насочени към
вътрешния web server.