当前位置:首页 > 运维 > 正文内容

linux中iptables防火墙详解

phpmianshi12个月前 (10-12)运维1819

1、iptables入门简介

Netfilter/Iptables(以下简称Iptables)是unix/linux自带的一款优秀且开放源代码的完全自由的基于包过滤的防火墙工具,主要工作在OSI七层的二、三、四层。它实际上由两个组件netfilter 和 iptables 组成。

Netfilter 组件也称为内核空间(kernelspace),是内核的一部分,由一些信息包过滤表组成,这些表包含内核用来控制信息包过滤处理的规则集。

Iptables 组件是一种工具,也称为用户空间(userspace),它使插入、修改和除去信息包过滤表中的规则变得容易。

2、iptables表与链功能

Iptables的规则链分为三种:输入、转发和输出。

  • 输入——这条链用来过滤目的地址是本机的连接。例如,如果一个用户试图使用SSH登陆到你的PC/服务器,iptables会首先匹配其IP地址和端口到iptables的输入链规则。

  • 转发——这条链用来过滤目的地址和源地址都不是本机的连接。例如,路由器收到的绝大数数据均需要转发给其它主机。如果你的系统没有开启类似于路由器的功能,如NATing,你就不需要使用这条链。

  • 输出——这条链用来过滤源地址是本机的连接。例如,当你尝试ping phpmianshi.com 时,iptables会检查输出链中与ping和 phpmianshi.com  相关的规则,然后决定允许还是拒绝你的连接请求。

注意:当ping一台外部主机时,看上去好像只是输出链在起作用。但是请记住,外部主机返回的数据要经过输入链的过滤。当配置iptables规则时,请牢记许多协议都需要双向通信,所以你需要同时配置输入链和输出链。人们在配置SSH的时候通常会忘记在输入链和输出链都配置它。

3、iptables数据包流程

在这里插入图片描述
数据包先经过PREOUTING,由该链确定数据包走向:

  • 目的地址是本地,则发送到INPUT,让INPUT决定是否接收下来送到用户空间,流程为①—>②;

  • 若满足PREROUTING的nat表上的转发规则,则发送给FORWARD,然后再经过POSTROUTING发送出去,流程为: ①—>③—>④—>⑥;

  • 主机发送数据包时,流程则是⑤—>⑥;

  • 其中PREROUTING和POSTROUTING指的是数据包的流向,如上图所示POSTROUTING指的是发往公网的数据包,而PREROUTING指的是来自公网的数据包。

在这里插入图片描述

4、iptables四张表&五条链

iptables具有Filter, NAT, Mangle, Raw四种内建表。

在这里插入图片描述

5、iptables下Filter表

Filter表示iptables的默认表,因此如果你没有自定义表,那么就默认使用filter表,它具有以下三种内建链:

  • INPUT链 – 处理来自外部的数据;

  • OUTPUT链 – 处理向外发送的数据;

  • FORWARD链 – 将数据转发到本机的其他网卡设备上。

6、iptables下NAT表

NAT (网络地址转换) 技术在平时是很多见的,如家庭中在使用路由器共享上网时,一般用的就是 NAT 技术,它可以实现众多内网 IP 共享一个公网 IP 上网。

NAT 的原理,简单的说就是当内网主机访问外网时,当内网主机的数据包要通过路由器时,路由器将数据包中的源内网 IP 地址改为路由器上的公网 IP 地址,同时记录下该数据包的消息;

外网服务器响应这次由内而外发出的请求或数据交换时,当外网服务器发出的数据包经过路由器时,原本是路由器上的公网 IP 地址被路由器改为内网 IP 。

SNAT 和 DNAT 是 iptables 中使用 NAT 规则相关的的两个重要概念。如上图所示,如果内网主机访问外网而经过路由时,源 IP 会发生改变,这种变更行为就是 SNAT;反之,当外网的数据经过路由发往内网主机时,数据包中的目的 IP (路由器上的公网 IP) 将修改为内网 IP,这种变更行为就是 DNAT 。NAT表有三种内建链:

  • PREROUTING链 – 处理刚到达本机并在路由转发前的数据包。它会转换数据包中的目标IP地址(destination ip address),通常用于DNAT(destination NAT)。

  • POSTROUTING链 – 处理即将离开本机的数据包。它会转换数据包中的源IP地址(source ip address),通常用于SNAT(source NAT)。

  • OUTPUT链 – 处理本机产生的数据包。

7、iptables配置文件

vi /etc/sysconfig/iptables
#规则配置文件,当使用命令保存内存中的规则后,规则将写入到该文件中;
#也可以直接在该文件中配置规则,重启iptables后该规则将全部重新加载到内存;


8、iptables 命令

iptables [选项] [参数]

#iptables命令选项输入顺序:
iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网> 
--sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作

选项

说明
-t <表>指定要操纵的表;
-A顺序添加,向规则链中添加新规则;
-D从规则链中删除条目,-D 后面加一数字表示删除哪行规则;
-I插入,插入一条新规则,-I 后面加一数字表示插入到哪行前面;
-R替换规则链中的条目,-R 后面加一个数字表示替换哪行规则;
-i <数据包进入的网卡>指定数据包进入本机的网络接口;
-o <数据包出口的网卡>指定数据包要离开本机所使用的网络接口。
-p tcp/udp/icmp指定要匹配的数据包协议类型;
-s指定要匹配的数据包源ip地址;
-d指定要匹配的数据包目的ip地址
–sport port指定源端口
–dport port指定目标端
-j <目标>指定要跳转的目标;
-L显示规则链中已有的条目;
-n表示以数字形式显示真实IP地址
–line-numbers表示显示规则序列号
-F清楚规则链中已有的条目;
-Z清空规则链中的数据包计算器和字节计数器;
-N创建新的用户自定义规则链;
-X删除一个自定义链,删除之前要保证次链是空的,而且没有被引用;
-P定义规则链中的默认规则;
-h显示帮助信息;
-E重命名链;

扩展匹配:除了上述的条件可以用于匹配,还有很多其他的条件可以用于匹配,这些条件泛称为扩展条件,这些扩展条件其实也是netfilter中的一部分,只是以模块的形式存在,如果想要使用这些条件,则需要依赖对应的扩展模块。

扩展匹配说明
-m state --state匹配状态的
-m multiport --source-port端口匹配,指定一组端口;
多个端口格式为:80,81;
范围格式为:79:81;
-m limit --limit 3/minute任意IP每分钟访问3次
-m limit --limit-burst 5只匹配5个数据包
-m string --string --algo bmkmp --string"xxxx"
-mtime–timestart 8:00 --timestop 12:00表示从哪个时间到哪个时间段
-mtime–days表示哪天
-m mac --mac-source xx:xx:xx:xx:xx:xx匹配源MAC地址
-m layer7 --l7proto qq表示匹配腾讯qq的 当然也支持很多协议,这个默认是没有的,需要我们给内核打补丁并重新编译内核及iptables才可以使用 -m layer7 这个显示扩展匹配

表名包括:

表名说明
raw高级功能,如
mangle数据包修改(QOS),用于实现服务质量。
net地址转换,用于网关路由器。
filter包过滤,用于防火墙规则。

规则链名包括:

规则链名说明
INPUT处理输入数据包。
OUTPUT处理输出数据包。
PORWARD处理转发数据包。
PREROUTING用于目标地址转换(DNAT)。
POSTOUTING用于源地址转换(SNAT)。

动作包括:

动作说明
ACCEPT接收数据包。
DROP丢弃数据包。
REJECT丢掉数据包,但是回复信息;
REDIRECT重定向、映射、透明代理。
SNAT源地址转换。
DNAT目标地址转换。
MASQUERADEIP伪装(NAT),用于ADSL。
LOG, --log-prefix “说明信息,自己随便定义”日志记录。

在这里插入图片描述

9、iptables规则文件解析

注意:IPtables规则文件中的规则是从上往下执行的,所以规则的顺序很重要!

[root@localhost ~]# vim /etc/sysconfig/iptables
:INPUT ACCEPT [0:0]
#该规则表示INPUT表默认策略是ACCEP([0:0]里记录的就是通过该规则的数据包和字节总数。)
:FORWARD ACCEPT [0:0]
#该规则表示FORWARD表默认策略是ACCEPT
:OUTPUT ACCEPT [0:0]
#该规则表示OUTPUT表默认策略是ACCEPT
-A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
#意思是允许进入的数据包只能是刚刚我发出去的数据包的回应,ESTABLISHED:已建立的链接状态。RELATED:该数据包与本机发出的数据包有关。
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
#意思就允许本地环回接口在INPUT表的所有数据通信,-i 参数是指定接口,接口是lo,lo就是Loopback(本地环回接口)
-A INPUT -j REJECT –reject-with icmp-host-prohibited
-A FORWARD -j REJECT –reject-with icmp-host-prohibited
#这两条的意思是在INPUT表和FORWARD表中拒绝所有其他不符合上述任何一条规则的数据包。并且发送一条host prohibited的消息给被拒绝的主机。

-A INPUT -m state –state NEW -m tcp -p tcp –dport 22 -j ACCEPT
说明:
-A:最后添加一条规则
-j:后面接动作,主要的动作有接受(ACCEPT)、丢弃(DROP)、拒绝(REJECT)及记录(LOG)
–dport:限制目标的端口号码。
-p 协议:设定此规则适用于哪种封包格式 主要的封包格式有: tcp, udp, icmp 及 all 。
-m state –state:模糊匹配一个状态,
NEW:用户发起一个全新的请求
ESTABLISHED:对一个全新的请求进行回应
RELATED:两个完整连接之间的相互关系,一个完整的连接,需要依赖于另一个完整的连接。
INVALID:无法识别的状态。


10、iptables案例详解

当在服务器安装好iptables软件之后,首先看看规则文件中默认的规则都有哪些,命令如下:

[root@localhost ~]# iptables -L -n --line-numbers
#该命令是查询当前系统内存中的规则
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
2    ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           
3    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
4    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22 
5    REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited 
Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination         
1    REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited 
Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination   
COMMIT


在这里重点关注的是filter表中第5条规则,意思是拒绝所有其他不符合上述任何一条规则的数据包。并且发送一条host prohibited的消息给被拒绝的主机。所以如果我们需要添加规则则需要添加到此项规则前面才行,否则在第5条规则就会被拒绝,那么下面的规则也就补齐作用了。

  1. WEB服务器,开启80端口;

[root@localhost ~]# iptables -t filter -I INPUT 5 -p tcp --dport 80 -j ACCEPT
[root@localhost ~]# iptables -t filter -A OUTPUT -p tcp --sport 80 -j ACCEPT


我们来解释下:当客户端访问服务器的web服务时,客户端发送报文到网卡,而tcp/ip协议栈是属于内核的一部分,所以,客户端的信息会通过内核的TCP协议传输到用户空间中的web服务中,而此时,客户端报文的目标终点为web服务所监听的套接字(IP:Port)上,所以在INPUT中使用“–dport 80”;当web服务需要响应客户端请求时,web服务发出的响应报文的目标终点则为客户端,这个时候,web服务所监听的IP与端口反而变成了原点,所以在OUPUT中需要使用“–sport 80”;如下图所示:

在这里插入图片描述

  1. 邮件服务器,开启25,110端口;

[root@localhost ~]# iptables -A INPUT -p tcp --dport 110 -j ACCEPT
[root@localhost ~]# iptables -A INPUT -p tcp --dport 25 -j ACCEPT
#上面的两条规则也可以合并为一条规则,命令如下:
[root@localhost ~]# iptables -A INPUT -m multiport -p tcp --dport 25,110 -j ACCEPT


  1. FTP服务器,开启21,20端口

[root@localhost ~]# iptables -A INPUT -p tcp --dport 21 -j ACCEPT
[root@localhost ~]# iptables -A INPUT -p tcp --dport 20 -j ACCEPT
或
[root@localhost ~]# iptables -A INPUT -m multiport -p tcp --dport 20,21 -j ACCEPT

        允许icmp包通过,也就是允许ping,

[root@localhost ~]# iptables -A OUTPUT -p icmp -j ACCEPT
#如果默认OUTPUT规则设置成DROP了,那么在下面的规则中必须添加一个单独的OUTPUT,否则会采用默认的OUTPUT规则
[root@localhost ~]# iptables -A INPUT -p icmp -j ACCEPT
#同理,如果默认INPUT设置成DROP的了,那么下面的规则必须单独添加INPUT规则,否则会采用默认的INPUT规则


注意:iptables默认规则的优先级低于单独设置的规则。


  1. 将本机的8080端口转发至其他主机80端口,主机IP:192.168.100.120,目标主机IP和端口:192.168.100.100:80,规则如下;

[root@localhost ~]# iptables -t nat -A PREROUTING  -d 192.168.100.120/32 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.168.100.100:80
[root@localhost ~]# iptables -t nat -A POSTROUTING -d 192.168.100.100/32 -p tcp -m tcp --dport 80 -j SNAT --to-source 192.168.100.120

[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
#同时开启iptables forward转发功能。

查看当前内存中的iptables规则;

[root@localhost ~]# iptables -t filter -L -n --line-numbers
#其中-L表示显示匹配规则类别,-t指定表,-n表示以数字形式显示真实IP地址,--line-numbers表示显示规则序列号
[root@localhost ~]# iptables -L -v
#输出详细信息,包含通过该规则的数据包数量,总字节数及相应的网络接口
[root@localhost ~]# iptables -L -x
#显示精确信息

保存iptables规则:

[root@localhost ~]# service iptables save
或
[root@localhost ~]# iptables-save > /etc/sysconfig/iptables
#iptables-save 打印当前内存中的规则

11、iptables企业案例规则实战

生产环境,线上门户网站iptables规则策略如下:

[root@localhost ~]# vim /etc/sysconfig/iptables
#Generated by iptables-save v1.4.7 on Wed Dec 14 21:05:31 2016
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [602:39593]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
#########################
-A INPUT -i lo -j ACCEPT
-A INPUT -s 116.22.202.146 -j DROP
-A INPUT -s 139.224.227.121 -j ACCEPT
##########################
-A INPUT -p icmp -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A INPUT -s 116.243.139.7 -p tcp -m state --state NEW -m tcp --dport 7001 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8801 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 25 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 110 -j ACCEPT
####
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
#Completed on Wed Dec 14 21:05:31 2016


版权声明:本文由PHP面试资料网发布,如需转载请注明出处。
分享给朋友:

相关文章

nginx实现高并发的优化手段有哪些

Nginx 是如何实现高并发的?异步,非阻塞,使用了epoll 和大量的底层代码优化。如果一个server采用一个进程负责一个request的方式,那么进程数就是并发数。正常情况下,会有很多进程一直在...


1、应用程序中调用read() 方法,这里会涉及到一次上下文切换(用户态->内核态),底层采用DMA(direct memory access)读取磁盘的文件,并把内容存储到内核地址空间的读取缓存区。

操作系统检测到进程向I/O设备发起请求后就暂停进程的运行,怎么暂停运行呢?

很简单:只需要记录下当前进程的运行状态并把CPU的PC寄存器指向其它进程的指令就可以了。
进程有暂停就会有继续执行,因此操作系统必须保存被暂停的进程以备后续继续执行,显然我们可以用队列来保存被暂停执行的进程。

注意:现代磁盘向内存copy数据时无需借助CPU的帮助,这就是所谓的DMA(Direct Memory Access)。

实际上:操作系统中除了有阻塞队列之外也有就绪队列,所谓就绪队列是指队列里的进程准备就绪可以被CPU执行了。
你可能会问为什么不直接执行非要有个就绪队列呢?

答案很简单:那就是僧多粥少,在即使只有1个核的机器上也可以创建出成千上万个进程,CPU不可能同时执行这么多的进程,因此必然存在这样的进程,即使其一切准备就绪也不能被分配到计算资源,这样的进程就被放到了就绪队列。

当进程A被暂停执行后CPU是不可以闲下来的,因为就绪队列中还有嗷嗷待哺的进程B,这时操作系统开始在就绪队列中找下一个可以执行的进程,也就是这里的进程B。
此时操作系统将进程B从就绪队列中取出,找出进程B被暂停时执行到的机器指令的位置,然后将CPU的PC寄存器指向该位置,这样进程B就开始运行啦。

此后磁盘终于将全部数据都copy到了进程A的内存中,这时磁盘通知操作系统任务完成啦,你可能会问怎么通知呢?这就是中断
操作系统接收到磁盘中断后发现数据copy完毕,进程A重新获得继续运行的资格,这时操作系统小心翼翼的把进程A从阻塞队列放到了就绪队列当中。

注意:从前面关于就绪状态的讨论中我们知道,操作系统是不会直接运行进程A的,进程A必须被放到就绪队列中等待,这样对大家都公平。

此后进程B继续执行,进程A继续等待,进程B执行了一会儿后操作系统认为进程B执行的时间够长了,因此把进程B放到就绪队列,把进程A取出并继续执行。

注意:操作系统把进程B放到的是就绪队列,因此进程B被暂停运行仅仅是因为时间片到了而不是因为发起I/O请求被阻塞。

进程A继续执行,此时buff中已经装满了想要的数据,进程A就这样愉快的运行下去了,就好像从来没有被暂停过一样


2、由于应用程序无法读取内核地址空间的数据,如果应用程序要操作这些数据,必须把这些内容从读取缓冲区拷贝到用户缓冲区。这个时候,read() 调用返回,且引发一次上下文切换(内核态->用户态),现在数据已经被拷贝到了用户地址空间缓冲区,这时,如果有需要,应用程序可以操作修改这些内容。

3、我们最终目的是把这个文件内容通过Socket传到另一个服务中,调用Socket的send()方法,这里又涉及到一次上下文切换(用户态->内核态),同时,文件内容被进行第三次拷贝,被再次拷贝到内核地址空间缓冲区,但是这次的缓冲区与目标套接字相关联,与读取缓冲区没有半点关系。

4、send()调用返回,引发第四次的上下文切换,同时进行第四次的数据拷贝,通过DMA把数据从目标套接字相关的缓存区传到协议引擎进行发送。

"在整个过程中,过程1和4是由DMA负责,并不会消耗CPU,只有过程2和3的拷贝需要CPU参与


如果在应用程序中,不需要操作内容,过程2和3就是多余的,如果可以直接把内核态读取缓存冲区数据直接拷贝到套接字相关的缓存区,是不是可以达到优化的目的?

Linux中nio的实现原理

我们上一篇文章 《linux中netstat和ss命令详解》中提到了nio 原文:https://phpmianshi.com/?id=105有一些小伙伴私信想了解什么是nio,我们这篇详细介绍下什么...

linux中后台进程管理利器supervisord

背景Linux的后台进程运行有好几种方法,例如nohup,screen等,但是,如果是一个服务程序,要可靠地在后台运行,我们就需要把它做成daemon,最好还能监控进程状态,在意外结束时能自动重启。s...

linux中Cannot assign requested address的问题处理

问题描述:最近系统报警有类型如下错误:Cannot assign requested address  主要是连接mysql时产生的错误。分析原因:客户端与服务端每建立一个连接,客户端一侧都...

linux中sed用法读这一篇就够了

1.概念sed是一种行编辑器,它一次处理一行内容。处理时,把 当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的...

进程、线程和协程三者之间的区别和联系

一、进程、线程、协程1,进程    进程,直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己独立的地址空间,有自己的堆,...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。