一、什么是防火墙
- 从功能角度来讲:
防火墙是位于内部网和外部网之间的屏障,它按照系统管理员预先定义好的规则来控制数据包的进
- 从功能实现角度来讲:
- 火墙是系统内核上的一个模块netfilter(数据包过滤机制)
- 通过netfiler来管理kernelspace中的策略
二、netfilterr简介
- Netfilter是Linux 2.4.x引入的一个子系统
- 它作为一个通用的、抽象的框架,提供一整套的hook函数的管理机制,使得诸如数据包过滤、网络地址转换(NAT)和基于协议类型的连接跟踪等等
- netfilter分析OSl七层协议的2、3、4层
- netfiler可以直接分析数据包头部数据,包括硬件地址,软件地址、TCP、UDP、ICMP等数据包的信息都可以进行过滤分析
- Inux的netfilter机制可以进行的工作有:
- 拒绝让Internet的数据包进入主机的某些端口
- 拒绝让某些来源ip的数据包进入
- 拒绝让带有某些特殊标志(fag)的数据包进入,最常拒绝的就是带有SYN的主动连接的标志
- 分析硬件地址(MAC)来决定连接与否。
- 地址转换
- 防火墙并不能有效阻挡病毒或木马程序,并且防火墙对于内部LAN的攻击无能为力
三、netfilter策略管理工具
- netfilter这个内核网络栈过滤框架的使用需要通过iptables或nftables来进行
- 与netfilter进行交互工具常用种类
- iptables服务使用iptables交互RHEL6之前系统默认使用此服务,管理手段丰富,配置比较。复杂
- firewalld服务使用nftables交互 RHEL6及之后的版本中默认使用此服务,配置类似windows火墙,功能模块度高,使用简单
四、netfilter的五类hook函数及iptables的默认表和链
NF_IP_PRE_ROUTING:位于路由之前,报文一致性检査之后(报文一致性检查包括: 报文版本、报文长度和checksum
NF_IP_LOCAL IN: 位于报文经过路由之后,并且目的是本机的
NF _IP FORWARD: 位于在报文路由之后,目的地非本机的。
NF_IP_LOCAL_OUT:由本机发出去的报文,并且在路由之前。
NF IP POST ROUTING:所有即将离开本机的报文
五、什么是内核空间的iptables
- Iptables 是基于Netfilter框架实现的报文选择系统
- iptables用于报文的过滤、网络地址转换和报文修改等功能
- lptables 本质上是包含了5个规则表,而规则表则包含了一些列的报文的匹配规则以及操作目标.
1、raw表:
第一优先级的表,设置raw表规则后,不会对数据包进行链接跟踪和NAT转换,使用于PREROUTING和OUTPUT链,对应的动作为NOTRACK。
2、mangle表:
第二优先级的表,根据规则,修改数据包的TOS(TypeOfService,服务类型)、TTL(TimeToLive,生存周期)以及设置Mark标记,以实现Qos以及策略路由等。
3、nat表
第三优先级的表,网络地址转换表,用于修改源和目的的地址,分SNAT(源目的地址转换)和DNAT(目的地址转换)。
4、filter表:
第四优先级的表,用于控制到达链(forward链、input链、output链)上的数据包,是放行(accepte)、丢弃(drop)或者拒绝(reject)。
5、security表:
最不常用的表(通常,我们说iptables只有4张表,security表是新加入的特性),用于在数据包上应用SELinux。
六、iptables服务
1.iptables介绍
iptables服务是用户管理内核空间的iptables的管理工具,通过iptables书写内核空间的iptables策略iptables的规则是至上而下的读取方式,遇到与数据包信息匹配的规则后直接采用
iptables的规则默认保存在内存中,如果需要永久保存需要把策略以字符的形式保存到/etc/sysconfig/iptables中
2.iptables命令的语法格式及常用参数
a.语法格式
cpp
iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网> --sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作
b.常用参数如下
|--------|-----------------------------------------------------------------------------------------------------------------------------------------------|
| 参数 | 说明 |
| -t | 对指定的表进行操作,table必须是raw,nat,filter,mangle中的一个。默认是filter表。 |
| -p | 指定要匹配的数据包协议类型 |
| -s | --source address/mask:把指定的一个或者一组地址作为源地址,按此规则进行过 滤。当后面没有mask 时,address 是一个地址,比如:192.168.1.1;当mask指定时,可以表示一组范围内的地址,比如:192.168.1.0/255.255.255.0 |
| -d | --destination address/mask:地址格式同上,但这里指定地址为目的地址,按此进行过滤 |
| -i | --in-interface name:指定数据包的来自来自网络接口,比如最常见的 eth0。注意:它只对INPUT,FORWARD,PREROUTING这三个链起作用。如果没有指定此选项,说明可以来自任何一个网络接口。同前面类似,"!"表示取反 |
| -o | --out-interface name:指定数据包出去的网络接口。只对 OUTPUT,FORWARDPOSTROUTING 三个链起作用 |
| -L | --list [chain]列出链 chain 上面的所有规则,如果没有指定链,列出表上所有链的所有规则 |
| -A | --append chain rule-specification:在指定链 chain 的末尾插入指定的规则,,也就是说,这条规则会被放到最后,最后才会被执行。规则是由后面的匹配来指定 |
| -I | --insert chain [rulenum]rue-specification:在链 chain 中的指定位置插入一条或多条规则。如果指定的规则号是1,则在链的头部插入。这也是默认的情况,如果没有指定规则号 |
| -D | --delete chain rule-specification -D,--delete chain rulenum:在指定的链 chain 中删除 一个或多个指定规则 |
| -R num | Replays替换/修改第几条规则 |
| -P | --policy chain target:为指定的链 chain 设置策略 target。注意,只有内置的链才允许有策略,用户自定义的是不允许的 |
| -F | --fush [chain] 清空指定链 chain 上面的所有规则。如果没有指定链,清空该表上所有链的所有规则 |
| -N | --new-chain chain 用指定的名字创建一个新的链 |
| -X | --delete-chain[chain]:删除指定的链,这个链必须没有被其它任何规则引用,而且这条 上必须没有任何规则。如果没有指定链名,则会删除该表中所有非内置的链 |
| -E | --rename-chain old-chain newchain:用指定的新名字去重命名指定的链。这并不会对 链内部照成任何影响 |
| -Z | --zero [chain]:把指定链,或者表中的所有链上的所有计数器清零 |
| -j | --jump target<指定目标>:即满足某条件时该执行什么样的动作。target 可以是内置的目标,比如 ACCEPT,也可以是用户自定义的链 |
| -h | 显示帮助信息 |
3.具体操作
cpp
[root@router ~]# systemctl disable --now firewalld
Removed "/etc/systemd/system/multi-user.target.wants/firewalld.service".
Removed "/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service".
[root@router ~]# systemctl mask firewalld
Created symlink /etc/systemd/system/firewalld.service → /dev/null.
[root@router ~]# dnf install iptables-nft-services.noarch
cpp
[root@router ~]# systemctl enable --now iptables.service #启动服务
Created symlink /etc/systemd/system/multi-user.target.wants/iptables.service → /usr/lib/systemd/system/iptables.service.
[root@router ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Perhaps iptables or your kernel needs to be upgraded.
[root@router ~]# iptables -t filter -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@router ~]# iptables -t raw -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@router ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
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
[root@router ~]# iptables -t security -nL
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@router ~]# cat /etc/sysconfig/iptables
# sample configuration for iptables service
# you can edit this manually or use system-config-firewall
# please do not ask us to add additional ports/services to this default configuration
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
[root@router ~]# iptables -F #刷新策略
[root@router ~]# iptables -nL
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@router ~]# systemctl restart iptables.service #重启服务
[root@router ~]# iptables -nL #查看当前策略
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
cpp
[root@router ~]# iptables -A INPUT -s 192.168.30.10 -p tcp --dport 22 -j REJECT
[root@router ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT tcp -- 192.168.30.10 0.0.0.0/0 tcp dpt:22 reject-with icmp
测试
cpp
[root@30 ~]# curl 192.168.30.100
curl: (7) Failed to connect to 192.168.30.100 port 80: Connection refused
cpp
[root@router ~]# iptables -A INPUT ! -s 192.168.30.10 -p tcp --dport 22 -j REJECT
[root@router ~]#
Socket error Event: 32 Error: 10053.
[root@router ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT tcp -- !192.168.30.10 0.0.0.0/0 tcp dpt:22 reject-with icmp-port-unreachable
[root@router ~]# iptables -R INPUT 1 -s 192.168.30.10 -p tcp --dport 22 -j ACCEPT #替换规则
[root@router ~]# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
[root@router ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.30.10 0.0.0.0/0 tcp dpt:22
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
[root@router ~]# echo hello sensen > /usr/share/nginx/html/index.html
测试:
cpp
[root@30 ~]# curl 192.168.30.100
hello sensen
开启内核路由功能
cpp
[root@router ~]# sysctl -a | grep ip_forwad
[root@router ~]# sysctl -a | grep ip_forward
net.ipv4.ip_forward = 0
net.ipv4.ip_forward_update_priority = 1
net.ipv4.ip_forward_use_pmtu = 0
[root@router ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@router ~]# cat /proc/sys/net/ipv4/ip_forward
1
snat地址转换
cpp
[root@78 ~]# ip route add default via 192.168.78.100
[root@78 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.78.100 0.0.0.0 UG 0 0 0 ens160
192.168.78.0 0.0.0.0 255.255.255.0 U 100 0 0 ens160
[root@router ~]# iptables -t nat -A POSTROUTING -o ens160 -j SNAT --to-source 192.168.30.100
[root@router ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
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
SNAT all -- 0.0.0.0/0 0.0.0.0/0 to:192.168.30.100
dnat地址转换
cpp
[root@router ~]# iptables -t nat -A PREROUTING -i ens224 -j DNAT --to-dest 192.168.78.10
[root@router ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT all -- 0.0.0.0/0 0.0.0.0/0 to:192.168.78.10
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
SNAT all -- 0.0.0.0/0 0.0.0.0/0 to:192.168.30.100
七、firewalld
1.firewalld服务管理方式与iptables的管理方式
- iptables是基于Linux内核的Netfilter子系统构建的,直接操作Netfilter;而firewalld则通过libnftables库与Netfilter交互,提供了一个更高的抽象层
- iptables使用基于表的规则集,包括filter、nat、mangle、raw及securty五个表;firewalld采用基于区域的规则集,包括default、public、internal、external和dmz五个区域iptables的配置较为复杂,需要用户掌握特定的命令行语法;firewalld提供了更直观和灵活的配置方式,支持命令行和图形界面
- 由于firewalld通过libnftables库与Netfilter交互,其性能相对于直接操作Netfilter的iptables来说较低。
- 由于firewalld通过libnftables库与Netfilter交互,其性能相对于直接操作Netfilter的iptables来说较
- 低。
2.firewalld域介绍
|----------------|---------------------------------------------------------|
| 区域 | 默认规则策略 |
| 阻塞区域 (block) | 拒绝流入的流量,除非与流出的流量相关 |
| 工作区域 (work) | 拒绝流入的流量,除非与流出的流量相关 |
| 家庭区域 (home) | 拒绝流入的流量,除非与流出的流量相关 |
| 公共区域 (public) | 不相信网络上的任何计算机,只有选择接受传入的网络连接。 |
| 隔离区域 (DMZ) | 隔离区域也称为非军事区域,内外网络之间增加的一层网络起到缓冲作用。对 于隔离区域,只有选择接受传入的网络连接。 |
| 信任区域 (trusted) | 允许所有的数据包。 |
| 丢弃区域(drop) | 拒绝流入的流量,除非与流出的流量相关 |
| 内部区域(internal) | 等同于home区域 |
| 外部区域(external) | 拒绝流入的流量,除非与流出的流量有关;而如果流量与ssh服务相关则允许 流量 |
Note
firewalld中默认使用的域是public
firewalld默认提供的九个zones的调用文件都保存在"/usr/lib/firewalld/zones"目录下
3.firewall-cmd命令详解
|-----------------------------|-----------------------------|
| 参数 | 作用 |
| --get-default-zone | 查询默认的区域名称 |
| --set-default-zone=<区域名称> | 设置默认的区域,使其永久生效 |
| --get-zones | 显示可用的区域 |
| --get-services | 显示预先定义的服务 |
| --get-active-zones | 显示当前正在使用的区域与网卡名称 |
| --add-source= | 将源自此IP或子网的流量导向指定的区域 |
| --remove-source= | 不再将源自此IP或子网的流量导向某个指定区域 |
| --list-all | 显示当前区域的网卡配置参数、资源、端口以及服务等信息 |
| --list-all-zones | 显示所有区域的网卡配置参数、资源、端口以及服务等信息 |
| --add-service=<服务名> | 设置默认区域允许该服务的流量 |
| --add-port=<端口号/协议> | 设置默认区域允许该端口的流量 |
| --remove-service=<服务名> | 设置默认区域不再允许该服务的流量 |
| --remove-port=<端口号/协议> | 设置默认区域不再允许该端口的流量 |
| --reload | 让"永久生效"的配置规则立即生效,并覆盖当前的配置规则 |
| --panic-on | 开启应急状况模式 |
| --panic-off | 关闭应急状况模式 |
示例:
1.火墙信息查看
cpp
[root@router ~]# firewall-cmd --staterunning
[root@router ~]# firewall-cmd --ist-a11public(active)
target: defaulticmp-block-inversion:no
interfaces:ensl60
sources:
services:cockpit dhcpv6-client dns http sshports:
protocols:
forward:
yesmasquerade:
noforward-ports:
source-ports:
icmp-blocks:
rich rules:
2.管理域
cpp
[root@router ~]# firewall-cmd --get-default-zonepublic
[root@router ~]# firewall-cmd --set-default-zone=trusted
[root@router ~]# firewall-cmd --get-zones
[root@router ~]# firewall-cmd --get-active-zonesdocker
interfaces:docker0trusted
interfaces:ens160
3.管理服务
cpp
[root@router ~]# firewall-cmd--get-services
[root@router ~]# firewall-cmd --ist-services --zone=public
[root@router ~]# firewall-cmd--permanent --add-service=http --zone=public
[root@router ~]# firewall-cmd --permanent --remove-service=http
4.管理IP
cpp
[root@router ~]# firewall-cmd--add-source=192.168.30.1 --zone=trusted
[root@router ~]# firewall-cmd--remove-source=192.168.30.1 --zone=trusted
5.管理port接口
cpp
[root@router ~]# firewall-cmd --add-port=80/tcp
[root@router ~]# firewall-cmd --remove-port=80/tcp
4.firewalld的高级规则
a.Direct Rules
通过 firewall-cmd 工具,可以使用 -direct 选项在运行时间里增加或者移除链。如果不熟悉 iptables,使用直接接口非常危险,因为您可能无意间导致防火墙被入侵
直接端口模式适用于服务或者程序,以便在运行时间内增加特定的防火墙规则。直接端口模式添加的规则优先应用。
示例:
仅允许192.168.30.10访问主机80端口
cpp
[root@router ~]#firewall-cmd --direct --get-a11-rules
[root@router ~]# firewall-cmd --direct --add-rule ipv4 filter IN_public_allow 0 -s 192.168.30.10 -ptcp --dport80 -j ACCEPT
[root@router ~]# firewall-cmd --direct --remove-rule ipv4 filter IN_public_allow 0 -s 192.1268.30.10 -p tcp --dport 80 -j ACCEPT
b.地址伪装与端口转发
地址伪装:
cpp
[root@78 ~]# firewall-cmd --add-masquerade
端口转发:
cpp
[root@78 ~#firewall-cmd --permanent--add-forward-port=port=22:proto=tcp:toport=80:toaddr=192.168.78.100
Note
注意在设置端口转发或地址伪装时,如果没有加--permanent参数,那么只在当前环境中生效,如果没有加,则表示在刷新火墙后才生效