Linux iptables 设置

一、概述

1. 什么是NAT

在传统的标准的TCP/IP通信过程中,所有的路由器仅仅是充当一个中间人的角色,也就是通常所说的存储转发,路由器并不会对转发的数据包进行修改,更为确切的说,除了将源MAC地址换成自己的MAC地址以外,路由器不会对转发的数据包做任何修改。NAT(Network Address Translation网络地址翻译)恰恰是出于某种特殊需要而对数据包的源ip地址、目的ip地址、源端口、目的端口进行改写的操作。

2. 为什么要进行NAT

我们来看看再什么情况下我们需要做NAT。
假设有一家ISP提供园区Internet接入服务,为了方便管理,该ISP分配给园区用户的IP地址都是伪IP,但是部分用户要求建立自己的WWW服务器对外发布信息,这时候我们就可以通过NAT来提供这种服务了。我们可以再防火墙的外部网卡上绑定多个合法IP地址,然后通过NAT技术使发给其中某一个IP地址的包转发至内部某一用户的WWW服务器上,然后再将该内部WWW服务器响应包伪装成该合法IP发出的包。
再比如使用拨号上网的网吧,因为只有一个合法的IP地址,必须采用某种手段让其他机器也可以上网,通常是采用代理服务器的方式,但是代理服务器,尤其是应用层代理服务器,只能支持有限的协议,如果过了一段时间后又有新的服务出来,则只能等待代理服务器支持该新应用的升级版本。如果采用NAT来解决这个问题,
因为只在应用层以下进行处理,不但可以获得很高的访问速度,而且可以无缝的支持任何新的服务或应用。
还有一个方面的应用就是重定向,也就是当接收到一个包后,不是转发这个包,而是将其重定向到系统上的某一个应用程序。最常见的应用就是和squid配合使用成为透明代理,在对http流量进行缓存的同时,可以提供对Internet的无缝访问。

3. NAT的类型

在linux2.4的NAT-HOWTO中,作者从原理的角度将NAT分成了两种类型,即源NAT(SNAT)和目的NAT(DNAT),顾名思义,所谓SNAT就是改变转发数据包的源地址,所谓DNAT就是改变转发数据包的目的地址。

二、原理

netfilter是Linux 核心中一个通用架构,它提供了一系列的”表”(tables),每个表由若干”链”(chains)组成,而每条链中可以有一条或数条规则(rule)组成。并且系统缺省的表是”filter”。但是在使用NAT的时候,我们所使用的表不再是”filter”,而是”nat”表,所以我们必须使用”-t nat”选项来显式地指明这一点。因为系统缺省的表是”filter”,所以在使用filter功能时,我们没有必要显式的指明”-t filter”。

同filter表一样,nat表也有三条缺省的”链”(chains),这三条链也是规则的容器,它们分别是:
PREROUTING:可以在这里定义进行目的NAT的规则,因为路由器进行路由时只检查数据包的目的ip地址,所以为了使数据包得以正确路由,我们必须在路由之前就进行目的NAT;
POSTROUTING:可以在这里定义进行源NAT的规则,系统在决定了数据包的路由以后在执行该链中的规则。
OUTPUT:定义对本地产生的数据包的目的NAT规则。

三、操作语法

如前所述,在使用iptables的NAT功能时,我们必须在每一条规则中使用”-t nat”显示的指明使用nat表。然后使用以下的选项:

1. 对规则的操作

加入(append) 一个新规则到一个链 (-A)的最后。

在链内某个位置插入(insert) 一个新规则(-I),通常是插在最前面。

在链内某个位置替换(replace) 一条规则 (-R)。

在链内某个位置删除(delete) 一条规则 (-D)。

删除(delete) 链内第一条规则 (-D)。

2. 指定源地址和目的地址

通过–source/–src/-s来指定源地址(这里的/表示或者的意思,下同),通过–destination/–dst/-d来指定目的地址。可以使用以下四中方法来指定ip地址:
a. 使用完整的域名,如“www.linuxaid.com.cn”;

b. 使用ip地址,如“192.168.1.1”;

c. 用x.x.x.x/x.x.x.x指定一个网络地址,如“192.168.1.0/255.255.255.0”;

d. 用x.x.x.x/x指定一个网络地址,如“192.168.1.0/24”这里的24表明了子网掩码的有效位数,这是 UNIX环境中通常使用的表示方法。

缺省的子网掩码数是32,也就是说指定192.168.1.1等效于192.168.1.1/32。

3. 指定网络接口

可以使用–in-interface/-i或–out-interface/-o来指定网络接口。从NAT的原理可以看出,对于PREROUTING链,我们只能用-i指定进来的网络接口;而对于POSTROUTING和OUTPUT我们只能用-o指定出去的网络接口。

4. 指定协议及端口

可以通过–protocol/-p选项来指定协议,如果是udp和tcp协议,还可–source-port/–sport和 –destination-port/–dport来指明端口。

详解:

建立规则和链
通过向防火墙提供有关对来自某个源、到某个目的地或具有特定协议类型的信息包要做些什么的指令,规则控制信息包的过滤。通过使用 netfilter/iptables 系统提供的特殊命令 iptables,建立这些规则,并将其添加到内核空间的特定信息包过滤表内的链中。关于添加/除去/编辑规则的命令的一般语法如下:

$ iptables [-t table] command [match] [target]

表(table)
[-t table] 选项允许使用标准表之外的任何表。表是包含仅处理特定类型信息包的规则和链的信息包过滤表。有三种可用的表选项:filter、nat 和 mangle。该选项不是必需的,如果未指定,则 filter 用作缺省表。

filter 表用于一般的信息包过滤,它包含 INPUT、OUTPUT 和 FORWARD 链。nat 表用于要转发的信息包,它包含 PREROUTING、OUTPUT 和 POSTROUTING 链。如果信息包及其头内进行了任何更改,则使用 mangle 表。该表包含一些规则来标记用于高级路由的信息包,该表包含 PREROUTING 和 OUTPUT 链。

注:PREROUTING 链由指定信息包一到达防火墙就改变它们的规则所组成,而 POSTROUTING 链由指定正当信息包打算离开防火墙时改变它们的规则所组成。

命令(command)
上面这条命令中具有强制性的 command 部分是 iptables 命令的最重要部分。它告诉 iptables 命令要做什么,例如,插入规则、将规则添加到链的末尾或删除规则。以下是最常用的一些命令:

-A 或 –append:该命令将一条规则附加到链的末尾。

示例:
$ iptables -A INPUT -s 205.168.0.1 -j ACCEPT

该示例命令将一条规则附加到 INPUT 链的末尾,确定来自源地址 205.168.0.1 的信息包可以 ACCEPT。

-D 或 –delete:通过用 -D 指定要匹配的规则或者指定规则在链中的位置编号,该命令从链中删除该规则。下面的示例显示了这两种方法。

示例:
$ iptables -D INPUT –dport 80 -j DROP

$ iptables -D OUTPUT 3

第一条命令从 INPUT 链删除规则,它指定 DROP 前往端口 80 的信息包。第二条命令只是从 OUTPUT 链删除编号为 3 的规则。

-P 或 –policy:该命令设置链的缺省目标,即策略。所有与链中任何规则都不匹配的信息包都将被强制使用此链的策略。

示例:
$ iptables -P INPUT DROP

该命令将 INPUT 链的缺省目标指定为 DROP。这意味着,将丢弃所有与 INPUT 链中任何规则都不匹配的信息包。

-N 或 –new-chain:用命令中所指定的名称创建一个新链。

示例:
$ iptables -N allowed-chain

-F 或 –flush:如果指定链名,该命令删除链中的所有规则,如果未指定链名,该命令删除所有链中的所有规则。此参数用于快速清除。

示例:
$ iptables -F FORWARD

$ iptables -F

-L 或 –list:列出指定链中的所有规则。

示例:
$ iptables -L allowed-chain

匹配(match)
iptables 命令的可选 match 部分指定信息包与规则匹配所应具有的特征(如源和目的地地址、协议等)。匹配分为两大类:通用匹配和特定于协议的匹配。这里,我将研究可用于采用任何协议的信息包的通用匹配。下面是一些重要的且常用的通用匹配及其示例和说明:

-p 或 –protocol:该通用协议匹配用于检查某些特定协议。协议示例有 TCP、UDP、ICMP、用逗号分隔的任何这三种协议的组合列表以及 ALL(用于所有协议)。ALL 是缺省匹配。可以使用 ! 符号,它表示不与该项匹配。

示例:
$ iptables -A INPUT -p TCP, UDP

$ iptables -A INPUT -p ! ICMP

在上述示例中,这两条命令都执行同一任务 — 它们指定所有 TCP 和 UDP 信息包都将与该规则匹配。通过指定 ! ICMP,我们打算允许所有其它协议(在这种情况下是 TCP 和 UDP),而将 ICMP 排除在外。

-s 或 –source:该源匹配用于根据信息包的源 IP 地址来与它们匹配。该匹配还允许对某一范围内的 IP 地址进行匹配,可以使用 ! 符号,表示不与该项匹配。缺省源匹配与所有 IP 地址匹配。

示例:
$ iptables -A OUTPUT -s 192.168.1.1

$ iptables -A OUTPUT -s 192.168.0.0/24

$ iptables -A OUTPUT -s ! 203.16.1.89

第二条命令指定该规则与所有来自 192.168.0.0 到 192.168.0.24 的 IP 地址范围的信息包匹配。第三条命令指定该规则将与除来自源地址 203.16.1.89 外的任何信息包匹配。

-d 或 –destination:该目的地匹配用于根据信息包的目的地 IP 地址来与它们匹配。该匹配还允许对某一范围内 IP 地址进行匹配,可以使用 ! 符号,表示不与该项匹配。

示例:
$ iptables -A INPUT -d 192.168.1.1

$ iptables -A INPUT -d 192.168.0.0/24

$ iptables -A OUTPUT -d ! 203.16.1.89

目标(target)
我们已经知道,目标是由规则指定的操作,对与那些规则匹配的信息包执行这些操作。除了允许用户定义的目标之外,还有许多可用的目标选项。下面是常用的一些目标及其示例和说明:

ACCEPT:当信息包与具有 ACCEPT 目标的规则完全匹配时,会被接受(允许它前往目的地),并且它将停止遍历链(虽然该信息包可能遍历另一个表中的其它链,并且有可能在那里被丢弃)。该目标被指定为 -j ACCEPT。

DROP:当信息包与具有 DROP 目标的规则完全匹配时,会阻塞该信息包,并且不对它做进一步处理。该目标被指定为 -j DROP。

REJECT:该目标的工作方式与 DROP 目标相同,但它比 DROP 好。和 DROP 不同,REJECT 不会在服务器和客户机上留下死套接字。另外,REJECT 将错误消息发回给信息包的发送方。该目标被指定为 -j REJECT。

示例:
$ iptables -A FORWARD -p TCP –dport 22 -j REJECT

RETURN:在规则中设置的 RETURN 目标让与该规则匹配的信息包停止遍历包含该规则的链。如果链是如 INPUT 之类的主链,则使用该链的缺省策略处理信息包。它被指定为 -jump RETURN。示例:

$ iptables -A FORWARD -d 203.16.1.89 -jump RETURN

还有许多用于建立高级规则的其它目标,如 LOG、REDIRECT、MARK、MIRROR 和 MASQUERADE 等。

保存规则
现在,您已经学习了如何建立基本的规则和链以及如何从信息包过滤表中添加或删除它们。但是,您应该记住:用上述方法所建立的规则会被保存到内核中,当重新引导系统时,会丢失这些规则。所以,如果您将没有错误的且有效的规则集添加到信息包过滤表,同时希望在重新引导之后再次使用这些规则,那么必须将该规则集保存在文件中。可以使用 iptables-save 命令来做到这一点:

$ iptables-save > iptables-script

现在,信息包过滤表中的所有规则都被保存在文件 iptables-script 中。无论何时再次引导系统,都可以使用 iptables-restore 命令将规则集从该脚本文件恢复到信息包过滤表,如下所示:

$ iptables-restore iptables-script

如果您愿意在每次引导系统时自动恢复该规则集,则可以将上面指定的这条命令放到任何一个初始化 shell 脚本中。

四、准备工作

1. 编译内核,编译时选中以下选项,具体可参看“用iptales实现包过虑型防火墙”一文:

Full NAT

MASQUERADE target support

REDIRECT target support

2. 要使用NAT表时,必须首先载入相关模块:

modprobe ip_tables

modprobe ip_nat_ftp

iptable_nat 模块会在运行时自动载入。

对RedHat Linux 8.0以上的版本,以上工作已经完成,不需要自己做了。

五、使用实例

1. 源NAT(SNAT)

比如,更改所有来自192.168.1.0/24的数据包的源ip地址为202.102.2.1:

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT –to
202.102.2.1

这里需要注意的是,系统在路由及过虑等处理直到数据包要被送出时才进行SNAT。

有一种SNAT的特殊情况是ip欺骗,也就是所谓的Masquerading,通常建议在使用拨号上网的时候使用,或者说在合法ip地址不固定的情况下使用。比如

# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

可以看出,这时候我们没有必要显式的指定源ip地址等信息。

2. 目的NAT(DNAT)

比如,更改来自192.168.1/24的数据包的目的ip地址为202.102.2.1:

iptables -t nat -A PREROUTING -s 192.168.1/24 -i eth1 -j DNAT –to 202.102.2.1

这里需要注意的是,系统是先进行DNAT,然后才进行路由及过虑等操作。

有一种DNAT的特殊情况是重定向,也就是所谓的Redirection,这时候就相当于将符合条件的数据包的目的ip地址改为数据包进入系统时的网络接口的ip地址。通常是在与squid配置形成透明代理时使用,假设squid的监听端口是3128,我们可以通过以下语句来将来自192.168.1.0/24,目的端口为80的数据包重定向到squid监听
端口:

iptables -t nat -A PREROUTING -i eth1 -p tcp -s 192.168.1.0/24 –dport 80

-j REDIRECT –to-port 3128

六、综合例子

1. 使用拨号带动局域网上网

小型企业、网吧等多使用拨号网络上网,通常可能使用代理,但是考虑到成本、对协议的支持等因素,建议使用ip欺骗方式带动区域网上网。

成功升级内核后安装iptables,然后执行以下脚本:

#载入相关模块
modprobe ip_tables

modprobe ip_nat_ftp

#启动路由转发:(*每次开机都要启动*)

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

#启动ip伪装:/etc/sysconfig/network中的
NETWORKING=yes
HOSTNAME=scisoftserver(*主机名*)
#以下三项需手工改动或添加
GATEWAY=255.255.255.0
#开机网络配置生效
ONBOOT=YES
#服务器支持路由转发
FORWARD_IPV4=yes

#进行ip伪装
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

2. ip映射

假设有一家ISP提供园区Internet接入服务,为了方便管理,该ISP分配给园区用户的IP地址都是伪IP,但是部分用户要求建立自己的WWW服务器对外发布信息。我们可以再防火墙的外部网卡上绑定多个合法IP地址,然后通过ip映射使发给其中某一个IP地址的包转发至内部某一用户的WWW服务器上,然后再将该内部WWW服务器响应包伪装成该合法IP发出的包。

我们假设以下情景:

该ISP分配给A单位www服务器的ip为:
伪ip:192.168.1.100
真实ip:202.110.123.100

该ISP分配给B单位www服务器的ip为:
伪ip:192.168.1.200
真实ip:202.110.123.200

linux防火墙的ip地址分别为:
内网接口eth1:192.168.1.1
外网接口eth0:202.110.123.1

然后我们将分配给A、B单位的真实ip绑定到防火墙的外网接口,以root权限执行以下命令:

ifconfig eth0 add 202.110.123.100 netmask 255.255.255.0

ifconfig eth0 add 202.110.123.200 netmask 255.255.255.0

成功升级内核后安装iptables,然后执行以下脚本:

#载入相关模块
modprobe ip_tables

modprobe ip_nat_ftp

首先,对防火墙接收到的目的ip为202.110.123.100和202.110.123.200的所有数据包进行目的NAT(DNAT):

iptables -t nat -A PREROUTING -i eth0 -d 202.110.123.100 -j DNAT –to 192.168.1.100

iptables -t nat -A PREROUTING -i eth0 -d 202.110.123.200 -j DNAT –to 192.168.1.200

其次,对防火墙接收到的源ip地址为192.168.1.100和192.168.1.200的数据包进行源NAT(SNAT):

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.100 -j SNAT –to 202.110.123.100

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.200 -j SNAT –to 202.110.123.200

这样,所有目的ip为202.110.123.100和202.110.123.200的数据包都将分别被转发给192.168.1.100和192.168.1.200;而所有来自192.168.1.100和192.168.1.200的数据包都将分别被伪装成由202.110.123.100和202.110.123.200,从而也就实现了ip映射。

七、安装ipp2p限制p2p软件

下载ipp2p-0.8.0.tar.gz

修改 Makefile 文件中 “IPTABLES_SRC = /usr/src/iptables-1.2.9”
为iptables源文件目录

make

复制 libipt_ipp2p.so 到 iptables lib 目录 (/lib/iptables/)
复制 ipt_ipp2p.o 或 ipt_ipp2p.ko 到 kernel modules 目录

depmod -a

这样ipp2p就安装完成了

iptables -m ipp2p –help 查看使用说明

八、限制客户线程数

iptables -I FORWARD -p tcp -s 192.168.0.18 -m connlimit –connlimit-above 100 –connlimit-mask 32 -j REJECT

–connlimit-above 指定线程数 –connlimit-mask 指定IP的mask 当32时就是对单个IP限制。

附:iptables处理流程图

“>

Comments are closed.