iptables防火墙简介,原理,规则编写,做网络防火墙,常见案例

防火墙简述

防火墙(firewall)一词本是建筑用于,本意是为了保护建筑物不受火灾侵害的。被借鉴到了在网络通信领域中,表示保护局域网或主机不受网络攻击的侵害。

防火墙: 工作在主机或者网络边缘,对于进出的数据报文按照事先定义好的规则进行检查,监控,一旦符合标准,我们就按照事先定义好的规则处理动作的一套机制组件叫做(网络)(主机)防火墙

目前市面上比较常见的有3,4层的防火墙,叫做网络层防火墙,还有七层的防火墙,其实是代理层的网关.

对于TCP/IP的七层模型来讲,我们知道第三层是网络层,三层的防火墙会在这层对源地址和目标地址进行检测,但是对于七层的防火墙,不管你是源端口或者目标端口,源地址或者目标地址是什么,都将对你所有的东西进行检查. 所以对于设计原理来讲,七层防火墙更加安全, 但是这却带来了效率更低, 所以市面上通常的防火墙方案,都是两者结合的. 而又由于我们都需要从防火墙所控制的这个口来访问,所以防火墙的工作效率就成了用户能访问数据多少的一个最重要的控制,配置的不好甚至可能成为流量的瓶颈.

根据防范的方式和侧重点的不通分为很多种类型, 但总体来讲可分为包过滤防火墙和代理服务器两种类型.

防火墙分类

主机防火墙

工作在某个主机边缘,主要对进出本主机

报文的分层识别,都是在系统内核级别实现的,故防火墙也工作在单台主机内核空间中[TCP/IP协议栈上],其只能作用于单台主机

网络防火墙

网络中的防火墙设备,可分为三种:代理防火墙、包过滤防火墙、状态监测防火墙。

代理防火墙

代理防火墙是代理内网主机上网的设备,可以是路由器,也可以是一台主机两块网卡,一连内网、一连公网,以代替内网主机访问公网资源,又被称为nat(网络地址转换服务器、或nat堡垒服务器);

工作原理

在应用层实现防火墙功能, 提供部分和传输有关的状态,能完全提供与应用相关的状态和部分传输的信息,他还能处理和管理信息.

包过滤防火墙

包过滤防火墙是检测所通过数据包,可监测到数据包中源ip、目的ip、源端口、目的端口、标记位等信息,并根据事先制定的通信规则决定数据包是否转发;

工作原理

在网络层对数据包进行选择过滤,采用访问控制列表(Access control table -ACL)检查数据流的源地址,目的地址,源和目的端口,IP等信息.

netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防火墙,与大多数Linux软件一样, 这个包过滤防火墙是免费的, 他可以替代昂贵的商业防火墙解决方案,完成封包过滤,封包重定向和网络地址转换(NAT)等功能.

状态监测防火墙

状态监测防火墙除了可以监测数据包中的内容外,还可以跟踪每个客户的每次通信,当有攻击数据在开始时伪装成正常访问,之后突然开始做攻击时,会被状态监测防火墙监测到并加以屏蔽。

在Linux系统中,防火墙工具使用的是iptables,可实现代理防火墙、包(数据报文)过滤防火墙,nat,mangle等规则的功能,而状态监测防火墙一般是企业购买专用的防火墙设备完成的。

软件防火墙

软件逻辑实现

软件防火墙由工作在通用计算机[即x86系列cpu]上的系统内核通过调用底层通用cpu指令集实现;

硬件防火墙

硬件和软件逻辑组合实现,为某种特殊功能设计和实现,灵活性差

硬件防火墙使用专业的CPU,其在CPU的硬件级别就能完成对于报文的拆封操作;其只能实现防火墙数据流控制的相关功能;

性能很好[因为其在CPU的指令级别就已经实现了相对复杂的功能,其不用在逻辑层进行复杂的指令组合即可完成对应功能

数据流向
/*
		数据包--> 网卡驱动 --> 内核内存空间--> TCP/IP协议栈分析目标IP 
		-->若是本机ip,则再查看端口并交由相关程序 
		--> 若不是本机ip,当开启路由转发功能后,
		内核将会查看本机路由表,将数据包交由对应网卡接口,作为下一跳;
		若没有路由条目,则将此报文交由默认网关,由默认网关将其转发到相关主机;
*/
报文流向
/*
		流入本机:PREROUTING --> INPUT
    由本机流出:OUTPUT --> POSTROUTING
    转发:PREROUTING --> FORWARD --> POSTROUTING
*/
netfilter路由功能发生时刻
/*
		报文进入本机后:判断目标主机是?
    报文离开本机后:判断经由哪个接口送往下一站。
*/
Linux内核通信逻辑

通信是进程之间进行的, 客户端和服务端的程序通过建立tcp连接, 通过套接字进行数据传输.

将所有端口开放给所有内部主机,以保证通信的正常进行, 而防火墙为了保证安全, 在所有端口之外进行了限制, 只有某些规定允许的端口才能开放给外部主机进行访问使用

Linux防火墙的发展:

/*
  1.0时代 --> ipfirewall
  2.0时代 --> ipchains
  3.0时代 --> iptables
  4.0时代 --> nftables
*/

Iptables工作原理(四表五链)

五链

五个钩子函数(hook functionns),也叫五个规则(rules)链(chains) (数据包传播的路径)

/*
		prerouting   路由前
		input				 数据包流入口
		forward			 转发网卡
		output			 数据包出口
		postrouting	 路由后
*/

这是NetFilter规定的五个规则链,任何一个数据包,只要经过本机,必将经过五个链中的其中一个链

防火墙策略一般分为两种, 一种叫"通"策略,一种叫"堵"策略:

/*
		通策略, 默认门是关着的, 必须要定义谁能进.
		堵策略,大门是打开的,但是你必须有身份你认证,否则不能进去.
*/
表的概念

我们再想想另外一个问题,我们对每个"链"上都放置了一串规则,但是这些规则有些很相似,比如,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张"表"中。
*/

Filter

filter实现包过滤,定义允许或者不允许的[ 只能做在3个链上: INPUT表(进入的包), FORWORD(转发的包), OUTPUT(处理本地生成的包), filter表只能对包进行接收和丢弃的操作.

NAT

nat网络地址转换(只能做在3个链上: Prerouting(修改即将到来的数据包), output(修改在路由之前本地生成的数据包), Postrouting(修改即将出去的数据包)

Mangle

mangle包重构(修改), 修改报文原数据就是来修改TTL的, 能够实现将数据包的元数据拆开, 在里面做标记/修改内容的. 而防火墙标记, 其实就是靠mangle来实现的. 五个链都可以做.

raw

数据跟踪处理

Iptables传输数据包过程

1. 当一个数据包进入网卡时, 他首先进入prerouting链, 内核根据数据包目的IP判断是否传送出去.

2. 如果数据包进入本机, 他就会沿着图向下移动, 到达input链, 数据包到了input链后,任何进程都会收到他,本机上运行的程序可以发送数据包, 这些数据包会经过output链, 然后到达postrouting链输出

3. 如果数据包要转发出去,且内核允许转发,数据包就会如图所示向右移动,经过Forward链, 然后到达Postrouting链输出

iptables/netfilter(这款软件)是工作在用户空间的,他可以让规则进行生效的,本身不是一种服务, 而且规则是立即生效的, 而我们iptables现在被做成了一个服务, 可以进行启动,停止的, 启动,则将规则直接生效, 停止,则将规则撤销.

自定义链

iptables还支持自己自定义链, 但是自己自定义的链, 必须是跟某种特定的链关联起来的, 在一个关卡设定, 指定当有数据的时候专门去找某个特定的链来处理, 当那个链处理完之后, 再返回,接着在特定的链中继续检查.只有在被调用时才能发挥作用, 而且如果没有自定义链中的

注意: 规则的次序非常关键,检查规则是按照从上往下的方式进行检查的

/*
		用户可以删除自定义的空链
		默认链无法删除
		
		每个规则都有两个内置的计数器
				被匹配的报文个数
				被匹配的报文体积大小之和
*/
表链关系

但是我们需要注意的是,某些"链"中注定不会包含"某类规则",就像某些"关卡"天生就不具备某些功能一样,比如,A"关卡"只负责打击陆地敌人,没有防空能力,B"关卡"只负责打击空中敌人,没有防御步兵的能力,C"关卡"可能比较NB,既能防空,也能防御陆地敌人,D"关卡"最屌,海陆空都能防。

那让我们来看看,每个"关卡"都有哪些能力,或者说,让我们看看每个"链"上的规则都存在于哪些"表"中。

我们还是以图为例,先看看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,output
		mangle表中的规则可以被那些链使用:  prerouting, input, forward,output, postrouting
		nat表中的规则可以被那些链使用:  prerouting, output, postrouting (centos7中还有input,centos6中没有)
		filter表中的规则可以被那些链使用:  input,forward,output
*/

其实我们还需要注意一点,因为数据包经过一个"链"的时候,会将当前链的所有规则都匹配一遍,但是匹配时总归要有顺序,我们应该一条一条的去匹配,而且我们说过,相同功能类型的规则会汇聚在一张"表"中,那么,哪些"表"中的规则会放在"链"的最前面执行呢,这时候就需要有一个优先级的问题

iptables为我们定义了四张表, 当他们处于同一张链时, 执行的优先级如下

/*
		prerouting链中的规则存放于三张表中, 而这三张表的规则执行优先级如下:
			raw --> mangle --> nat

		优先级次序(由高而低)
			raw --> managle --> nat --> filter
*/

但是我们前面说过,某些链天生就不能使用某些表中的规则,所以,4张表中的规则处于同一条链的目前只有output链,它就是传说中海陆空都能防守的关卡。

为了更方便的管理,我们还可以在某个表里面创建自定义链,将针对某个应用程序所设置的规则放置在这个自定义链中,但是自定义链接不能直接使用,只能被某个默认的链当做动作去调用才能起作用,我们可以这样想象,自定义链就是一段比较"短"的链子,这条"短"链子上的规则都是针对某个应用程序制定的,但是这条短的链子并不能直接使用,而是需要"焊接"在iptables默认定义链子上,才能被IPtables使用,这就是为什么默认定义的"链"需要把"自定义链"当做"动作"去引用的原因。这是后话,后面再聊,在实际使用时我们即可更加的明白。

结合上述所有的描述,我们可以将数据包通过防火墙的流程总结为下:

我们在写Iptables规则的时候,要时刻牢记这张路由次序,灵活配置规则。

我们将经常用到的对应关系重新写在此处,方便对应图例查看。

链的规则存放于哪些表中(从链到表的对应关系):

/*	
		PREROUTING  的规则可以存在于:raw表,mangle表,nat表。
		INPUT     的规则可以存在于:mangle表,filter表,(centos7中还有nat表,centos6中没有)。
		FORWARD    的规则可以存在于:mangle表,filter表。
		OUTPUT    的规则可以存在于:raw表mangle表,nat表,filter表。
		POSTROUTING  的规则可以存在于:mangle表,nat表。
		
		
		表中的规则可以被哪些链使用(从表到链的对应关系):
		raw   表中的规则可以被哪些链使用:PREROUTING,OUTPUT
		mangle  表中的规则可以被哪些链使用:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
		nat   表中的规则可以被哪些链使用:PREROUTING,OUTPUT,POSTROUTING(centos7中还有INPUT,centos6中没有)
		filter  表中的规则可以被哪些链使用:INPUT,FORWARD,OUTPUT
*/

iptables规则写法

规则的概念

规则

根据指定的匹配条件来尝试匹配每个流经此处的报文,一旦匹配成功,则由规则后面指定的处理动作进行处理;

那么我们来通俗的解释一下什么是iptables的规则,之前打过一个比方,每条"链"都是一个"关卡",每个通过这个"关卡"的报文都要匹配这个关卡上的规则,如果匹配,则对报文进行对应的处理,比如说,你我二人此刻就好像两个"报文",你我二人此刻都要入关,可是城主有命,只有器宇轩昂的人才能入关,不符合此条件的人不能入关,于是守关将士按照城主制定的"规则",开始打量你我二人,最终,你顺利入关了,而我已被拒之门外,因为你符合"器宇轩昂"的标准,所以把你"放行"了,而我不符合标准,所以没有被放行,其实,"器宇轩昂"就是一种"匹配条件","放行"就是一种"动作","匹配条件"与"动作"组成了规则。

规则由匹配条件和处理动作组成

匹配条件

/*
		分为基本匹配条件与扩展匹配条件
		
		基本匹配条件:
				源地址Source IP, 目标地址DestinationIP.
				
		扩展匹配条件:
				分为
            1.隐含扩展: 不用特别指明那个模块进行的扩展,因为此时用-p {tcp|udp|icmp}
              除去上面条件可以用于匹配,还有其他条件可以用于匹配,这些条件泛称为扩展条件.
              这些扩展条件其实是netfilter中的一部分, 只是以模块的形式存在,如果想使用这些条件,则需要依赖对应的扩展模块.
              源端口Source Port,目标端口Destination Port
           
        		2.显式扩展: 必须指明由那个模块进行的扩展,在iptables中使用-m选项既可完成功能.
*/

处理动作

处理动作在iptables中被称为target(这样说并不准确,我们暂且这样称呼),动作也可以分为基本动作和扩展动作.

/*
		ACCEPT:允许数据包通过。
    DROP:直接丢弃数据包,不给任何回应信息,这时候客户端会感觉自己的请求泥牛入海了,过了超时时间才会有反应。
    REJECT:拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息。
    SNAT:源地址转换,解决内网用户用同一个公网地址上网的问题。
    MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的ip上。
    DNAT:目标地址转换。
    REDIRECT:在本机做端口映射。
    LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配。
*/

语法构成
/*
		iptables  [-t  表名]  选项(增删)  [链名]  [-m matchaname(匹配型模块)]  [per-match-options(模块自带选项)]  -j targetname[(操作型模块)控制类型]  [per-target-options(对应选项)]
		
		注意事项
				1. 不指定表名时, 默认指filter表.
				2. 不指定链名时, 默认指表内的所有链.
				3. 除非设置链的默认策略, 否则必须指定匹配条件.
				4. 选项,链名,控制类型使用大写字母,其余均小写
				
				
		规则组成:
			匹配条件 + 处理动作
				根据匹配条件尝试匹配报文,一旦匹配成功,就由定义的处理动作做出匹配.
				
				匹配条件: [尽可能准确指向要处理目标报文类型]
						基本匹配条件[内建]
						扩展匹配条件[外部扩展模块]
				处理动作:
						基本处理动作[内建]
						扩展处理动作[外部扩展模块]
						自定义处理机制
*/
规则编写逻辑
/*
		1. 先设置默认规则,全局拒绝或者全局接受[即白名单或黑名单]
		2. iptables规则检查时,是由上而下进行检查,一个请求报文符合某个条件时, 便被放心,不再接受下面的规则;
		3. 对于同一类规则中, 检查条件更苛刻规则放在前面; 对于不通类的规则[即控制不同服务的规则条目], 访问请求量更大的放在前面;
				! 修改默认规则为DROP之前, 必须先把自己主机IP设置在ssh服务白名单中,否则ssh连接会立刻断开.
			 [保险的做法是先定义一条计划任务,过一段时间后将规则清空,以防万一,确定无误后,将计划任务删掉;]
           INPUT:iptables -A INPUT -d 本身ip -j REJECT
           OUTPUT:iptables -A OUTPUT -s 本身ip -j REJECT
           FORWARD:iptables -A FORWARD -d 本身ip -j REJECT
        将所有前面未匹配到的规则都拒绝掉,如此就可以避免失误造成ssh服务被禁止;此外,这样设置可以使本机可以通过 127.0.0.1 访问本机;
     	! 或者可以直接在网卡级别进行设置;若有多个网卡则将其全部写入一个自定义链上,最后调用一下即可;
     	iptables -A INPUT -i ens33 -j REJECT
     	iptables -A OUTPUT -o ens33 -j REJECT
     	
   添加规则考量点:
   		1. 要实现那种功能: 判断添加到那个表上.
   		2. 报文流经的路径: 判断添加到那个链上.
   			链:链上的规则次序,即为检查的次序;因此,隐含一定的应用法则;
            (1)同类规则(访问同一应用),匹配范围小的放上面;
            (2)不同类的规则(访问不同应用),匹配到报文频率较大的放在上面;
            (3)将那些可由一条规则描述的多个规则合并起来;
            (4)设置默认规则
    iptables是高度模块化的,其由诸多扩展模块来实现其检查条件或处理动作的功能;
    rpm -ql iptables --> 在/usr/lib64/xtables/下有许多以'.so'结尾的文件,其中大写字母的是动作相关模块,小写字母是条件相关模块;其共称为iptables的扩展;    
    IPv6为libip6t_开头的,IPv4的是libipt_开头的,以libxt_开头的也适用于ipv4;
*/
规则command(增删)
/*
		添加新的规则:
				-A:  在链的末尾追加一条规则
				-I:  在链的开头(或指定序号)插入一条规则,省略时表示第一条.
				-s:  --src:  指定源地址,支持连续端口
				-s 匹配来源地址IP/MASK,加叹号"!"表示除这个IP外。
				--tcp-flags mask comp   只检查mask指定的标志位,是逗号分隔的标志位列表; comp: 此列表中出现的标记位必须为1, comp中没出现, 而mask中出现的必须为0;
						--tcp-flags SYN,FIN,ACK,RST SYN,ACK == --syn
						SYN为1,其他都为0,意味着三次握手的第一次,有一个特殊的简要写法
				--syn:   匹配三次握手的第一次	
				-o 		网卡名称 匹配从这块网卡流出的数据
				-i 		网卡名称 匹配从这块网卡流入的数据
				
				
          
				-d:  --dst:  指定目标地址
				-P 设置默认策略:iptables -P INPUT (DROP|ACCEPT)
				-p:  {tcp|udp|icmp}:  指定协议
						--icmp-type
								0:  echo-reply
								8:  echo-request
								
						udp
								--sport
								--dport
								
				ip_conntrack:  实时记录当前主机客户端,服务端正在建立连接的关系,是什么状态,
				可以只允许本地主机出去的连接必须为已经建立的连接,对别人的响应,否则不放行.
				因为是通过IP报文进行的追踪,tcp,udp都可以应用. 
				/proc/net/ip_conntrack可以查看建立连接信息,或者iptstate -t
				
				-i(INTERFACE):  指定数据报文流入的接口PREROUINT.
				-o(INTERFACE):  指定数据报文流出的接口.


				iptables  -t filter -A INPUT -p tcp -j ACCEPT
				iptables  -I INPUT  -p udp -j ACCEPT
				iptables  -I INPUT 2 -p icmp  -j ACCEPT
				
		 查看规则
				iptables -L INPUT --line-numbers
				-L:  列出所有规则条目
				-n:  以数字形式显示主机地址,端口等信息
				-v:  以更详细的方式显示规则信息
				--line-numbers:  查看规则时,显示规则的序号
				-v:  显示详细信息
				-vv:  更详细
				-x:   明确说明多少个字节,显示计数器精确值
				
				iptables -L -n 
          Chain INPUT (policy ACCEPT)
          [链]					[策略] [允许]
          target     prot opt source               destination 
          
				iptables -n -L -v
          Chain INPUT (policy ACCEPT 220 packets, 17378 bytes)
          pkts bytes target     prot opt in     out     source               destination         
				
				  chain:  [链]
				  policy:  [策略]
				  accept:  [允许]
        	pkts:  [被某一条规则匹配到数据包的个数]
					bytes:  [bytes] 字节数
					
		执行动作
					-j
							1. ACCEPT: 		允许通过
              2. DROP:  		直接丢弃,不给出任何回应
              3. REJECT: 		拒绝通过,必要时会给出提示.
              4. LOG:  			记录日志信息, 然后传给下一条规则继续匹配
              5. SNAT:  		修改数据包源地址
              6. REDIRECT:  端口重定向
              7. MASQUERADE: 做地址伪装(地址转换)
              8. LOG:     	日志
              9. MARK:			打标记
              
		替换规则
				-R CHAIN [num]:  替换指定的规则

		删除,清空规则
				-D: 删除链内指定序号(或内容)的一条规则.或者指明规则本身
				-F: 清空所有的规则链
				
				-R: replace, 替换指定链上的指定规则
				
				iptables -D INPUT 3
				iptables -n -L INPUT
				
				iptables [-t table] {-A|-C|-D} chain rule-specification    
        iptables [-t table] -I chain [rulenum] rule-spectification
             指定插入第几条,其后的所有规则都推后;
        iptables [-t table] -D chain relunum
        iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]
				
				
			
    管理链
				-P CHAIN: 	设定指定链默认策略
				-N:    自定义一个新的空链
				-X:    删除一个自定义空链
				-E:    置零指定链中所有规则的计数器
*/

Example

// 先写好规则,防止自己登录不上去
iptables -t filter -A INPUT -s 10.211.55.0/24 -d 10.211.55.3 -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -s 10.211.55.3 -d 10.211.55.0/24 -p tcp --sport 22 -j ACCEPT


iptables -t filter -A INPUT -s 192.168.43.0/24 -d 192.168.43.86 -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -s 192.168.43.86 -d 192.168.43.0/24 -p tcp --sport 22 -j ACCEPT

// 允许所有ssh连接的请求
iptables -A INPUT -i ens32 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o ens32 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

/*
		我们把iptables的链全部DROP
		iptables -P INPUT DROP
		iptables -P OUTPUT DROP
		iptables -P FORWARD DROP
		
		当INPUT链和OUTPUT链都设置成DROP时,对于每一个防火墙规则,我们都应该定义两个规则。
		例如:一个传入另一个传出。在下面所有的例子中,由于我们已将DROP设置成INPUT链和OUTPUT链的默认策略,
		每种情况我们都将制定两条规则。当然,如果你相信你的内部用户,则可以省略上面的最后一行。
		例如:默认不丢弃所有出站的数据包。在这种情况下,对于每一个防火墙规则要求,
		你只需要制定一个规则——只对进站的数据包制定规则。
		
		
		yum -y install httpd && systemctl start httpd
		
		当我们要开通任意IP访问时候0.0.0.0可以不用写,默认就是.
		
		开通80端口访问进出报文规则
		iptables -I INPUT -d 10.211.55.3 -p tcp --dport 80 -j ACCEPT
		iptables -I OUTPUT -s 10.211.55.3 -p tcp --sport 80 -j ACCEPT
		
		允许ping自己
		iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -i lo -j ACCEPT
		iptables -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -o lo -j ACCEPT
		
		iptables -A OUTPUT -s 10.211.55.4 -p icmp --icmp-type 8 -j ACCEPT
		iptables -A INPUT -d 10.211.55.4 -p icmp --icmp-type 0 -j ACCEPT
		
		
		开启ip_conntrack
		注意这个值改大一点,否则并发一高,大批量链接超时
		 sysctl -w net.ipv4.ip_conntrack_max=65535
		 cat /proc/sys/net/ipv4/ip_conntrack_max
		
		iptables -A INPUT -d 10.211.55.3 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
		iptables -A OUTPUT -s 10.211.55.3 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
		iptables -P INPUT DROP
		iptables -P OUTPUT DROP
		
		iptables -A INPUT -d 10.211.55.3 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
		iptables -A OUTPUT -s 10.211.55.3 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
		出去的报文必须是响应报文.
		
		iptables -A INPUT -d 10.211.55.3 -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED  -j ACCEPT
		iptables -A OUTPUT -s 10.211.55.3 -p icmp --icmp-type 0 -m state --state ESTABLISHED -j ACCEPT
		
*/
链管理
/*
		 -N:new,自定义一条新的规则链;
                iptables [-t tables] -N chain --> 链名不能与内置链冲突;
                    Chain in_web_rules (0 references) --> 引用计数,被引用一次加一;

            -X:delete,删除自定义的规则链;
                iptables [-t tables] -X in_web_rules
                    1、当一个链上有规则时,删不掉;
                    2、一个自定义链上的引用计数不为0时,删不掉;
                    3、内置链不能删;
                    · 即仅能删除‘自定义的’ ‘空的’ ‘未被引用’ 的链;

            -P:Policy,设置默认规则策略,对filter表而言,其默认策略有:
                ACCEPT:接受[内建]
                DROP:丢弃[内建]  --> 能DROP,就别REJECT;使用DROP虽然更安全,会花费更长时间;
                REJECT:拒绝[模块扩展]

            -E:重命名自定义链;被引用过的自定义链不能被重命名,也不能被删除;        
                eg:
                    iptables -N in_web
                    iptables -E  in_web in_web_rules
                    iptables -X  in_web_rules

            -F:flush,清空指定链上的规则,或一个表上的所有规则
                eg:
                    iptables -F IN_public --> 清除IN_public链上的所有规则;

            -Z:zero,置零两个计数器;
*/
保存生效规则
/*
		iptables不是服务,但有服务脚本, 服务脚本的主要作用在于管理保存的规则.因为iptables的所有规则定义完成后都保存在内核内存之中.
		装载及移除iptables/netfilter相关的内核模块:
		iptables_nat, iptables_filter,iptables_mangle, iptables_raw,ip_nat,ip_conntrack
		
		重载: systemctl reload iptables --> 默认从/etc/sysconfig/iptables中读取iptables规则;
		! 重载之后,只是规则生效,但是之前手动加载到内核的模块,不会被重新载入;
    ! 需要写脚本进行重载,或者更直接可以将所有iptables命令写入脚本,让其开机自动执行一遍;
		
		service iptables save
		iptables-save > /etc/sysconfig/iptables.2020.11.09
		iptables-restore < /etc/sysconfig/iptables.2020.11.09
*/

常用案例

iptables禁止某IP访问

在CentOS下封停IP,有封杀网段和封杀单个IP两种形式。一般来说,现在的攻击者不会使用一个网段的IP来攻击(太招摇了),IP一般都是散列的。于是下面就详细说明一下封杀单个IP的命令,和解封单个IP的命令。

在CentOS下,使用ipteables来维护IP规则表。要封停或者是解封IP,其实就是在IP规则表中对入站部分的规则进行添加操作。

要封停一个IP,使用下面这条命令:

iptables -I INPUT -s 172.18.80.5 -j DROP
# 也可以换成一个网段
iptables -I INPUT -s ***.***.***.*** -j DROP

要解封一个IP,使用下面这条命令

iptables -I INPUT -s 172.18.80.5 -j DROP
iptables -D INPUT -s ***.***.***.*** -j DROP

参数-I是表示Insert(添加),-D表示Delete(删除)。后面跟的是规则,INPUT表示入站,...表示要封停的IP,DROP表示放弃连接。

此外,还可以使用下面的命令来查看当前的IP规则表:

iptables --list

比如现在要将123.44.55.66这个IP封杀,就输入:

iptables -I INPUT -s 123.44.55.66 -j DROP

要解封则将-I换成-D即可,前提是iptables已经有这条记录。如果要想清空封掉的IP地址,可以输入:

iptables --flush

要添加IP段到封停列表中,使用下面的命令:

iptables -I INPUT -s 121.0.0.0/8 -j DROP

其实也就是将单个IP封停的IP部分换成了Linux的IP段表达式。关于IP段表达式网上有很多详细解说的,这里就不提了。

仅允许指定网络的ssh连接
[root@86 ~]# iptables -A INPUT -i ens32 -p tcp -s 192.168.43.84 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
[root@86 ~]# iptables -A OUTPUT -o ens32 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
允许http和https的连接请求
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT


// 允许所有来自web - https的连接请求
iptables -A INPUT -i eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
使用multiport将多个规则

允许多个端口从外界连入,除了为每个端口都写一条独立的规则外,我们可以用multiport将其组合成一条规则。如下所示: 例:允许所有ssh,http,https的流量访问

iptables -A INPUT -i eth0 -p tcp -m multiport --dports 22,80,443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m multiport --sports 22,80,443 -m state --state ESTABLISHED -j ACCEPT
允许从本地发起的ssh
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

# 请注意,这与允许ssh连入的规则略有不同。本例在OUTPUT链上,我们允许NEW和ESTABLISHED状态。
# 在INPUT链上,我们只允许ESTABLISHED状态。ssh连入的规则与之相反。
仅允许从本地发起一个指定网络域的ssh请求
# 仅允许从内部连接到网域192.168.100.0/24
iptables -A OUTPUT -o eth0 -p tcp -d 192.168.100.0/24 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
允许从本地发起的https连接请求
# 下面的规则允许输出安全的网络流量。如果你想允许用户访问互联网,这是非常有必要的。
# 在服务器上,这些规则能让你使用wget从外部下载一些文件
iptables -A OUTPUT -o eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT

# 对于HTTP web流量的外联请求,只需要将上述命令中的端口从443改成80即可。
负载均衡传入的网络流量
# 使用iptables可以实现传入web流量的负载均衡,我们可以传入web流量负载平衡使用iptables防火墙规则。 
# 例:使用iptables nth将HTTPS流量负载平衡至三个不同的ip地址.

iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 0 -j DNAT --to-destination 192.168.1.101:443
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 1 -j DNAT --to-destination 192.168.1.102:443
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 2 -j DNAT --to-destination 192.168.1.103:443
允许内部主机ping通内部主机
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
允许内部主机ping外部主机
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
允许回环访问
# 在服务器上允许127.0.0.1回环访问。
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
允许内部网络与外部网络通信

防火墙服务器上的其中一个网卡连接到外部,另一个网卡连接到内部服务器,使用以下规则允许内部网络与外部网络的通信。此例中,eth1连接到外部网络(互联网),eth0连接到内部网络(例如:192.168.1.x)。

iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
允许出站的DNS连接
iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT
允许NIS连接

如果你使用NIS管理用户帐户,你需要允许NIS连接。如果你不允许NIS相关的ypbind连接请求,即使SSH连接请求已被允许,用户仍然无法登录。NIS的端口是动态的,先使用命令rpcinfo –p来知道端口号,此例中为853和850端口。 rpcinfo -p | grep ypbind 例:允许来自111端口以及ypbind使用端口的连接请求

iptables -A INPUT -p tcp --dport 111 -j ACCEPT
iptables -A INPUT -p udp --dport 111 -j ACCEPT
iptables -A INPUT -p tcp --dport 853 -j ACCEPT
iptables -A INPUT -p udp --dport 853 -j ACCEPT
iptables -A INPUT -p tcp --dport 850 -j ACCEPT
iptables -A INPUT -p udp --dport 850 -j ACCEPT

# 当你重启ypbind之后端口将不同,上述命令将无效。有两种解决方案:
# 1)使用你NIS的静态IP 
# 2)编写shell脚本通过“rpcinfo - p”命令自动获取动态端口号,并在上述iptables规则中使用。
允许指定网络的rsync连接请求

允许来自网络192.168.101.0/24的rsync连接请求

iptables -A INPUT -i eth0 -p tcp -s 192.168.101.0/24 --dport 873 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 873 -m state --state ESTABLISHED -j ACCEPT
允许来自指定网络的Mysql请求

很多情况下,MySQL数据库与web服务跑在同一台服务器上。有时候我们仅希望DBA和开发人员从内部网络(192.168.100.0/24)直接登录数据库,可尝试以下命令:

iptables -A INPUT -i eth0 -p tcp -s 192.168.100.0/24 --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 3306 -m state --state ESTABLISHED -j ACCEPT
允许Sendmail,PostFix邮件服务

Sendmail和postfix都使用了25端口,因此我们只需要允许来自25端口的连接请求即可。

iptables -A INPUT -i eth0 -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
允许IMAP和IMAPS
# 允许IMAP/IMAP2流量,端口为143
iptables -A INPUT -i eth0 -p tcp --dport 143 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 143 -m state --state ESTABLISHED -j ACCEPT

# 允许IMAPS流量,端口为993
iptables -A INPUT -i eth0 -p tcp --dport 993 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 993 -m state --state ESTABLISHED -j ACCEPT
允许POP3 和POP3S
# 允许POP3访问
iptables -A INPUT -i eth0 -p tcp --dport 110 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 110 -m state --state ESTABLISHED -j ACCEPT


# 允许POP3S访问
iptables -A INPUT -i eth0 -p tcp --dport 995 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 995 -m state --state ESTABLISHED -j ACCEPT
防止Dos攻击
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT

# 上述例子中:
# -m limit: 启用limit扩展
# –limit 25/minute: 允许最多每分钟25个连接(根据需求更改)。
# –limit-burst 100: 只有当连接达到limit-burst水平(此例为100)时才启用上述limit/minute限制。
端口转发

将来自422端口的流量全部转到22端口。 这意味着我们既能通过422端口又能通过22端口进行ssh连接

iptables -t nat -A PREROUTING -p tcp -d 192.168.102.37 --dport 422 -j DNAT --to 192.168.102.37:22
  
# 除此之外,还需要允许连接到422端口的请求
iptables -A INPUT -i eth0 -p tcp --dport 422 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 422 -m state --state ESTABLISHED -j ACCEPT

iptables常用扩展模块

iprangne
/*
		-m iprange
				--src-range
				--dst-range
		iptables -A INPUT -p tcp -m iprange --src-range 10.211.55.4-10.211.55.5 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
*/	
connlimit
/*	
		连接数限制(connlimit)
			限定每一个IP最多发起多少个连接数.
		
			! --connlimit-above n 
			iptables -A INPUT -d 10.211.55.2 -p tcp --dport 80 -m connlimit --connlimit-above 2 -j ACCEPT
			
			tc
					令牌桶机制限流:  
					
			iptables -I INPUT -d 10.211.55.4 -p tcp --dport 22 -m limit --limit 3/minute --limit-burst 3 -j ACCEPT
			iptables -A INPUT -d 10.211.55.4 -p tcp --dport 80 -m con
*/
string

限定用户访问字符串

/*
		--algo {bm|kmp}
		--string "STRING"
		
		无法检查文件内容
		iptables -I OUTPUT -p tcp -m string --string "qq.com" --algo bm -j DROP
		iptables -I OUTPUT -p udp -m string --string "qq.com" --algo bm -j DROP
		这样就无法访问与QQ相关的业务了,但是代理好像还是可以
		
		
		如果是匹配到对应test页面名字就拒绝请求
		iptables -I INPUT -d 10.211.55.3 -m string --algo kmp --string "test" -j REJECT
		
		响应的报文是不会经过INPUT的,用户请求的报文也没有包含,所以需要把包改成对应名字, 除非加到OUTPUT
		iptables -I OUTPUT -s 10.211.55.3 -m string --algo kmp --string "zhou" -j REJECT
*/
Log
/*
		iptables -I INPUT 4 -d 10.211.55.3 -p icmp --icmp-type 8 -j LOG --log-prefix "--firewall log for icmp--"
*/
recent

利用iptables的recent模块抵御DOS攻击

/*
		iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
   iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
   iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-prefix "SSH Attach: "
   iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP
*/

cat /proc/net/xt_recent/SSH
src=192.168.43.219 ttl: 64 last_seen: 4295139283 oldest_pkt: 5 4295096752, 4295121813, 4295126037, 4295138280, 4295139283

// 一个IP连接三次后再去连接就会被拒绝
ssh 192.168.43.86
yssh: connect to host 192.168.43.86 port 22: Connection timed out

/*
		利用conlimit模块将单IP的并发设置为3,会误杀使用NAT上网的用户,可以根据实际情况增大该值
		利用recent和state模块限制单IP在300s内只能与本机建立3个新连接, 被限制五分钟后即可恢复访问.
		
		上面第二句记录tcp 22端口的新连接, 记录名称为SSH --set记录数据包的来源IP,如果IP已经存在将更新已经存在的条目.
		
		第三句是指SSH记录中的IP, 300s内发起超过3次连接则拒绝此IP的连接
		--update 是指每次建立连接都更新列表
		--seconds必须与 --rcheck或者--update同时使用
		--hitcount必须与--rcheck或者--update同时使用
	
*/

记录日志

/*
		iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --name SSH --second 300 --hitcount 3 -j LOG --log-prefix "SSH Attack"
*/

NAT表

主要功能

1、为了隐藏主机;

2、解决了ip地址短缺的问题;

问题:

当内外网将开启路由转发的Linux作为网关进行通信时,Linux对数据包并不会做任何改变,故内网主机的IP会暴露;黑客主机可以通过扫描工具对此内网主机ip进行扫描,并渗透;

解决:

nat表的功能可以实现,将经过自身的数据包进行改变,将其中的源地址修改为自身的ip,以此实现隐藏内网主机ip的功能;

nat表在修改数据包ip的同时,会将相关记录在内核内存中的连接追踪表中,当回应数据包到达自身时,其又会将数据包目的ip修改为内网主机ip,从而实现内网主机的正常通信

只需要关注请求的数据报文封装信息,因为响应的数据报文是由nat表的内建工作机制控制的,一般情况下无需人为干预(连接追踪机制)

被nat表所匹配到的数据报文,内核会修改报文的ip和端口,为了让转发机能在接收到返回报文后知道将此报文发送至何处,需要开启连接追踪机制;所谓连接追踪机制就是在内核内存空间中,开辟一块空间用于存放连接追踪表;转发机在修改报文ip和端口的同时,会在追踪表中进行记录,信息包括:请求的源地址,源端口,目标地址,目标端口,及报文序列号等;当响应报文到达时,转发机会根据响应报文中的源地址和端口查看此表,将相应转发到对应的服务器;

/*
		iptables -N clean_in
		iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP
		iptables -A clean_in -p tcp ! --syn -m state --state NEW -j DROP
*/
NAT类型(SNAT)

源地址转换

过程

内网主机网关指向NAT转发主机的内网IP, 当内网主机访问外网时,数据包经NAT转发主机, NAT转发主机开启内核转发机制, 并且在NAT表上设置相关规则, 同时打开链接追踪机制,由NAT转发主机的内核对数据包的源IP进行修改, 将其改为自身的IP, 并发送至请求的目标主机. 当响应报文返回时, 其目标ip为nat转发主机ip,nat转发主机收到后,根据内核中记录的连接追踪表,将此数据包转发给对应的内网主机,从而实现内网主机的nat通信.

特点

/*
		只能在POSTROUTING链上做:
		原因:
				1. 在POSTROUTING上的数据包,是已经被路由过的,其流向都已经确定.
				2. 第二次路由之前, 此数据包将要从那块网卡出去并不确定, 故只能在第二次路由之后的POSTROUTING上进行SNAT.
*/

应用场景

/*
		SNAT策略的典型应用环境
			区域网主机共享单个公网IP地址接入Internet
			
		SNAT策略的原理
			源地址转换, Source Network Address Translation
			修改数据包的源地址
*/
NAT类型(DNAT)

目标地址转换

服务器通过nat转发主机,向外网提供服务,对外提供的服务ip是nat网关的IP,客户端向nat网关发起请求,由nat网关根据请求的端口,以及自身规则,将数据包的目标ip地址转换为内网真实服务器ip;真实服务器的网关指向nat网关,当真实服务器回复响应数据包时,其目标ip地址是客户端的ip,而其源地址是自身ip,当通过nat网关时,由nat网关根据自身记录的连接追踪表,将源地址改为自身ip,发送给客户端,如此可以实现对内网服务器的隐藏;

特点

/*
		1. 只能在PREROUTING上做.
		2. NAT主机本身并不需要监听任何端口, 其内核自身就能通过数据包识别请求报文的请求目标端口.
				[无法通过ss,netstat等网络工具看到开放的监听端口]
		3. 所设置的规则只对某些端口生效: [因为其本质就像是一个四层的代理]
				原因: 因为数据包都是发给NAT网关本机的,若不在第一次路由之前做,有可能会被转发到自身的内核空间中.
*/
PAT[端口地址转换]

过程

在DNAT的基础上,对port也进行修改, 访问nat网关某个port的请求, 会被映射到后端真实服务器的真实port,返回时,再将目标端口修改为自身端口.

特点

/*
		只能在PREROUTING上做.
		原因: 因为数据包都是发给nat网关本机的,若不在第一次路由之前做,将会被转发到自身的内核空间中; 
*/
与数据包过滤结合

SNAT

SNAT和DNAT都会经过FORWARD,在FORWARD上配置iptables规则能实现包的过滤功能:

/*
		--使用方式: [SNAT和DNAT一般不不会在同一台主机上同时使用]
		SNAT:[一般开放所有服务的所有端口,-j]
		选项:
			--to-source [ipaddr[-ipaddr]] [:port[-port]]
				此选项用来定义要将原地址转换成什么地址对外进行访问,可以是一个地址区间[轮流使用];
			--ramdom
				当指定一个地址范围或多个地址作为原地址时, 将会随机进行挑选,而不是轮训.
			--persistent
				对于同一个客户端,其第一次访问时所分配的ip将被记录下来, 今后此客户端的每一个访问都将使用此IP;
				eg:
					iptables -t nat -A POSTROUTING -s 192.168.206.135 -j SNAT --to-source  10.0.128.50.
					在POSTROUTING链上做设置, 数据包的源地址是192.168.206.0/24的, 将会使用10.0.128.50作为源IP转发到目的IP上.
					
	MASQUERADE
		SNAT场景中,当外网地址不固定时,使用此动作.
		应用于POSTROUTING链上的规则,实现原地址转换.
*/

DNAT

[一般只开放有限协议的有限端口] --> PAT是DNAT的一种延伸,可以对端口进行修改

/*
		选项:
			--to-destination
				指定将目标地址修改为后端真实服务器IP
					eg: iptables -t nat -A PREROUTING -d 10.0.128.50 -p tcp --dport 80 -j DNAT --to-destination 192.168.206.135
					
		PEDIRECT:
			作用:
				此动作用于单台主机上,通过修改数据包的目标端口实现映射.
			特点: 
				工作在PREROUTING和OUTPUT链上;
				因为其要在请求数据包被路由之前对数据包中的目标端口进行修改,以此改变数据包的流向;
				eg:
					iptables -t nat -A PREROUTING -d 10.0.128.49 -p tcp --dport 80 -j REDIRECT --to-ports 8080
*/

Linux作为网络防火墙

当Linux作为网络防火墙时,目标不是本机的报文,将会在内核中被分配到对应的网卡接口;

其所依赖的规则为路由表:

在路由器中,数据包的流向通过路由表来决定,不同的目标ip将会从对应的网卡上被分发出去;

路由表的生成:

/*
		1、在小规模的内网中,或专用网络中,可以由管理人员通过添加路由条目的方式设置静态路由;
    2、更为普遍的方式是,通过专用的协议,从其他路由器上,获取共享的路由信息,动态生成路由条目;
            优点:
                [这种方式可以动态的判断哪些路由线路是失效的,会将对应的路由条目标记为不可用]
            缺点:
                1) [这种方式会消耗额外的网络带宽,因为其路由条目的生成过程也是需要发送网络报文的]
                2) [在本地需要安装专门的应用程序后,才能完成这种复杂功能,对于系统资源有一定消耗(此种应用程序可以提供相关的协议和算法)]
                
      			--> 如GNU项目的"zebra"[斑马];
                  他可以基于TCP/IP的路由协议,将Linux变成一台全功能路由器。其所支持的协议包括:RIP,OSPF,BGP
                  ~ 扩展:
                     动态路由条目生成的常用协议包括:
                     RIP2:矢量的
                        -->根据所要经过的网关数量来判断最优线路;
                       [但是这样判断出的最优线路所花费时间并不一定最短,因为某些链路可能会堵塞]
                       OSPF(开放式最短路径优先):链路状态
                        -->判断能到达目标的线路中,哪条线路是最通畅的;
                        ...还有其他很多类似的算法和协议;
    3 因为其工作在通用架构cpu上,故其对于数据报文转发的效率并不高;[只能承担压力较轻的数据转发]        
        
*/
数据流经过程
/*
		->PREROUTING,对数据包进行初步操作;
        -->进行路由,拆数据包到网络层,判断数据包目标ip是否是本机ip。
         若是,则路由进INPUT链,进入本机;
         若不是,则数据包进入FORWARD链;由		FRORWARD的相关规则进行匹配过滤;
         再次路由,对不同的数据包进行分析,根据路由表来规定,将数据包从哪个网卡发送到下一跳;
        POSTROUTING,
        进入网卡队列等待发送                    
    所以,过滤规则的设置,只能在FORWARD之上进行设置;
    FORWARD链规则,不论正向还是反向,其都要经过FORWARD,故其规则的设置是通过数据流向来进行定义的;
        根据state,即状态匹配扩展模块来实现;
        在FORWARD这一条链上,定义一个ESTABLISHED,和一条NEW,新请求接受判断,已建立连接的请求直接放过;
*/
Example

环境

/*
		
        内网主机:192.168.206.135
        Linux网络交换机:
            ens33 10.0.128.50
            ens37 192.168.206.133
        外网主机:10.0.128.49 
        内网主机网关指向防火墙的ens37,外网主机网关指向防火墙的ens33;
        网络防火墙打开核心转发功能;
        	内外网主机可以相互ping通,并且服务也正常开启    
        	配置外网主机能访问内网某台主机的相关服务:
*/

配置Linux网络交换机

vim /etc/sysctl.conf 
net.ipv4.ip_forward = 1
sysctl -p /etc/sysctl.conf

[root@86 network-scripts]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:0b:ea:c3 brd ff:ff:ff:ff:ff:ff
    inet 192.168.43.86/24 brd 192.168.43.255 scope global dynamic ens32
       valid_lft 2951sec preferred_lft 2951sec
3: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:0b:ea:cd brd ff:ff:ff:ff:ff:ff
    inet 172.18.80.2/24 brd 172.18.80.255 scope global ens34
       valid_lft forever preferred_lft forever

[root@86 network-scripts]# cat ifcfg-ens32 
BOOTPROTO="dhcp"
NAME="ens32"
DEVICE="ens32"
ONBOOT="yes"

[root@86 network-scripts]# cat ifcfg-ens34
IPADDR=172.18.80.2
NETMASK=255.255.255.0
DNS1=114.114.114.114
BOOTPROTO="none"
NAME="ens34"
DEVICE="ens34"
ONBOOT="yes"

配置模拟内网机器

[root@47 network-scripts]# cat ifcfg-ens32 
IPADDR=172.18.80.3
NETMASK=255.255.255.0
GATEWAY=172.18.80.2
DNS1=114.114.114.114
BOOTPROTO="none"
NAME="ens32"
DEVICE="ens32"
ONBOOT="yes"

[root@47 network-scripts]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.18.80.2     0.0.0.0         UG    100    0        0 ens32
172.18.80.0     0.0.0.0         255.255.255.0   U     100    0        0 ens32

外网主机

[root@219 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:27:24:ef brd ff:ff:ff:ff:ff:ff
    inet 192.168.43.219/24 brd 192.168.43.255 scope global dynamic ens32
       valid_lft 3024sec preferred_lft 3024sec
SNAT_Example
# 客户端本来不通的
[root@47 network-scripts]# ping baidu.com
^C
[root@47 network-scripts]# ssh 192.168.43.219
^C



# 通过防火墙转发
[root@86 network-scripts]# iptables -t nat -A POSTROUTING -s 172.18.80.0/24 -o ens32 -j SNAT --to-source 192.168.43.86


# 客户端测试
[root@47 network-scripts]# curl 192.168.43.219 -I
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Wed, 11 Nov 2020 08:44:12 GMT
Content-Type: text/html
Content-Length: 4833
Last-Modified: Fri, 16 May 2014 15:12:48 GMT
Connection: keep-alive
ETag: "53762af0-12e1"
Accept-Ranges: bytes

  
[root@47 network-scripts]# ping baidu.com
PING baidu.com (220.181.38.148) 56(84) bytes of data.
64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=1 ttl=49 time=7.12 ms  
  
# ping: unknown host www.baidu.com要是出现这个问题就添加一个DNS服务器地址/etc/resolv.conf也可以写在和主机一起的配置文件当中,DNS地址最好是服务器的DNS地址。 


# server端使用地址伪装
[root@86 network-scripts]# iptables -t nat -A POSTROUTING -s 172.18.80.0/24 -o ens32 -j MASQUERADE

# 客户端测试效果一样
# 地址伪装技术更加接近我们实际的工作生活当中因为我们拨号上网有可能我们使用的公网IP就发生了变化。
DNAT_Example

/*
		区域网的Web服务能够访问Internet
		网关的外网地址有正确的DNS解析记录
		Linux网关支持IP路由支持
		
		编写DNAT转换规则
		iptables -t nat -A PREROUTING -i eth0 -d 218.29.30.31 -p tcp --dport  80 -j DNAT --to-destination 192.168.1.6
*/

编写DNAT规则

iptables -t nat -A PREROUTING -i ens34 -d 172.18.80.2 -p tcp  --dport 80 -j DNAT --to-destination 192.168.43.86

[root@86 network-scripts]# iptables -nL -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  0.0.0.0/0            172.18.80.2          tcp dpt:80 to:192.168.43.219
DNAT       tcp  --  0.0.0.0/0            172.18.80.2          tcp dpt:80 to:192.168.43.86

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.18.80.0/24       0.0.0.0/0 

Commond

/*
		iptables -A FORWARD -j REJECT
    iptables -I FORWARD 2 -d 172.18.80.3 -s 192.168.43.219 -p tcp -m multiport --dports 21,22,23,80,139,445,3306 -m state --state NEW -j ACCEPT
    iptables -I FORWARD 3 -d 172.18.80.3 -s 192.168.43.219 -p udp --dport 137:138 -m state --state NEW -j ACCEPT
		iptables -I FORWARD 1 -d -m state --state ESTABLISHED,RELATED -j ACCEPT

		iptables -I FORWARD 4 -s 172.18.80.0/24 -m state --state NEW -j ACCEPT


		iptables -A FORWARD -j REJECT
    iptables -I FORWARD 2 -d 192.168.206.135 -s 10.0.128.49 -p tcp -m multiport --dports 21,22,23,80,139,445,3306 -m state --state NEW  -j ACCEPT
     iptables -I FORWARD 3 -d 192.168.206.135 -s 10.0.128.49 -p udp --dport 137:138 -m state --state NEW -j ACCEPT
     iptables -I FORWARD 1 -d -d 172.18.80.3 -s 192.168.43.219 -m state --state ESTABLISHED,RELATED -j ACCEPT
     
     
     配置内网主机访问外网一切服务:
         iptables -I FORWARD 4 -s 192.168.206.0/24 -m state --state NEW -j ACCEPT
    
    
     配置Linux防火墙支持ftp服务,加载内核模块:
            modprobe nf_conntrack_ftp
                [/etc/sysconfig/iptables-config]
                --->在此配置文件中的 IPTABLES_MODULES="" 中添加模块类型即可实现启动自动加载
                !!只适用于FORWARD链
                
                
                
                
   iptables -t nat -A PREROUTING -i ens34 -d 172.18.80.2  -p tcp --dport 80 -j DNAT --to-destination 192.168.43.86     
*/
或者通过host.allow限制特定IP来访
# 生效是立即发生的,但是对于已经打开的shell无效,所以一边留着shell设置,一边再开shell
tail -1 /etc/hosts.allow
sshd:39.108.140.0:allow        # 允许此IP登陆

tail -1 /etc/hosts.deny
sshd:all                       # 禁止所有机器登陆

tail -1 /etc/ssh/sshd_config
allowusers root@ip             # 允许某个IP用什么账户登陆,否则登陆不上去

cat /etc/ssh/sshd_config |grep 10086
Port 10086              
posted @ 2020-11-08 18:13  常见-youmen  阅读(2218)  评论(0编辑  收藏  举报