Firewall: 防火墙,隔离工具;工作于主机或网络的边缘,对于进出本主机或网络的报文根据事先定义好的检查规则作匹配检测,对于能够被规则所匹配到的报文做出相应处理的组件;介于3-4层的传输 ——管理控制服务的提供。
系统安全: 第三方监控杀毒软件,系统策略,文件权限;防火墙规则:原地址 目标地址 端口 协议 mac 数据包中的标志,类似ACL访问控制列表:过滤
主机防火墙:针对于单个主机进行防护。
网络防火墙:往往处于网络入口或边缘,针对于网络入口进行防护,服务于防火墙背后的本地局域网。网络防火和主机防火墙并不中突,可以理解为,网络防火墙主外(集体),主机防火墙主内(个人)。
硬件防火墙:在硬件级别实现部分防火墙功能,另一部分功能基于软件实现,性能高,成本高。如:思科ASA 华为防火墙 天融信防火墙 等。
软件防火墙:应用软件处理逻辑运行于通用硬件平台之上的防火墙,性能低,成本低。如:iptables firewall(centos7独有的)等。
iptables其实不是真正的防火墙,我们可以把它理解成一个客户端代理,用户通过iptables这个代理,将用户的安全设定执行到对应的"安全框架"中,这个"安全框架"才是真正的防火墙,这个框架的名字叫netfilter
netfilter才是防火墙真正的安全框架(framework),netfilter位于内核空间。
iptables其实是一个命令行工具,位于用户空间,我们用这个工具操作真正的框架。
netfilter/iptables(下文中简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,它可以代替昂贵的商业防火墙解决方案,完成封包过滤、封包重定向和网络地址转换(NAT)等功能。
Netfilter是Linux操作系统核心层内部的一个数据包处理模块,它具有如下功能:网络地址转换(Network Address Translate), 数据包内容修改, 以及数据包过滤的防火墙功能
所以虽然我们使用service iptables start启动iptables"服务",但是其实准确的来说,iptables并没有一个守护进程,所以并不能算是真正意义上的服务,而应该算是内核提供的功能。
Linux中最常用的基本防火墙软件称为iptables。该iptables防火墙的工作原理是与包过滤在Linux内核的网络栈挂钩交互。这些内核挂钩被称为netfilter框架。
进入网络系统的每个数据包(传入或传出)都会在堆栈中前进时触发这些挂钩,从而使注册到这些挂钩的程序可以在关键点与流量进行交互。与iptables这些模块关联的内核模块在这些钩子处注册,以确保流量符合防火墙规则所规定的条件。
netfilter程序在内核可以注册五个钩子函数(hooks function)。当数据包通过堆栈时,它们将触发已向这些挂钩注册的内核模块。数据包将触发的挂钩取决于数据包是传入还是传出,数据包的目的地,以及数据包是否在上一时刻被丢弃或拒绝。
NF_IP_PRE_ROUTING
注意:进入网络堆栈后不久,任何传入流量都会触发此挂钩。在做出关于将数据包发送到何处的任何路由决策之前,将处理此挂钩。NF_IP_LOCAL_IN
注意:如果将数据包发送到本地系统,则在路由进来的数据包后触发此挂钩。NF_IP_FORWARD
注意:如果要将该数据包转发到另一台主机,则在路由传入数据包之后将触发此挂钩。NF_IP_LOCAL_OUT
:此钩子在到达网络堆栈后立即由任何本地创建的出站流量触发。NF_IP_POST_ROUTING
:此钩子在路由发生之后和即将被放置到线路上之前由任何传出或转发的流量触发。在这些内核钩子上注册的内核模块必须提供优先级编号,以帮助确定在钩子被触发时调用它们的顺序。这提供了将多个模块(或同一模块的多个实例)以确定性顺序连接到每个挂钩的函数。每个模块将依次被调用,并将netfilter
在处理后向框架返回一个决定,该决定指示应该对数据包执行什么操作。
该iptables防火墙使用表格来组织规则。这些表根据规则的决策类型对规则进行分类。例如,如果一个规则处理网络地址转换,它将被放入nat表中。如果使用该规则来决定是否允许数据包继续到达其目的地,则可能会将其添加到filter
表中。
在每个iptables
表中,规则在单独的“链”中进一步组织。表是由它们所持有规则的一般目的定义的,而内置链则表示netfilter
触发它们的钩子。链条基本上确定何时评估规则。
如我们所见,内置链的名称反映了netfilter
它们与之关联的钩子的名称:
PREROUTING
:由NF_IP_PRE_ROUTING
挂钩触发。INPUT
:由NF_IP_LOCAL_IN
挂钩触发。FORWARD
:由NF_IP_FORWARD
挂钩触发。OUTPUT
:由NF_IP_LOCAL_OUT
挂钩触发。POSTROUTING
:由NF_IP_POST_ROUTING
挂钩触发。链允许管理员控制将在数据包的传递路径中的每个规则。由于每个表都有多个链,因此表的影响力可以在处理过程中的多个点进行。因为某些类型的决策仅在网络堆栈中的某些点才有意义,所以每个表都不会在每个内核挂钩中都注册一个链。
只有五个netfilter
内核挂钩,因此在每个挂钩上都注册了来自多个表的链。例如,三个表具有PREROUTING
链。当这些链在关联的NF_IP_PRE_ROUTING
钩子上注册时,它们会指定一个优先级,该优先级指示了每个PREROUTING
表链的调用顺序。PREROUTING在移至下一个PREROUTING
链之前,将对最高优先级链中的每个规则进行顺序评估。我们稍后将看每个链的具体顺序。
让我们退后一会,看看提供的不同表iptables
。这些代表按关注区域组织的不同规则集,用于评估数据包。
过滤器表是中使用最广泛的表之一iptables
。该filter
表用于决定是让数据包继续到达其预期的目的地还是拒绝其请求。用防火墙的话来说,这就是所谓的“过滤”数据包。下表提供了人们讨论防火墙时会想到的大量功能。
主要用于对数据包进行过滤,根据具体的规则决定是否放行该数据包(如DROP、ACCEPT、REJECT、LOG)。filter 表对应的内核模块为iptable_filter,包含三个规则链:
INPUT
链:INPUT
针对那些目的地是本地的包FORWARD
链: 过滤所有不是本地产生的并且目的地不是本地(即本机只是负责转发)的OUTPUT
链:OUTPUT
是用来过滤所有本地生成的包主要用于修改数据包的IP地址、端口号等信息(网络地址转换,如SNAT、DNAT、MASQUERADE、REDIRECT)。属于一个流的包(因为包的大小限制导致数据可能会被分成多个数据包)只会经过
这个表一次。如果第一个包被允许做NAT或Masqueraded,那么余下的包都会自动地被做相同的操作,也就是说,余下的包不会再通过这个表。表对应的内核模块为 iptable_nat,包含三个链
PREROUTING
链:作用是在包刚刚到达防火墙时改变它的目的地址OUTPUT
链:改变本地产生的包的目的地址POSTROUTING
链:在包就要离开防火墙之前改变其源地址主要用于修改数据包的TOS(Type Of Service,服务类型)、TTL(Time To Live,生存周期)指以及为数据包设置Mark标记,以实现Qos(Quality Of Service,服务质量)调整以及策略路由等应用,由于需要相应的路由设备支持,因此应用并不广泛。包含五个规则链——PREROUTING
,POSTROUTING
,INPUT
,OUTPUT
,FORWARD
。
该表还可以在包上放置一个内部内核“标记”,以便在其他表中以及由其他联网工具进行进一步处理。该标记不会触及实际的数据包,但会将标记添加到数据包的内核表示中。
该iptables
防火墙是有状态的,这意味着数据包的问候评估他们的关系以前的数据包。建立在netfilter
框架顶部的连接跟踪功能允许iptables
将数据包视为正在进行的连接或会话的一部分,而不是离散的,不相关的数据包流。通常在数据包到达网络接口后不久就应用连接跟踪逻辑。
该raw
表具有非常狭窄的定义的功能。其唯一目的是提供一种标记数据包的机制,以选择退出连接跟踪。
是自1.2.9以后版本的iptables新增的表,主要用于决定数据包是否被状态跟踪机制处理。在匹配数据包时,raw
表的规则要优先于其他表。包含两条规则链——OUTPUT
、PREROUTING
NEW
:该包想要开始一个连接(重新连接或将连接重定向)RELATED
:该包是属于某个已经建立的连接所建立的新连接。例如:FTP的数据传输连接就是控制连接所 RELATED出来的连接。--icmp-type 0 ( ping 应答) 就是--icmp-type 8 (ping 请求)所RELATED出来的。ESTABLISHED
:只要发送并接到应答,一个数据连接从NEW变为ESTABLISHED,而且该状态会继续匹配这个连接的后续数据包。INVALID
:数据包不能被识别属于哪个连接或没有任何状态比如内存溢出,收到不知属于哪个连接的ICMP错误信息,一般应该DROP这个状态的任何数据。注意:在高并发下开启
raw
的连接追踪机制会导致内存耗尽,从而导出请求不能正常处理!
该security
表用于在数据包上设置内部SELinux
安全上下文标记,这将影响SELinux
或其他可以解释SELinux
安全上下文的系统如何处理数据包。这些标记可以在每个数据包或每个连接的基础上应用。
我们已经分别讨论了表和链。让我们看一下每个表中可用的链。该讨论中暗含了有关注册到同一钩子的链的评估顺序的进一步讨论。如果三个表都有PREROUTING
链,则按什么顺序进行进行捕获呢?
下表指示了iptables
从左到右读取时每个表中可用的链。例如,我们可以说该raw
表同时具有PREROUTING
和OUTPUT
链。从上到下读取时,它还会显示netfilter
触发关联的挂钩时调用每个链的顺序。
应该注意几件事。在下面的表示中,该nat
表已在DNAT
操作(更改数据包目的地址的SNAT操作)和操作(更改源地址的操作)之间进行了划分,以便更清楚地显示其顺序。我们还包含一些行,这些行代表进行路由决策和启用连接跟踪的点,以便更全面地了解正在发生的过程:
Tables/Chains-> | PREROUTING | INPUT | FORWARD | OUTPUT | POSTROUTING |
---|---|---|---|---|---|
(routing decision) | | | | √ | |
raw | √ | | | √ | |
(connection tracking enabled) | √ | | | √ | |
mangle | √ | √ | √ | √ | √ |
nat(DNAT) | √ | | | √ | |
(routing decision) | √ | | | √ | |
filter | | √ | √ | √ | |
security | | √ | √ | √ | |
nat(SNAT) | | √ | | | √ |
当数据包触发netfilter
钩子时,相关链将按照上表从上到下的顺序进行处理。数据包将触发的挂钩(列)取决于它是传入还是传出数据包,做出的路由决策以及数据包是否通过过滤标准。
某些事件将导致在处理过程中跳过表的链。例如,将仅根据NAT规则评估连接中的第一个数据包。nat对第一个数据包做出的任何决定都将应用于连接中的所有后续数据包,而无需进行其他评估。对NAT连接的响应将自动应用反向NAT规则以正确路由。
假设服务器知道如何路由数据包,并且防火墙规则允许其传输,则以下流表示在不同情况下将遍历的路径:
PREROUTING
-> INPUT
PREROUTING
-> FORWARD
-> POSTROUTING
OUTPUT
-> POSTROUTING
如果我们将上面的信息与前一个表中列出的顺序结合起来,我们可以看到,将首先根据raw
、mangle
和nat
表的PREROUTING
链来评估发送到本地系统的传入包。然后,它将遍历mangle
、filter
、security
和nat
表的输入链,最后传递到本地套接字。
我们知道 iptables是按照规则来办事的,我们就来说说规则( rules),规则其实就是网络管理员预定义的条件,规则一般的定义为"如果数据包头符合这样的条件,就这样处理
这个数据包”。规则存储在内核空间的信息包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如TCP、UDP、|CMP)和服务类型(如HTP、FP和SMTP)等。
数据包与规则匹配时, iptables就根据规则所定义的方法来处理这些数据包,如放行( accept)、拒绝( reject))和丢弃(drop)等。配置防火墙的主要工作就是添加、修改和删除这些规则。
这样说可能并不容易理解,我们来换个容易理解的角度,从头说起
当客户端访问服务器的web服务时,客户端发送报文到网卡,而tcp/ip协议栈是属于内核的一部分,所以,客户端的信息会通过内核的TCP协议传输到用户空间中的web服务中,而此时,客户端报文的目标终点为web服务所监听的套接字(P:Port)上,当web服务需要响应客户端请求时,web服务发出的响应报文的目标终点则为客户端,这个时候,web服务所监听的IP与端囗反而变成了原点,我们说过, netfilter 才是真正的防火墙,它是内核的部分,所以,如果我们想要防火墙能够达到"防火"的目的,则需要在内核中设置关卡,所有进出的报文都要通过这些关卡,经过检查后,符合放行条件的才能放行,符合阻拦条件的则需要被阻止,于是,就出现了input关卡和 output关卡,而这些关卡在 iptables中不被称为关卡"而被称为链"。
其实我们上面描述的场景并不完善,因为客户端发来的报文访问的目标地址可能并不是本机,而是其他服务器,当本机的内核支持IP_FORWARD
时,我们可以将报文转发给其他服务器,所以,这个时候,我们就会提到iptables
中的其他"关卡
",也就是其他"链
",他们就是 "路由前
"、"转发
"、"路由后
",他们的英文名是:PREROUTING
、FORWARD
、POSTROUTING
.
也就是说,当我们启用了防火墙功能时,报文需要经过如下关卡,也就是说,根据实际情况的不同,报文经过"链
"可能不同。如果报文需要转发,那么报文则不会经过input
链发往用户空间,而是直接在内核空间中经过forward
链和postrouting
链转发出去的。
所以,根据上图,我们能够想象出某些常用场景中,报文的流向:
PREROUTING
--> INPUT
PREROUTING
--> FORWARD
--> POSTROUTING
OUTPUT -->
POSTROUTING`现在,我们想象一下,这些"关卡"在iptables中为什么被称作"链
"呢?我们知道,防火墙的作用就在于对经过的报文匹配"规则
",然后执行对应的"动作
",所以,当报文经过这些关卡的时候,则必须匹配这个关卡上的规则,但是,这个关卡上可能不止有一条规则,而是有很多条规则,当我们把这些规则串到一个链条上的时候,就形成了"链
",所以,我们把每一个"关卡
"想象成如下图中的模样,这样来说,把他们称为"链
"更为合适,每个经过这个"关卡
"的报文,都要将这条"链
"上的所有规则匹配一遍,如果有符合条件的规则,则执行规则对应的动作。
我们再想想另外一个问题,我们对每个"链
"上都放置了一串规则,但是这些规则有些很相似,比如,A类规则都是对IP或者端口的过滤,B类规则是修改报文,那么这个时候,我们是不是能把实现相同功能的规则放在一起呢,必须能的。
我们把具有相同功能的规则的集合叫做"表
",所以说,不同功能的规则,我们可以放置在不同的表中进行管理,而iptables已经为我们定义了4种表,每种表对应了不同的功能,而我们定义的规则也都逃脱不了这4种功能的范围,所以,学习iptables之前,我们必须先搞明白每种表的作用。
iptables为我们提供了如下规则的分类,或者说,iptables为我们提供了如下"表
"
filter
表:负责过滤功能,防火墙;内核模块:iptables_filter
nat
表:network address translation
,网络地址转换功能;内核模块:iptable_nat
mangle
表:拆解报文,做出修改,并重新封装 的功能;iptable_mangle
raw
表:关闭nat表上启用的连接追踪机制;iptable_raw
也就是说,我们自定义的所有规则,都是这四种分类中的规则,或者说,所有规则都存在于这4张"表
"中。
但是我们需要注意的是,某些"链
"中注定不会包含"某类规则
",就像某些"关卡
"天生就不具备某些功能一样,比如,A"关卡
"只负责打击陆地敌人,没有防空能力,B"关卡
"只负责打击空中敌人,没有防御步兵的能力,C"关卡
"可能比较NB,既能防空,也能防御陆地敌人,D"关卡
"最厉害,海陆空都能防。
那让我们来看看,每个"关卡
"都有哪些能力,或者说,让我们看看每个"链
"上的规则都存在于哪些"表
"中。
我们还是以图为例,先看看prerouting
"链"上的规则都存在于哪些表中。
注意:下图只用于说明
prerouting
链上的规则存在于哪些表中,并没有描述表的顺序。
这个流程图的意思是说,prerouting"链"只拥有nat表、raw表和mangle表所对应的功能,所以,prerouting中的规则只能存放于nat表、raw表和mangle表中。
那么,根据上述思路,我们来总结一下,每个"关卡"都拥有什么功能,或者说,每个"链"中的规则都存在于哪些"表"中。
PREROUTING
的规则可以存在于:raw表,mangle表,nat表。INPUT
的规则可以存在于:mangle表,filter表,(centos7中还有nat表,centos6中没有)。FORWARD
的规则可以存在于:mangle表,filter表。OUTPUT
的规则可以存在于:raw表mangle表,nat表,filter表。POSTROUTING
的规则可以存在于:mangle表,nat表。但是,我们在实际的使用过程中,往往是通过"表"作为操作入口,对规则进行定义的,之所以按照上述过程介绍iptables,是因为从"关卡"的角度更容易从入门的角度理解,但是为了以便在实际使用的时候,更加顺畅的理解它们,此处我们还要将各"表"与"链"的关系罗列出来,
表(功能)<--> 链(钩子):
raw
表中的规则可以被哪些链使用:PREROUTING,OUTPUTmangle
表中的规则可以被哪些链使用:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTINGnat
表中的规则可以被哪些链使用:PREROUTING,OUTPUT,POSTROUTING(centos7中还有INPUT,centos6中没有)filter
表中的规则可以被哪些链使用:INPUT,FORWARD,OUTPUT--->PRE------>[ROUTE]--->FWD---------->POST------>
Conntrack | Mangle ^ Mangle
Mangle | Filter | NAT (Src)
NAT (Dst) | | Conntrack
(QDisc) | [ROUTE]
v |
IN Filter OUT Conntrack
| Conntrack ^ Mangle
| Mangle | NAT (Dst)
v ---->local---->| Filter
prerouting链中的规则存放于三张表中,而这三张表中的规则执行的优先级:raw --> mangle --> nat 但是我们知道,iptables为我们定义了4张"表",当他们处于同一条"链"时,执行的优先级如上图所示,优先级次序(由左而右):raw --> mangle --> nat --> filter 但是我们前面说过,某些链天生就不能使用某些表中的规则,所以,4张表中的规则处于同一条链的目前只有output链,它就是传说中海陆空都能防守的关卡。 为了更方便的管理,我们还可以在某个表里面创建自定义链,将针对某个应用程序所设置的规则放置在这个自定义链中,但是自定义链接不能直接使用,只能被某个默认的链当做动作去调用才能起作用,我们可以这样想象,自定义链就是一段比较"短"的链,这条"短"链上的规则都是针对某个应用程序制定的,但是这条短的链并不能直接使用,而是需要"焊接"在iptables默认定义链上,才能被IPtables使用,这就是为什么默认定义的"链"需要把"自定义链"当做"动作"去引用的原因。
- `INPUT`链:当接收到防火墙本机地址的数据包(入站)时,应用此链中的规则。
- `OUTPUT`链:当防火墙本机向外发送数据包(出站)时,应用此链中的规则。
- `FORWARD`链:当接收到需要通过防火墙发送给其他地址的数据包(转发)时,应用此链中的规则。
- `PREROUTING`链:在对数据包作路由选择之前,应用此链中的规则,如DNAT。
- `POSTROUTING`链:在对数据包作路由选择之后,应用此链中的规则,如SNAT。其中中
工作流程:网口数据包由底层的网卡NIC接收,通过数据链路层的解包之后(去除数据链路帧头),就进入了TCP/IP协议栈(本质就是一个处理网络数据包的内核驱动)和Netfilter混合的数据包处理流程中了。数据包的接收、处理、转发流程构成一个有限状态向量机,经过一些列的内核处理函数、以及Netfilter Hook点,最后被转发、或者本次上层的应用程序消化掉。
- 当一个数据包进入网卡时,数据包首先进入PREROUTING链,在PREROUTING链中我们有机会修改数据包的DestIP(目的IP),然后内核的"路由模块"根据"数据包目的IP"以及"内核中的路由表"判断是否需要转送出去(注意,这个时候数据包的DestIP有可能已经被我们修改过了)
- 如果数据包就是进入本机的(即数据包的目的IP是本机的网口IP),数据包就会沿着图向下移动,到达INPUT链。数据包到达INPUT链后,任何进程都会-收到它
- 本机上运行的程序也可以发送数据包,这些数据包经过OUTPUT链,然后到达POSTROTING链输出(注意,这个时候数据包的SrcIP有可能已经被我们修改过了)
- 如果数据包是要转发出去的(即目的IP地址不再当前子网中),且内核允许转发,数据包就会向右移动,经过FORWARD链,然后到达POSTROUTING链输出(选择对应子网的网口发送出去)
在写iptables规则的时候,要时刻牢记这张路由次序图,根据所在Hook点的不同,灵活配置规则
链的规则存放于哪些表中(从链到表的对应关系):
PREROUTING
的规则可以存在于:raw表,mangle表,nat表。INPUT
的规则可以存在于:mangle表,filter表,(centos7中还有nat表,centos6中没有)。FORWARD
的规则可以存在于:mangle表,filter表。OUTPUT
的规则可以存在于:raw表,mangle表,nat表,filter表。POSTROUTING
的规则可以存在于:mangle表,nat表。raw
表中的规则可以被哪些链使用:PREROUTING,OUTPUTmangle
表中的规则可以被哪些链使用:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTINGnat
表中的规则可以被哪些链使用:PREROUTING,OUTPUT,POSTROUTING(centos7中还有INPUT,centos6中没有)filter
表中的规则可以被哪些链使用:INPUT,FORWARD,OUTPUT功能的优先级次序:raw --> mangle --> nat --> filter
规则:根据指定的匹配条件来尝试匹配每个流经此处的报文,一旦匹配成功,则由规则后面指定的处理动作进行处理;
那么我们来通俗的解释一下什么是iptables的规则,之前打过一个比方,每条"链"都是一个"关卡",每个通过这个"关卡"的报文都要匹配这个关卡上的规则,如果匹配,则对报文进行对应的处理,比如说,你我二人此刻就好像两个"报文",你我二人此刻都要入关,可是城主有命,只有器宇轩昂的人才能入关,不符合此条件的人不能入关,于是守关将士按照城主制定的"规则",开始打量你我二人,最终,你顺利入关了,而我已被拒之门外,因为你符合"器宇轩昂"的标准,所以把你"放行"了,而我不符合标准,所以没有被放行,其实,"器宇轩昂"就是一种"匹配条件","放行"就是一种"动作","匹配条件"与"动作"组成了规则。
了解了规则的概念,那我们来聊聊规则的组成部分,此处只是大概的将规则的结构列出,后面的文章中会单独对规则进行总结。
规则由匹配条件和处理动作组成。
匹配条件分为基本匹配条件与扩展匹配条件.
源地址Source IP,目标地址 Destination IP
上述内容都可以作为基本匹配条件。
除了上述的条件可以用于匹配,还有很多其他的条件可以用于匹配,这些条件泛称为扩展条件,这些扩展条件其实也是netfilter中的一部分,只是以模块的形式存在,如果想要使用这些条件,则需要依赖对应的扩展模块。
源端口Source Port, 目标端口Destination Port
上述内容都可以作为扩展匹配条件
处理动作在iptables中被称为target(这样说并不准确,我们暂且这样称呼),动作也可以分为基本动作和扩展动作。
此处列出一些常用的动作,之后的文章会对它们进行详细的示例与总结:
ACCEPT
:允许数据包通过。DROP
:直接丢弃数据包,不给任何回应信息,这时候客户端会感觉自己的请求泥牛入海了,过了超时时间才会有反应。REJECT
:拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息。SNAT
:源地址转换,解决内网用户用同一个公网地址上网的问题。MASQUERADE
:是SNAT的一种特殊形式,适用于动态的、临时会变的ip上。DNAT
:目标地址转换。REDIRECT
:在本机做端口映射。LOG
:在/var/log/messages
文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配。版权属于:龙之介大人
本文链接:https://cloud.tencent.com/developer/article/1619659
本站所有原创文章采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 您可以自由的转载和修改,但请务必注明文章来源和作者署名并说明文章非原创且不可用于商业目的。