iptables
-t 指定表
-A 指定链
-j 指定规则
-s(–source)指定源ip
-d(–destination)目标ip
–dport 目标端口
-p 指定协议
-R INPUT 1 可替换INPUT表中第一条规则为新规则
iptables -F 全部删除
iptables -vnL –line-number 展示规则
iptables -vnL INPUT –line-number 具体的链条,-t可以指定表
删除规则
iptables -D INPUT 1 # 建议使用对应链上的序号删除
==注意==:规则就删除和增加,更改:就先删除原规则,再增加
自定义链
dnf -y install iptables-services # 使用iptables-services自动管理
systemctl start iptables.service
systemctl enable iptables.service
iptables -F #清楚所有规则
service iptables save # 保存一下
iptables -t filter -N WEB_CHAIN # 创建自定义链
iptables -t filter -A INPUT -s 192.168.18.1 -j WEB_CHAIN # 自定义链规则,绑定至filter表中的INPUT链
iptables -t filter -A WEB_CHAIN -p tcp -m multiport --dports 80,443 -j ACCEPT # 自定义链规则为允许80,443端口
iptables -t filter -A INPUT -p tcp -m multiport --dports 80,443 -j DROP # 拒绝所有80,443端口
iptables -L
curl 127.0.0.1 # 无法访问
# 浏览器访问192.168.18.129,可以访问
# 链的规则从1开始逐个匹配
[root@192 ~]# iptables -vnL --line-numbers
Chain INPUT (policy ACCEPT 2608 packets, 130K bytes)
num pkts bytes target prot opt in out source destination
1 2372 118K WEB_CHAIN all -- * * 192.168.18.1 0.0.0.0/0
2 3 180 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 80,443
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 10120 packets, 1015K bytes)
num pkts bytes target prot opt in out source destination
Chain WEB_CHAIN (1 references)
num pkts bytes target prot opt in out source destination
1 18 2455 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 80,443


iptables模块实验
1. string模块
# 注意是output和sport
iptables -A OUTPUT -p tcp --sport 80 -m string --algo bm --string "world" -j REJECT
2. ssh实验尽量使用xshell,mobaxterm中的文件管理也会占用ssh通道
3. limit-burst和limit,这里背景是一个令牌桶算法深入理解令牌桶算法:实现分布式系统高效限流的秘籍 在高并发系统中,“限流” 是保障服务稳定的核心手段 —— 当请求量超 – 掘金
4. tcp flag了解即可,一般是方式tcp异常包的
iptables -A INPUT -p tcp --tcp-flags SYN,FIN,ACK SYN
掩码:SYN, FIN, ACK(只检查这 3 个位,其他位无视)
目标:SYN(要求 SYN=1,FIN=0,ACK=0)
匹配结果:匹配 TCP 握手的第一步(纯 SYN 包),这是建立新连接的标准包。
iptables -A FORWARD -p tcp --tcp-flags ALL SYN,ACK
掩码:ALL(这是 SYN,ACK,FIN,RST,URG,PSH 的简写,检查所有标志位)
目标:SYN,ACK(要求 SYN=1,ACK=1,其他所有位必须为 0)
匹配结果:匹配 TCP 握手的第二步(SYN-ACK 包),即服务器响应客户端的包。
==高并发请求场景(令牌桶+iptables)==
令牌桶的“保护机制”拆解
1. 核心逻辑:控制“进入内核协议栈”的包速率
text
外部请求 ──→ 网卡 ──→ iptables (limit匹配) ──→ 允许进入协议栈 ──→ 应用服务
│
▼ (无令牌)
直接 DROP(拒绝)
- 关键点:拒绝发生在内核层,不经过用户态应用(如 Nginx/Java 进程)。
- 好处:即使拒绝,也几乎不消耗 CPU/内存,避免了应用层处理带来的资源开销。
2. 令牌桶参数如何应对突发流量
| 参数 | 含义 | 高并发下的作用 |
|---|---|---|
--limit-burst | 初始令牌数(桶容量) | 允许短时突发流量通过,避免正常业务波动被误杀 |
--limit | 令牌补充速率 | 长期平均速率的上限,保证整体负载可控 |
举例:
bash
iptables -A INPUT -p tcp --dport 80 -m limit --limit 100/minute --limit-burst 200 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j DROP
- 瞬间来了 500 个并发请求:
- 前 200 个有令牌 → 通过
- 剩下 300 个 → 直接 DROP(不经过 Nginx)
- 之后按 100 个/分钟(约 1.67 个/秒)补充令牌
- 如果持续高压,长期速率被锁死在 ~1.67 req/s,服务器负载稳定
==总结==:
令牌桶 + iptables 是在网络层给服务器戴上一个“泄压阀”——超过阈值直接在内核丢弃,不让压力传导到应用层,从而保证服务在过载时仍能部分可用,而不是完全僵死。
iptables日常管理从rocky9.0开始推荐使用firewalld
启用 iptables 防火墙 – 文档 – Rocky Linux 文档
iptables snat实验
机器初始状态(如果你的机器ip和我的有区别,按照nat网卡和桥接网卡查询结果一起更改即可)
# server1
nat: 192.168.18.129/24 #使用dhcp分配的或者自行配置的ip地址都可以,确保可以上网
host-only: 192.168.199.128/24
# server2
host-only: 192.168.199.129/24 # 默认无法上网,但是与server仅主机网卡处于一个子网
需要配置项目
# server1
1.开启 Linux 内核路由转发
默认情况下,Linux 收到不是发给自己的数据包会直接丢弃。我们需要允许它转发数据
sysctl -w net.ipv4.ip_forward=1 # 开启转发,立即且临时生效
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-ipforward.conf # 写入配置文件永久生效,此/etc/sysctl.conf文件是根配置,依然使用子配置文件的方式
sysctl -p # 立即加载配置文件中参数
iptables -F -t nat
iptables -t nat -A POSTROUTING -s 192.168.199.0/24 -o ens160 -j MASQUERADE # 网卡是可上网的网卡
# iptables -t nat -A POSTROUTING -s 192.168.199.0/24 -o ens160 -j SNAT --to-source 192.168.18.129
# server2
vi /etc/NetworkManager/system-connections/ens160.nmconnection
[ipv4]
method=manual
address1=192.168.199.129/24,192.168.199.128 # ip地址不变,网关更改为server1的ip地址
dns=114.114.114.114 # dns正常添加,否则无人能提供域名解析
配置完成后,按以下顺序在 Server2 上进行检查,很容易排查出卡在哪一步:
1. 测试内网连通性: ping 192.168.199.128 (确保能连上 Server1)
2. 测试跨网段连通性: ping 192.168.18.129 (确保能连上 Server1 的外网网卡,如果这一步通了,说明 Server1 的 ip_forward 转发成功了)
3. 测试外网 IP 连通性: ping 114.114.114.114 (如果这一步通了,说明 iptables NAT 规则成功生效)
4. 测试域名解析: ping www.baidu.com (如果这一步通了,说明 DNS 配置正确,实验完全成功)
两条核心命令解析
iptables -t nat -A POSTROUTING -s 192.168.199.0/24 -o ens160 -j MASQUERADE
- -t nat (去哪张表?)
指定我们要操作的是 nat 表,即修改数据包的源 IP 或目的 IP。
- -A POSTROUTING
A 代表 Append,POSTROUTING是nat表里的一个链,字面意思是“路由之后”
告诉内核,当数据包已经决定了要从哪块网卡送出去、即将离开Server1这一瞬间,把它拦下来执行后面的操作
- -s 192.168.199.0/24
只有来自192.168.199.0/24这个仅主机局域网段的数据包,才会触发这条规则
- -o ens33
限定只有当数据包打算从 ens33 发送出去时,规则才生效。
- -j MASQUERADE
j 代表 Jump(跳转动作)。MASQUERADE 的字面意思是“伪装”,它会对符合上述所有条件的数据包做动态源地址转换(Dynamic SNAT)
iptables -t nat -A POSTROUTING -s 192.168.199.0/24 -o ens160 -j SNAT --to-source 192.168.18.129
当检查到从 ens160 网卡出去、且源自内网 192.168.199.0/24 的数据包时,强行将其源 IP 地址(Source IP)重写为固定的 192.168.18.129
抓包分析观察nat过程
server1上开启tcpdump抓包
# 没有tcpdump,就dnf install tcpdump
# -nn 第一个n:不解析ip地址为域名,第二个n:不解析端口号为协议
[root@server1 ~]# tcpdump -i any -nn host www.baidu.com
tcpdump: data link type LINUX_SLL2
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
23:53:46.110400 ens224 In IP 192.168.199.129 > 180.101.49.44: ICMP echo request, id 12, seq 1, length 64
23:53:46.110423 ens160 Out IP 192.168.18.129 > 180.101.49.44: ICMP echo request, id 12, seq 1, length 64
23:53:46.121616 ens160 In IP 180.101.49.44 > 192.168.18.129: ICMP echo reply, id 12, seq 1, length 64
23:53:46.121634 ens224 Out IP 180.101.49.44 > 192.168.199.129: ICMP echo reply, id 12, seq 1, length 64
server2上ping 百度一下,你就知道
iptables dnat实验
web server转发(端口转发)
在server2上启动一个http server,期望通过server1的nat网卡访问到
dnf install -y httpd
systemctl start httpd
# 宿主机浏览器访问192.168.199.129:80,可以看到网站
# 我们期望通过访问server1 192.168.18.129:8080 可以访问的的上述网站
iptables -t nat -A PREROUTING -d 192.168.18.129 -p tcp --dport 8080 -j DNAT --to-destination 192.168.199.129:80
-t nat:依然是在 nat 表中做配置
-A PREROUTING:在数据包刚进入 Server1、还没决定去哪里之前,把它拦下。因为如果等路由决定做完了,Server1 就会觉得“这是发给我 8080 的包,我自己又没开这个端口”,从而直接拒绝连接。
-d 192.168.18.129 -p tcp –dport 8080:只有当访问的“目的地 IP”是 Server1 外网卡,且协议是 TCP,且“目标端口”是 8080 时,才触发规则。
-j DNAT –to-destination 192.168.199.129:80:强行把这个数据包的“目的地”改成内网机 Server2 的 IP 和 80 端口。
ssh本地端口
可以使用192.168.18.129:3322 通过ssh连接至server2
# server1
iptables -t nat -A PREROUTING -d 192.168.18.129 -p tcp --dport 3322 -j DNAT --to-destination 192.168.199.129:22
ssh本地转发
将本机目的6666端口流量在路由前直接转发至22端口
# server1
iptables -t nat -A PREROUTING -p tcp --dport 6666 -j REDIRECT --to-port 22
可以使用192.168.18.129:6666连接至server1自己
firewalld核心命令
firewall-cmd --list-all --zone=public --permanent # 查看永久生效的
firewall-cmd --list-all --zone=public # 查看所有public规则
firewall-cmd --zone=public --add-service=http # 临时放行
firewall-cmd --zone=public --add-port=80/tcp # 用端口放行
# 注意:永久生效仅重启后才能生效,如果想要永久配置立即生效需要reload
firewall-cmd --zone=public --add-port=80/tcp --permanent # 永久生效
# firewall-cmd --reload
firewall-cmd --zone=public --remove-service=http
firewall-cmd --zone=public --remove-service=http --permanent # 永久删除
# 富规则,此处注意ip地址换成你自己的
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.18.1" port port="80" protocol="tcp" drop'






==firewalld==
1. Firewalld 放行策略的两种思路
- 方法一(服务名):基于预定义的服务协议(如
http)放行。它实际是端口和协议的“别名映射”,适合通用场景,但存在命名歧义风险(例如http默认对应 80/tcp,若不熟悉映射关系容易混淆)。 - 方法二(端口+协议):直接指定具体端口和传输层协议(如
80/tcp)。这种方式的优势是精确、无歧义,无需依赖服务名数据库,排障时一目了然,符合精细控制的需求。
2. 区域(Zone)的默认逻辑
public是 Firewalld 的默认区域。若不特意切换,所有网卡接口默认归属该区域,策略只管这一处即可,无需被其他区域概念干扰。- 临时规则(无
--permanent)立即生效但重启丢失;永久规则(加--permanent)需重载配置,注意两者的生效时机差异。
3. 验证与排查的工具链逻辑
ss:查看服务端口的监听状态(LISTEN)及进程关联,确认 Python/HTTP 服务已正确绑定0.0.0.0:端口。curl:充当测试客户端,发起 HTTP 请求报文。通过curl -I仅查看响应头即可快速验证放行是否生效,无需依赖浏览器。- 抓包工具(tcpdump / Wireshark):分别工作在 Linux 命令行和 Windows 图形界面,本质相同——提供数据包层面的证据链,可确认请求是否真正到达网卡、防火墙是否丢弃、代理是否转发。
4. “不用名字”的设计原则
- 防火墙策略精确到传输层(端口+TCP/UDP),而不依赖应用层别名(如
http),可以避免因服务名定义变化或误读带来的配置偏差。 - 这与网络排查的思路一致:分层解耦——防火墙只负责网络层的门禁开关,不关心门内跑的具体是什么应用;应用层问题(如 403、500)交给
curl返回内容和应用日志去判断。
==总结==:防火墙firewalld
1. Firewalld 永久生效与立即生效的逻辑
- 运行时(Runtime):修改立即生效,但重启丢失。
- 永久(Permanent):修改写入配置文件,但不会自动作用于当前运行状态。
- 完整操作:必须执行 “永久修改 + 重载(Reload)” 组合。重载的作用是用永久配置覆盖当前运行时配置,使两者同步,从而达到既永久又立即生效。注意:
--reload会中断长连接,而--complete-reload更彻底。
2. 浏览器缓存 vs. curl 的测试差异
- 浏览器(强缓存):默认遵循 HTTP 缓存协议(如 Cache-Control),命中强缓存时直接读取磁盘/内存文件,不向服务器发起网络请求。此时若用浏览器测试防火墙放行是否生效,会被缓存干扰,误以为服务异常或正常。
- curl:每次都完整发起 TCP 连接和 HTTP 请求,默认不缓存任何资源,完全走网络链路。因此,验证防火墙策略、端口连通性、服务可用性时,curl 是更纯粹、更可信的测试工具,能绕过客户端缓存层的干扰。
3. 端口转发(Port Forwarding)的本质
- 这是 DNAT(目标地址转换) 或 重定向(Redirection) 行为。操作对象是进入网卡的数据包。
- 关键点:转发规则工作在防火墙的
nat表(或filter表的 FORWARD 链配合),不依赖目标端口是否有程序在监听。它是在数据包到达本地协议栈之前,将目标端口(如 8080)修改为另一个端口(如 80),修改后再交由协议栈处理。因此,只要最终转到的那个端口上有程序监听,流量就能被正常接收。
4. 防火墙 IP 限制的局域网与外网差异
- 局域网(同网段):设备基于 ARP 广播直接二层通信,防火墙可以依据源 IP 轻松实施访问控制(如禁止 192.168.1.x 访问)。
- 外网(跨网段/公网):外网请求经过 NAT(网络地址转换)进入内网时,防火墙看到的是转换后的公网源 IP,或仅能看到网关接口。若想限制外网特定 IP,需在网关的外网接口入向做策略;若限制内网特定主机对外访问,需在 FORWARD 链或 OUTPUT 链做策略。本质上防火墙依然基于五元组过滤,只是外网流量通常绕过了直接的内网 IP 寻址,需配合路由和 NAT 一起分析。
5. Netfilter 五链四表
- 内核数据包经历的核心钩子点为 五链:
PREROUTING→INPUT→FORWARD→OUTPUT→POSTROUTING。 - 数据流向:
- 发往本机:PREROUTING(处理目标地址转换)→ INPUT(过滤进站)→ 本地进程。
- 经本机转发(作为路由器):PREROUTING → FORWARD(过滤转发)→ POSTROUTING(处理源地址转换)。
- 本机发出:OUTPUT(过滤出站)→ POSTROUTING。
- 你说的“基本都在 filter”:是对的。
filter表挂载在 INPUT、FORWARD、OUTPUT 链上,用于允许/拒绝数据包(准入控制)。而nat表挂在 PREROUTING、POSTROUTING、OUTPUT 上,用于修改地址/端口。常规的”端口放行”操作在 filter 表的 INPUT 链;”端口转发”操作在 nat 表的 PREROUTING 链。
6. Firewalld 与 iptables 的冲突本质
- 两者操作的是同一个内核 Netfilter 框架,但管理方式冲突:
- Firewalld 是动态守护进程,维护自己的规则集快照,重启或
--reload时会完全覆盖内核中的规则。 - Iptables 命令直接读写内核当前规则集,是底层瞬时操作。
- Firewalld 是动态守护进程,维护自己的规则集快照,重启或
- 冲突后果:手动用
iptables添加的规则,不会被 firewalld 记录。一旦执行firewall-cmd --reload,firewalld 会根据其配置文件重新生成规则,直接冲掉之前手动用 iptables 添加的所有规则。 - 原则:生产环境只选其一。若用 firewalld,所有策略必须通过
firewall-cmd管理;若必须引入 iptables 脚本,需通过 firewalld 的--direct或--passthrough接口注入,避免配置被冲刷。


Firewalld实践




==注意==:启用一个服务器,下面添加防火墙




==解禁==




云平台的防火墙
阿里云安全组,腾讯云安全组等
实践
从这段终端日志来看,你(或某个操作者)在一台 Rocky Linux 服务器上完成了一次典型的 Web 环境部署与安全测试,具体步骤如下:
- 安装 Nginx Web 服务器
通过包管理器安装了nginx 及其依赖(nginx-core、nginx-filesystem)。
同时还安装了 rocky-logs-httpd(可能是日志相关包)和 cmatrix(一个终端字符动画小游戏,与业务无关,可能顺手装的)。
-
启动并验证 Nginx 启动
Nginx服务,并查看状态,确认 运行正常(Active: active (running)),配置文件语法检查也通过了。 -
添加防火墙规则(阻断 Web 访问) 执行了一条 iptables 命令:
iptables -A INPUT -p TCP --dport 80 -j DROP意思是 在 INPUT 链添加规则,丢弃所有目标端口为 80 的 TCP 请求。 -
查看当前防火墙规则 用
iptables -vnl --line-numbers列出所有规则,确认刚才添加的DROP规则已生效(显示在Chain INPUT的第一条)。




这条命令在INPUT 链 上添加了一条规则:丢弃所有目标端口为 80 的 TCP 数据包。
==注意==:默认添加的规则都在filter表里面


定时任务
系统定时任务相关配置说明
| 配置文件/目录路径 | 适合场景 | 核心格式与要求 | 触发机制与 Rocky 9 特有行为 |
|---|---|---|---|
| /etc/cron.d/ | 高频、精准定时的任务。(如:每 5 分钟同步一次数据,或每天凌晨 2:00 精准备份) | 任意命名的文件。格式必须包含“运行用户”:/5 * root /usr/bin/script | 独立 Crontab 格式,由 crond 守护进程直接管理,时间高度精准。 |
| /etc/crontab | 系统自带的全局配置。不建议日常运维直接修改它。 | 格式与 /etc/cron.d/ 完全一致,同样必须指定用户 | 独立 Crontab 格式,属于历史保留的全局总入口,建议保持原样。 |
| /etc/cron.hourly/ | 需要每小时执行一次的普通脚本。 | 纯可执行脚本 | 按时执行,每小时的第 1 分钟左右,由 crond 强制触发执行。 |
| /etc/cron.daily/ | 每天跑一次,但对具体几点几分没有严格要求的任务(如清理临时文件)。 | 纯可执行脚本 | Anacron 异步触发,默认在凌晨 03:00 – 22:00 之间随机时间执行。如果服务器半夜关机,开机后会自动补跑。 |
| /etc/cron.weekly/ | 每周跑一次的任务(如每周一次的大型日志轮转)。 | 纯可执行脚本 | Anacron 异步触发,由 Anacron 自动控制在每周的某一天随机延迟执行。 |
| /etc/cron.monthly/ | 每月跑一次的任务(如每月度的数据对账、审计统计)。 | 纯可执行脚本 | Anacron 异步触发,由 Anacron 自动控制在每月的某一天的随机延迟执行。 |
系统定时任务调用过程
[系统运行]
↓
1. crond 守护进程每分钟扫描一次配置
↓
2. 每小时的第 1 分钟,crond 触发执行 `/etc/cron.d/0hourly`
↓
3. 0hourly 调用 `run-parts /etc/cron.hourly` 目录
↓
4. 该目录下有一个核心脚本叫 `0anacron`,它被执行了
↓
5. `0anacron` 唤醒了 `anacron` 进程
↓
6. anacron 检查上次执行时间,开始异步调度 `/etc/cron.daily/weekly/monthly` 目录中的脚本
为什么 Rocky Linux 9 要这么设计?
因为传统的 cron 很死板,如果任务定在凌晨 3 点,而当时服务器断电关机了,cron 开机后绝对不会补跑。 所以,RHEL 9 / Rocky 9 的策略是:用 cron 来保证每小时雷打不动地唤醒 anacron;再让 anacron 去负责天/周/月级别的任务。anacron 会记录上一次成功的执行时间,发现错过了就会在开机后自动补跑。
配置详解
[root@localhost cron.hourly]# cat /etc/cron.d/0hourly
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly #每小时的第 1 分钟,以 root 身份去把 /etc/cron.hourly/ 目录里的脚本全跑一遍。
[root@localhost cron.hourly]# cat /etc/cron.hourly/0anacron
#!/usr/bin/sh
# Check whether 0anacron was run today already
if test -r /var/spool/anacron/cron.daily; then
day=`cat /var/spool/anacron/cron.daily`
fi
if [ `date +%Y%m%d` = "$day" ]; then
exit 0
fi
# Do not run jobs when on battery power
online=1
for psupply in /sys/class/power_supply/* ; do
if [ `cat "$psupply/type" 2>/dev/null`x = Mainsx ] && [ -f "$psupply/online" ]; then
if [ `cat "$psupply/online" 2>/dev/null`x = 1x ]; then
online=1
break
else
online=0
fi
fi
done
if [ $online = 0 ]; then
exit 0
fi
/usr/sbin/anacron -s #这里的 -s 它代表串行化执行)告诉 anacron 严格按照 /etc/anacrontab 里规定的延迟时间,排好队一个接一个地去跑 daily、weekly、monthly 里的任务,不要同时爆发,防止瞬间消耗尽服务器的 CPU 和 IO 资源
anacron的配置文件
[root@localhost cron.hourly]# cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45# 为了防止多台服务器或者多个大型任务在同一秒钟同时爆发,把 CPU 和磁盘 I/O 瞬间吃满,anacron 在启动任务前会随机生成一个 0 到 45 之间的分钟数,作为额外的等待时间
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22 # 允许任务启动的时间窗口(凌晨3点-晚上22点)
#周期(天数) 基础延迟(分钟) 任务标识符 具体执行的命令
#period in days delay in minutes job-identifier command
# 每天当 anacron 被唤醒时,先等待 5 分钟加上一段随机时间,然后以较低的 CPU 优先级自动执行 /etc/cron.daily 目录下的所有无后缀脚本
1 5 cron.daily nice run-parts /etc/cron.daily
# 每隔 7 天当 anacron 被唤醒时,先等待 25 分钟加上一段随机时间,然后以较低的 CPU 优先级自动执行 /etc/cron.weekly 目录下的所有无后缀脚本
7 25 cron.weekly nice run-parts /etc/cron.weekly
# 每月当 anacron 被唤醒时,先等待 45 分钟加上一段随机时间,然后以较低的 CPU 优先级自动执行 /etc/cron.monthly 目录下的所有无后缀脚本
@monthly 45 cron.monthly nice run-parts /etc/cron.monthly
现在全局看下cron任务调度的特点
1. 针对“脚本目录”,它确实只是个“传话筒”
对于 /etc/cron.daily/、weekly/、monthly/,crond 唯一的贡献就是在每小时的第 1 分钟通过 0hourly 去唤醒 0anacron 脚本。一旦把 anacron 唤醒了,crond 就收工了。接下来的时间计算、漏跑补回、降低优先级(nice)执行,全由 anacron 独立完成。
2. 但对于“精准定时”,**亲自每分钟刷新**
虽然它把天/周/月的脚本目录外包给了 anacron,但crond自己依然在以 “每分钟扫描一次” 的频率盯着以下几个地方:
/etc/crontab(系统全局总入口文件)
/etc/cron.d/ 目录(你存放自定义精准任务的地方,比如你自己建的 my-sync 文件)
/var/spool/cron/ 目录(所有普通用户通过 crontab -e 提交的任务)
平时想使用系统定时任务的特性可写入的文件
1. /etc/cron.d/ 由crond调用
2. /etc/cron.daily/ 由crond调用
3. /etc/cron.weekly/ 由于anacron调用,有补跑能力
4. /etc/cron.hourly/ 由于anacron调用,有补跑能力
5. /etc/cron.monthly/ 由于anacron调用,有补跑能力
6. /etc/anacrontab 直接由anacron调用(本质上依然是依靠crond刷新/etc/cron.hourly/)
任务是否会补跑
anacron补跑的原理
[root@localhost cron.hourly]# cd /var/spool/anacron/
[root@localhost anacron]# ls
cron.daily cron.monthly cron.weekly # anacron是如何知道有没有补跑?在相应周期anacron跑完之后,会更新对应文件,如果文件小于对应周期,则不补跑,否则,补跑并且结束后更新此文件
哪些任务会被补跑
仅被anacron管理的任务才会自己补跑,即/etc/cron.daily/,/etc/cron.monthly/,/etc/cron.weekly/下放入的脚本会补跑,其余均不会补跑。
另一个可以定时操作的服务
Systemd 中的Timer Unit不仅可以做到微秒级的定时,还原生支持失败重试
[root@localhost cron.daily]# systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
Sun 2026-07-26 21:08:23 CST 1h 0min left Sun 2026-07-26 19:48:01 CST 19min ago dnf-makecache.timer dnf-makecache.service
Mon 2026-07-27 00:00:00 CST 3h 52min left - - logrotate.timer logrotate.service
Mon 2026-07-27 19:30:25 CST 23h left Sun 2026-07-26 19:30:25 CST 37min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
dnf-makecache.timer(元数据缓存更新)
logrotate.timer(日志切割)
systemd-tmpfiles-clean.timer(临时文件清理)