linux-运维进阶-13 iptables与firewalld防火墙

linux-运维进阶-13 iptables与firewalld防火墙

iptables

  iptables是centos6以及之前版本的默认防火墙工具,在centos7中默认防火墙工具已经替换为firewalld。

区别

1)iptables防火墙的底层是netfiter

2)firewalld防火墙的底层是iptables

注意:iptables和firewalld是冲突的,同时只能使用一个防火墙

netfilter模块

  在centos6上,我们用的是iptables服务,而在centos7上,我们用的是firewalld服务。同样的,centos6上安装的是iptables包,而centos7上安装的是firewalld包。不管是centos6还是centos7,核心其实都是netfilter,netfilter是linux的一个内核模块,iptables命令是linux内核自带的。centos6上的iptables服务和centos7上的firewalld服务,其实都是用来定义防火墙规则功能的防火墙管理工具。它们都是将定义好的规则交由内核中的netfilter即网络过滤器来读取,从而真正实现防火墙功能,所以其实在配置规则的思路上是完全一致的。

Iptables的Forward链、Input链和Output链

Input链

  如果数据包的目的地址是本机,则系统将数据包送往Input链。如果通过规则检查,则该包被发给相应的本地进程处理;如果没有通过规则检查,系统就会将这个包丢掉。

Forward链

  如果数据包的目的地址不是本机,也就是说,这个包将被转发,则系统将数据包送往Forward链。如果通过规则检查,则该包被发给相应的本地进程处理;如果没有通过规则检查,系统就会将这个包丢掉。

Output链

  如果数据包是由本地系统进程产生的,则系统将其送往Output链。如果通过规则检查,则该包被发给相应的本地进程处理;如果没有通过规则检查,系统就会将这个包丢掉。

区别

  input只对要访问本机的包有效,forward只对不是访问本机,但是要通过这台机器转发的包有效,制定规则的时候有个原则就是放行的要先放在前面, 禁止的要放在最后。

在centos7中开启iptables的使用

1
2
3
4
5
6
7
8
9
10
# 禁用firewalld防火墙
[root@localhost ~]# systemctl stop firewalld.service
[root@localhost ~]# systemctl mask firewalld.service
Created symlink from /etc/systemd/system/firewalld.service to /dev/null.

# 安装iptables 服务
[root@localhost ~]# yum install iptables-services -y

# 开启iptables服务
[root@localhost ~]# systemctl start iptables

注意:systemctl mask firewalld.service 是注销firewalld服务的意思。

注销服务意味着:

  1)该服务在系统重启的时候不会启动

  2)该服务无法进行做systemctl start/stop/restart操作

  3)该服务无法进行systemctl enable/disable操作

取消firewalld的注销状态:systemctl unmask firewalld

iptables命令的基本参数

参数 作用
-P 设置默认策略
-F 清空规则链
-L 查看规则链
-A 在规则链的末尾加入新规则
-I num 在规则链的头部加入新规则
-D num 删除某一条规则
-s 匹配来源地址IP/MASK,加叹号“!”表示除这个IP外
-d 匹配目标地址
-i网卡名称 匹配从这块网卡流入的数据
-o网卡名称 匹配从这块网卡流出的数据
-p 匹配协议,如TCP、UDP、ICMP
–dport num 匹配目标端口号

使用iptables

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 清除iptables中所有的规则
[root@localhost ~]# iptables -F

# 查看iptables防火墙中所有的规则
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@localhost ~]# iptables -P INPUT DROP
#默认INPUT全部允许


禁止所有人ping服务器
[root@localhost ~]# iptables -I INPUT -p icmp -j DROP
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP icmp -- anywhere anywhere

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
# 这个是服务器接收到icmp的包之后丢弃

接下来在物理机上验证能否ping通虚拟机:

1
C:\Users\zhong>ping 192.168.141.12

结果是ping不通

接下来咱们删掉丢失包的规则,也就是刚刚咱们创建的那条禁止ping的规则

1
2
[root@localhost ~]# iptables -D INPUT 1
[root@localhost ~]#

现在又可以ping通了

接下来咱们创建一条拒绝ping的规则

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost ~]# iptables -I INPUT -p icmp -j REJECT 
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT icmp -- anywhere anywhere reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@localhost ~]#

现在再用物理机来ping虚拟机:

1
C:\Users\zhong>ping 192.168.141.12

显示不可达。

查看iptables中的防火墙规则

1
2
3
4
5
6
7
8
9
10
11
[root@localhost ~]# iptables -L -n --line-numbers 
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 REJECT icmp -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT)
num target prot opt source destination

Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
[root@localhost ~]#

可以看到,拒绝ping的那条规则的规则号是1(ping是属于icmp协议的),待会咱们把这条规则删掉

删除规则

1
iptables -D [INPUT | OUTPUT | FORWARD] 规则号

删除input表中的第一个规则

1
2
3
4
5
6
7
8
9
10
11
[root@localhost ~]# iptables -D INPUT 1
[root@localhost ~]# iptables -L -n --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination

Chain FORWARD (policy ACCEPT)
num target prot opt source destination

Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
[root@localhost ~]#

可以看到那条规则以及删除了,于是此时物理机又可以ping通虚拟机了

添加规则

iptables -I 插入一条规则,默认加在最前面(注意别看错了,这是字母i的大写)

iptables -A增加一条规则,默认增加在最后

举例:注意下面我的虚拟机和物理机的VM网卡是192.168.141网段的,不同电脑网段可能不同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@localhost ~]# iptables -A INPUT -s 192.168.141.0/24 -p tcp --dport 22 -j ACCEPT
[root@localhost ~]# iptables -A INPUT -p tcp --dport 22 -j REJECT
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.141.0/24 anywhere tcp dpt:ssh
REJECT tcp -- anywhere anywhere tcp dpt:ssh reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@localhost ~]#

  如果现在要增加一条规则,使172.25.0.0/24这个网段允许访问本机的22端口,那么不能使用-A参数增加,只能使用 -I 插入规则

1
iptables -I INPUT 2 -s 172.25.0.0/24 -p tcp --dport 22 -j ACCEPT

其中,INPUT 2表示插入的是Chain INPUT 的规则号为2的规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@localhost ~]# iptables -L -n --line-numbers 
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT tcp -- 192.168.141.0/24 0.0.0.0/0 tcp dpt:22
2 REJECT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT)
num target prot opt source destination

Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
[root@localhost ~]# iptables -I INPUT 2 -s 172.25.0.0/24 -p tcp --dport 22 -j ACCEPT
[root@localhost ~]# iptables -L -n --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT tcp -- 192.168.141.0/24 0.0.0.0/0 tcp dpt:22
2 ACCEPT tcp -- 172.25.0.0/24 0.0.0.0/0 tcp dpt:22
3 REJECT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT)
num target prot opt source destination

Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
[root@localhost ~]#

保存防火墙状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@localhost ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]

# 防火墙保存了之后,在/etc/sysconfig/iptables文件中就会出现相应的规则
[root@localhost ~]# cat /etc/sysconfig/iptables
# Generated by iptables-save v1.4.21 on Thu Jan 24 23:42:17 2019
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [30:3540]
-A INPUT -s 192.168.141.0/24 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -s 172.25.0.0/24 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j REJECT --reject-with icmp-port-unreachable
COMMIT
# Completed on Thu Jan 24 23:42:17 2019
[root@localhost ~]#

保存出错时的解决方案

如果保存命令执行失败报出:

1
The service command supports only basic LSB actions (start, stop, restart, try-restart, reload, force-reload, status). For other actions, please try to use systemctl.

解决方案:

1
2
3
4
5
6
7
systemctl stop firewalld 关闭防火墙
yum install iptables-services 安装或更新服务
再使用systemctl enable iptables 启动iptables
最后 systemctl start iptables 打开iptables
再执行service iptables save
重启iptables服务service iptables restart
执行完毕之后/etc/syscofig/iptables文件就有规则了

firewalld

  firewalls是centos7的默认防火墙,安装完centos7 默认开启,默认开放22端口(所以用xshell的ssh能连上)和dhcpv6-client端口

开启firewalld防火墙

1
2
3
4
5
6
7
[root@localhost ~]# systemctl stop iptables.service 
[root@localhost ~]# systemctl mask iptables.service
Created symlink from /etc/systemd/system/iptables.service to /dev/null.
[root@localhost ~]# systemctl unmask firewalld.service
Removed symlink /etc/systemd/system/firewalld.service.
[root@localhost ~]# systemctl restart firewalld.service
[root@localhost ~]#

如果你之前没有启动iptables是不需要做上面的操作的,直接systemctl restart firewalld.service 即可。

防火墙一般只关心进来的流量,不关心出去的流量。

注意:出去之后再回来的流量定义为出去的流量

九大区域

firewalld防火墙默认定义了9大区域:

  • drop:
    除非与传出流量相关,否则拒绝所有传入流量(不产生包含ICMP的错误响应)
    
  • block:
    除非与传出流量相关,否则拒绝所有传入流量。
    
  • dmz:
    除非与传出流量相关或者与ssh预定义服务匹配,否则拒绝传入流量
    
  • external:
    除非与传出流量相关或者与ssh预定义服务匹配,否则拒绝传入流量。通过此区域转发的IPv4传出流量将进行伪装,使其看起来像传出网络接口的IPv4地址而不是主机的源IP
    
  • internel:
    初始状态与home相同
    
  • home:
    除非与传出流量相关或者与ssh、mdns、ipp-client、dhcpv6-client、samba-client预定义服务匹配,否则拒绝传入流量
    
  • work:
    除非与传出流量相关或者与ssh、ipp-client、dhcpv6-client预定义的服务匹配,否则拒绝传入流量。此区域为网络接口的默认区域
    
  • public:
    除非与传出流量相关或者与ssh、dhcpv6-client预定义的服务匹配,否则拒绝传入流量。此区域为网络接口的默认区域
    
  • trusted:
    允许所有流量传入
    

配置firewalld防火墙的三种方法:

  • 使用图形工具firwalld-config
  • 使用命令行工具firewalld-cmd

查看区域中的规则

查看public区域中的所有信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@localhost ~]# firewall-cmd --list-all --zone=public
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client #可以看到这里默认只放行ssh和dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

[root@localhost ~]#

允许访问本机的http服务

第一种方法:添加服务名允许访问,要求http服务使用默认端口80,不然规则无效

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@localhost ~]# yum install httpd -y
[root@localhost ~]# systemctl restart httpd
[root@localhost ~]# firewall-cmd --add-service=http
success
[root@localhost ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client http #可以看到这里除了默认放行的ssh和dhcpv6-client,多了个http
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

第二种方法:放行端口号80(http协议对应端口号为80)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[root@localhost ~]# firewall-cmd --remove-service=http	#先把上面放行的http移除掉
success
[root@localhost ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client
ports: #可以看到本来没有通过端口号放行的协议
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

[root@localhost ~]# firewall-cmd --add-port=80/tcp
success
[root@localhost ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client
ports: 80/tcp #可以看到现在多了个放行的使用80端口号的http协议
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

[root@localhost ~]#

保存已经设置的规则

  防火墙使用firewall-cmd添加实时生效的规则之后,重启Linux系统或者重启防火墙服务之后,运行时修改的规则都会丢失,如果要保存规则,有以下几种方式:

方式1.在规则后面添加 –permanent,这时这条命令不会实时生效,但会把规则号添加到配置文件中

1
2
[root@localhost ~]# firewall-cmd --add-port=8080/tcp --permanent 
success

这条命令敲完后,我们查看防火墙规则,发现并没有实时生效

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@localhost ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client
ports: 80/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

[root@localhost ~]#

让其生效的三种方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@localhost ~]# firewall-cmd --reload 
success
[root@localhost ~]# systemctl restart firewalld.service
[root@localhost ~]# firewall-cmd --add-port=8080/tcp

验证:
[root@localhost ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client
ports: 8080/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

[root@localhost ~]#

方式2.让runtime时配置的规则永久保存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[root@localhost ~]# firewall-cmd --add-port=10000/tcp
success
[root@localhost ~]# firewall-cmd --add-port=10001/tcp
success
[root@localhost ~]# firewall-cmd --add-port=10086/tcp
success

# 下面的命令可以将上面的规则在运行时永久保存到防火墙配置中
[root@localhost ~]# firewall-cmd --runtime-to-permanent
success

验证:
[root@localhost ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client
ports: 8080/tcp 10000/tcp 10001/tcp 10086/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

[root@localhost ~]#

富规则

拒绝所有172.25.0.0/24网段的ip访问本机的ssh服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@localhost ~]# firewall-cmd --add-rich-rule="rule family="ipv4" source address="172.25.0.0/24" service name="ssh" reject"
success
[root@localhost ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33 ens37
sources:
services: ssh dhcpv6-client
ports: 8080/tcp 10000/tcp 10001/tcp 10086/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="172.25.0.0/24" service name="ssh" reject
[root@localhost ~]#

TCP Wrapper

应用层流量控制工具

  TCP Wrappers是RHEL 7系统中默认启用的一款流量控制程序,它能够根据来访主机的地址与本机的目标服务程序作出允许或拒绝的操作。

  系统将会先检查允许控制列表文件(/etc/hosts.allow),如果匹配到相应的允许策略则放行流量;如果没有匹配,则去进一步匹配拒绝控制列表文件(/etc/hosts.deny),若找到匹配项则拒绝该流量。如果这两个文件全都没有匹配到,则默认放行流量。

在配置TCP Wrappers服务时需要遵循两个原则:

  • 编写拒绝策略规则时,填写的是服务名称,而非协议名称;
  • 建议先编写拒绝策略规则,再编写允许策略规则,以便直观地看到相应的效果。

格式为:

服务名:规则

规则

客户端类型 示例 满足示例的客户端列表
单一主机 192.168.10.10 IP地址为192.168.10.10的主机
指定网段 192.168.10. IP段为192.168.10.0/24的主机
指定网段 192.168.10.0/255.255.255.0 IP段为192.168.10.0/24的主机
指定DNS后缀 .aaa.com 所有DNS后缀为.aaa.com的主机
指定主机名称 www.aaa.com 主机名称为www.aaa.com的主机
指定所有客户端 ALL 所有主机全部包括在内

利用tcp wrapper控制应用层数据的流量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# vim /etc/hosts.allow
1 #
2 # hosts.allow This file contains access rules which are used to
3 # allow or deny connections to network services that
4 # either use the tcp_wrappers library or that have been
5 # started through a tcp_wrappers-enabled xinetd.
6 #
7 # See 'man 5 hosts_options' and 'man 5 hosts_access'
8 # for information on rule syntax.
9 # See 'man tcpd' for information on tcp_wrappers
10 #
在最后一行添加:
11 sshd:192.168.9. 172.25.0.1
表示上述两个网段的用户使用本虚拟机的sshd服务

[root@localhost ~]# vim /etc/hosts.deny
1 #
2 # hosts.deny This file contains access rules which are used to
3 # deny connections to network services that either use
4 # the tcp_wrappers library or that have been
5 # started through a tcp_wrappers-enabled xinetd.
6 #
7 # The rules in this file can also be set up in
8 # /etc/hosts.allow with a 'deny' option instead.
9 #
10 # See 'man 5 hosts_options' and 'man 5 hosts_access'
11 # for information on rule syntax.
12 # See 'man tcpd' for information on tcp_wrappers
13 #
在最后一行添加:
14 sshd:ALL
表示拒绝所有网段的用户使用sshd服务
欢迎打赏,谢谢
------ 本文结束------
0%