linux防火墙

centos6 中为 iptables
centos7 中为 firewalld
centos8在为 ntf

概览和一些重要概念(五表五链)

iptables等只是用户使用的工具,真正实现防火墙功能的是内核的netfilter模块,所以,说iptables是防火墙是不准确的。
在这里插入图片描述
一种常见的公司网络结构
在这里插入图片描述
DMZ称为非军事化区,是允许外网访问的区域。

硬件防火墙内其实是一个精简的linux,核心功能也由内核中的 netfilter 实现

在linux系统中查看内核开启了哪些功能?
查看/boot/config—文件
注释了的功能在内核中未开启
=y的功能被编译到内核中了,功能开启
=m的功能以模块的方式启用了,但是没有编译到内核中

打开/boot/config—文件中搜索到 netfilter 组件

[root@localhost ~]# cat /boot/config-4.18.0-408.el8.x86_64 |grep NETFILTER

centos8上 事实上 iptables 已经指向了 nft

iptables的处理流程
在这里插入图片描述
数据包从网卡进入,首先会被PREROUTING这个内置的规则链处理。之后会进行路由判断。如果目的地址是本机,则会走INPUT规则链,然后提交给本机程序处理;如果目的地不是本机地址,且开启了转发功能,则会经过FORWARD规则链,然后准备将数据包发出。本机要发出的数据包和经过FORWARD的数据包,会经过路由判断,然后再经过POSTROUTING规则链,最后从网卡发出。这里的ethX和ethY 可以是同一个网卡。

iptables的五表五链

netfilter 中的五个钩子函数和报文流向

Netfilter在内核中选取五个位置放了五个hook(勾子) function(INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING),而这五个hook function向用户开放,用户可以通过一个命令工具(iptables)向其写入规则

由信息过滤表(table)组成,包含控制IP包处理的规则集(rules),规则被分组放在链(chain)上
在这里插入图片描述
事实上:内核叫函数,iptables中叫 chain 链,一个链对应一个钩子函数,一条链,就是一种数据的流向


五个内置链:
PREROUTING INPUT FORWARD OUTPUT POSTROUTING
自定义链:


表应用在链上,对这个链上的数据按规则进行控制。
五个表:

作用
filter过滤规则表,根据预定义的规则过滤符合条件的数据包,默认表,不指定表时,默认为filter表
natnetwork address translation,地址转换规则表
mangle修改数据标记位规则表
raw关闭启用的连接跟踪机制,加快封包穿越防火墙速度
security用于强制访问控制(MAC)网络规则,由Linux安全模块(如SELinux)实现

五表的优先级,规则冲突的话
security> raw >man >nat >filter

iptables 的组成
不同的链只能用固定的一些表,而非所有的表
在这里插入图片描述

iptables 的格式详解

格式

iptables [-t table] SUBCOMMAND chain [-m matchname [per-match-options]]
-j targetname [per-target-options]

1)-t table :指定表
security raw mangle nat filter

2)SUBCOMMAND
-N:new,自定义一条新的规则链
-E:重命名自定义链:引用计数不为0的自定义链不能够被重命名,也不能被删除
-X: delete,删除自定义的空的规则链
-P:Policy,设置默认策略;对filter表中的链而言,其默认策略有:ACCEPT:接受,DROP:丢弃
-L:list,列出指定·上的所有规则,本选项须置后-n: numberic,以数字格式显示地址和端口号
-V:verbose,详细信息
-VV:更详细
–line-numbers:显示规则的序号
-S:selected,以iptables-save命令格式显示链上规则
-A:添加一条规则。
-D:删除一条规则。
-I:插入一条规则到指定位置。
-F:清空规则表。
-R:替换规则

3)chain
PREROUTING INPUT FORWARD OUTPUT POSTROUTING

4)匹配条件
基本:通用的,PARAMETERS
扩展:需加载模块,MATCH EXTENTIONS

5)处理动作
ACCEPT:
DROP:
REJECT:–reject-with:默认 icmp-port-unreachable
RETURN:返回调用链
REDIRECT:端口重定向
LOG:记录日志,dmesgMARK:做防火墙标记
DNAT:目标地址转换
SNAT:源地址转换
MASQUERADE:地址伪装

iptables 的匹配条件

基本匹配
基本匹配条件:无需加载模块,由iptables/netfilter自行提供

-s,--source address[/mask][,...]:源IP地址或者不连续的IP地址
-d,--destination address[/mask][,...]:目标IP地址或者不连续的IP地址
-p,--protoco1 protoco1:指定协议,可使用数字如0 (all)
protocol: tcp,udp,icmp,icmpv6,udplite,esp,ah,sctp,mh or"a1l"
-i,--in-interface name:报文流入的接口;只能应用于数据报文流入环节,只应用于INPUT、FORWARD、PREROUTING链
-o,--out-interface name:报文流出的接口;只能应用于数据报文流出的环节,只应用于FORWARD、OUTPUT、POSTROUTING链

拓展匹配
需要加载扩展模块(/usr/lib64/xtables/*.so),才可生效,扩展模块查看帮助: man iptables-extensions
隐式扩展
iptables在使用-p选项指明了特定的协议时(如tcp,udp,icmp),无需再用-m选项指明扩展模块的扩展机制,不需要手动加载扩展模块(即不需要再-m添加模块)

iptables -A INPUT -s 1.1.1.1 -p tcp --dport 21 -j REJECT
指定tcp协议后可指定的拓展选项
--source-port,--sport port[:port]:匹配报文源端口,可为端口连续范围
--destination-port,--dport port[:port]:匹配报文目标端口,可为连续范围
--tcp-flags mask  comp
mask 需检查的标志位列表,用,分隔,例如SYN ,ACK,FIN, RST
comp 在mask列表中必须为1的标志位列表,无指定则必须为0,用,分隔tcp协议的扩展选项

--tcp-flags SYN,ACK,FIN,RST  SYN表示要检查的标志位为SYN,ACK ,FIN ,RST四个,其中SYN必须为1,余下的必须为0,即表示第一次握手
--tcp-flags  SYN, ACK ,FIN ,RST    SYN,ACK  即表示第二次握手

iptables -A INPUT -s 1.1.1.1 -p udp --sport 1 -j REJECT
--source-port,--sport port[:port]:匹配报文源端口,可为端口连续范围
--destination-port,--dport port[:port]:匹配报文目标端口,可为连续范围

iptables -A INPUT -s 1.1.1.1 -p icmp --icmp-type 8 -j REJECT
--icmp-type icmp的type/code

显式的拓展

multiport扩展,以离散方式定义多端口匹配,最多指定15个端口
iptables -A INPUT -s 1.1.1.1 -p tcp -m multiport --dport 445,223 -j REJECT

iprange扩展
指明连续的(但一般不是整个网络)ip地址范围
--src-range from[-to]  源IP地址范围
--dst-range from[-to]  目标IP地址范围
iptables -A 工NPUT -d 1.1.1.1 -p tcp --dport 80 -m iprange --src-range 2.2.2.2-2.2.2.6 -j DROP

mac扩展
mac模块可以指明源MAC地址,适用于:PREROUTING, FORWARD,INPUT
--mac-source xX :XX:XX:XX:XX:XX
iptables -A INPUT -s 1.1.1.1 -m mac --mac-source 00:50:56:12:34:56 -j ACCEPT

connlimit扩展
根据每客户端IP做并发连接数数量匹配
可防止Dos(Denial of Service,拒绝服务)攻击
--connlimit-upto N #连接的数量小于等于N时匹配
--connlimit-above N #连接的数量大于N时匹配
iptables -A INPUT -d 1.1.1.1 -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REECT

limit拓展
基于报文的收发速度做匹配

state拓展

state扩展模块,可以根据"连接追踪机制“去检查连接的状态,较耗资源
conntrack机制:追踪本机上的请求和响应之间的关系
状态类型:
NEW:新发出请求;连接追踪信息库中不存在此连接的相关信息条目,因此,将其识别为第一次发出的请求
ESTABLISHED: NEW状态之后,连接追踪信息库中为其建立的条目失效之前期间内所进行的通信状态
RELATED:新发起的但与已有连接相关联的连接,如: ftp协议中的数据连接与命令连接之间的关系
INVALID:无效的连接,如flag标记不正确
UNTRACKED:未进行追踪的连接,如: raw表中关闭追踪已经追踪到的并记录下来的连接信息库

连接跟踪,需要加载模块: modprobe nf_conntrack,高版本执行了带state模块的命令会自动加载

#查看已经记录的连接记录
[root@localhost ~]# cat /proc/net/nf_conntrack
ipv4     2 icmp     1 6 src=192.168.100.10 dst=192.168.100.11 type=8 code=0 id=1 src=192.168.100.11 dst=192.168.100.10 type=0 code=0 id=1 mark=0 zone=0 use=2
ipv4     2 tcp      6 299 ESTABLISHED src=192.168.100.10 dst=192.168.100.1 sport=22 dport=59815 src=192.168.100.1 dst=192.168.100.10 sport=59815 dport=22 [ASSURED] mark=0 zone=0 use=2

调整连接追踪功能所能够容纳的最大连接数量
[root@centos8 ~]#cat /proc/sys/net/nf_conntrack_max
26624
#查看连接跟踪有多少条目
[root@centos8 ~]#cat /proc/ sys/net/netfilter/nf_conntrack_count
10
#连接跟踪,需要加载模块: modprobe nf_conntrack,高版本会自动加载
#lsmod | grep nf_conntrack 无显示时,需要手动加载
#当服务器连接多于最大连接数时,日志中可以观察到:
#kernel: ip_conntrack: table full, droppingpacket错误,并且导致建立TCP连接很慢。

临时调整nf_conntrack_max的值
echo 1 > /proc/sys/net/netfi1ter/nf_conntrack_max
持久调整nf_conntrack_max的值
vim /etc/sysctl.conf
#写入
net.nf_conntrack_max=1
#保存后执行 sysctl -p 生效
[root@rocky8-10 ~]# cat /proc/sys/net/netfilter/nf_conntrack_max 
24576
[root@rocky8-10 ~]# 
[root@rocky8-10 ~]# echo net.nf_conntrack_max=65535 >> /etc/sysctl.conf 
[root@rocky8-10 ~]# sysctl -p
net.nf_conntrack_max = 65535


state实现1可以访问2,2不能访问1
在主机1.1.1.1上执行
iptables -A INPUT -s 1.1.1.2 -m state --state NEW -j REJECT
拒绝来自主机2的状态为NEW的报文

抓包
tcpdump -i ens33 -nn icmp

查看启用的规则

# v 可视化 n 数字化 L 列出
[root@localhost ~]iptables -vnL  

带序号查看启用的规则

iptables -vnL --line-numbers

iptabls规则的执行:
iptables会按列出的规则的次序依次检查是否满足规则的条件,满足则执行此条规则。因此,规则的排列次序具有重要的意义。

可以更改现有的规则的次序
插入
指定插入到第二行,不指定数字将默认插入到第一行

[root@localhost ~]iptables -I INPUT 2 -s 192.168.100.10 -j ACCEPT

删除规则
删除INPUT 链上编号为1的规则

iptables -D INPUT 1

关于自定义链

新增自定义链
iptables -N WEB-CHAIN

在自定义的chain中新增完规则,将这个自定义chain插入或者加入到INPUT链中的某个位置
iptables -I INPUT 3 -j WEB-CHAIN

可以将这个自定义链想象成函数,如上,检查是否匹配1,2两条规则后,检查web-chain这个函数中的规则集。
要删除自定义链,先取消INPUT 对web的调用,再清空链中的所有规则(iptables -F web-chain),再删除链(iptables -X WEB-CHAIN)

limit模块


target

ACCPET DROP REJECT RETURN LOG SNAT DNAT REDIRECT MASQUERADE 等
LOG 满足条件的事件将记录日志
RETURN 提前结束自定义链 回到外层规则

保存制定的规则

iptables -F 清除所有规则
直接运行iptables命令加的规则只是临时的,重启会失效
需要将规则写进文件里
在centos7/8中
iptables-save会将规则以一定的格式输出到标准输出,可以重定向的文件中

iptables-save > /data/iptables.rules

从文件恢复到规则

iptables-restore < /data/iptables.rules 

实现开机自动加载规则

在/etc/rc.local中加入命令
iptables-restore < /data/iptables.rules
最后 chmod +x /etc/rc.local 即可

或者利用service实现:
安装iptables-service,启动服务,用iptables新增规则后
可以使用iptables-sava > /etc/sysconfig/iptables 即可实现开机自加载

FORWARD链实现内外网络的流量控制

启用FORWARD模块
sysctl -a |grep ip_for*
vim /etc/sysctl.conf 写入 ip_for*=1

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

利用state模块实现内网访问可以访问外网,外网禁止访问内网

iptables -I FORWARD  -d 192.168.100.0/24 -m state --state NEW -j REJECT

iptables -I FORWARD  -m state --state ESTABLISHED  -j  ACCEPT

NAT地址转换原理

我们通常所说的NAT其实包含了PAT 端口号转换的过程。

SNAT 内网访问互联网
DNAT 互联网访问内网 端口映射,公网对某个端口的请求转换为私网某个端口

查询添加的nat表,iptables -vnL -t nat

实现SNAT :nat表写在postrouting链
专线地址实现 --to IP
动态地址实现 MASQUERADE

iptables -t nat -A POSTROUTING -s ip -j SNAT MASQUERADE

实现DNAT:nat 表写在prerouting链
防火墙实现端口的转发

实现端口转发之后,ss 命令查看被监听的端口发现没有80,但是依旧可以正常转发给80端口。因为这样的监听是内核实现的,ss命令只能查看程序的窗口监听情况。

有时防火墙的策略更改不方便,不修改防火墙的情况下可以在后端服务器上做REDIRECT,重定向端口。
REDIRECT转发:如下,对11主机中80端口的访问将重定向到11主机的9090端口

#安装httpd,编辑/etc/httpd/conf/httpd.conf,修改httpd的默认端口为9090,重启httpd服务
[root@localhost11 ~]echo port 80 redirect to 9090 > /var/www/html/index.html

#重定向
[root@localhost11 ~]iptables -t nat -A PREROUTING -d 192.168.100.11 -p tcp --dport 80 -j REDIRECT --to-ports 9090

#可以看到已经启用9090端口
[root@localhost11 ~]# ss -ntl
State          Recv-Q         Send-Q                   Local Address:Port                   Peer Address:Port         Process         
LISTEN         0              10                      192.168.100.11:53                          0.0.0.0:*                            
LISTEN         0              10                           127.0.0.1:53                          0.0.0.0:*                            
LISTEN         0              128                            0.0.0.0:22                          0.0.0.0:*                            
LISTEN         0              128                          127.0.0.1:953                         0.0.0.0:*                            
LISTEN         0              128                                  *:9090                              *:*                            
LISTEN         0              10                               [::1]:53                             [::]:*                            
LISTEN         0              128                               [::]:22                             [::]:*                            
LISTEN         0              128                              [::1]:953                            [::]:*     

#10主机访问11主机80端口
[root@localhost10 ~]# curl 192.168.100.11:80
port 80 redirect 9090

用iptables将流量转发到另一台服务器
当客户端访问某一个服务器的某端口时(此处称这台服务器为转发服务器),将流量转发到另外一台服务器的某一个端口
在这里插入图片描述
为了能让数据包转发到目的地址,转发服务器上需要在第一个路由判断之前,将目的地址用DNAT改成目的服务器的地址,这样数据包就不会提交给上层程序。然后在数据包出网卡之前,将原来的源地址改成转发服务器的地址,这样目的服务器返回时会返回给转发服务器,转发服务器会根据之前建立的映射表再返回给客户端。需要注意的是我们应该打开ipv4时的转发功能。

具体实现:
客户端,ip 192.168.100.10
转发服务器,ip 192.168.100.11
目的服务器,ip 192.168.100.12

转发服务器上

# 开启ip_forward
[root@localhost-11 ~]# sysctl -a |grep ip_forw*
net.ipv4.ip_forward = 0
net.ipv4.ip_forward_update_priority = 0
net.ipv4.ip_forward_use_pmtu = 0
[root@localhost-11 ~]# 
[root@localhost-11 ~]# echo net.ipv4.ip_forward=1 > /etc/sysctl.conf 
[root@localhost-11 ~]# 
[root@localhost-11 ~]# sysctl -p
net.ipv4.ip_forward = 1

# PREROUTING上做DNAT
[root@localhost-11 ~] iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.100.12:999

# POSTROUTING上做SNAT
[root@localhost-11 ~] iptables -t nat -A POSTROUTING -d 192.168.100.12 -p tcp --dport 999 -j SNAT --to 192.168.100.11

# 必要的话需要在forward链上放行流量,防止上面的流量被forward链拦截

目的服务器上

#安装httpd,实现http服务
[root@localhost-12 ~]# yum install -y httpd
[root@localhost-12 ~]# echo hello,here is 192.168.100.12:999 > /var/www/html/index.html

#修改httpd默认的端口为999
[root@localhost-12 ~]# vim /etc/httpd/conf/httpd.conf 
[root@localhost-12 ~]# 
[root@localhost-12 ~]# systemctl start httpd
[root@localhost-12 ~]# 
[root@localhost-12 ~]# curl 192.168.100.12:80
curl: (7) Failed to connect to 192.168.100.12 port 80: 拒绝连接
[root@localhost-12 ~]# 
[root@localhost-12 ~]# curl 192.168.100.12:999
hello,here is 192.168.100.12:999
# 此时主机12已经可以通过999端口对外提供http服务

客户端验证

# 此时主机11不需要启动80端口
[root@localhost-10 ~]# curl 192.168.100.11:80
hello,here is 192.168.100.12:999
[root@localhost-10 ~]# 

firewalld 和 nft

  • 34
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值