Iptables与Firewalld

防火墙分类

按保护范围划分:

主机防火墙:服务范围为当前一台主机

网络防火墙:服务范围为防火墙一侧的局域网

按实现方式划分:

硬件防火墙:在专用硬件级别实现部分功能的防火墙;另一个部分功能基于软件实现,如:华为,山石hillstone,天融信,启明星辰,绿盟,深信服, PaloAlto , fortinet飞塔, Cisco, Checkpoint,NetScreen(2004年被 Juniper 用40亿美元收购)等

软件防火墙:运行于通用硬件平台之上的防火墙的应用软件,Windows 防火墙 ISA --> ForefrontTMG

按网络协议划分:

一、网络层防火墙:OSI模型下四层,又称为包过滤防火墙

        网络层对数据包进行选择,选择的依据是系统内设置的过滤逻辑,被称为访问控制列表(ACL),通过检查数据流中每个数据的源地址,目的地址,所用端口号和协议状态等因素,或他们的组合来确定是否允许该数据包通过

优点:对用户来说透明,处理速度快且易于维护

缺点:无法检查应用层数据,如病毒等

二、应用层防火墙/代理服务器:proxy 代理网关,OSI模型七层

        应用层防火墙/代理服务型防火墙,也称为代理服务器(Proxy Server) ;将所有跨越防火墙的网络通信链路分为两段;内外网用户的访问都是通过代理服务器上的“链接”来实现

优点:在应用层对数据进行检查,比较安全

缺点:增加防火墙的负载

提示

现实生产环境中所使用的防火墙一般都是二者结合体,即先检查网络数据,通过之后再送到应用层去检查

Netfilter

iptables是一个免费开源的软件,工作在用户空间;底层是netfilter,工作在内核空间,是内核的一部分。iptables 在用户空间的插入、修改、删除等操作最终都会作用到netfilter,netfilter 触发相应的回调函数(hook 钩子机制)执行相应的防护动作。

五个勾子函数

PREROUTINGINPUTFORWARDOUTPUTPOSTROUTING

可以通过命令行工具向其写入规则。

由信息过滤表table组成,包含控制IP包处理的规则集rules,规则被分组放在链chain上。

三种报文流向

  • 流入本机:PREROUTING ---> INPUT ---> 用户进程
  • 流出本机:用户进程 ---> OUTPUT ---> POSTROUTING
  • 转发:PREROUTING ---> FORWARD ---> POSTROUTING

防火墙工具

iptables(CentOS6)

工作在用户空间,用来编写规则,写好的规则被送往netfilter,告诉内核如何处理数据

软件包

  • Iptables
  • iptables-services

firewalld(CentOS7)

软件包

  • firewalld
  • firewalld-config

nftables(CentOS8)

软件包

  • nftables

iptables

分类

iptables根据保护范围可分为主机防火墙(Filter)和网络防火墙(Nat)

五表(table)五链(chain)

五表:

  • Filter:iptables默认表;负责过滤数据包;
  • Nat:负责网络地址转换;
  • Mangle:负责修改数据包头部信息;
  • Raw:负责对数据包进行状态跟踪;
  • Security:用于强制访问控制(MAC)网络规则,由SELinux实现。
    • 此表用的少,所以俗称四表

五链:

  • PREROUTING:负责目标地址转换
  • INPUT:负责处理进来的数据包
  • FORWARD:负责转发数据包
  • OUTPUT:负责处理出去的数据包
  • POSTROUTING:负责源地址转换

链分为

  • 内置链:五链即内置链;每个内置链对应一个钩子函数
  • 自定义链:对内置链的拓展补充,只有hook钩子函数调用自定义链时才生效。

表链关系

查看表链关系:iptables -vnL -t 表名

Filter:INPUT、FORWARD、OUTPUT

Nat:PREROUTING、POSTROUTING、OUTPUT

Mangle:INPUT、FORWARD、OUTPUT、PREROUTING、POSTROUTING、OUTPUT

Raw:PREROUTING、OUTPUT

Security:INPUT、FORWARD、OUTPUT

表优先级从高到低

Security --> Raw --> Mangle --> Nat --> Filter

规则

规则组成

规则:管理员自定义的规则,匹配成功即执行规则。规则要添加在链上,才生效;添加在自定义链上不会自动生效。

顺序:链上规则的顺序即为检查匹配时顺序

匹配条件:同时满足,且

基本匹配:IP、端口、TCP的Flags(SYN、ACK等)

拓展匹配:通过复杂高级功能匹配

处理动作:称为Target,跳转目标

  • 内建处理动作:ACCEPT、REJECT、DROP、SNAT、DNAT...
  • 自定义处理动作:自定义chain,利用分类管理复杂情形

白名单:只有特定主机可以访问,其余全拒绝

黑名单:只有特定主机不能访问,其余全允许

添加规则考虑

要实现哪种功能:判断添加在哪张表上

报文流经的路径:判断添加在哪个链上

报文的流向:判断源和目的

匹配规则:业务需要

命令

iptable  -t  表名   子命令   链名   匹配条件   -j 处理动作

默认为 filter 表;filter、nat、mangle、raw

子命令

常用组合:-vnL 或 --vvnxL --line-numbers

-L:列出指定链的所有规则

-n:数字格式显示地址和端口号

-v:详细信息

-vv:更详细

-x:显示计数器结果的精确值

--line-numbers:显示链中规则序号

-S:以iptables-save命令格式显示链的规则

-A:追加,默认为最后一条规则

-I:插入,可指定插入的规则序号,默认为第一条规则

-D:删除,可指定链中的规则序号,如: iptables -D FORWARD 5 。删除一条规则后,序号可能会发生变化,需注意。

-R:替换,替换指定序号的规则

-F:清空,可指定链名;默认清空所有规则

-Z:置0,iptables的每条规则都有两个计数器:匹配的报文个数、匹配的所有报文的大小之和

-N:创建一条新的自定义链

-E:重命名自定义链

-X:删除自定义的空的链

-P:设置默认策略,对filter而言,默认策略有:接受ACCEPT,丢弃DROP。如:iptables -P OUTPUT DROP

链名

PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING

匹配条件

基本:通用,由iptables或netfilter自行提供

拓展:需要加载拓展模块

处理动作Target

ACCEPT放行数据包,进行完此处理动作后,不再对比其它规则,直接跳往下一个规则链
REJECT拦截数据包,并传送数据包通知对方可以传送的数据包有几个选择:ICMP port-unreachable、ICMP echo-reply 或是tcp-reset(这个数据包会要求对方关闭联机),进行完此处理动作后,将不再比对其它规则,直接 中断过滤程序。

DROP

丢弃包不予处理,进行完此处理动作后,将不再比对其它规则,直接中断过滤程序。
REDIRECT将包重定向到另一个端口(PNAT),进行完此处理动作后,将会继续比对其它规则。 这个功能可以用来实作通透式porxy 或用来保护 web 服务器。
MASQUERADE改写数据包来源 IP为防火墙 NIC IP,可以指定 port 对应的范围,进行完此处理动作后,直接跳往下一个规则。这个功能与 SNAT 略有不同,当进行 IP 伪装时,不需指定要伪装成哪个 IP,IP 会从网卡直接读取,当使用拨号连接时,IP 通常是由 ISP 公司的 DHCP 服务器指派的,这个时候 MASQUERADE 特别有用。
LOG

将封包相关讯息纪录在 /var/log/message 中,详细位置请查阅 /etc/syslog.conf 配置文件,进行完此处理动作后,将会继续比对其规则。

SNAT改写封包来源 IP 为某特定 IP 或 IP 范围,可以指定 port 对应的范围,进行完此处理动作后,将直接跳往下一个规则
DNAT改写封包目的地 IP 为某特定 IP 或 IP 范围,可以指定 port 对应的范围,进行完此处理动作后,将会直接跳往下一个规炼
MIRROR镜像数据包,也就是将来源 IP 与目的地 IP 对调后,将数据包送回,进行完此处理动作后,将会中断过滤程序
QUEUE中断过滤程序,将数据包放入队列,交给其它程序处理
RETURN结束在目前规则链中的过滤程序,返回主规则链继续过滤
MARK将数据包标上某个代号,以便提供作为后续过滤的条件判断依据,进行完此处理动作后,将会继续比对其它规则

以LOG为例

--log-level level:日志级别debug,info,notice,warning,error,crit,alert,emerg

--log-prefix prefix:日志前缀,可用于区分不同的日志,最多29个字符

[root@wenzi ~]#iptables -I INPUT 2 -p tcp --dport 22 -j LOG --log-prefix "ssh connections:"
[root@wenzi ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
23544 1295K ACCEPT     all  --  *      *       192.168.28.1         0.0.0.0/0
    0     0 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 LOG flags 0 level 4 prefix "ssh connections:"
    2   144 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

测试,用192.168.28.30 ssh连接192.168.28.10
[root@wenzi ~]#tail -f /var/log/messages
Jan  9 17:14:01 wenzi rhsmd[13359]: In order for Subscription Manager to provide your system with updates, your system must be registered with the Customer Portal. Please enter your Red Hat login to ensure your system is up-to-date.
...
Jan  9 18:13:06 wenzi kernel: ssh connections:IN=ens160 OUT= MAC=00:0c:29:3a:01:ff:00:0c:29:dd:03:cb:08:00 SRC=192.168.28.30 DST=192.168.28.10 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=51445 DF PROTO=TCP SPT=35176 DPT=22 WINDOW=29200 RES=0x00 SYN URGP=0

基本匹配条件

无需加载模块,由iptables/netfilter自行提供

-s IP:源IP地址。可指定网段 192.168.28.0/24;可为不连续的IP,使用逗号,隔开 10.0.0.10,10.0.0.12;可在 -s 前加叹号!,表示取反,除此之外

-d IP:目标IP地址,用法同上 -s。

-p 协议:指定协议。tcp、udp、icmp等;0表示all;可加叹号!

- i 网卡名:报文流入的接口,只应用于PROROUTING、INPUT、FORWARD;可加叹号!

- o 网卡名:报文流出的接口,只应用于POSTROUTING、OUTPUT、FORWARD;可加叹号!

允许Windows连接,Windows的IP 192.168.28.1
[root@wenzi ~]#iptables -A INPUT -s 192.168.28.1 -j ACCEPT

允许自己ping自己
方法一:指明IP
[root@wenzi ~]#iptables -A INPUT -s 127.0.0.1 -j ACCEPT
方法二:指明网卡
[root@wenzi ~]#iptables -A INPUT -i lo -j ACCEPT

拒绝所有连接。当连接不符合前两条规则时,匹配此条规则,即禁止连接。此规则应为最后一条,否则可能无法远程此主机。
[root@wenzi ~]#iptables -A INPUT -j REJECT


查看已有规则,默认显示 filter表
[root@wenzi ~]#iptables -vnL --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1     2757  153K ACCEPT     all  --  *      *       192.168.28.1         0.0.0.0/0
2        0     0 ACCEPT     all  --  *      *       127.0.0.1            0.0.0.0/0
3       25  1900 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination


清空INPUT链
[root@wenzi ~]#iptables -F INPUT
若主机有两个IP,ens160是192.168.28.10,子接口ens160:1是192.168.28.11,设置只能访问ens160

新增子接口
[root@wenzi ~]#ip a a 192.168.28.11/24 dev ens160 label ens160:1
[root@wenzi ~]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
...
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen ....
    inet 192.168.28.10/24 brd 192.168.28.255 scope global noprefixroute ens160
       valid_lft forever preferred_lft forever
    inet 192.168.28.11/24 scope global secondary ens160:1
...

查看现有iptables INPUT规则,当前从外部ping ens160和ens160:1 都是不通的
[root@wenzi ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
  134  8128 ACCEPT     all  --  *      *       192.168.28.1         0.0.0.0/0
    0     0 ACCEPT     all  --  *      *       127.0.0.1            0.0.0.0/0
    0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination


允许使用icmp协议ping 192.168.28.10 的数据包通过防火墙
[root@wenzi ~]#iptables -I INPUT 3 -d 192.168.28.10 -p icmp -j ACCEPT

查看现在规则
[root@wenzi ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
 3593  204K ACCEPT     all  --  *      *       192.168.28.1         0.0.0.0/0
    0     0 ACCEPT     all  --  *      *       127.0.0.1            0.0.0.0/0
    2   168 ACCEPT     icmp --  *      *       0.0.0.0/0            192.168.28.10
   21  1959 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
...

测试,从外部ping ens160和ens160:1
可以ping通
[root@wenzi ~]#ping 192.168.28.10    
PING 192.168.28.10 (192.168.28.10) 56(84) bytes of data.
64 bytes from 192.168.28.10: icmp_seq=1 ttl=64 time=0.184 ms
64 bytes from 192.168.28.10: icmp_seq=2 ttl=64 time=0.978 ms
...

不可ping通,因为使用的是REJECT,所以有回显
[root@wenzi ~]#ping 192.168.28.11    
PING 192.168.28.11 (192.168.28.11) 56(84) bytes of data.
From 192.168.28.11 icmp_seq=1 Destination Port Unreachable
...

测试ssh也无法连接
[root@wenzi ~]#ssh 192.168.28.10
ssh: connect to host 192.168.28.10 port 22: Connection refused


删除子接口ens160:1
[root@wenzi ~]#ip a flush dev ens160 label ens160:1

拓展匹配条件

需要加载扩展模块(/usr/lib64/xtables/*.so),方可生效

隐式扩展

当 iptables 使用 -p 指定协议时,无需再用 -m 指明扩展模块。

tcp

--sport 端口:匹配报文源端口,端口可以是连续的范围;可加叹号!

--dport 端口:匹配报文目标端口,端口可以是连续的范围;可加叹号!

--tcp-flags mask comp:其中mask表示需要检查的标志位列表,用逗号,分割;如SYN、ACK等;其中comp表示再mask列表中必须为1的标志位,无指定则必须为0

--syn:匹配第一次握手,等价于:--tcp-flags SYN,ACK,FIN,RST SYN;可加叹号!

udp

--sport 端口:匹配报文源端口,端口可以是连续的范围;可加叹号!

--dport 端口:匹配报文目标端口,端口可以是连续的范围;可加叹号!

icmp

--icmp-type 消息类型:其中消息类型0表示icmp应答,8表示icmp请求

显式扩展

必须使用 -m 指定扩展模块名称

帮助文档
  • CentOS 7/8:man iptables-extensions
  • CentOS 6:man iptables
multiport扩展

--sports port:指定多个源端口。如 20:22,80 表示 20 至 22范围内的端口和80端口。可加叹号!

--dports port:指定多个目标端口。用法同上。可加叹号!

--ports port:指定多个源/目标端口。用法同上。可加叹号!

允许外部通过tcp协议访问本机http端口80和ssh端口22
[root@wenzi ~]#iptables -I INPUT 2 -p tcp -m multiport --dports 22,80 -j ACCEPT
[root@wenzi ~]#iptables -vnL --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1     1036 62462 ACCEPT     all  --  *      *       192.168.28.1         0.0.0.0/0
2        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport dports 22,80
3        2   120 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
...
iprange扩展

指明连续的IP地址

--src-range IP01-IP02:源ip地址范围。

--dst-range IP01-IP02:目标ip地址范围。

仅允许来源IP范围在192.168.28.20 - 192.168.28.30 可以ping本机
[root@wenzi ~]#iptables -I INPUT 2  -p icmp -m iprange --src-range 192.168.28.20-192.168.28.30 -j ACCEPT
[root@wenzi ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
 3766  231K ACCEPT     all  --  *      *       192.168.28.1         0.0.0.0/0
    2   168 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            source IP range 192.168.28.20-192.168.28.30
   10   696 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
...
mac扩展

指明源MAC地址。适用于PREROUTING,FORWARD,INPUT

--mac-source MAC地址:可加叹号!

允许IP 地址 172.16.0.100 且 MAC 源地址为 00:50:56:12:34:56 的数据包通过防火墙。
iptables -A INPUT -s 172.16.0.100 -m mac  --mac-source 00:50:56:12:34:56 -j
ACCEPT
string扩展

--algo 算法:bm算法;kmp算法

--from offset:开始偏移;通常为62

--to offset:结束偏移

--string pattern:要检测的字符串模式;可加叹号!

本机有两个网页,index01内容是baidu,index02内容是google,检测关键字google禁止访问
注意是 OUTPUT,因为别人访问本机是请求,是INPUT;本机回应别人是数据报文流出,是OUTPUT
[root@wenzi ~]#echo "baidu" > /var/www/html/index01.html
[root@wenzi ~]#echo "google" > /var/www/html/index02.html
[root@wenzi ~]#iptables -A OUTPUT -m string --algo kmp --from 62 --string "google" -j REJECT
[root@wenzi ~]#iptables -I INPUT 2 -p tcp --dport 80 -j ACCEPT
[root@wenzi ~]#iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
 3653  221K ACCEPT     all  --  *      *       192.168.28.1         0.0.0.0/0
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
    6   424 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            STRING match  "google" ALGO name kmp FROM 62 TO 65535 reject-with icmp-port-unreachable

测试,效果实现
[root@wenzi ~]#curl 192.168.28.10:/index01.html
baidu
[root@wenzi ~]#curl 192.168.28.10:/index02.html
curl: (56) Recv failure: Connection reset by peer
time扩展

将报文到达的时间与指定的时间范围进行匹配。

CentOS7及以上版本系统默认为UTC时间,差8个小时

--datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:开始日期

--datestop  YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:结束日期

--timestart hh:mm[:ss]:开始时间

--timestop  hh:mm[:ss]:结束时间

--monthdays day[,day...]:每个月的几号

--weekdays day[,day...]:星期几,1 – 7 分别表示星期一到星期日

CentOS8中此模块有问题

将在星期六和星期日的下午2:30到6:30之间丢弃所有来自 172.16.0.0/16 网段、目标端口为172.16.100.10:80的TCP数据包。
iptables -A INPUT -s 172.16.0.0/16 -d 172.16.100.10 -p tcp --
dport 80 -m time --timestart 14:30 --timestop 18:30 --weekdays 6,7 -j DROP
connlimit扩展

根据每个客户端IP做并发连接数数量匹配限制,可防止Dos(Denial of Service,拒绝服务)攻击

--connlimit-upto N:连接的数量小于等于N时匹配

--connlimit-above N:连接的数量大于N时匹配

对于进入本机的 TCP 数据包,如果它们访问的端口号是 80,并且与该连接相关的并发连接数量超过了2,那么这些数据包将被拒绝
iptables -A INPUT  -p tcp --dport 80 -m connlimit --connlimit-above 2 -j REJECT
limit扩展

limit模块可以限制报文收发速率

--limit #[/second|/minute|/hour|/day]:限制收发报文速率

--limit-burst number:指定前多少个报文不限制

filter表input链添加规则,指定每分钟接收20个报文,并且前5个报文不进行限制
[root@centos8 ~]#iptables -A INPUT -p icmp --icmp-type 8 -m limit --limit 20/minute --limit-burst 5 -j ACCEPT

上面需要配合此条规则一起使用,否则第一条规则不成立,默认会全部允许访问
[root@centos8 ~]#iptables -A INPUT -j REJECT  
state扩展

通过state状态跟踪模块,判断新旧用户发起的请求,从而进行访问控制。

conntrack机制:追踪本机上请求与响应之间的关系

状态类型

NEW:新发出请求;连接追踪信息库中不存在此连接的相关信息条目,因此,将其识别为第一次发出的请求,即new为一次连接的第一个请求;如断开连接后,重新建立连接,再次发送请求,此请求也为new;

ESTABLISHED:NEW状态之后,连接追踪信息库中(/proc/net/nf_conntrack)为其建立的条目失效之前期间内所进行的通信状态,即第一次请求之后的请求都为ESTABLISHED;如某主机ping本机,第一个来的包为NEW,响应其的包就为ESTABLISHED。

RELATED:新发起的但与已有连接相关联的连接,如:ftp协议中的数据连接与命令连接之间的关系;

INVALID:无效的连接,如flag标记位不正确,如TCP6个标记位都为0或者都为1;

UNTRACKED:未进行追踪的连接,如raw表中关闭追踪;

连接跟踪

当建立起state模块相关规则后会自动加载一些内核模块:lsmod | grep nf

查看已经追踪到的并已记录下来的连接信息库
cat /proc/net/nf_conntrack


查看连接追踪功能所能够容纳的最大连接数量
cat /proc/sys/net/netfilter/nf_conntrack_max
cat /proc/sys/net/nf_conntrack_max


修改可容纳的最大连接数量为10
echo 10 > /proc/sys/net/netfilter/nf_conntrack_max


查看连接跟踪有多少条目
cat /proc/sys/net/netfilter/nf_conntrack_count


不同的协议的连接追踪时长
ll /proc/sys/net/netfilter/

当服务器连接多于最大连接数时 /var/log/message 可以观察到

centos8 kernel: nf_conntrack: nf_conntrack: table full, dropping

原因就是 /proc/sys/net/netfilter/nf_conntrack_max 记录满了

会导致建立TCP连接很慢;解决办法:

(1) 加大nf_conntrack_max 值

vim /etc/sysctl.conf
net.nf_conntrack_max = 393216
net.netfilter.nf_conntrack_max = 393216

(2) 降低 nf_conntrack timeout时间

vim /etc/sysctl.conf
net.netfilter.nf_conntrack_tcp_timeout_established = 300
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
iptables -t nat -L -n

--state state:可加叹号!

允许本机远程访问 192.168.28.158,但允许192.168.28.164访问本机
在158上设置规则
[root@wenzi ~]# iptables -A INPUT -s 192.168.28.1 -j ACCEPT
[root@wenzi ~]# iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
[root@wenzi ~]# iptables -A INPUT -s 192.168.28.164 -m state --state NEW -j REJECT
[root@wenzi ~]# iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
  148 10976 ACCEPT     all  --  *      *       192.168.28.1         0.0.0.0/0
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state ESTABLISHED
    0     0 REJECT     all  --  *      *       192.168.28.164       0.0.0.0/0            state NEW reject-with icmp-port-unreachable

设定规则建议

1、安全放行所有入站和出站的状态为ESTABLISHED状态连接,建议放在第一条,效率更高

2、谨慎放行入站的新请求

3、有特殊目的限制访问功能,要在放行规则之前加以拒绝

4.、同类规则(访问同一应用,比如:http ),匹配范围小的放在前面,用于特殊处理

5. 不同类的规则(访问不同应用,一个是http,另一个是mysql ),匹配范围大的放在前面,效率更高

6. 应该将那些可由一条规则能够描述的多个规则合并为一条,减少规则数量,提高检查效率

7. 设置默认策略,建议白名单(只放行特定连接);规则的最后定义规则做为默认策略,推荐使用,放在最后一条

保存规则

使用iptables命令定义的规则,手动删除之前,其生效期限为kernel存活期限

CentOS7/8

iptables-save > 规则保存路径

CentOS6

service iptables save 将规则覆盖保存至/etc/sysconfig/iptables 文件中

加载规则

CentOS7/8 重新载入规则文件中的规则

iptables-restore > 规则保存路径

CentOS6

service iptables  restart   会自动从/etc/sysconfig/iptables 重新载入规则

iptables-restore选项

  • -n:不清除原有规则
  • -t:仅分析生成规则集,不提交

开机自动重载规则

1、用脚本保存各个iptables命令,使脚本开机后自动运行。在 /etc/rc.d/rc.local文件中添加脚本路径

2、用规则文件保存各个规则,开机时自动载入此规则文件中的规则。在/etc/rc.d/rc.local文件中添加 iptables-restore < 规则文件路径

3、定义Unit文件,CentOS7/8安装iptables-services实现iptables.service,设为开机自启。

1、安装iptables-services服务
yum -y install iptables-services

2、保存现有规则到文件
iptables-save > /etc/sysconfig/iptables

3、设定服务为开机自启
systemctl enable --now iptables-services

4、可选;将firewalld、nftables服务注销
systemctl mask firewalld.service nftables.service

网络防火墙

iptables/netfilter 利用filter表的FORWARD链,可以充当网络防火墙。

注意:

请求、响应报文均会经由FORWARD链,注意规则的方向

如果要启用conntrack机制,建议将双方向的状态为ESTABLISHED的报文直接放行

NAT表

支持PREROUTING,INPUT,OUTPUT,POSTROUTING四个链

请求报文:修改源/目标IP,自定义如何修改

响应报文:修改源/目标IP,根据跟踪机制自动实现

分类

  • SNAT:source NAT,支持POSTROUTING,INPUT,让本地网络中的主机通过某一特定地址访问外部网络,实现地址伪装。请求报文:修改源IP
  • DNAT:destination NAT,支持PREROUTING,OUTPUT,把本地网络中的主机上的某服务开放给外部网络访问(发布服务和端口映射),但隐藏真实IP,请求报文:修改目标IP
  • PNAT:port nat,端口和IP都进行修改

SNAT

需要开启ip_forward

SNAT:基于nat表的target,适用于 固定 的公网IP。如专线。

--to-source [ipaddr[-ipaddr]][:port[-port]]:指定修改后的源地址

格式:
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j SNAT --to[-source]
ExtIP

例如:
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 ! –d 10.0.0.0/24 -j SNAT --to
source 172.18.1.6-172.18.1.9

将从 10.0.0.0/24 网络发出的、目的地址不是 10.0.0.0/24 的数据包的源 IP 地址改为 172.18.1.6-172.18.1.9 范围内的地址

MASQUERADE:基于nat表的target,既支持专线(固定公网IP),也支持拨号(动态公网IP)

to-ports port[-port]:

格式:
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j MASQUERADE

例如:
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j MASQUERADE

将从 10.0.0.0/24 网络发出的、目的地址不是 10.0.0.0/24 的数据包进行地址伪装,将其源 IP 地址自动更改为路由器或网关的 IP 地址

DNAT

需要开启ip_forward

nat表的target,适用于端口映射,既可重定向到本机,也支持重定向至不同主机的不同端
口,但不支持多目标,即不支持负载均衡功能。

--to-destination [ipaddr[-ipaddr]][:port[-port]]:

格式:
iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp --dport PORT -j DNAT --to-destination InterSeverIP[:PORT]

例如:

iptables -t nat -A PREROUTING -s 0/0 -d 172.18.100.6 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.22:8080

将所有发往 172.18.100.6 端口 80 的 TCP 数据包的目的地址和端口改为 10.0.1.22 的地址和端口 8080

SNAT+DNAT实验 

IP网关主机名作用
192.168.28.10(NAT)192.168.28.30lan1内网web
192.168.28.20(NAT)192.168.28.30lan2内网web

192.168.28.30(NAT-内)

172.16.0.10(仅主机-外)

fw防火墙,有两块网卡
172.16.28.20(仅主机)wlan外网web

三个web服务器网页内容为各自IP

当内网服务器访问外网服务器时:SNAT

开启防火墙fw的ip_forward。

[root@fw ~]#echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
[root@fw ~]#sysctl -p
net.ipv4.ip_forward = 1
[root@fw ~]#cat /proc/sys/net/ipv4/ip_forward
1

配置fw,实现SNAT

[root@fw ~]#iptables -t nat -A POSTROUTING -s 192.168.28.0/24 ! -d 192.168.28.0/24 -j MASQUERADE
[root@fw ~]#iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 2 packets, 144 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    4   296 MASQUERADE  all  --  *      *       192.168.28.0/24     !192.168.28.0/24

Chain OUTPUT (policy ACCEPT 2 packets, 152 bytes)
 pkts bytes target     prot opt in     out     source               destination

测试

 

可见当内网访问外网时,源地址已经发生改变;此时外网无法访问内网。

当外网服务器访问内网服务器时:DNAT

开启防火墙fw的ip_forward。

配置fw,实现DNAT

--dport指定的端口可随意,并没有在fw上监听,前后端口可不一致,后面的端口为真实web服务的端口

当外网访问fw公网IP的80端口时,将目标IP改为lan1
[root@fw ~]#iptables -t nat -A PREROUTING -d 172.16.0.10 -p tcp --dport 80 -j DNAT --to-destination 192.168.28.10:80

当外网访问fw公网IP的81端口时,将目标IP改为lan2
[root@fw ~]#iptables -t nat -A PREROUTING -d 172.16.0.10 -p tcp --dport 81 -j DNAT --to-destination 192.168.28.20:80

[root@fw ~]#iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 4 packets, 264 bytes)
 pkts bytes target     prot opt in     out     source               destination
    2   120 DNAT       tcp  --  *      *       0.0.0.0/0            172.16.0.10          tcp dpt:80 to:192.168.28.10:80
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            172.16.0.10          tcp dpt:81 to:192.168.28.20:80

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 2 packets, 120 bytes)
 pkts bytes target     prot opt in     out     source               destination
   15  1068 MASQUERADE  all  --  *      *       192.168.28.0/24     !192.168.28.0/24

Chain OUTPUT (policy ACCEPT 11 packets, 804 bytes)
 pkts bytes target     prot opt in     out     source               destination

测试

可见当外网访问内网时,会暴漏外网IP。

此时实验完成,内网外网互通。

REDIRECT转发

无需开启ip_forward

REDIRECT是NAT表的 target,通过改变目标IP和端口,将接受的包转发至同一个主机的不同端口。可用于PREROUTING、OUTPUT链。

--to-ports port[-port]:

例如:

iptables -t nat -A PREROUTING -d 172.16.100.10 -p tcp --dport 80 -j REDIRECT --to-ports

8080

将发往 172.16.100.10 端口 80 的 TCP 数据包重定向到端口 8080

练习

阻止来自特定IP地址192.168.1.50的所有流量

iptables -A INPUT -s 192.168.1.50 -j REJECT

 

如何允许来自172.16.0.0/16网络的所有设备访问您的HTTP服务器(端口80)?

iptables -A INPUT -p tcp --dport 80 -s 172.16.0.0/16 -j ACCEPT

限制SSH连接速率
设置一个规则,限制同一IP在任何60秒内最多可以建立5个新的SSH连接。

iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m limit --limit 5/min -j ACCEPT

iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j DROP

创建并使用自定义日志链
创建一个名为LOGGING_CHAIN的日志链,并配置它来记录被丢弃的数据包。

# 创建自定义日志链 iptables -N LOGGING_CHAIN # 添加日志记录规则到LOGGING_CHAIN

iptables -A LOGGING_CHAIN -m limit --limit 2/min -j LOG --log-prefix "IPTables-Dropped: " --log-level 4

# 在INPUT链中添加规则跳转到LOGGING_CHAIN,并在最后DROP数据包

iptables -A INPUT -j LOGGING_CHAIN iptables -A LOGGING_CHAIN -j DROP

允许ICMP回显请求(ping)
写出一条规则以允许来自任何地方的ICMP echo请求(即ping命令),但仅限于每分钟不超过3次。

iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 3/minute -j ACCEPT

阻止除HTTP和HTTPS外的所有出站流量
配置iptables,使所有未匹配规则的出站流量都被拒绝,除了到HTTP(80)和HTTPS(443)端口的流量。

iptables -A OUTPUT -p tcp -m multiport ! --dports 80,443 -j REJECT

允许内部网络访问外部网络
允许来自内部网络192.168.0.0/24的所有设备访问互联网。

iptables -A OUTPUT -s 192.168.0.0/24 -j ACCEPT

设置默认策略
将INPUT、FORWARD和OUTPUT链的默认策略设置为DROP。

iptables -P INPUT DROP

iptables -P FORWARD DROP

iptables -P OUTPUT DROP

允许本地环回接口的所有流量
写出规则以允许所有通过本地环回接口(lo)的流量。

iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT

转发规则
假设您正在运行一个路由器,如何设置规则以允许转发来自内部网络192.168.1.0/24的数据包?

iptables -A FORWARD -s 192.168.1.0/24 -j ACCEPT

DNAT规则
如果您想要将所有到达服务器上TCP端口8080的流量重定向到内部服务器192.168.1.10的端口80,应该怎样配置?

iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.10:80

SNAT规则
配置SNAT规则,以便内部网络192.168.1.0/24中的所有设备都通过公共IP203.0.113.1上网。

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to-source 203.0.113.1

多端口规则
如何编写一条规则来允许SSH(22)、HTTP(80)和HTTPS(443)三个服务的同时访问?

iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT

基于MAC地址过滤
写出规则以允许只有具有特定MAC地址00:1A:2B:3C:4D:5E的设备访问网络。

iptables -A INPUT -m mac --mac-source 00:1A:2B:3C:4D:5E -j ACCEPT

时间条件下的规则
设置规则,在工作日的工作时间内(周一至周五,上午9点到下午5点)允许SMTP(25)邮件流量。

iptables -A INPUT -p tcp --dport 25 -m time --timestart 09:00 --timestop 17:00 --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT

限制国家代码的访问
使用GeoIP模块限制某些国家的访问,例如只允许来自中国的IP访问Web服务器。

iptables -A INPUT -m geoip --src-cc CN -j ACCEPT

链的插入和删除
插入一条规则到INPUT链的顶部,然后将其删除而不影响其他规则。

# 插入规则到INPUT链的顶部

iptables -I INPUT 1 -s 192.168.1.100 -j ACCEPT

# 删除该规则

iptables -D INPUT 1

状态检查
写出规则只允许已建立或相关的连接进入,而拒绝所有新的未经请求的连接。

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -m conntrack --ctstate NEW -j DROP

端口扫描检测
使用limit模块配置规则,以检测并阻止可能的端口扫描活动。

ip6tables -A INPUT -s 2001:db8::50 -j REJECT --reject-with icmp6-adm-prohibited

FIrewalld防火墙

内核模块:netfilter

RHEL6中是iptables,RHEL7中是firewalld

区域zone

介绍

过滤规则的集合。每个zone单独对应一个xml配置文件,位于/usr/lib/firewalld/services目录。自定义zone需要新建 zone名.xml文件,然后向其中添加规则。每个zone都有一个默认的处理行为,包括default、ACCEPT、REJECT、DROP

类型

firewalld 将网卡对应到不同的区域zone;最终一个区域的安全程度取决于管理员在此区域中设置的规则;可以根据网络规模,使用一个或多个区域,但是任何一个活跃区域至少需要关联源地址或接口

trusted(信任区域)允许所有网络流量连接,即使没有开放任何服务,那么使用此 zone 的流量照样通过
public(公共区域)默认的 zone,部分公开,不信任网络中其他计算机,只放行特定服务
external(外部区域)允许与 ssh 预定义的服务传入流量,其余均拒绝。默认将通过此区域转发的 IPv4 传出流量进行地址伪装,可用于为路由器启用了伪装功能的外部网络
home(家庭区域)允许与 ssh、ipp-client、mdns、samba-client 或 dhcpv6-client 预定义的服务传入流量,其余均拒绝
internal(内部区域)默认值时与 home 区域相同
work(工作区域)允许与 ssh、ipp-client、dhcpv6-client 预定义的服务传入流量,其余均拒绝
dmz(隔离区域也称为非军事区域)允许与 ssh 预定义的服务传入流量,其余均拒绝
block(限制区域)任何流入的包都被拒绝,返回 icmp-host-prohibited 报文(ipv4)或 icmp6-adm-prohibited 报文(ipv6)。只允许由该系统初始化的网络连接
drop(丢弃区域)任何流入的包都被丢弃,不做任何响应,只允许流出的数据包

常用的firewall-cmd命令选项

  • firewall-config    使用图形界面
  • --reload    重新加载配置,修改 firewalld 配置后需执行此命令
  • --get-default-zone    显示当前默认区域
  • --set-default-zone=    设置默认区域,= 后面跟区域
  • --get-active-zones    显示当前正在使用的区域及其对应的网卡接口
  • --get-zones    显示所有可用的区域
  • --get-zone-of-interface=    显示指定接口绑定的区域,= 后面跟网口
  • --zone= --add-interface=    为指定接口绑定区域
  • --zone= --change-interface=    为指定的区域更改绑定的网络接口
  • --zone= --remove-interface=    为指定的区域删除绑定的网络接口
  • --get-zone-of-source=[/]    显示指定源地址绑定的区域
  • --zone= --add-source=[/]    为指定源地址绑定区域
  • --zone= --change-source=[/]    为指定的区域更改绑定的源地址
  • --zone= --remove-source=[/]    为指定的区域删除绑定的源地址
  • --list-all-zones    显示所有区域及其规则
  • --zone= --list-all    显示所有指定区域的所有规则,省略 --zone= 时表示仅对默认区域操作
  • --zone= --list-services    显示指定区域内允许访问的所有服务
  • --zone= --add-service=    为指定区域设置允许访问的某项服务
  • --zone= --remove-service=    删除指定区域已设置的允许访问的某项服务
  • --zone= --list-ports    显示指定区域内允许访问的所有端口号
  • --zone= --add-port=[端口号]/[协议名]    为指定区域设置允许访问的某个或某段端口号(包括协议名)
  • --zone= --remove-port=[端口号]/[协议名]    删除指定区域已设置的允许访问的端口号(包括协议名)
  • --zone= --list-icmp-blocks    显示指定区域内拒绝访问的所有 ICMP 类型
  • --zone= --add-icmp-block=    为指定区域设置拒绝访问的某项 ICMP 类型
  • --zone= --remove-icmp-block=    删除指定区域已设置的拒绝访问的某项 ICMP 类型
  • firewall-cmd --get-icmptypes    显示所有 ICMP 类型

实验

web服务器 192.168.29.141     客户端 192.168.29.1

#检查firewalld是否开启
[root@wenzi ~]#systemctl status firewalld.service 
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2023-07-09 04:22:46 CST; 6s ago
     Docs: man:firewalld(1)
 Main PID: 1483 (firewalld)
    Tasks: 2 (limit: 4840)
   Memory: 30.0M
   CGroup: /system.slice/firewalld.service
           └─1483 /usr/libexec/platform-python -s /usr/sbin/firewalld --nofork --nopid
#安装httpd
[root@wenzi ~]#yum -y install httpd
[root@wenzi ~]#systemctl start httpd.service 
[root@wenzi ~]#systemctl status httpd.service 
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since Sun 2023-07-09 04:25:00 CST; 36s ago
     Docs: man:httpd.service(8)
 Main PID: 2076 (httpd)
   Status: "Running, listening on: port 80"
    Tasks: 213 (limit: 4840)
   Memory: 33.5M
   CGroup: /system.slice/httpd.service
           ├─2076 /usr/sbin/httpd -DFOREGROUND
           ├─2078 /usr/sbin/httpd -DFOREGROUND
           ├─2079 /usr/sbin/httpd -DFOREGROUND
           ├─2080 /usr/sbin/httpd -DFOREGROUND
           └─2081 /usr/sbin/httpd -DFOREGROUND

#查看当前默认区域
[root@wenzi ~]#firewall-cmd --get-default-zone 
public
#查看所有可用区域
[root@wenzi ~]#firewall-cmd --get-zones 
block dmz drop external home internal public trusted work
#查看当前正在使用的区域及对应的网卡接口
[root@wenzi ~]#firewall-cmd --get-active-zones 
public
  interfaces: ens160

使用客户端访问web服务,无法访问主页

方式一、将使用的区域设定为trusted

[root@wenzi ~]#firewall-cmd --set-default-zone=trusted 
success
[root@wenzi ~]#firewall-cmd --reload 
success
[root@wenzi ~]#firewall-cmd --get-active-zones 
trusted
  interfaces: ens160

客户端再次访问,访问成功 

方式二、放行80端口

#查看已放行端口
[root@wenzi ~]#firewall-cmd --list-ports 

#查看public中规则
[root@wenzi ~]#firewall-cmd --zone=public --list-all 
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens160
  sources: 
  services: cockpit dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
#放行80端口
[root@wenzi ~]#firewall-cmd --zone=public --add-port=80/tcp --permanent 
success
[root@wenzi ~]#firewall-cmd --reload 
success
[root@wenzi ~]#firewall-cmd --zone=public --list-all 
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens160
  sources: 
  services: cockpit dhcpv6-client ssh
  ports: 80/tcp
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

客户端再次访问,访问成功

三、放行http服务

[root@wenzi ~]#firewall-cmd --zone=public --add-service=http --permanent 
success
[root@wenzi ~]#firewall-cmd --reload 
success
[root@wenzi ~]#firewall-cmd --zone=public --list-all 
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens160
  sources: 
  services: cockpit dhcpv6-client http ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

客户端再次访问,访问成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值