防火墙介绍
防火墙的作用可以理解为是一堵墙,是一个门,用于保护服务器安全的。
防火墙可以保护服务器的安全,还可以定义各种流量匹配的规则。
防火墙的作用
防火墙具有对服务器很好的保护作用,入侵者必须穿透防火墙的安全防护线,才能接触到目标机器。
防火墙的功能
防火墙对经过它的流量进行扫描,这样就能过滤一些恶意的流量以免在目标机器上执行
防火墙还能阻挡,关闭一些不常用的端口,禁止该端口的流量进出
服务器的端口就像银行的窗口,能够进行流量的进入和流出
防火墙的概念
linux 下防火墙一般分为软件防护墙(程序员写出来的工具比如 iptables )和硬件防火墙
硬件防火墙:只要花钱去买,按照手册使用就可以
硬件防火墙是在硬件级别实现防火墙功能,流量过滤功能,特点是性能高成本也很高
硬件防火墙跟服务器一样,就是机器,他的作用是保证服务器安全,在这台机器里面定制一些网络流量,过滤一些条件,一些策略,但是硬件防火墙成本太高,因此就出现了软件防火墙。
软件防火墙:
是程序员写出来的软件,在软件系统内核级别实现网络流量的过滤,性能稍弱,但是成本很低。因此很多公司选择使用软件防火墙。阻挡一些常见的流量,还有一些公司软件防火墙与硬件防火墙结合起来用,都可以。
在 linux 上提供的软件防火墙,名字叫 iptables, 它是防火墙命令行工具,我们通过 iptables 在命令行终端去写防火墙的各种各样的规则,去定义好各种各样的策略。因此 iptables 它是一个工具。还可以理解为:iptables 是客户端代理。通过 iptables 的代理,将用户配置的安全策略,执行到对应的安全框架中是 netfilter ,netfilter 才是真正在系统内核级别,操作系统级别,实现网络流量过滤的工具
iptables 只是一个命令行工具,iptables 处于用户空间和我们用户离得是最近的,属于用户空间
真正实现流量过滤的软件是 netfilter
它处于系统内核空间,和操作系统离得是最近的。
因此,iptables+netfilter 这个两个软件共同组成了 linux 的软件防火墙,一般用来替代昂贵的硬件防火墙了
在 ccentos7 系统下,防火墙它又做了改进
firewalld软件,又替代了 iptables 工具。
iptables 是把用户配置的防火墙规则,交给内核层的 netfilter工具去处理
firewalld 服务把用户配置的防火墙规则,交给内核层的 nftables 网络过滤器工具去处理
两个工具二选一即可,用哪个都可以下一节介绍 iptables 如何去用,如何去写规则?
iptables
iptables 就是按照规则办事,由运维人员制定流量的出入把控,
iptables 默认会自下而上去读取防火墙规则,匹配到正确的规则后,就结束匹配的工作,并且执行对应的工作,如果读取防火墙所有规则 都没有符合的,就执行默认的策略。
规则就存储在 linux 内核空间的信息包过滤表中,这些规则,我们运维人员定制的规则,它制定了源地址的信息以及目的地址的信息,还有传输的协议类型。
默认分为两种:
允许:
拒绝:
-
当默认的规则全部都是拒绝的时候,你就得设置一些允许通过的流量,否则所有的流量都禁止了,就没有意义了。
-
当默认的规则全部是允许的时候,就得设置一些禁止,决绝的匹配规则,以保证服务器的安全。
防火墙的规则默认是存储在 linux 内核空间的信息包中,这些规则定义了源地址信息,目的地址信息,传输的协议类型 (比TCP,UDP,邮件协议,RPC协议等,我们会针对这些协议作一个管控,比如 允许所有的TCP协议,允许所有的UDP协议,),服务类型(你是走的是SSH服务,还是FTP服务呢?或者说是其他等等服务)
当数据包符合规则条件时,iptables 就根据所定义的动作,来处理这些数据包,比如 放行 拒绝 丢弃
# 查看防火墙规则 流量把控,
iptables -L # 这条命令是查看默认防火墙规则root@ubuntu-master:~# iptables -L
Chain INPUT (policy ACCEPT) # 默认输入策略 默认链的输入是全部放行 第一条链
target prot opt source destinationChain FORWARD (policy ACCEPT) # 默认转发链是放行的
Chain FORWARD (policy DROP) # 转发策略 转发链 策略下降
target prot opt source destination
DOCKER-USER all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhereChain OUTPUT (policy ACCEPT) # 默认输出策略 默认输出链也是放行的
target prot opt source destinationChain DOCKER (1 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
RETURN all -- anywhere anywhereChain DOCKER-ISOLATION-STAGE-2 (1 references)
target prot opt source destination
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhereChain DOCKER-USER (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
root@ubuntu-master:~#
链
iptables服务把用于处理或者过滤流量的策略称之为规则,多条规则就组成了一个 规则链,规则链根据数据包处理位置的不同进行分类。
多条规则组成了一个规则链,并且规则链还有默认的动作,规则链根据数据包所处的不问位置,进行不同的分类, iptables 默认有5条链
iptables服务把用于处理和过滤流量的策略,称之为规则。这个规则可以理解为你们小区门口的保安大叔他们所遵循的一些规则 比如说
规则一:你必须携带出入证
规则二: 你的体温没有超过37度
小区保安会在门口设置一些关卡
一般来说,服务器内网向外网发出数据包都是安全的
linux 默认的5个规则链
-
路由选择前处理数据包的链 prerouting链
-
处理流入的数据包,input 链,小区的入口
-
处理流出的数据包,output 链,小区的出口
-
处理转发的数据包,forward 链,
-
进行路由选择后处理数据包,postrouting 链 对数据包作路由选择后应用此链中的规则
正常情况下,服务器内网向外网发出的流量一般是良性可控的,主要处理的都是 input 链,从外网流入的流量,需要严格把控,能够很大程度防止恶意流量,造成服务器隐患。
主要使用的都是 input 链 因为通过互联网向服务器发入的流量还比较危险的,
比如学校 规则一:禁止送外卖 规则二:共享单车禁止入内
动作
校园大门口的保安,除了在门上贴上告示,定义一些 规则链 以外,在学生进入后还得有一些动作,好比
服务器流量在通过 input 链之后,进入到服务器内,还得遵循一些动作去处理这些数据包,
-
Accept, 允许数据包通过
-
Reject, 拒绝数据包通过,还会给客户端一个响应,告知它被拒绝了
-
log, 在 linux 系统的日志目录下 /var/log/message 中记录防火墙日志,在进行下一个数据处理
-
drop,直接丢弃数据包,不给于客户端任何的回应,客户端会认为自己的请求丢进了大海,直到请求超时或者报错结束
-
SNAT,源地址转换,这个用在 forward 链 这里,可以解决内网用户用同一个公网的问题,
-
DNAT,目标地址转换
-
Redirect, 在本机做端口映射
[drop 和 reject 区别]
例如 小明在家,忽然有陌生人敲门,发现是自己的朋友来找自己出去玩,但是不想去,因此拒绝了他们( 这就是 reject )
如果小明通过猫眼发现门外是一个坏人,小明闷不吭声,假装自己不在家(这就是 drop)
iptables 规则实践
iptables 命令
语法
iptables (选项)(参数)这些选项指定执行明确的动作:若指令行下没有其他规定,该行只能指定一个选项,对于长格式的命令和选项名,所用字母长度只...-A -append
在所选择的链来添加一条或更多规则。当源(地址) 或者/与 目的(地址)转换为多于一个(多个)地址时,这条规则会加到所有可能的地址(组合)后面-D -delete
从所选链中删除一条或更多规则。这条命令可以有两种方法:可以把被删除规则 指定为链中的序号(第一条序号为1),或者指定为要匹配的规则-R -replace
从选中的链中取代一条规则。如果源(地址)或者/与 目的(地址)被转换为多地址,该命令会失败。规则序号从1开始。-I -insert
根据给出的规则序号向所选链中插入一条或更多规则。所以,如果规则序号为1,规则会被插入链的头部。这也是不指定规则序号...-L -list
显示所选链的所有规则。如果没有选择链,所有链将被显示。也可以和 z 选项一起使用,这时链会被自动列出和归零。精确输出...-F -flush
清空所选链。这等于把所有规则一个个的删除。--Z -zero
把所有链的包及字节的计数器清空。它可以和 -L 配合使用,在清空前察看计数器,请参-前文。-N -new-chain
根据给出的名称建立一个新的用户定义链。这必须保证没有同名的链存在。-X -delete-chain
删除指定给的用户自定义链。这个链必须没有被引用,如果被引用,在删除之前你必须删除或者替换之有关的规则。如果没有给...-P -policy
设置链的目标规则。-E -rename-chain
根据用户给出的名字对指定链进行重命名,这仅仅是修饰,对整个表的结构没有影响。 TARGES 参数给出一个合法的目标。只...-h Help
帮助。给出当前命令语法非常简短的说明。p -protocal [!]protocol
规则或者包检查(待检查包)的协议,指定协议可以是tcp,udp,icmp中的一个或者全部也可以是数值,代表这些协议中的...-s -source [!] address[/mask]
指定源地址,可以是主机名,网络名和清楚的 IP 地址,mask说明可以是网络掩码,或者清楚的数字,在网络掩码的左边指定网络掩码左边 "1" 的个数,因此,mask 值为 24 等于 255.255.255.0.在指定地址前加上 "1" 说明指定了相反的地址段。标志
--src 是这个选项的简写。-d --destination [!] address[/mask]
指定目标地址,要获取详细说明请参见 -s 标志的说明。标志 --dst 是这个选项的简写。-j --jump target
( -j 目标跳转)指定规则的目标:也就是说,如果包匹配应当做什么。目标可以是用户自定义链(不是这条规则所在的),某个。。。-i -in-interface [!] [name]
(i -进入的(网络) 接口 [!] [名称])这是包经由该接口接收的可选的入口名称,包通过该接口接收(在链 INPUT.FORWARD...)...-o --out-interface [!] [name]
(-o --输出接口【名称】)这是包经由该接口送出的可选的出口名称,包通过该口输出(在 链 FORWARD,OUTPUT 和 POSTROUTING...)...--dport num 匹配目标端口号
--sport num 匹配来源端口号
iptables命令顺序
iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网> --sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作
iptables 命令实践
参数
-s -source [!] address[/mask]
指定源地址,可以是主机名,网络名和清楚的IP地址,mask 说明可以是网络掩码或清楚的数字,在网络掩码左边指定网络掩码左边 "1" 的个数,因此,mask 值为24 等于 255.255.255.0.在指定地址前加上 "1" 说明指定了相反的地址段。标志
--src 是这个选项的简写。-A -append
从所选择的链未添加一条或更多规则,当源(地址)或者/与 目的(地址) 转换 为 多与一个(多个)地址时,这条规则会加到所有可能的地址(组合)后面。-D -delete
从所选链中删除一条或更多规则,这条命令可以有两种方法:可以把被删除规则 指定为链中的序号(第一条序号为1),或者指定为要匹配的规则。
四表五链
表名包括:
-
raw:高级功能,如:网址过滤。
-
mangle: 数据包修改 (QOS), 用于实现服务质量。
-
net:地址转换,用于网关路由器。
-
filter:包过滤,用于防火墙规则。
规则链名包括:
-
INPUT 链: 处理输入数据包。
-
OUTPUT 链:处理输出数据包。
-
FORWARD 链:处理转发数据包。
-
PREROUTING 链: 用于目标地址转换(DNAT)
-
POSTROUTING 链:用于源地址转换(SNAT)
动作包括:
-
ACCEPT: 接收数据包。
-
DROP: 丢弃数据包。
-
REDIRECT: 重定向,映射,透明代理。
-
SNAT: 源地址转换。
-
DNAT: 目标地址转换。
-
MASQUERADE: IP伪装(NAT),用于ADSL.
-
LOG: 日志记录。
iptables案例
1. 查看 linux 本地的 iptables 规则
root@ubuntu-master:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destinationChain FORWARD (policy DROP)
target prot opt source destinationChain OUTPUT (policy ACCEPT)
target prot opt source destination
2. 清空本地防火墙规则
iptables -Froot@ubuntu-master:~# iptables -F
root@ubuntu-master:~#
3. 禁止服务器被 ping,服务器拒绝 icmp 协议的流量,【直接丢弃;丢弃后给与响应 drop 与 reject】
iptables -A INPUT -p icmp --icmp-type 8 -s 0/0 -j REJECT参数解释
'-A' 指定链 比如 INPUT.OUTPUT,FORWARD,PREROUTING,POSTROUTING
'-P' 指定网络协议为 icmp
'--icmp-type 8' 指定 icmp 协议类型
'8' 表示回旋协议
'-s' 指定源 IP 网段
'0/0' 表示所有网段(任何ip,任何子网掩码都可以)
'-j' 代表你要执行的动作 比如 REJECT
4. 删除指定的 iptables 规则
root@ubuntu-master:~# iptables -D INPUT 1
root@ubuntu-master:~#
5. 服务器禁止 ping 直接丢弃请求,不给于响应 DROP
iptables -A INPUT -p icmp --icmp-type 8 -s 0/0 -j DROP
6. 注意云服务器不要随意练习 iptables ,因为云服务器是不用软件防火墙的。如果你随意的禁止端口,禁止流量,可能会造成云服务器无法远程连接,一般用 iptables 是对内网环境的管控,对公网意义不大。云服务器是有自己的硬件防火墙的。
7. 禁止访问服务器的 80 端口
iptables -A INPUT -p tcp --dport 80 -j DROP
8. 禁止服务器的 FTP 端口被访问 端口默认是21
# 禁止服务器的 FTP 端口被访问 端口默认是21
iptables -A INPUT -p tcp --dport 21 -j ACCEPT# 禁止服务器的 MYSQL 端口被访问 端口默认是3306
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT
9. 指定允许的 IP 地址网段连接该服务器的22端口,指定客户端进行远程连接,拒绝所有其他的流量
1. 允许某一个客户端连接该服务器的22端口 只允许局域网段连接该服务器
iptables -A INPUT -s 172.18.22.0/24 -p tcp --dport 22 -j ACCEPT2.拒绝所有其他流量
# 如下命令慎用,一旦用了,远程连接就禁用了,若要重新恢复远程连接,就必须找到该服务器本体,在服务器是找到下面这条命令执行的结果,然后用 iptables -D INPUT n 删除下面这条命令执行的结果,恢复远程连接。
iptables -A INPUT -s 0/0 -p tcp --dport 22 -j DROP # iptables 自上而下的匹配规则,一旦找到匹配,就不在向下匹配[点击并拖拽以移动]
10. 禁止指定的机器,访问本机 80 端口
iptables -A INPUT -p tcp -s 172.18.22.0/24 --dport 80 -j REJECT
11. 禁止所有的主机网段,访问该服务器的8000-9000端口
有时候我们部署的服务器的某些网段,不希望别人访问,可以参考如下操作:
注意:这里要写所有的tcp 和 udp 连接
iptables -A INPUT -p tcp -s 0/0 --dport 8000:9000 -j REJECT
iptables -A INPUT -p udp -s 0/0 --dport 8000:9000 -j REJECT参数解释
'8000:9000' 表示从8000端口到9000端口
'0/0' 表示所有主机网段注意:这里要写所有的tcp 和 udp 连接
iptables 实战
1. 在服务端执行的命令
# 查看 linux 本地的 iptables 规则
root@ubuntu-master:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destinationChain FORWARD (policy DROP)
target prot opt source destinationChain OUTPUT (policy ACCEPT)
target prot opt source destinationChain DOCKER (0 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-1 (0 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-2 (0 references)
target prot opt source destinationChain DOCKER-USER (0 references)
target prot opt source destination# 清空本地防火墙规则
root@ubuntu-master:~# iptables -F# 禁止服务器被 ping,服务器拒绝 icmp 协议的流量
root@ubuntu-master:~# iptables -A INPUT -p icmp --icmp-type 8 -s 0/0 -j REJECT# 再次查看 linux 本地的 iptables 规则 INPUT 链的规则有一条有关 icmp 协议的规则
root@ubuntu-master:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT icmp -- anywhere anywhere icmp echo-request reject-with icmp-port-unreachableChain FORWARD (policy DROP)
target prot opt source destinationChain OUTPUT (policy ACCEPT)
target prot opt source destinationChain DOCKER (0 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-1 (0 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-2 (0 references)
target prot opt source destinationChain DOCKER-USER (0 references)
target prot opt source destination
root@ubuntu-master:~## 删除指定的 iptables 规则
root@ubuntu-master:~# iptables -D INPUT 1
root@ubuntu-master:~## 再次查看 linux 本地的 iptables 规则 INPUT 链的规则没有
root@ubuntu-master:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destinationChain FORWARD (policy DROP)
target prot opt source destinationChain OUTPUT (policy ACCEPT)
target prot opt source destinationChain DOCKER (0 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-1 (0 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-2 (0 references)
target prot opt source destinationChain DOCKER-USER (0 references)
target prot opt source destination
root@ubuntu-master:~## 服务器禁止 ping 直接丢弃请求,不给于响应 DROP
root@ubuntu-master:~# iptables -A INPUT -p icmp --icmp-type 8 -s 0/0 -j DROP# 再次查看 linux 本地的 iptables 规则 INPUT 链的规则有一条有关 icmp 协议的规则
root@ubuntu-master:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP icmp -- anywhere anywhere icmp echo-requestChain FORWARD (policy DROP)
target prot opt source destinationChain OUTPUT (policy ACCEPT)
target prot opt source destinationChain DOCKER (0 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-1 (0 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-2 (0 references)
target prot opt source destinationChain DOCKER-USER (0 references)
target prot opt source destination
root@ubuntu-master:~## 禁止访问服务器的 80 端口
root@ubuntu-master:~# iptables -A INPUT -p tcp --dport 80 -j DROP
root@ubuntu-master:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp -- anywhere anywhere tcp dpt:httpChain FORWARD (policy DROP)
target prot opt source destinationChain OUTPUT (policy ACCEPT)
target prot opt source destinationChain DOCKER (0 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-1 (0 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-2 (0 references)
target prot opt source destinationChain DOCKER-USER (0 references)
target prot opt source destination
root@ubuntu-master:~## 指定允许的 IP 地址网段连接该服务器的22端口,指定客户端进行远程连接,拒绝所有其他的流量# 允许某一个客户端连接该服务器的22端口 只允许局域网段连接该服务器
root@ubuntu-master:~# iptables -A INPUT -s 172.18.22.0/24 -p tcp --dport 22 -j ACCEPT
root@ubuntu-master:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- 172.18.22./24 anywhere tcp dpt:sshChain FORWARD (policy DROP)
target prot opt source destinationChain OUTPUT (policy ACCEPT)
target prot opt source destinationChain DOCKER (0 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-1 (0 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-2 (0 references)
target prot opt source destinationChain DOCKER-USER (0 references)
target prot opt source destination
root@ubuntu-master:~## 拒绝所有其他流量
拒绝所有其他流量
# 如下命令慎用,一旦用了,远程连接就禁用了,若要重新恢复远程连接,就必须找到该服务器本体,在服务器是找到下面这条命令执行的结果,然后用 iptables -D INPUT n 删除下面这条命令执行的结果,恢复远程连接。
iptables -A INPUT -s 0/0 -p tcp --dport 22 -j DROP # iptables 自上而下的匹配规则,一旦找到匹配,就不在向下匹配# 禁止指定的机器,访问本机 80 端口
root@ubuntu-master:~# iptables -A INPUT -p tcp -s 172.18.22.0/24 --dport 80 -j REJECT
root@ubuntu-master:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT tcp -- 172.18.22.0/24 anywhere tcp dpt:http reject-with icmp-port-unreachableChain FORWARD (policy DROP)
target prot opt source destinationChain OUTPUT (policy ACCEPT)
target prot opt source destinationChain DOCKER (0 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-1 (0 references)
target prot opt source destinationChain DOCKER-ISOLATION-STAGE-2 (0 references)
target prot opt source destinationChain DOCKER-USER (0 references)
target prot opt source destination
root@ubuntu-master:~#---------客户端-----
1.执行ping命令# 没有在服务端添加 REJECT 之前,是可以 ping 通的
root@ubuntu-node:~# ping 172.18.22.128
PING 172.18.22.128 (172.18.22.128) 56(84) bytes of data.
64 bytes from 172.18.22.128: icmp_seq=1 ttl=64 time=1.16 ms
---172.18.22.128 ping statistics ---
9 packets transmitted, 9 received, 0% packet loss, time 8155ms
rtt min/avg/max/mdev = 0.243/0.463/1.162/0.270 ms# 在服务端添加 REJECT 之后,服务器返回目的地不可达
root@ubuntu-node:~# ping 172.18.22.128
PING 172.18.22.128 (172.18.22.128) 56(84) bytes of data.
From 172.18.22.128 icmp_seq=1 Destination Port Unreachable--- 172.18.22.128 ping statistics ---
9 packets transmitted, 0 received, +9 errors, 100% packet loss, time 8188ms# 在服务端添加 DROP 之后,执行 ping 命令 发生了数据包丢失
root@ubuntu-node:~# ping 172.18.22.128
PING 172.18.22.128 (172.18.22.128) 56(84) bytes of data.
^C
--- 172.18.22.128 ping statistics ---
88 packets transmitted, 0 received, 100% packet loss, time 89095msroot@ubuntu-node:~# curl 172.18.22.128root@ubuntu-node:~# curl 172.18.22.128
curl: (7) Failed to connect to 172.18.22.128 port 80 after 0 ms: Connection refused
root@ubuntu-node:~#