|
楼主 |
发表于 2010-6-25 14:00:35
|
显示全部楼层
[Linux防火墙].(Linux.Firewalls.Attack.Detection.and.Response.with.iptables,.psad,.and.fwsnort)(美)拉什.中文高清PDF版——阅读笔记
第一章 简介
iptables和netfilter的区别:netfilter是一个Linux的项目,提供一个框架,iptables使用netfilter建立防火墙功能。
每一条规则应用于一个表中的一个链,每条链是一个规则集。
表是一个大类的描述,包括了filter、nat、mangle和raw。
2.4以后的内核基本上都已经开启了netfilter,但是基本上都被精简了,需要通过编译内核让必要的子系统启用。完整安装的linux所用内核文件在/usr/src下,执行命令make menuconfig可以开启tui进行配置。
找到位置network-networking option-network packet filtering framework。其中比较关键的配置项是core netfilter configuration和ip:netfilter configuration。保存退出后通过grep “_NF_” .config和grep NETFILTER .config来检查配置项。
内核编译才用LKM方式更方便和安全,可以使用rmmod命令去掉任意的模块从而避免存在安全漏洞的模块。但是这样做的结果和可能让入侵者直接加载一个黑客用模块,从而避免系统发现他的所有行为。
编译过程:
make
su -
Password:
mount /boot
cd /usr/src/kernel/xxxxxx
make install && make modules_install
我在make的时候出现“没有规则可以创建“init/built-in.o”需要的目标“init/main.o””错误,原来是因为没有下载内核源码包的缘故。
如果使用grub引导系统还需要编写grub文件以使系统通过新的内核启动。
title linux-2.6.x.x
root (hd0,0) \\boot所在分区
kernel /boot/vmlinuz-2.6.x.x root=/dev/hdax \\根分区所在
然后重启 shutdown -r now
以上完成了内核的支持工作,还需要安装用户层程序:http://www.netfilter.org/project ... ables-1.4.8.tar.bz2
CentOS自带的是1.3.5版本,现在安装最新版。
首先./configure,然后执行make KERNEL_DIR=/usr/src/kernels/2.6.18-194.3.1.el5-i686 BINDIR=/sbin LIBDIR=/lib \\分别指明内核位置以放置C头文件,还有二进制文件以及库文件放置的位置。
然后make install KERNEL_DIR=/usr/src/kernels/2.6.18-194.3.1.el5-i686 BINDIR=/sbin LIBDIR=/lib
为确定成功安装,查看iptables的版本:iptables -V \\如果之前有旧版本会比较麻烦,可以rpm -e xxx --nodeps强制删除,否则关联一堆。
阅读本书可以参照网址:http://www.cipherdyne.org/LinuxFirewalls,该网址还配有原文中所用拓扑图。
[IMG]https://qkzabg.bay.livefilestore.com/y1m-ajBeGNcu92bwQVe5IgV8xIM9y7NDio646tSUTEKDR-DC4zXI8fZc_ny3A6clgQchWdpMq3s21pDPSck5LztloXX4fco_ZrUGqbwGcyuQkYIQOJAyuk7QcExKI22C1VaOvKU7udeRR6C8Gbzpg7Y6Q/LF_default_network_thumb[1].png?download&psid=1[/IMG]
策略需求:
DNS
FTP
NTP
SSH
SMTP
HTTP/HTTPS
whois查询
其它通信应被拒绝,从内部起的会话都应该被跟踪,同事防火墙提供nat功能。防火墙允许内部用户ssh,其它地方不行,除非有fwknop。防火墙接收内外网的icmp回显请求,其它丢弃。要有日志记录和丢弃规则,对扫描有记录。
为方便查找,贴出选项含义:
[IMG]https://qkzabg.bay.livefilestore.com/y1mwTxayi9_OOOk3OAqM-5K-eCfZ39GKeAgW6ti7u9r8TNCL9mOYgZfh-tVwbn6PN2WcP1QMICsefdvKFSQ7NGbrF7uY3C_wsUueLjji9Ur_5lEtXA5D_AAa_0UK6vagWJAQtXEp-iII0WWEKr3YeetoA/image_thumb[1]%2036940D0A.png?download&psid=1[/IMG]
[IMG]https://qkzabg.bay.livefilestore.com/y1maONypNiMSrvgeqzIBRIboPqeN5Lu0WxoAdoDBkS60e75kWePCDhekOCsgWqTMvTx9aG7KEww_wZy-vLdvnhVQ91KJh7YzvCUdyn3TrcEXPt18BD1Vkx4OlSrddKbabYq6LO0liF0EKSPOlfFOj2hjg/image_thumb[4].png?download&psid=1[/IMG]
从网站摘录完整的脚本:
#!/bin/sh
#
#############################################################################
#
# File: iptables.sh
#
# Purpose: To build a basic iptables policy with default log and drop rules.
# This script was written for the book "Linux Firewalls: Attack
# Detection and Response" published by No Starch Press.
#
# Copyright (C) 2006-2009 Michael Rash (mbr@cipherdyne.org)
#
# License (GNU Public License):
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
#
#############################################################################
#
# $Id: index.html 2813 2010-07-11 13:20:26Z mbr $
#
IPTABLES=/sbin/iptables \\说明iptables和modprobe的执行文件位置
IP6TABLES=/sbin/ip6tables
MODPROBE=/sbin/modprobe
INT_NET=192.168.10.0/24 \\定义内网地址和掩码
### flush existing rules and set chain policy setting to DROP
echo "[+] Flushing existing iptables rules..." \\去掉所有自带策略,并全部置为丢弃
$IPTABLES -F
$IPTABLES -F -t nat
$IPTABLES -X
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP
### this policy does not handle IPv6 traffic except to drop it.
#
echo "[+] Disabling IPv6 traffic..."
$IP6TABLES -P INPUT DROP
$IP6TABLES -P OUTPUT DROP
$IP6TABLES -P FORWARD DROP
### load connection-tracking modules \\加载连接跟踪
#
$MODPROBE ip_conntrack
$MODPROBE iptable_nat
$MODPROBE ip_conntrack_ftp
$MODPROBE ip_nat_ftp
###### INPUT chain ###### \\iptables是ip层上的,所以ARP管不了,默认下开启了mac地址扩展,可以根据mac过滤ip
#
echo "[+] Setting up INPUT chain..." \\无效链接丢弃并记录,有效链接允许
### state tracking rules
$IPTABLES -A INPUT -m state --state INVALID -j LOG --log-prefix "DROP INVALID " --log-ip-options --log-tcp-options
$IPTABLES -A INPUT -m state --state INVALID -j DROP \\突然到达的fin都会触发无效
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT \\连接两端,或者从源触发的目的回包是已建立或相关
### anti-spoofing rules \\防欺骗
$IPTABLES -A INPUT -i eth1 -s ! $INT_NET -j LOG --log-prefix "SPOOFED PKT "
$IPTABLES -A INPUT -i eth1 -s ! $INT_NET -j DROP
### ACCEPT rules
$IPTABLES -A INPUT -i eth1 -p tcp -s $INT_NET --dport 22 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type echo-request -j ACCEPT \\特别指定--syn和state new是因为new状态的触发不一定是syn,这里可以过滤所有的非syn链接从而保证new确实是受到请求的。
### default INPUT LOG rule
$IPTABLES -A INPUT -i ! lo -j LOG --log-prefix "DROP " --log-ip-options --log-tcp-options
### make sure that loopback traffic is accepted
$IPTABLES -A INPUT -i lo -j ACCEPT
##############################################################################################
###### OUTPUT chain ###### \\按照功能需求进行设置,不详解
#
echo "[+] Setting up OUTPUT chain..."
### state tracking rules
$IPTABLES -A OUTPUT -m state --state INVALID -j LOG --log-prefix "DROP INVALID " --log-ip-options --log-tcp-options
$IPTABLES -A OUTPUT -m state --state INVALID -j DROP
$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
### ACCEPT rules for allowing connections out
$IPTABLES -A OUTPUT -p tcp --dport 21 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 22 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 25 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 43 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 80 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 443 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 4321 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p tcp --dport 53 -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p udp --dport 53 -m state --state NEW -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
### default OUTPUT LOG rule
$IPTABLES -A OUTPUT -o ! lo -j LOG --log-prefix "DROP " --log-ip-options --log-tcp-options
### make sure that loopback traffic is accepted
$IPTABLES -A OUTPUT -o lo -j ACCEPT
##############################################################################################
###### FORWARD chain ######
#
echo "[+] Setting up FORWARD chain..."
### state tracking rules
$IPTABLES -A FORWARD -m state --state INVALID -j LOG --log-prefix "DROP INVALID " --log-ip-options --log-tcp-options
$IPTABLES -A FORWARD -m state --state INVALID -j DROP
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
### anti-spoofing rules
$IPTABLES -A FORWARD -i eth1 -s ! $INT_NET -j LOG --log-prefix "SPOOFED PKT "
$IPTABLES -A FORWARD -i eth1 -s ! $INT_NET -j DROP
### ACCEPT rules
$IPTABLES -A FORWARD -p tcp -i eth1 -s $INT_NET --dport 21 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p tcp -i eth1 -s $INT_NET --dport 22 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p tcp -i eth1 -s $INT_NET --dport 25 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p tcp -i eth1 -s $INT_NET --dport 43 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p tcp --dport 80 --syn -m state --state NEW -j ACCEPT \\将任何http、https和dns查询以及icmp回显放行
$IPTABLES -A FORWARD -p tcp --dport 443 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p tcp -i eth1 -s $INT_NET --dport 4321 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p tcp --dport 53 -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p udp --dport 53 -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -p icmp --icmp-type echo-request -j ACCEPT
### default LOG rule
$IPTABLES -A FORWARD -i ! lo -j LOG --log-prefix "DROP " --log-ip-options --log-tcp-options
##############################################################################################
###### NAT rules ###### \\实现NAT转发,把不同的服务请求转发到各自目标,并允许内网访问外网
#
echo "[+] Setting up NAT rules..."
$IPTABLES -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to 192.168.10.3:80
$IPTABLES -t nat -A PREROUTING -p tcp --dport 443 -i eth0 -j DNAT --to 192.168.10.3:443
$IPTABLES -t nat -A PREROUTING -p udp --dport 53 -i eth0 -j DNAT --to 192.168.10.4:53
$IPTABLES -t nat -A POSTROUTING -s $INT_NET -o eth0 -j MASQUERADE
###### forwarding ###### \\启用路由转发
#
echo "[+] Enabling IP forwarding..."
echo 1 > /proc/sys/net/ipv4/ip_forward
exit
### EOF ###
题外话:iptables怎么实现NAT的?http://www.netfilter.org/documen ... NAT-HOWTO.html#toc1 \\文字编码调成繁体中文。
原文经过整理后如下:
1.Introduction
亲爱的读者﹐欢迎您﹗
您将要探索的是引人入胜(有时蛮恐怖)的NAT(Network Address Translation)世界﹐同时﹐您甚至可以把这份HOWTO当成Linux 2.4核心及以后版本的精确指南呢。
在Linux 2.4里面﹐有一个叫`netfilter'的东东﹐它是专门撕裂(mangling*)封包的。在它再上一个层级﹐就是提供NAT功能的了﹐则是完全由以往的核心实作而成的。
(译者注﹕很奇怪﹐原作者用mangle这一词﹐似乎在过往的中文文件中都没碰到过﹐查过好多字典都不知道怎么翻译好。这里暂时勉强用‘撕裂’这个词代替﹐不过后面我就不尝试翻译这词了﹐让读者自己去理解吧。)
2.官方的网站和通信论坛何处觅﹖
目前有三个官方网站可供浏览﹕
感谢Filewatcher(http://netfilter.filewatcher.org).
感谢The Samba Team and SGI (http://www.samba.org/netfilter).
感谢Harald WeltE (http://netfilter.gnumonks.org).
而官方的netfilter邮件论坛﹐则可以到这里看﹕http://www.netfilter.org/contact.html#list
2.1何为Network Address Translation?
一般来说﹐在网络上封包从其来源(比方您家中的计算机)出去﹐然后到达目的地(比方www.gnumonks.org)﹐会经过许许多多个不同的连接(links)﹕就我所在的澳洲来说就大约有19个之多。没有任何一个连接会真的去更改您的封包﹕他们仅仅是将之传送出去而已。
假如其中一个连接会做NAT的话﹐然后它们就会更改那些经它而过的封包之来源或目的地地址。诚如您能想象得到的﹐这并非系统被设计成这样的﹐而是NAT所做的手脚而已。通常要做NAT的联机会记住它如何mangled封包的﹐然后当响应封包从另一方向过来的时候﹐然后就反过来mangling那个响应封包﹐所以所有东西都工作起来了。
2.2为什么我要做NAT呢﹖
在完美的世界里﹐您无需这样做啦。在目前来说﹐还是有其理由的﹕
用modem拨接上网
大多数的ISP在您连上去的时候只会给您一个单一IP地址。您喜欢的话﹐以任何来源地址把封包送出去都行﹐但只有响应到这个来源地址的封包?nbsp;可以回到您那里。如果您想用多台不同主机(例如家中网络)透过该连接上internet的话﹐那您就要NAT了。
这也就是今天NAT最常用之处﹐而在Linux世界最为人知的就是所谓的`masquerading(封包伪装术)'了。我称之为SNAT﹐因为您改变了第一个封包的source(来源)地址的缘故。
多重服务器
有时候﹐您会想去改变那些进入您网络的封包之路向。这最常是因为(如上述)您只有一个IP地址﹐但您却想让别人能够连接到`真实'IP地址后面的主机去。如果您重写这些内送封包的目的地址﹐这样您就可以管理它们了。
一个常见的变动是负载分担(load-sharing)﹐也就是在一组机器上面为封包做映对(mapping)的动作。这类型的NAT﹐在以前的的Linux版本中也就被称为port-forwarding。
透明**(Transparent Proxying)
有时候﹐您或许想要每一个经过您的Linux主机的封包送至主机本身的一个程序去。这就需要进行透明**的动作了﹕一个**就是一个位于您的网络和?nbsp;部网络的程序﹐为彼此双方负起沟通的任务。而所谓的透明﹐则是因为您的网络甚至无须知道在和一个**对讲﹐当然了﹐除非**不再工作了吧。
Squid可以配置成这样的工作方式﹐这就是在过往的Linux版本中所谓的重导向(redirection)﹑或透明**了。
3.两种类型的NAT
我将NAT分为两种不同的类型﹕Source NAT(SNAT)与Destination NAT(DNAT)
Source NAT就是您将改变第一个封包的来源地址﹕例如﹐您为传入的联机做caching的动作。Source NAT永远会在封包传出网线之前就做好post-routing的动作。封包伪装(Masquerading)就是一个SNAT特例。
Destination NAT就是您将改变第一个封包的目的地地址﹕例如您要为传出的联机做caching的动作。Destination NAT永远会在封包从网线进入之后就马上做好pre-routing的动作。Port forwarding﹑负载分担﹑以及透明**﹐都属于DNAT。
4.从2.0到2.2核心的快速转变
非常抱歉﹐假如您仍然忙于从2.0(ipfwadm)到2.2(ipchains)的转型的话。不过﹐这也是个喜?nbsp;参半的消息啦。
首先﹐您可以轻易的一如往昔地使用ipchains和ipfwadm。要这样做的话﹐您需要将最新的netfilter套件中的`ipchains.o'或`ipfwadm.o'核心模块加载。它们是相互排斥的(您应已获警告了)﹐同时也不能和其它netfilter模块同时整合在一起。
一旦其中一个模块被加载﹐您就可以如常使用ipchains和ipfwadm了﹐但也有如下一些变化啦﹕
用ipchains -M -S﹐或是ipfwadm -M -s作伪装逾时将不再有效。因为逾时设定已经移至新的NAT牯c中﹐所以这里也就没什么所谓了。
在伪装列表中显示的ini seq﹑delte﹑和previous delta字段﹐将永远为零。
同时归零(zeroing)和列示记数器(counter)的`-Z -L'已无作用﹕记数器将不能再归零了。
Hacker们仍要留意之处﹕
您现在可以捆绑61000-65095之间的埠口﹐而无需理会您是否使用封包伪装技术。在过去﹐封包伪装程序会把此值域内的所有东西捕获进来﹐所以其它程序就不可用之了。
至于(尚未成文之)getsockname破解﹐在过去﹐透明**程序可以找出那些不再有效联机之真正目的地。
至于(尚未成文之)bind-to-foreign-address破解﹐同样尚未实作﹔这在过去用以完善透明**的构想。
4.1救命啊﹗我只想要封包伪装而已﹗
没错﹐这也是大多数朋友之需。如果您用PPP拨接获得的动态IP(如果您不了解的话﹐那您应该是了)﹐您或许只想单纯告诉您的主机让所有来自您内部网络的封包﹐看起来如来自该PPP拨接主机一样。
# Load the NAT module (this pulls in all the others).
modprobe iptable_nat
# In the NAT table (-t nat), Append a rule (-A) after routing
# (POSTROUTING) for all packets going out ppp0 (-o ppp0) which says to
# MASQUERADE the connection (-j MASQUERADE).
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
# Turn on IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
注﹕您这里并没做任何封包过滤﹕如要的话﹐请参考 Packet Filtering HOWTO﹕将NAT和封包过滤合并起来就是了。
4.2那ipmasqadm怎么了﹖
这个其实取决于使用者而已﹐所以我并不是很为向后兼容问题而担心。您可以单纯使用iptables -t nat做port forwarding的动作。例如﹐在Linux2.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 pre-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
假如您想让这条规则同时修改本机联机的话(如﹐即使在NAT主机本身﹐要连接1.2.3.4的8080埠口之telnet联机﹐会帮您连接至192.168.1.1的80埠口)﹐您就可以插入相同的规则至OUTPUT链中(它只适用于本机传出的封包)﹕
# Linux 2.4
iptables -A OUTPUT -t nat -p tcp -d 1.2.3.4 --dport 8080 -j DNAT --to 192.168.1.1:80
5. 控制哪些要NAT
您需要建立一些NAT规则﹐来告诉核心哪些联机要改变﹐同时如何去改变它们。要做到这点﹐我们需要一个非常多用?nbsp;的iptables工具﹐同时指定`-t nat'选项告诉它去修改NAT表格。
NAT规则的表格含有三个列表叫做`chains'﹕每一条规则都按顺序检查﹐直到找到一个相符的比对。该三个链就叫做PREROUTING(对Destination NAT来说﹐因为封包首先是传入的)﹑POSTROUTING(对Source NAT来说﹐因为封包是离开的)﹑以及OUTPUT(对Destination NAT来说﹐是指那些由本机产生的封包)。
假如我够艺术天份的话﹐下面的图示将准确仿真出上面所说的概念。
_____ _____
/ \ / \
PREROUTING -->[Routing ]----------------->OSTROUTING----->
\D-NAT/ [Decision] \S-NAT/
| ^
| __|__
| / \
| | OUTPUT|
| \D-NAT/
| ^
| |
--------> Local Process ------
于前述的每一点﹐当一个封包通过我们要查看的相关联机之时﹐如果它是一个新建联机﹐我们查看它在NAT表格里对应的链﹐看看能对之做些什么动作。而由此获得的答案就应用于该联机将来的所有封包。
5.1用iptables做简单的选择
iptables具有如后所列的许多标准选项。所有那些带双减号的选项都是可以缩写的﹐只要iptables仍可将之与其它可能的选项区分开来就行。如果您的核心以模块形式来支持iptables﹐您就需要首先加载ip_tables.o﹕`insmod ip_tables'。
这里﹐最重要的一个选项是表格选择选项﹕`-t'。对于所有的NAT操作﹐您会想用`-t nat'来表示NAT表格。第二个重要的选项是以`-A'增加一条新规则至链的末端(如﹕`-A POSTROUTING')﹐或以`-I'插入至前端(如﹕`-I PREROUTING')。
您可以指定您要做NAT的封包来源地址(`-s'或`--source')与目的地(`-d'or`--destination')。这两个选项后面可以后接一个单一的IP地址(如﹕192.168.1.1)﹐或一个名称(如﹕www.gnumonks.org)﹐或一个网 ... 0/255.255.255.0)。
您也可以指定要比对的传入(`-i'或`--in-interface')和传出(`-o' or `--out-interface')界面﹐但哪一个界面可以指定则取决于您要将规则写入哪一个链去﹕对于PREROUTING﹐您可以选择传入界面﹐但对于POSTROUTING(以及OUTPUT)﹐您可以选择传出界面。如果您不小心用错了﹐iptables就会给您一个错?nbsp;。
5.2关于挑选哪些封包来mangle的细节
我前面已经说过﹐您可以指定来源和目的地地址。如果您省略来源地址的选项﹐那么就泛指任何来源。如果您省略目的地地址﹐则泛指所有目的地地址。
您还可以指定一个特定协议(`-p' or `--protocol')呢﹐例如TCP或UDP﹕只有这些协议的封包?nbsp;符合该规则。其主要原因是﹐指定tcp或udp协议可以允许更多选项﹕尤其是`--source-port'与`--destination-port'选项(缩写为`--sport'与`--dport')。
这些选项可以让您指定只有哪些特定来源和目的地埠口的封包?nbsp;符合该规则。这在您要重导web请求(TCP port 80或8080)但又怕影响其它封包的时候﹐就很好用了。
这些选项必须接在`-p'选项的后面(这会在为该协定加载共享函式库时有副作用)。您可以使用端口口号码﹐或者是在/etc/services档中的名称。
所有这些您能选择的封包之不同?nbsp;质﹐都详细列在那个详细得有点恐怖的manual page中了(man iptables)。
6.谈谈要怎样Mangle封包
现在﹐我们知道如何去挑选那些我们要mangle的封包。为了要完善我们的规则﹐我们需要准确无?nbsp;的告诉核心﹐什么?nbsp;是我们要对封包做的。
6.1SourceNAT
您想要做Source NAT﹐是要去将联机的来源地址换成别的什么的。这就要在它最后要送出去之前﹐于POSTROUTING链中完成了﹔这是一个非常重要的细节﹐因为它意味着所有在Linux主机本身上的其它东西(routing,packet filtering)都只看见那个还没改变的封包。同时﹐这也就是说﹐`-o'(传出界面)选项可以派上用场了。
Source NAT是用`-j SNAT'来指定的﹐同时﹐`--to source'则指定一个IP地址﹑或一段IP地址﹑以及一个可配选的埠口或一段值域的埠口(仅适用于UDP和TCP协议)。
## 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
封包伪装(Masquerading)
有一个Source NAT之特例﹐叫做封包伪装﹕它只用于动态分配的IP地址﹐例如标准的拨接(如果用静态IP地址﹐则使用前述之SNAT)。
您无需明确地将masquerading放进来源地址那里去﹕它将会使用封包传出界面作为来源地址。但更重要的是﹐如果该连接(link)断掉的话﹐那么联机(connections﹐无可避免的将失掉)也会被忘掉﹐当联机用新的IP地址回来的时候就会有问题了。
## Masquerade everything out ppp0.
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
6.2 Destination NAT
一旦封包进入﹐会由PREROUTING链完成处理﹔也就是说﹐除了该主机自己的其它东西(诸如﹕路由﹑封包过滤)都将封包看成要送到`真正'目的地。另?nbsp;﹐那个`-i'(传入界面)选项也可以在这里使用。
需要修改本机产生的封包之目的地的话﹐那么OUTPUT链就可以用上了﹐不过这并不常碰到。
Destination NAT必须以`-j DNAT'来指定使用﹐同时用`--to destination'选项指定一个IP地址﹑或一段IP地址﹐以及可以配选一个埠口或一段埠口值域(只能用于UDP和TCP协定上面)。
## Change destination addresses to 5.6.7.8
# iptables -t nat -A PREROUTING -i eth1 -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 eth1 -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 eth1 -j DNAT --to 5.6.7.8:8080
## Redirect local packets to 1.2.3.4 to loopback.
# iptables -t nat -A OUTPUT -d 1.2.3.4 -j DNAT --to 127.0.0.1
重导向(Redirection)
在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 进一步的映对(Mappings)
还有许多 NAT 上面的解决方案是大多数人无需用到的。这里不妨和那些有兴趣的朋友探讨一下﹕
同一范围内的复合地址(Multiple Addresses)之选择。
如果您已经指定了一段 IP地址﹐而IP地址的使用选择是基于机器所知联机目前最少使用之IP。它可以提供最原始的平衡负载(load-balancing)。
建立空NAT映对
您可以使用`-j ACCEPT'目标来让一个联机通过﹐而绕过NAT的处理。
标准的NAT行为(Behaviour)
默认的行为是在用户制定的规则限制内﹐尽可能少的改变联机。换而言之﹐非不得已不要重映对(remap)埠口。
绝对来源埠口映对
如果其它联机已经被映对到新的联机﹐就算对于一个无需NAT的联机来说﹐来源埠口的转换有时或是必须绝对存在的。让我们假设一个封包伪装的情形﹐这已经非常普遍了﹕
1.一个网页联机由一台192.1.1.1的机器从port 1024建立﹐要连接到www.netscape.com port 80。
2.它被封包伪装主机以其自己的IP地址(1.2.3.4)进行伪装。
3.该封包伪装主机尝试由1.2.3.4(它的?nbsp;部界面地址)port 1024来做一个网页联机至www.netscape.com port 80。
4.然后NAT程序改变第二个联机的来源埠口为1025﹐所以这两个联机不至于相冲(clash)。
当这个绝对来源映对存在之时﹐埠口被拆分为三个等级﹕
512以下的埠口
512到1023之间的埠口
1024以上的埠口
任何一个埠口都不会被绝对映对到不同的等级去。
当NAT失效时会怎样﹖
如果没有办法如用户要求那样独一无二地映对联机﹐那么联机就会被挡掉。当一个封包不能够界定为任何联机的时候﹐结果也一样﹐因为它们可算是畸形的﹐或者是该机器内存耗光了﹐诸如此类。
复合映对﹑重迭﹑和相冲(clash)
您可以设定NAT规则在同一个范围之上映对封包﹔NAT程序足以聪明的去避免相冲。比方说﹐用两条规则将192.168.1.1和192.168.1.2这两个来源地址分别映对到1.2.3.4﹐是完全可行的。
再来﹐您可以映对到真实的﹑已用的IP地址﹐只要这些地址通过这个映对主机就行。所以﹐如果您获得一个网络(1.2.3.0/24)﹐但有一个内部网络使用这些地址﹐而另一个使用私有地址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主机自己使用的地址﹕这其实就是封包伪装如何工作的了(分享伪装封包地址和来自主机本身封包之`真实'地址。)
更甚者﹐您还可以映对相同的封包到许多不同的目标(targets)上去﹐而且它们都是共享的。例如﹐如果您不想映对任何东西到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
改变本机产生的联机之目的地
如果本机产生的封包之目的地改变了(例如﹐用 OUTPUT 链)﹐而这样会导致封包由不同的界面送出去﹐这样来源地址也跟着变为那个界面。举例子说﹐改变一个环回(loopback)封包之目的地由 eth0送出﹐会让来源地址也由127.0.0.1变成eth0的地址﹔而不像其它来源地址映对那样﹐这是立即完成的。当然﹐所有这些映对在响应封包进入时是颠倒过来的。
7.特殊协议
有些协定是并不想要做NAT的。对于每一个这样的协议而言﹐有两个延伸设定(extension)是必须要写清楚的:一个是关于协议之联机追踪﹐另一个关于实际的NAT。
在netfilter发行套件里面﹐有一些关于ftp的现行模块﹕ip_conntrack_ftp.o与ip_nat_ftp.o。如果您把这些插入到您的核心里面(或您永久性的编译它们)﹐那么要在ftp联机上做任何种类的NAT都是可行的。如果您不这样的话﹐那您可以使用被动模式ftp﹐不过如果您要做一些动作甚于简单Source NAT的话﹐这就可能不那么可靠了。
8.NAT的一些限制(caveats)
如果在一个联机上做NAT﹐所有双向(传出和传入)的封包﹐都必须要通过NAT主机?nbsp;行﹐否则并不可靠。尤其在联机追踪程序重组碎片(fragments)的时候﹐也就是说﹐不但联机追踪会不可能﹐而且您的封包根本就不能通过﹐因为碎片会被挡下。
9.Source NAT与路由
如果您要做SNAT﹐您会想要确定经过SNAT封包所传给的主机会将响应送回给NAT主机。例如﹐如果您映对某些传出封包到来源地址1.2.3.4之上﹐那么?nbsp;部的路由器就必须知道要将响应封包(目的地为1.2.3.4)送回给该主机。这可以用如下方法做到﹕
1.如果您要在主机自己的地址(路由和其它所有运作皆正常)上面做SNAT﹐您无需做任何动作。
2.如果您要在一个在本机网络上尚未使用的地址做SNAT(例如﹐映对到在1.2.3.0/24网络上的一个可用IP 1.2.3.99)﹐您的NAT主机就需要响应关于该地址的ARP请求﹐一如它自己本身的一样﹕最简单的方法就是建立IP alias﹐例如﹕
# ip address add 1.2.3.99 dev eth0
3.如果您要在一个完全不同的地址上做SNAT﹐您就要确定SNAT封包抵达的机器能够路由回该NAT主机。如果NAT主机是它们的默认网关的话﹐是可以做到的﹐否则﹐您就要广告(advertize)一个路由(如果跑路由协议的话)﹐或是手工的在每一台参与机器上增斥竷恁C
10.在同一网络上的Destination NAT
如果您要做portforwarding回到同一个网络﹐您要确定前向和响应封包双方都经过该NAT主机(这样它们?nbsp;能被修改)。NAT程序从现在开始(2.4.0-test6以后)﹐会挡掉后面情形所产生的传出ICMP重导向﹕那些已经NAT的封包以它所进入的相同界面传出﹐而接收端服务器仍尝试直接响应到客户端(不认可该响应)。
经典的情形是内部人员尝试连接到您的`公有(public)'网站服务器﹐实际上是从公有地址(1.2.3.4)DNAT到一个内部的机器(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服务器﹐它知道您的公有网站的真正(内部)IP地址﹐而将其它请求转传给?nbsp;部的DNS服务器。换而言之﹐关于您网站服务器的记录会正确地显示为内部IP地址。
而另一个方法是同时让这台NAT主机将该等联机之来源IP地址映对为它自己的地址﹐我们可以像如下那样做(假设NAT主机之内部IP地址为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规则是最先执行的﹐对内部网站服务器而言﹐封包就已经被定向好了﹕我们可以内定好哪个为来源IP地址。
11.感谢
首先感谢在我工作期间相信netfilter的构想并支持我的WatchGuard和David Bonn。
以及所有其他帮我指正NAT之不足的朋友﹐尤其是那些读过我的日记的。
Rusty.
-----------------------------------------------------------------------------------------------
编写完脚本后通过./iptables.sh进行启用。为了保证重启后能快速恢复,使用:
iptables-save > /root/ipt.save
cat /root/ipt.save | grep iptables-restore
测试TCP:通过内网和外网的扫描机进行TCP连接,nc -v x.x.x.x 5500,一个防火墙规定之外的端口,理论上是被drop,因为drop,所以不存在返回rst/ack,扫描端出现挂起状态。
测试UDP:使用hping -2 -p 5500 x.x.x.x,观察iptables的日志记录。
说明:在没有全部修改安全策略的情况下,针对单台设备的安全防护也是有必要的。
测试ICMP:hping -1 --icmptype echo-reply x.x.x.x
hping -1 --icmptype echo-reply x.x.x.x
配置了一个完整的初始化防火墙,第一章完。 |
|