您的位置:首页 > 运维架构 > Linux

Linux -- 系统安全之Iptables防火墙(2)

2014-09-19 11:29 525 查看
一、iptables防水墙的实现方式及iptables命令的格式

iptables防火墙介绍netfilter/iptables是Linux系统提供的一个非常优秀的防火墙工具,它完全免费、功能强大、使用灵活、占用系统资源少,可以对经过的数据进行非常细致的控制。本节首先介绍有关iptables防火墙的基本知识,包括netfilter框架、iptables防火墙结构与原理、iptables命令格式等内容。
netfilter框架Linux内核包含了一个强大的网络子系统,名为netfilter,它可以为iptables内核防火墙模块提供有状态或无状态的包过滤服务,如NAT、IP伪装等,也可以因高级路由或连接状态管理的需要而修改IP头信息。netfilter位于Linux网络层和防火墙内核模块之间,如图9-1所示。


虽然防火墙模块构建在Linux内核,并且要对流经IP层的数据包进行处理,但它并没有改变IP协议栈的代码,而是通过netfilter模块将防火墙的功能引入IP层,从而实现防火墙代码和IP协议栈代码的完全分离。netfilter模块的结构如图9-2所示。



对IPv4协议来说,netfilter在IP数据包处理流程的5个关键位置定义了5个钩子(hook)函数。当数据包流经这些关键位置时,相应的钩子函数就被调用。从图9-2中可以看到,数据包从左边进入IP协议栈,进行IP校验以后,数据包被第一个钩子函数PRE_ROUTING处理,然后就进入路由模块,由其决定该数据包是转发出去还是送给本机。若该数据包是送给本机的,则要经过钩子函数LOCAL_IN处理后传递给本机的上层协议;若该数据包应该被转发,则它将被钩子函数FORWARD处理,然后还要经钩子函数POST_ROUTING处理后才能传输到网络。本机进程产生的数据包要先经过钩子函数LOCAL_OUT处理后,再进行路由选择处理,然后经过钩子函数POST_ROUTING处理后再发送到网络。说明:内核模块可以将自己的函数注册到钩子函数中,每当有数据包经过该钩子点时,钩子函数就会按照优先级依次调用这些注册的函数,从而可以使其他内核模块参与对数据包的处理。这些处理可以是包过滤、NAT以及用户自定义的一些功能。

iptables防火墙内核模块netfilter框架为内核模块参与IP层数据包处理提供了很大的方便,内核的防火墙模块正是通过把自己的函数注册到netfilter的钩子函数这种方式介入了对数据包的处理。这些函数的功能非常强大,按照功能来分的话主要有4种,包括连接跟踪、数据包过滤、网络地址转换(NAT)和对数据包进行修改。其中,NAT还分为SNAT和DNAT,分别表示源网络地址转换和目的网络地址转换,内核防火墙模块函数的具体分布情况如图9-3所示。由图9-3可以看出,防火墙模块在netfilter的LOCAL_IN、FORWARD和LOCAL_OUT 3个位置分别注册了数据包过滤函数,数据包经过这些位置时,防火墙模块要对数据包进行过滤。这三个位置也称为三条链,名称分别为INPUT、FORWARD和OUTPUT,它们共同组成了一张过滤表,每条链可以包含各种规则,每一条规则都包含0个或多个匹配以及一个动作。当数据包满足所有的匹配时,则过滤函数将执行设定的动作,以便对数据包进行过滤的。


注意:这些规则的次序是很重要的,过滤函数对数据包执行了某一规则动作后,对数据包的处理即告结束,即使这个数据包还满足后面其他规则的所有匹配,也不会执行那些规则所设定的动作。从图9-3中可以看出,除了过滤表以外,在PRE_ROUTING、LOCAL_OUT和POST_ ROUTING 3个位置各有一条有关NAT的链,名称分别为PREROUTING、OUTPUT和POSTROUTING,它们组成了NAT表。NAT链里面也可以包含各种规则,它指出了如何对数据包的地址进行转换。此外,5个钩子函数位置的mangle链还组成了一张mangle表,这个表的主要功能是根据规则修改数据包的一些标志位,例如TTL、TOS等,也可以在内核空间为数据包设置一些标志。防火墙内的其他规则或程序(如tc等)可以利用这种标志对数据包进行过滤或高级路由。以上介绍的是iptables防火墙的内部结构,Linux系统还提供了iptables防火墙的用户接口,它可以在上述各张表所包含的链中添加规则,或者修改、删除规则,从而可以根据需要构建自己的防火墙。具体来说,用户是通过输入iptables命令来实现上述功能的。
iptables命令格式

在RHEL 5中,iptables命令由iptables-1.3.5-1.2.1软件包提供,默认时,系统已经安装了该软件包,因此,用户可以直接输入iptables命令对防火墙中的规则进行管理。iptables命令相当复杂,具体格式如下所示。
iptables [-t 表名] <命令> [链名] [规则号] [规则] [-j 目标]
-t选项用于指定所使用的表,iptables防火墙默认有filter、nat和mangle 3张表,也可以是用户自定义的表。表中包含了分布在各个位置的链,iptables命令所管理的规则就是存在于各种链中的。该选项不是必需的,如果未指定一个具体的表,则默认使用的是filter表。命令选项是必须要有的,它告诉iptables要做什么事情,是添加规则、修改规则还是删除规则。有些命令选项后面要指定具体的链名称,而有些可以省略,此时,是对所有的链进行操作。还有一些命令要指定规则号。具体的命令选项名称及其与后续选项的搭配形式如下所示。
iptables命令格式中的规则部分由很多选项构成,主要指定一些IP数据包的特征。例如,上一层的协议名称、源IP地址、目的IP地址、进出的网络接口名称等,下面列出构成规则的常见选项。-p<协议类型>:指定上一层协议,可以是icmp、tcp、udp和all。-s<IP地址/掩码>:指定源IP地址或子网。-d<IP地址/掩码>:指定目的IP地址或子网。-i<网络接口>:指定数据包进入的网络接口名称。-o<网络接口>:指定数据包出去的网络接口名称。注意:上述选项可以进行组合,每一种选项后面的参数前可以加"!",表示取反。对于-p选项来说,确定了协议名称后,还可以有进一步的子选项,以指定更细的数据包特征。常见的子选项如下所示。-p tcp --sport <port>:指定TCP数据包的源端口。-p tcp --dport <port>:指定TCP数据包的目的端口。-p tcp --syn:具有SYN标志的TCP数据包,该数据包要发起一个新的TCP连接。-p udp --sport <port>:指定UDP数据包的源端口。-p udp --dport <port>:指定UDP数据包的目的端口。-p icmp --icmp-type <type>:指定icmp数据包的类型,可以是echo-reply、echo-request等。上述选项中,port可以是单个端口号,也可以是以port1:port2表示的端口范围。每一选项后的参数可以加"!",表示取反。上面介绍的这些规则选项都是iptables内置的,iptables软件包还提供了一套扩展的规则选项。使用时需要通过-m选项指定模块的名称,再使用该模块提供的选项。
最后,iptables命令中的-j选项可以对满足规则的数据包执行指定的操作,其后的"目标"可以是以下内容。-j ACCEPT:将与规则匹配的数据包放行,并且该数据包将不再与其他规则匹配,而是跳向下一条链继续处理。-j REJECT:拒绝所匹配的数据包,并向该数据包的发送者回复一个ICMP错误通知。该处理动作完成后,数据包将不再与其他规则匹配,而且也不跳向下一条链。-j DROP:丢弃所匹配的数据包,不回复错误通知。该处理动作完成后,数据包将不再与其他规则匹配,而且也不跳向下一条链。-j REDIRECT:将匹配的数据包重定向到另一个位置,该动作完成后,会继续与其他规则进行匹配。-j LOG:将与规则匹配的数据包的相关信息记录在日志(/var/log/message)中,并继续与其他规则匹配。-j <规则链名称>:数据包将会传递到另一规则链,并与该链中的规则进行匹配。除了上述目标动作外,还有一些与NAT有关的目标,将在9.4节中讲述。所有的目标也可以通过查看iptables命令的手册页获得。

二、用iptables命令配置主机防火墙、网络防火墙
iptables主机防火墙主机防火墙主要用于保护防火墙所在的主机免受外界的攻击,当一台服务器为外界提供比较重要的服务,或者一台客户机在不安全的网络环境中使用时,都需要在计算机上安装防火墙。本节主要介绍iptables主机防火墙规则的配置,包括iptables防火墙的运行与管理、RHEL 5默认防火墙规则的解释、用户根据需要添加自己的防火墙规则等内容。9.2.1 iptables防火墙的运行与管理RHEL 5默认安装时,已经在系统中安装了iptables软件包,可以用以下命令查看。
[root@localhost ~]# rpm -qa | grep iptables  iptables-1.3.5-1.2.1  iptables-ipv6-1.3.5-1.2.1  #
一般情况下,iptable开机时都已经默认运行,但与其他一些服务不同,iptables的功能是管理内核中的防火墙规则,不需要常驻内存的进程。如果对防火墙的配置做了修改,并且想保存已经配置的iptables规则,可以使用以下命令。
# /etc/rc.d/init.d/iptables save
此时,所有正在使用的防火墙规则将保存到/etc/sysconfig/iptables文件中,可以用以下命令查看该文件的内容。
# more /etc/sysconfig/iptables

# Generated by iptables-save v1.3.5 on Fri Jan 16 14:58:31 2009

*filter

:INPUT ACCEPT [0:0]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [2237:2371316]

:RH-Firewall-1-INPUT - [0:0]

-A INPUT -j RH-Firewall-1-INPUT

-A FORWARD -j RH-Firewall-1-INPUT

-A RH-Firewall-1-INPUT -i lo -j ACCEPT

-A RH-Firewall-1-INPUT -p icmp -m icmp --icmp-type any -j ACCEPT

-A RH-Firewall-1-INPUT -p esp -j ACCEPT

-A RH-Firewall-1-INPUT -p ah -j ACCEPT

-A RH-Firewall-1-INPUT -d 224.0.0.251 -p udp -m udp --dport 5353 -j ACCEPT

-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT

-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT

-A RH-Firewall-1-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

-A RH-Firewall-1-INPUT -p tcp -m state --state NEW
-m tcp --dport 21 -j ACCEPT

-A RH-Firewall-1-INPUT -p tcp -m state --state NEW
-m tcp --dport 22 -j ACCEPT

-A RH-Firewall-1-INPUT -p tcp -m state --state NEW
-m tcp --dport 80 -j ACCEPT

-A RH-Firewall-1-INPUT -p tcp -m state --state NEW
-m tcp --dport 25 -j ACCEPT

-A RH-Firewall-1-INPUT -p tcp -m state --state NEW
-m tcp --dport 808 -j ACCEPT

-A RH-Firewall-1-INPUT -p tcp -m state --state NEW
-m tcp --dport 8080 -j ACCEPT

可以看到,/etc/sysconfig/iptables文件中包含了一些iptables规则,这些规则的形式与iptables命令类似,但也有区别。注意:一般不建议用户手工修改这个文件的内容,这个文件只用于保存启动iptables时,需要自动应用的防火墙规则。可以看到,/etc/sysconfig/iptables文件中包含了一些iptables规则,这些规则的形式与iptables命令类似,但也有区别。注意:一般不建议用户手工修改这个文件的内容,这个文件只用于保存启动iptables时,需要自动应用的防火墙规则。以上看到的实际上是默认安装RHEL 5时该文件中的内容,其所确定的规则的解释见9.2.2小节。还有一种保存iptables规则的方法是使用iptables-save命令,格式如下:
# iptables-save > abc
此时,正在使用的防火墙规则将保存到abc文件中。如果希望再次运行iptables,可以使用以下命令。
# /etc/rc.d/init.d/iptables start
上述命令实际上是清空防火墙所有规则后,再按/etc/sysconfig/iptables文件的内容重新设定防火墙规则。还有一种复原防火墙规则的命令如下:
# iptables-restore < abc
此时,由iptables-save命令保存在abc文件中的规则将重新载入到防火墙中。如果使用以下命令,将停止iptables的运行。
# /etc/rc.d/init.d/iptables stop

RHEL 5开机时默认的防火墙规则在Linux系统中,可以通过使用iptables命令构建各种类型的防火墙。RHEL 5操作系统默认安装时,iptables防火墙已经安装,并且开机后会自动添加了一些规则,这些规则实际上是由/etc/sysconfig目录中的iptables文件决定的。可以通过"iptables -L"命令查看这些默认添加的规则。
# iptables -L

Chain INPUT (policy ACCEPT) #INPUT链中的规则

target prot opt source destination

RH-Firewall-1-INPUT all -- anywhere anywhere #规则1

Chain FORWARD (policy ACCEPT) # FORWARD链中的规则

target prot opt source destination

RH-Firewall-1-INPUT all -- anywhere anywhere #规则2

Chain OUTPUT (policy ACCEPT) # OUTPUT链中的规则

target prot opt source destination

Chain RH-Firewall-1-INPUT (2 references) #自定义的
RH-Firewall-1-INPUT链

中的规则,
被其他链引用两次

target prot opt source destination

ACCEPT all -- anywhere anywhere
#规则3

ACCEPT icmp -- anywhere anywhere
icmp any #规则4

ACCEPT esp -- anywhere anywhere
#规则5

ACCEPT ah -- anywhere anywhere
#规则6

ACCEPT udp -- anywhere 224.0.0.251
udp dpt:mdns #规则7

ACCEPT udp -- anywhere anywhere
udp dpt:ipp #规则8

ACCEPT tcp -- anywhere anywhere
tcp dpt:ipp #规则9

ACCEPT all -- anywhere anywhere state RELATED,
ESTABLISHED #规则10

ACCEPT tcp -- anywhere anywhere state NEW
tcp dpt:ftp #规则11

ACCEPT tcp -- anywhere anywhere state NEW
tcp dpt:ssh #规则12

ACCEPT tcp -- anywhere anywhere state NEW
tcp dpt:http #规则13

ACCEPT tcp -- anywhere anywhere state NEW
tcp dpt:smtp #规则14

REJECT all -- anywhere anywhere
reject-with icmp-host-

prohibited #规则15

#

由于上面的iptables命令没有用-t选项指明哪一张表,也没有指明是哪一条链,因此默认列出的是filter表中的规则链。由以上结果可以看出,filter表中总共有4条链。其中,INPUT、FORWARD和OUTPUT链是内置的,而RH-Firewall-1-INPUT链是用户自己添加的。1.规则列在前面列出的防水墙规则中,每一条规则列出了5项内容。target列表示规则的动作目标。prot列表示该规则指定的上层协议名称,all表示所有的协议。opt列出了规则的一些选项。source列表示数据包的源IP地址或子网,而destination列表示数据包的目的IP地址或子网,anywhere表示所有的地址。除了上述5列以外,如果存在,每一条规则的最后还要列出一些子选项,如RH-Firewall-1-INPUT链中的规则4等。如果执行iptables命令时加了-v选项,则还可以列出每一条规则当前匹配的数据包数、字节数,以及要求数据包进来和出去的网络接口。如果加上-n选项,则不对显示结果中的IP地址和端口做名称解析,直接以数字的形式显示。还有,如果加上"--line-number"选项,可以在第一列显示每条规则的规则号。2.规则解释INPUT链中的规则1其target列的内容是RH-Firewall-1-INPUT,opt列是all,source和destination列均为anywhere,表示所有的数据包都交给自定义的RH-Firewall-1-INPUT链去处理。FORWARD链的规则2与规则1完全一样。OUTPUT链中没有规则。在自定义的RH-Firewall-1-INPUT链中,列出了很多的规则,规则3表示接收所有的数据包。需要注意的是,如果在iptables中加-v选项列出这条规则时,将会看到in列是lo,即要求数据包是从环回接口中进来的,而不是任意网络接口进来的数据包都接收。规则4表示所有icmp数据包都接收,即其他计算机ping本机时,予以接收,而且在OUTPUT链中没有规则,因此本机的ICMP回复数据包也能顺利地进入网络,被对方收到。规则5和规则6表示接收所有的esp和ah协议的数据包,这两种协议属于IPv6协议。规则7表示目的地址是224.0.0.251,目的端口是mdns的UDP数据包允许通过。224.0.0.251是一种组播地址,mdns是端口号的一种名称。如果执行iptables命令时加了-n选项,则会显示数字5353,它是组播地址的DNS端口。规则8和规则9表示允许所有目的端口是ipp的UDP和TCP数据包通过,ipp是端口631的名称解析,它是用于网络打印服务的端口。规则10表示所有状态是RELATED和ESTABLISHED的数据包通过,RELATED状态表示数据包要新建一个连接,而且这个要新建的连接与现存的连接是相关的,如FTP的数据连接。ESTABLISHED表示本机与对方建立连接时,对方回应的数据包。规则11至规则14表示允许目的端口是ftp、ssh、http和smtp,状态是NEW的TCP数据包通过,状态为NEW即意味着这个TCP数据包将与主机发起一个TCP连接。这几条规则的端口对应的都是最常见的网络服务,它们的端口号分别是21、22、80和25。最后一条规则15表示拒绝所有的数据包,并向对方回应icmp-host-prohibited数据包。3.补充解释需要再次提醒的是,这些规则是有次序的。当一个数据包进入RH-Firewall-1-INPUT链后,将依次与规则3至规则15进行比较。按照这些规则的目标设置,如果数据包能与规则3至14中的任一条匹配,则该数据包将被接收。如果都不能匹配,则肯定能和规则15匹配,于是数据包被拒绝。由于RH-Firewall-1-INPUT链是被INPUT链调用的,如果要返回到INPUT链,需要执行名为RETURN的目标动作。说明:在FORWARD链中也调用了RH-Firewall-1-INPUT链,即数据包如果不是发送给本机的,当经过FORWARD链时,还要进入RH-Firewall-1-INPUT链,与规则3到规则15再次进行匹配。
管理主机防火墙规则可以有很多功能种类的防火墙,有些是安装在某一台主机上,主要用于保护主机本身的安全;有些是安装在网络中的某一节点,专门用于保护网络中其他计算机的安全;也有一些可以为内网的客户机提供NAT服务,使内网的客户机共用一个公网IP,以便节省IP地址资源。下面首先介绍一下主机防火墙的应用示例。当一台服务器为外界提供比较重要的服务,或者一台客户机在不安全的网络环境中使用时,都需要在计算机上安装防火墙,以最大限度地防止主机受到外界的攻击。9.2.2小节介绍的开机时默认的防火墙设置非常典型,用户可以根据自己主机的功能关闭已经开放的端口,或者开放更多的端口,以便允许符合更多规则的数据包通过。例如,为了使主机能为外界提供telnet服务,除了配置好telnet服务器外,还需要开放TCP23号端口。因为在默认的防火墙配置中,并不允许目的端口为23的TCP数据包进入主机。为了开放TCP23号端口,可以有两种办法,一种是在RH-Firewall-1-INPUT链中加入相应的规则,还有一种是把规则加到INPUT链中。但需要注意的是,规则是有次序的,如果使用以下命令,则是没有效果的。
# iptables -A RH-Firewall-1-INPUT -p tcp --dport 23 -j ACCEPT
上述命令执行后,可以再次查看规则情况。
# iptables -L -n --line-number



Chain RH-Firewall-1-INPUT (2 references)

num target prot opt source destination



11 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0
state NEW tcp dpt:80

12 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0
state NEW tcp dpt:25

13 REJECT all -- 0.0.0.0/0 0.0.0.0/0
reject-with icmp-host-

prohibited

14 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0
tcp dpt:23

# 新添加的规则

#

可以看到,新添加的规则位于最后的位置。由于所有的数据包都可以与目标动作为REJECT的规则号为13的规则匹配,而REJECT代表的是拒绝,因此数据包到达新添加的规则前肯定已被丢弃,这条规则是不会被使用的。为了解决这个问题,需要把上述规则插入到现有的规则中,要位于规则13的前面。下面是正确的开放TCP23号端口的命令。
# iptables -I RH-Firewall-1-INPUT 11 -p tcp --dport 23 -j ACCEPT
以上命令中,"-I RH-Firewall-1-INPUT 11"表示在RH-Firewall-1-INPUT链原来的规则11前面插入一条新规则,规则内容是接受目的端口为23的TCP数据包。为了删除前面添加的无效规则,可以执行以下命令。
# iptables -D RH-Firewall-1-INPUT 15
15是第一次添加的那条无效规则此时的规则号,也可能是其他的数值,可根据具体显示结果加以改变。如果希望新加的规则与原来的规则11、12等类似,可以执行以下命令。
# iptables -I RH-Firewall-1-INPUT 11 -m state
--state NEW -p tcp --dport 23 -j ACCEPT

以上是在RH-Firewall-1-INPUT链中添加规则,以开放TCP23号端口。还有一种开放TCP23号端口的方法是在INPUT链中添加规则,具体命令如下所示。
# iptables -I INPUT 1 -p tcp --dport 23 -j ACCEPT

# iptables -L --line-number

Chain INPUT (policy ACCEPT)

num target prot opt source destination

1 ACCEPT tcp -- anywhere
anywhere tcp dpt:telnet

2 RH-Firewall-1-INPUT all -- anywhere anywhere



注意:添加的规则也要位于原来规则2的前面,否则,任何数据包都匹配规则2,将会跳到RH-Firewall-1-INPUT链,并且不再回来。因此,添加在规则2后面的规则都是无效的。前面介绍的是在RHEL5默认防火墙规则的基础上添加用户自己的防火墙规则,以开放TCP23号端口。在很多的时候,用户可能希望从最初的状态开始,构建自己的防火墙。为了从零开始设置iptables防火墙,可以用以下命令清空防火墙中所有的规则。
# iptables -F
然后再根据要求,添加自己的防火墙规则。一般情况下,保护防火墙所在主机的规则都添加在INPUT内置链中,以挡住外界访问本机的部分数据包。本机向外发送的数据包只经过OUTPUT链,一般不予限制。如果不希望本机为外界数据包提供路由转发功能,可以在FORWARD链中添加一条拒绝一切数据包通过的规则,或者干脆在内核中设置不转发任何数据包。常用的主机防火墙规则当设置主机防火墙时,一般采取先放行,最后全部禁止的方法。也就是说,根据主机的特点,规划出允许进入主机的外界数据包,然后设计规则放行这些数据包。如果某一数据包与放行数据包的规则都不匹配,则与最后一条禁止访问的规则匹配,被拒绝进入主机。下面列出一些主机防火墙中常用的iptables命令及其解释,这些命令添加的规则都放在filter表的INPUT链中。示例1:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
功能:允许目的端口为80的TCP数据包通过INPUT链。说明:这种数据包一般是用来访问主机的Web服务,如果主机以默认的端口提供Web服务,应该用这条规则开放TCP80端口。
使用图形界面管理主机防火墙规则为了使初学者也能构建iptables主机防火墙,在RHEL 5中,还为用户提供了配置主机防火墙的图形界面。在RHEL 5桌面环境下,选择"系统"|"管理"|"安全级别和防火墙"命令后,将出现图9-4所示的对话框。在图9-4中,名为"信任的服务"的列表框中列出了常见的网络服务名称,前面打勾的服务所对应的网络端口是开放的,允许外界的用户访问。如果用户需要开放更多的端口,可以在列出的服务名称前的框内单击鼠标,打上勾后再单击"应用"按钮即可。此外,窗口中还提供了启用或禁用防水墙的选择菜单,如图9-5所示。还有,如果在图9-4中单击了"其他端口"标签,将在下面出现如图9-5所示的一个列表框和"添加"、"删除"按钮,用于添加和删除"信任的服务"列表框中未列出的端口。






在图9-5中,如果单击"添加"按钮,将出现图9-6所示的对话框。此时,可以输入需要开放的端口号,并选择TCP或UDP协议,然后单击"确定"按钮,将返回到图9-5所示的防火墙设置对话框,然后在"其他端口"列表框中将出现所添加的端口号和协议名称。单击"删除"按钮可以删除列表框中选中的端口。为了使添加或删除端口生效,需要单击图9-5中的"应用"按钮,此时将出现图9-7所示的对话框,要求用户确认该操作。





以上是通过图形界面管理主机防火墙规则,实际的结果和命令方式是一样的。例如,如果刚才在图9-6所示的窗口中输入8080端口并选择TCP协议,然后再到终端查看防火墙中的规则时,将会发现如下结果。

[root@localhost sysconfig]# iptables -L --line-number  …  11   ACCEPT     tcp  --  anywhere     anywhere   state NEW tcp dpt:http   12   ACCEPT     tcp  --  anywhere     anywhere   state NEW tcp dpt:smtp   13   ACCEPT     tcp  --  anywhere     anywhere   state NEW tcp dpt:webcache   14   REJECT   all  --  anywhere   anywhere  reject-with icmp-host-   prohibited   #
从以上结果可以看出,与初始的设置相比,规则13原来是没有的,它是刚才通过图形界面操作后添加的。也就是说,刚才的图形界面操作相当于输入了以下命令。
iptables -I RH-Firewall-1-INPUT 13 -m state -
-state NEW -m tcp -p tcp --dport 8080 -j ACCEPT

说明:实际上,RHEL5提供的防火墙图形界面管理功能非常有限,远不如命令方式功能丰富。

iptables网络防火墙配置与主机防火墙不一样,网络防火墙主要用于保护内部网络的安全,此时,一般由一台专门的主机承担防火墙角色,有时还要承担网络地址转换(NAT)的功能,其配置要比主机防火墙复杂。本节主要讲述有关网络防火墙的过滤配置,以及通过给数据包做标志的方法进行策略路由的例子。
保护服务器子网的防火墙规则与主机防火墙不一样,保护网络的防火墙一般有多个网络接口,而且绝大部分的规则应该添加在filter表的FORWARD链中,其配置要比主机防火墙复杂得多。为了使iptables承担网络防火墙的角色,首先要确保Linux能够在各个网络接口之间转发数据包,其方法是输入以下命令,使ip_forward文件的内容为1。
echo "1">/proc/sys/net/ipv4/ip_forward
上述命令的结果在系统重启后会失效。为了使系统在每次开机后能自动激活IP数据包转发功能,需要编辑配置文件/etc/sysctl.conf,它是RHEL 5的内核参数配置文件,其中包含了ip_forward参数的配置。具体方法是确保在/etc/sysctl.conf文件中有以下一行:
net.ipv4.ip_forward = 1
即原来的值如果是0的,现把它改为1。然后执行以下命令使之生效:
# sysctl -p
上述命令的功能是实时修改内核运行时的参数。IP数据包转发功能激活后,就可以设置网络防火墙规则了。下面以图9-8所示的网络结构为例,介绍iptables网络防火墙的配置方法。在图9-8中,安装了iptables的Linux主机安装了3块网卡。其中,eth0的IP地址是192.168.0.1,它通过一台网关设备与Internet连接;eth1的IP地址是10.10.1.1,它与子网10.10.1.0/24连接;eth2的IP地址是10.10.2.1,它连接的子网是10.10.2.0/24。


现假设10.10.1.0/24子网里运行的是为外界提供网络服务的服务器,而10.10.2.0/24子网里的计算机是用户上网用的客户机。对于服务器来说,它向外提供服务的端口号是固定的,为了保证其安全,应该只开放这些端口,即只允许目的端口是这些端口的数据包进入服务器子网,其余的数据包一律禁止。下面是一些在防火墙上执行的保护服务器子网的iptables命令。

iptables -A FORWARD -p tcp --dport 22 -i eth0 -o eth1 -j ACCEPT  iptables -A FORWARD -p tcp --dport 25 -i eth0 -o eth1 -j ACCEPT  iptables -A FORWARD -p udp --dport 53 -i eth0 -o eth1 -j ACCEPT  iptables -A FORWARD -p tcp --dport 80 -i eth0 -o eth1 -j ACCEPT
假设服务器子网采用默认端口为外界提供了SSH、SMTP、DNS和HTTP服务,以上4条命令在filter表的FORWARD链中加入了4条规则,允许从eth0网进入、到eth1网卡,并且协议和目的端口分别是TCP22、TCP25、UDP53和TCP80的数据包通过,这些协议和端口对应了该子网提供的网络服务。以上4条命令确定了从eth0到eth1转发数据包的规则。这些数据包是进入服务器子网的数据包,而从服务器子网出去的数据包目前还是畅通无阻的,因为FORWARD链中还没有规则对eth1到eth0的数据包做任何限制。需要注意的是,前面的规则规定了放行哪些数据包后,最后必须要有一条规则拒绝所有的数据包。否则,即使数据包与前面所有的规则都不匹配,最后也照样能被转发。因此,为了达到保护服务器子网的目的,还需要执行以下命令。
iptables -A FORWARD -i eth0 -o eth1 -j DROP
以上命令把从网卡eth0到eth1的数据包全部丢弃,当然,这些数据包是那些与前面的规则都不匹配的数据包。此外,也可以用以下命令指定FORWARD链的默认目标动作来代替上述命令。
iptables -P FORWARD DROP
上面命令的意思是与所有规则都不匹配的数据包将采用DROP目标动作予以丢弃,对于只保护服务器子网的防火墙来说,可以这样做。注意:由于图9-8的网络结构中还要为10.10.2.0/24子网的客户机提供上网服务。如果设定默认目标动作为DROP,需要添加明确的规则放行该子网的数据包。另外,如果发现某些计算机,如IP为11.22.33.44的计算机对服务器子网有攻击行为,防火墙可以不转发这些数据,把它阻挡在防火墙的外面,命令如下:
iptables -A FORWARD -i eth0 -o eth1 -s 11.22.33.44 -j DROP
或者如果发现服务器子网发往某一台主机,如55.66.77.88的数据流量特别大,出现了异常情况,可以执行以下命令,限制其流量。此时,数据流向应该是从eth1到eth0。
iptables -A FORWARD -i eth1 -o eth0 -d 55.66.
77.88 -m limit --limit 60/m --limit-burst 80 -j ACCEPT

网卡eth0收到的是来自Internet的数据包,因此,对它们作了严格的限制。但对于来自10.10.2.0/24子网的数据包来说,其限制应该相对宽松,因为它是内网。下面是几条有关内网到服务器子网的转发规则的设置命令。
iptables -A FORWARD -i eth2 -o eth1 -m multiport --dport 1:1024,2049,32768 -j ACCEPT  iptables -A FORWARD -i eth2 -o eth1 -s 10.10.2.2 -j ACCEPT  iptables -A FORWARD -i eth2 -o eth1 -s 10.10.2.3 -j ACCEPT
上面的第一条命令允许来自eth2网卡的数据包转发到服务器子网eth1网卡,前提是数据包的目的端口号是1至1024、2049或者32768。1至1024包含了大部分网络服务默认使用的端口,2049和32768是NFS服务器工作时需要开放的端口。第二条和第三条命令允许源IP地址是10.10.2.2或10.10.2.3数据包通过,这两台计算机可能是由管理员使用的。也有一些服务要使用1024号以上的端口,可以采用类似的命令加入规则,以开放这些端口。最后,如果不是采用-P选项指定默认的DROP策略,还需要在FORWARD链中加入以下命令,以拒绝所有不匹配的数据包。
iptables -A FORWARD -i eth2 -o eth1 -j DROP
上面的这条命令也可以和前面的"iptables -A FORWARD -i eth0 -o eth1 -j DROP"命令合并在一起,成为以下命令。
iptables -A FORWARD -o eth1 -j DROP
显然,上面这条命令指定的规则应该放在最后的位置。另外,每一台主机还可以根据自己的特点设置自己的主机防火墙,以提供更多的保护。
护内部客户机的防火墙规则上个小节介绍的是针对服务器子网的防火墙配置,侧重点是如何对其进行保护。因此,规则排列的特点是先放行指定的数据包,再拒绝所有的数据包。但对于图9-8中的子网10.10.2.0/24来说,配置的原则应该是不一样的,因为这个子网中的计算机是用户上网的计算机,为了给用户提供尽量多的上网功能,应该放行所有的数据包,但事先要对部分有问题的数据包进行拒绝。要限制的数据包分为两类,一类是限制用户对Internet上某些内容的访问,还有一类是不允许Internet上的某些内容进入该子网。前者的数据包是从网卡eth2到eth0,而后者应该是从eth0到eth2。例如,如果不希望内网的计算机使用QQ,可以使用以下命令进行限制。
iptables -A FORWARD -p UDP --dport 8000 -i eth2 -o eth0 -j DROP
说明:UDP协议8000号端口是QQ客户端登录服务器时使用的目的端口,该命令限制内网的计算机向外发送目的端口是8000的数据包。下面的这条命令与上面命令功能相同,但它限制的是进来的数据包,客户端发起登录请求的数据包还是能通过的,效果不如上面那条命令好。
iptables -A FORWARD -p UDP --sport 8000 -i eth0 -o eth2 -j DROP
但实际上,目前QQ也可以通过TCP协议的80和443端口进行登录,而这两个端口是不能封的,否则,用户的浏览器将不能访问网站。因此,比较可靠的方法是封锁访问QQ服务器IP地址的数据包,具体命令如下:
iptables -A FORWARD -p tcp -d 60.191.124.236 -i eth2 -o eth0 -j DROP  iptables -A FORWARD -p tcp -d 58.60.15.38 -i eth2 -o eth0 -j DROP  …
60.191.124.236和58.60.15.38等IP址是QQ服务器的地址,有几十个IP,而且是动态变化的,需要即时搜集更新。此外,如果有些网站或者其他服务器也不允许内网的用户访问,可以查出其IP地址后,使用类似的命令进行限制。有些计算机病毒或木马程序要使用固定的端口进行传播或通信,为了保护内网不受这些程序的影响,需要把这部分端口封掉,例子命令如下所示。
iptables -A FORWARD -i eth0 -o eth2 -m multiport
--dport 135:139,445,593,5554 -j DROP

135至139是Windows网络共享使用的端口号,为了防止内网数据可能会泄露,一般要封掉该端口,使内网和Internet之间不能进行Windows网络共享。其他几个端口都是 病毒或木马程序端口,如果有最新的病毒或木马使用其他端口,应该在上述命令中添加 进去。有些蠕虫病毒发作时会产生大量的ICMP数据包,可以设置拒绝ICMP数据包的规则。但由于ping命令也是使用ICMP数据包工作的,如果设置拒绝转发ICMP数据包,内网将不能ping外网的任何主机,会给网络维护带来不便,因此比较好的办法是限制ICMP数据包的注量,命令如下所示。
iptables -A FORWARD -p icmp -m limit --limit
50/m --limit-burst 60 -j ACCEPT

前面的规则限制了10.10.2.0/24子网与Internet之间的部分数据包,管理员可以根据具体情况随时添加更多的规则或删除、修改部分规则。最后,还应该添加使所有数据包都能通过的规则,具体命令如下所示。
iptables -A FORWARD  -i eth2 -o eth0 -j ACCEPT  iptables -A FORWARD  -i eth0 -o eth2 -j ACCEPT
由于还有一个与服务器相连的eth1网卡,它默认时是不允许数据包通过的,因此上述命令要指明是在eth2和eth0网卡之间可以通过所有的数据包。
mangle表应用举例前面介绍的防火墙规则其所在的规则链都位于filter表,下面再看一个有关mangle表的使用例子。mangle表的主要功能是根据规则修改数据包的一些标志位,以便其他规则或程序可以利用这种标志对数据包进行过滤或策略路由。图9-9所示的是一种典型的网络结构,内网的客户机通过Linux主机连入Internet,而Linux主机与Internet连接时有两条线路,它们的网关如图所示。现要求对内网进行策略路由,所有通过TCP协议访问80端口的数据包都从ChinaNet线路出去,而所有访问UDP协议53号端口的数据包都从Cernet线路出去。


这是一个策略路由的问题,为了达到目的,在对数据包进行路由前,要先根据数据包的协议和目的端口给数据包做上一种标志,然后再指定相应规则,根据数据包的标志进行策略路由。为了给特定的数据包做上标志,需要使用mangle表,mangle表共有5条链,由于需要在路由选择前做标志,因此应该使用PREROUTING链,下面是具体的命令。

iptables -t mangle -A PREROUTING -i eth0 -p tcp
--dport 80 -j MARK --set- mark 1

iptables -t mangle -A PREROUTING -i eth0 -p udp
--dprot 53 -j MARK --set- mark 2

以上命令在mangle表的PREROUTING链中添加规则,为来自eth0接口的数据包做标志,其匹配规则分别是TCP协议、目的端口号是80和UDP协议、目的端口号是53,标志的值分别是1和2。数据包经过PREROUTING链后,将要进入路由选择模块,为了对其进行策略路由,执行以下两条命令,添加相应的规则。
ip rule add from all fwmark 1 table 10  ip rule add from all fwmark 2 table 20
以上两条命令表示所有标志是1的数据包使用路由表10进行路由,而所有标志是2的数据包使用路由表20进行路由。路由表10和20分别使用了ChinaNet和Cernet线路上的网关作为默认网关,具体设置命令如下所示。
ip route add default via 10.10.1.1 dev eth1 table 10  ip route add default via 10.10.2.1 dev eth2 table 20
以上两条命令在路由表10和20上分别指定了10.10.1.1和10.10.2.1作为默认网关,它们分别位于ChinaNet和Cernet线路上。于是,使用路由表10的数据包将通过ChinaNet线路出去,而使用路由表20的数据包将通过Cernet线路出去。上面介绍了有关mangle表在策略路由上的应用,有关策略路由的具体内容,可参见8.3节。

三、用iptables防火墙实现动态地址转换(NAT)的配置方法

ptables防火墙的NAT配置NAT(Network Address Translation,网络地址转换)是一项非常重要的Internet技术,它可以让内网众多的计算机访问Internet时,共用一个公网地址,从而解决了Internet地址不足的问题,并对公网隐藏了内网的计算机,提高了安全性能。本章主要介绍利用iptables防火墙实现NAT的方法。 NAT简介NAT并不是一种网络协议,而是一种过程,它将一组IP地址映射到另一组IP地址,而且对用户来说是透明的。NAT通常用于将内部私有的IP地址翻译成合法的公网IP地址,从而可以使内网中的计算机共享公网IP,节省了IP地址资源。可以这样说,正是由于NAT技术的出现,才使得IPv4的地址至今还足够使用。因此,在IPv6广泛使用前,NAT技术仍然还会广泛地应用。1.NAT的工作原理NAT的工作原理如图9-10所示。



内网中IP为10.10.1.10的计算机发送的数据包其源IP地址是10.10.1.10,但这个地址是Internet的保留地址,不允许在Internet上使用,Internet上的路由器是不会转发这样的数据包的。为了使这个数据包能在Internet上传输,需要把源IP地址10.10.1.10转换成一个能在Internet上使用的合法IP地址,如218.75.26.35,才能顺利地到达目的地。这种IP地址转换的任务由NAT服务器完成,运行NAT服务的主机一般位于内网的出口处,至少需要有两个网络接口,一个设置为内网IP,一个设置为外网合法IP。NAT服务器改变出去的数据包的源IP地址后,需要在内部保存的NAT地址映射表中登记相应的条目,以便回复的数据包能返回给正确的内网计算机。当然,从Internet回复的数据包也并不是直接发送给内网的,而是发给了NAT服务器中具有合法IP地址的那个网络接口。NAT服务器收到回复的数据包后,根据内部保存的NAT地址映射表,找到该数据包是属于哪个内网IP的,然后再把数据包的目的IP转换回来,还原成原来的那个内网地址,最后再通过内网接口路由出去。以上地址转换过程对用户来说是透明的,计算机10.10.1.10并不知道自己发送出去的数据包在传输过程中被修改过,只是认为自己发送出去的数据包能得到正确地响应数据包,与正常情况没有什么区别。通过NAT转换还可以保护内网中的计算机不受到来自Internet的攻击。因为外网的计算机不能直接发送数据包给使用保留地址的内网计算机,只能发给NAT服务器的外网接口。在内网计算机没有主动与外网计算机联系的情况下,在NAT服务器的NAT地址映射表中是无法找到相应条目的,因此也就无法把该数据包的目的IP转换成内网IP。说明:在有些情况下,数据包还可能会经过多次的地址转换。2.动态NAT以上介绍的NAT也称为源NAT,即改变数据包的源IP地址,通常也称为静态NAT,它用于内网的计算机共用公网IP上网。还有一种NAT是目的NAT,改变的是数据包的目的IP地址,通常也称为动态NAT,它用于把某一个公网IP映射为某一内网IP,使两者建立固定的联系。当Internet上的计算机访问公网IP时,NAT服务器会把这些数据包的目的地址转换为对应的内网IP,再路由给内网计算机。3.端口NAT另外还有一种NAT称为端口NAT,它可以使公网IP的某一端口与内网IP的某一端口建立映射关系。当来自Internet的数据包访问的是这个公网IP的指定端口时,NAT服务器不仅会把数据包的目的公网IP地址转换为对应的内网IP,而且会把数据包的目的端口号也根据映射关系进行转换。除了存在单独的NAT设备外,NAT功能还通常被集成到路由器、防火墙等设备或软件中。iptables防火墙也集成了NAT功能,可以利用NAT表中的规则链对数据包的源或目的IP地址进行转换。下面两个小节将分别介绍在iptables防火墙中实现源NAT和目的NAT的方法。使用iptables配置源NAT在前面的有关章节中,已经介绍了路由和过滤数据包的方法,它们都不牵涉到对数据包的IP地址进行改变。但源NAT需要对内网出去的数据包的源IP地址进行转换,用公网IP代替内网IP,以便数据包能在Internet上传输。iptables的源NAT的配置应该是在路由和网络防火墙配置的基础上进行的。iptables防火墙中有3张内置的表,其中的nat表实现了地址转换的功能。nat表包含PREROUTING、OUTPUT和POSTROUTING 3条链,里面包含的规则指出了如何对数据包的地址进行转换。其中,源NAT的规则在POSTROUTING链中定义。这些规则的处理是在路由完成后进行的,可以使用"-j SNAT"目标动作对匹配的数据包进行源地址转换。在图9-10所示的网络结构中,假设让iptables防火墙承担NAT服务器功能。此时,如果希望内网10.10.1.0/24出去的数据包其源IP地址都转换外网接口eth0的公网IP地址218.75.26.35,则需要执行以下iptables命令。
# iptables -t nat -A POSTROUTING -s 10.10.
1.0/24 -o eth0 -j SNAT --to-source 218.75.26.35

以上命令中,"-t nat"指定使用的是nat表,"-A POSTROUTING"表示在POSTROUTING链中添加规则,"--to-source 218.75.26.35"表示把数据包的源IP地址转换为218.75.26.35,而根据-s选项的内容,匹配的数据包其源IP地址应该是属于10.10.1.0/24子网的。还有,"-o eth0"指定了只有从eth0接口出去的数据包才做源NAT转换,因为从其他接口出去的数据包可能不是到Internet的,不需要进行地址转换。以上命令中,转换后的公网地址直接是eth0的公网IP地址。也可以使用其他地址,例如,218.75.26.34。此时,需要为eth0创建一个子接口,并把IP地址设置为218.75.26.34,使用的命令如下所示。
# ifconfig eth0:1 218.75.26.34 netmask 255.255.255.240
以上命令使eth0接口拥有两个公网IP。也可以使用某一IP地址范围作为转换后的公网地址,此时要创建多个子接口,并对应每一个公网地址。而"--to-source"选项后的参数应该以"a.b.c.x-a.b.c.y"的形式出现。
前面介绍的是数据包转换后的公网IP是固定的情况。如果公网IP地址是从ISP服务商那里通过拨号动态获得的,则每一次拨号所得到的地址是不同的,并且网络接口也是在拨号后才产生的。在这种情况下,前面命令中的"--to-source"选项将无法使用。为了解决这个问题,iptables提供了另一种称为IP伪装的源NAT,其实现方法是采用"-j MASQUERADE"目标动作,具体命令如下所示。
# iptables -t nat -A POSTROUTING -s 10.10.1.0/24 -o ppp0 -j MASQUERADE
以上命令中,ppp0是拨号成功后产生的虚拟接口,其IP地址是从ISP服务商那里获得的公网IP。"-j MASQUERADE"表示把数据包的源IP地址改为ppp0接口的IP地址。注意:除了上面的源NAT配置外,在实际应用中,还需要配置其他一些有关iptables网络防火墙的规则,同时,路由的配置也是必不可少的。使用iptables配置目的NAT目的NAT改变的是数据包的目的IP地址,当来自Internet的数据包访问NAT服务器网络接口的公网IP时,NAT服务器会把这些数据包的目的地址转换为某一对应的内网IP,再路由给内网计算机。这样,使用内网IP地址的服务器也可以为Internet上的计算机提供网络服务了。如图9-11所示,位于子网10.10.1.0/24的是普通的客户机,它们使用源NAT访问Internet。而子网10.10.2.0/24是服务器网段,里面的计算机运行着各种网络服务,它们不仅要为内网提供服务,而且要为Internet上的计算机提供服务。但由于使用的是内网地址,因此需要在NAT服务器配置目的NAT,才能让来自Internet的数据包能顺利到达服务器网段。


假设IP为10.10.2.3的计算机需要为Internet提供网络服务,此时,可以规定一个公网IP地址,使其与10.10.2.3建立映射关系。假设使用的公网IP是218.75.26.34,则配置目的NAT的命令如下:

# iptables -t nat -A PREROUTING -i eth0 -d
218.75.26.34/32 -j DNAT --to 10.10.2.3

以上命令是在PREROUTING链中添加规则,这条链位于路由模块的前面,因此是在路由前改变了数据包的目的IP,这将对路由的结果造成影响。由于网络接口eth0与Internet连接,因此,"-i eth0"保证了数据包是来自Internet的数据包。"-d 218.75.26.34/32"表示数据包的目的地是到218.75.26.34主机,而这个IP应该是eth0某个子接口的地址,这样才能由NAT服务器接收数据包,否则,数据包将会因为无人接收而丢弃。"-j DNAT"指定了目标动作是DNAT,表示要对数据包的目的IP进行修改,它的子选项"--to 10.10.2.3"表示修改后的IP地址是10.10.2.3。于是,目的IP修改后,接下来将由路由模块把数据包路由给10.10.2.3服务器。以上是让一个公网IP完全映射到内网的某个IP上,此时同10.10.2.3主机直接位于Internet,并且使用218.75.26.34地址是没有区别的。因此这种方式虽然达到了地址转换的目的,但实际上并没有带来多大好处,因为使用NAT的主要目的是为了能够共用公网IP地址,以节省日益紧张的IP地址资源。为了达到共用IP地址的目的,可以使用端口映射。端口映射是把一个公网IP地址的某一端口映射到内网某一IP地址的某一端口上去。它使用起来非常灵活,两个映射的端口其端口号可以不一样,而且同一个公网IP的不同端口可以映射到不同的内网IP地址上去。例如,假设主机10.10.2.3只为外网提供Web服务,因此,只需要开放80端口,而主机10.10.2.9为外网提供了FTP服务,因此需要开放21号端口。在这种情况下,完全可以把公网IP地址218.75.26.34的80号和21号端口分别映射到10.10.2.3和10.10.2.9的80号和21号端口,以便两台内网服务器可以共用一个公网IP。具体命令如下所示。
# iptables -t nat -A PREROUTING -i eth0 -d
218.75.26.34/32 -p tcp --dport 80 -j DNAT --to 10.10.2.3:80

# iptables -t nat -A PREROUTING -i eth0 -d
218.75.26.34/32 -p tcp --dport 21 -j DNAT --to 10.10.2.9:21

以上命令中,目的地址是218.75.26.34的TCP数据包。当目的端口是80时,将转发给10.10.2.3主机的80端口;当目的端口是21时,将转发给10.10.2.9主机的21号端口。当然,两个映射的端口完全可以不一样。例如,如果还有一台主机10.10.2.8也通过80端口提供Web服务,并且映射的IP地址也是218.75.26.34,此时需要把218.75.26.34的另一个端口,如8080,映射到10.10.2.8的80端口,命令如下:
# iptables -t nat -A PREROUTING -i eth0 -d
218.75.26.34/32 -p tcp --dport 8080 -j DNAT --to 10.10.2.8:80

注意:上面介绍的只是有关iptables中的DNAT配置,在实际应用中,还需要其他一些配置的配合才能真正成功。例如,filter表的3个链应该允许相应的数据包通过,应该为每一个外网IP创建eth0接口的子接口等。此外,对于FTP服务来说,由于21号端口只是建立控制连接时用到的端口,真正传输数据时要使用其他端口。而且在被动方式下,客户端向FTP服务器发起连接的端口号是随机的,因此,无法通过开放固定的端口来满足要求。为了解决这个问题,可以在Linux系统中载入以下两个模块。
modprobe ip_conntrack_ftp  modprobe ip_nat_ftp
这两个模块可以监控FTP控制流,以便能事先知道将要建立的FTP数据连接所使用的端口,从而可以允许相应的数据包通过,即使防火墙没有开放这个端口。

参考: http://book.51cto.com/art/200912/169182.htm

http://book.51cto.com/art/200912/169262.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息