45-Linux学习之旅之防火墙与WEB加固

Linux学习之旅之防火墙与WEB加固

一 、IPtables防火墙

1.1、什么是Netfilter

bash 复制代码
	Netfilter 是 Linux 内核里的网络数据包处理框架(内核子系统),是 Linux 防火墙、NAT 的底层核心,从 Linux 2.4 内核正式引入。简单一句话:Netfilter 在内核网络栈埋了 5 个检查站(Hook 钩子),数据包路过时,可以被拦截、放行、修改、打日志;iptables/nftables 只是用户态工具,用来给 Netfilter 写规则。
	从 Linux 2.4.x 版本的内核开始,netfilter 就正式成为了新一代的 Linux 防火墙机制,是Linux内核的一个子系统。Netfilter采用模块化设计,具有良好的可扩充性,提供扩展网络服务的结构化底层框架。Netfilter与IP协议栈是无缝契合,并允许对数据包进行过滤、地址转换、处理等操作。

1.2、5 个检查站

钩子名称 触发时机 适用流量 核心作用 iptables 对应内置链
PREROUTING 数据包进入内核,路由查找之前 所有从网卡进入主机的数据包 DNAT 端口映射、修改入报文头部、给入包打 mark 标记 PREROUTING
INPUT 路由判断完成,包目标为本机,交给本地应用之前 目的 IP 是本机的入站流量 入站防火墙过滤,控制外部访问本机的端口 / IP INPUT
FORWARD 路由判断完成,包不是本机,需要转发 经过本机网关转发的跨网段流量 转发流量防火墙过滤,控制内网和外网之间转发包 FORWARD
OUTPUT 本机应用生成数据包,路由查找之前向外发送 本机进程向外发出的数据包 本机出站流量过滤、修改本机发出报文 OUTPUT
POSTROUTING 路由完成,数据包即将离开网卡之前 所有要从本机网卡出去的包(本机发包 + 转发包) SNAT/MASQUERADE 源地址转换,共享公网 IP 上网 POSTROUTING

PREROUTING 路由前,INPUT 本机收;FORWARD 做转发,OUTPUT 本机发;POSTROUTING 出网卡。

1.3、IPtables组成

表名 核心作用 可用的链(Netfilter 钩子)
filter 默认表,数据包过滤防火墙,控制包放行 / 丢弃,最常用 INPUT、FORWARD、OUTPUT
nat 网络地址转换,SNAT/DNAT/MASQUERADE、端口映射 PREROUTING、POSTROUTING、OUTPUT
mangle 修改数据包报文头部信息,打 mark 标记,调整 TTL/TOS,用于 QoS、策略路由 PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING(5 条链全都支持)
raw 最高优先级,用于关闭连接跟踪(nf_conntrack),绕过状态检测 PREROUTING、OUTPUT
security 安全访问控制,配合 SELinux,对数据包设置安全上下文 INPUT、FORWARD、OUTPUT

二、IPtables命令配置

2.1、命令格式

2.1.1、命令格式
bash 复制代码
iptables [-t 表名] 命令选项 [链名] [匹配条件] [-j 动作]
2.1.2、命令选项
参数 含义
-A Append,追加规则,加到链末尾
-I Insert,插入规则 ,默认插在第 1 行;-I INPUT 3插到第 3 行
-D Delete,删除一条规则
-F Flush,清空链所有规则
-L List,列出规则
-n 数字格式,不解析域名(加速,推荐搭配 - L)
-v verbose,详细信息(数据包、字节计数)
-P Policy,设置链默认策略
-Z Zero,清空数据包计数器
-N 新建自定义链
-X 删除自定义空链
2.1.3、匹配条件
参数 含义
-s 源IP 源地址,-s 192.168.1.0/24
-d 目的IP 目的地址
-p 协议 协议:tcp/udp/icmp/all
--sport 源端口(配合 - p tcp/udp)
--dport 目的端口
-i 网卡 入网卡(PREROUTING/INPUT/FORWARD)
-o 网卡 出网卡(FORWARD/OUTPUT/POSTROUTING)
-m state --state 状态匹配:NEW,ESTABLISHED,RELATED,INVALID
2.1.4、最终动作
target 说明
ACCEPT 放行数据包
DROP 丢弃,无任何回应
REJECT 拒绝,返回 ICMP 报错
LOG 记录内核日志,不改变数据包
SNAT 静态源地址转换
MASQUERADE 源地址伪装(动态公网 IP)
DNAT 目的地址转换 / 端口映射
MARK 给数据包打内核 mark 标记

2.2、命令基础配置

2.2.1、命令简单操作

拒绝数据

bash 复制代码
# 准备两台主机 
# ping 10.0.0.7主机
[root@rocky9-6 ~]# ping 10.0.0.7
PING 10.0.0.7 (10.0.0.7) 56(84) bytes of data.
64 bytes from 10.0.0.7: icmp_seq=1 ttl=64 time=0.580 ms

# 将来自10.0.0.6 的数据包丢弃
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.6 -j DROP
[root@ubuntu2404ser:~#]

# 会到主机6 可以观察到ping没有反应了,因为主机6不知道数据被丢弃了还在一直发生

# 查看规则
[root@ubuntu2404ser:~#] iptables -vnL
Chain INPUT (policy ACCEPT 281 packets, 19658 bytes)
 pkts bytes target     prot opt in     out     source               destination
  158 13272 DROP       0    --  *      *       10.0.0.6             0.0.0.0/0

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
[root@ubuntu2404ser:~#]

清除规则

bash 复制代码
[root@ubuntu2404ser:~#] iptables -F


[root@ubuntu2404ser:~#] iptables -vnL
Chain INPUT (policy ACCEPT 367 packets, 25119 bytes)
 pkts bytes target     prot opt in     out     source               destination

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
[root@ubuntu2404ser:~#]
2.2.2、规则保存与还原
bash 复制代码
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.6 -j DROP
[root@ubuntu2404ser:~#] iptables -nvL
Chain INPUT (policy ACCEPT 513 packets, 34809 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       0    --  *      *       10.0.0.6             0.0.0.0/0

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
 
# 保存规则
[root@ubuntu2404ser:~#] iptables-save > iptables.rules
[root@ubuntu2404ser:~#] iptables -F
[root@ubuntu2404ser:~#] iptables -nvL
Chain INPUT (policy ACCEPT 610 packets, 40994 bytes)
 pkts bytes target     prot opt in     out     source               destination

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

# 还原规则
[root@ubuntu2404ser:~#] iptables-restore < iptables.rules
[root@ubuntu2404ser:~#] iptables -nvL
Chain INPUT (policy ACCEPT 6 packets, 384 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       0    --  *      *       10.0.0.6             0.0.0.0/0

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

Chain OUTPUT (policy ACCEPT 4 packets, 384 bytes)
 pkts bytes target     prot opt in     out     source               destination
2.2.3、规则清除
bash 复制代码
# 床架几个规则
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.6 -j DROP
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.7 -j DROP
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.8 -j DROP
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.9 -j DROP
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.10 -j DROP
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.11 -j DROP

# 查看规则,--line-numbers显示行号
[root@ubuntu2404ser:~#] iptables -nL INPUT --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    DROP       0    --  10.0.0.6             0.0.0.0/0
2    DROP       0    --  10.0.0.6             0.0.0.0/0
3    DROP       0    --  10.0.0.7             0.0.0.0/0
4    DROP       0    --  10.0.0.8             0.0.0.0/0
5    DROP       0    --  10.0.0.9             0.0.0.0/0
6    DROP       0    --  10.0.0.10            0.0.0.0/0
7    DROP       0    --  10.0.0.11            0.0.0.0/0

# 1. 删除指定行规则
[root@ubuntu2404ser:~#] iptables -D INPUT 3
[root@ubuntu2404ser:~#] iptables -nL INPUT --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    DROP       0    --  10.0.0.6             0.0.0.0/0
2    DROP       0    --  10.0.0.6             0.0.0.0/0
3    DROP       0    --  10.0.0.8             0.0.0.0/0
4    DROP       0    --  10.0.0.9             0.0.0.0/0
5    DROP       0    --  10.0.0.10            0.0.0.0/0
6    DROP       0    --  10.0.0.11            0.0.0.0/0

# 指定规则名字删除规则
[root@ubuntu2404ser:~#] iptables -D INPUT -s 10.0.0.11 -j DROP
[root@ubuntu2404ser:~#] iptables -nL INPUT --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    DROP       0    --  10.0.0.6             0.0.0.0/0
2    DROP       0    --  10.0.0.6             0.0.0.0/0
3    DROP       0    --  10.0.0.8             0.0.0.0/0
4    DROP       0    --  10.0.0.9             0.0.0.0/0
5    DROP       0    --  10.0.0.10            0.0.0.0/0

# 先让主机6 ping几个包
[root@rocky9-6 ~]# ping 10.0.0.7
PING 10.0.0.7 (10.0.0.7) 56(84) bytes of data.
# pkts列是接收几个数据包
[root@ubuntu2404ser:~#] iptables -nvL INPUT
Chain INPUT (policy ACCEPT 475 packets, 30877 bytes)
 pkts bytes target     prot opt in     out     source               destination
    7   588 DROP       0    --  *      *       10.0.0.6             0.0.0.0/0
    0     0 DROP       0    --  *      *       10.0.0.6             0.0.0.0/0
    0     0 DROP       0    --  *      *       10.0.0.8             0.0.0.0/0
    0     0 DROP       0    --  *      *       10.0.0.9             0.0.0.0/0
    0     0 DROP       0    --  *      *       10.0.0.10            0.0.0.0/0
[root@ubuntu2404ser:~#]

# 2. 清除数据包条目
[root@ubuntu2404ser:~#] iptables -Z
[root@ubuntu2404ser:~#] iptables -nvL INPUT
Chain INPUT (policy ACCEPT 24 packets, 1886 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       0    --  *      *       10.0.0.6             0.0.0.0/0
    0     0 DROP       0    --  *      *       10.0.0.6             0.0.0.0/0
    0     0 DROP       0    --  *      *       10.0.0.8             0.0.0.0/0
    0     0 DROP       0    --  *      *       10.0.0.9             0.0.0.0/0
    0     0 DROP       0    --  *      *       10.0.0.10            0.0.0.0/0

# 3. 全部删除
[root@ubuntu2404ser:~#] iptables -X    #自定义规则删除

[root@ubuntu2404ser:~#] iptables -F
[root@ubuntu2404ser:~#] iptables -nvL INPUT
Chain INPUT (policy ACCEPT 75 packets, 5081 bytes)
 pkts bytes target     prot opt in     out     source               destination
2.2.4、最终动作
2.2.4.1、丢弃规则
bash 复制代码
# 创建丢弃规则
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.6 -j DROP
[root@ubuntu2404ser:~#] iptables -nvL
Chain INPUT (policy ACCEPT 26930 packets, 38M bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       0    --  *      *       10.0.0.6             0.0.0.0/0

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
# 对网卡抓包
[root@ubuntu2404ser:~#] tcpdump -i ens33 -nn icmp

[root@rocky9-6 ~]# ping 10.0.0.7
PING 10.0.0.7 (10.0.0.7) 56(84) bytes of data.


# 观察tcpdump抓包 :可以观察到只有
[root@ubuntu2404ser:~#] tcpdump -i ens33 -nn icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), snapshot length 262144 bytes
02:42:38.965494 IP 10.0.0.6 > 10.0.0.7: ICMP echo request, id 6, seq 158, length 64
02:42:39.989736 IP 10.0.0.6 > 10.0.0.7: ICMP echo request, id 6, seq 159, length 64
02:42:41.014494 IP 10.0.0.6 > 10.0.0.7: ICMP echo request, id 6, seq 160, length 64
02:42:42.037691 IP 10.0.0.6 > 10.0.0.7: ICMP echo request, id 6, seq 161, length 64
02:42:43.062203 IP 10.0.0.6 > 10.0.0.7: ICMP echo request, id 6, seq 162, length 64
02:42:44.085509 IP 10.0.0.6 > 10.0.0.7: ICMP echo request, id 6, seq 163, length 64
2.2.4.2、拒绝规则
bash 复制代码
[root@ubuntu2404ser:~#] iptables -F

[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.6 -j REJECT
[root@ubuntu2404ser:~#] iptables -nvL INPUT
Chain INPUT (policy ACCEPT 27426 packets, 38M bytes)
 pkts bytes target     prot opt in     out     source               destination
    3   252 REJECT     0    --  *      *       10.0.0.6             0.0.0.0/0            reject-with icmp-port-unreachable

# 主机6显示目标不可达
From 10.0.0.7 icmp_seq=376 Destination Port Unreachable
From 10.0.0.7 icmp_seq=377 Destination Port Unreachable
From 10.0.0.7 icmp_seq=378 Destination Port Unreachable
From 10.0.0.7 icmp_seq=379 Destination Port Unreachable
From 10.0.0.7 icmp_seq=380 Destination Port Unreachable
From 10.0.0.7 icmp_seq=381 Destination Port Unreachable
From 10.0.0.7 icmp_seq=382 Destination Port Unreachable
From 10.0.0.7 icmp_seq=383 Destination Port Unreachable
From 10.0.0.7 icmp_seq=384 Destination Port Unreachable
From 10.0.0.7 icmp_seq=385 Destination Port Unreachable
From 10.0.0.7 icmp_seq=386 Destination Port Unreachable

# 抓包看看
[root@ubuntu2404ser:~#] tcpdump -i ens33 -nn icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), snapshot length 262144 bytes
02:47:15.877527 IP 10.0.0.6 > 10.0.0.7: ICMP echo request, id 6, seq 429, length 64
02:47:15.877574 IP 10.0.0.7 > 10.0.0.6: ICMP 10.0.0.7 protocol 1 port 33799 unreachable, length 92
02:47:16.923639 IP 10.0.0.6 > 10.0.0.7: ICMP echo request, id 6, seq 430, length 64
02:47:16.923685 IP 10.0.0.7 > 10.0.0.6: ICMP 10.0.0.7 protocol 1 port 40596 unreachable, length 92
02:47:17.948277 IP 10.0.0.6 > 10.0.0.7: ICMP echo request, id 6, seq 431, length 64
02:47:17.948327 IP 10.0.0.7 > 10.0.0.6: ICMP 10.0.0.7 protocol 1 port 36403 unreachable, length 92
02:47:18.972590 IP 10.0.0.6 > 10.0.0.7: ICMP echo request, id 6, seq 432, length 64
# 0.7主机返回的都是icmp端口不可达的报文
2.2.4.3、允许规则
bash 复制代码
# 创建三个规则
[root@ubuntu2404ser:~#] iptables -F
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.1 -j ACCEPT  #允许0.1主机访问,windows本机
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.0/24 -j REJECT #拒绝10.0.0网段拒绝访问
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.6 -j ACCEPT    #0.6主机允许访问呢
[root@ubuntu2404ser:~#] iptables -nvL INPUT
Chain INPUT (policy ACCEPT 27737 packets, 38M bytes)
 pkts bytes target     prot opt in     out     source               destination
  194 13041 ACCEPT     0    --  *      *       10.0.0.1             0.0.0.0/0
   23  1932 REJECT     0    --  *      *       10.0.0.0/24          0.0.0.0/0            reject-with icmp-port-unreachable
    0     0 ACCEPT     0    --  *      *       10.0.0.6             0.0.0.0/0


# 无奖竞猜:10.0.0.6可以ping通10.0.0.7吗
C:\Users\XUEYUN>ping 10.0.0.7  # windows主机测试 可以访问

正在 Ping 10.0.0.7 具有 32 字节的数据:
来自 10.0.0.7 的回复: 字节=32 时间=1ms TTL=64
来自 10.0.0.7 的回复: 字节=32 时间=1ms TTL=64

10.0.0.7 的 Ping 统计信息:
    数据包: 已发送 = 2,已接收 = 2,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 1ms,最长 = 1ms,平均 = 1ms
    
[root@rocky9-6 ~]# ping 10.0.0.7			
PING 10.0.0.7 (10.0.0.7) 56(84) bytes of data.
From 10.0.0.7 icmp_seq=1 Destination Port Unreachable
From 10.0.0.7 icmp_seq=2 Destination Port Unreachable
# 为什么0.6主机访问失败呢,规则里有可以访问
答:规则匹配是从上而下的匹配,当0.6访问时匹配第二条,发现是10.0.0全段拒绝就不会向下匹配了,所有在创建规则是详细规则在最前面,模糊规则在后面
2.2.4.4、规则插入
bash 复制代码
[root@ubuntu2404ser:~#] iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 27737 packets, 38M bytes)
num   pkts bytes target     prot opt in     out     source               destination
1      240 15770 ACCEPT     0    --  *      *       10.0.0.1             0.0.0.0/0
2      220 18480 REJECT     0    --  *      *       10.0.0.0/24          0.0.0.0/0            reject-with icmp-port-unreachable
3        0     0 ACCEPT     0    --  *      *       10.0.0.6             0.0.0.0/0

[root@ubuntu2404ser:~#] iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 27743 packets, 38M bytes)
num   pkts bytes target     prot opt in     out     source               destination
1      383 24687 ACCEPT     0    --  *      *       10.0.0.1             0.0.0.0/0
2        0     0 DROP       0    --  *      *       10.0.0.11            0.0.0.0/0
3      220 18480 REJECT     0    --  *      *       10.0.0.0/24          0.0.0.0/0            reject-with icmp-port-unreachable
4        0     0 ACCEPT     0    --  *      *       10.0.0.6             0.0.0.0/0
2.2.4.5、黑白名单
bash 复制代码
[root@ubuntu2404ser:~#] iptables -D INPUT 2
[root@ubuntu2404ser:~#] iptables -D INPUT 2
[root@ubuntu2404ser:~#] iptables -D INPUT 2
[root@ubuntu2404ser:~#] iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 27743 packets, 38M bytes)
num   pkts bytes target     prot opt in     out     source               destination
1      493 31588 ACCEPT     0    --  *      *       10.0.0.1             0.0.0.0/0

# 添加拒绝所有规则
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -j REJECT
[root@ubuntu2404ser:~#] iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 27743 packets, 38M bytes)
num   pkts bytes target     prot opt in     out     source               destination
1      797 50650 ACCEPT     0    --  *      *       10.0.0.1             0.0.0.0/0
2        0     0 REJECT     0    --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
[root@ubuntu2404ser:~#]


# 访问本机失败
[root@ubuntu2404ser:~#] ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
^C
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 2087ms

[root@ubuntu2404ser:~#] iptables -t filter -I INPUT -s 127.0.0.1 -j ACCEPT
[root@ubuntu2404ser:~#] iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 27743 packets, 38M bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        4   336 ACCEPT     0    --  *      *       127.0.0.1            0.0.0.0/0
2     1170 74569 ACCEPT     0    --  *      *       10.0.0.1             0.0.0.0/0
3       16  1512 REJECT     0    --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable

[root@ubuntu2404ser:~#] ping 127.0.0.1 -c 1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.028 ms

--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.028/0.028/0.028/0.000 ms

# 精确匹配在前,模糊匹配在后
2.2.5、基础匹配
2.2.5.1、规则取反
bash 复制代码
# 将不是10.0.0.1的源地址拒绝
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT ! -s 10.0.0.1 -j REJECT
[root@ubuntu2404ser:~#] iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 27855 packets, 38M bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 REJECT     0    --  *      *      !10.0.0.1             0.0.0.0/0            reject-with icmp-port-unreachable

[root@rocky9-6 ~]# ping 10.0.0.7 -c 1
PING 10.0.0.7 (10.0.0.7) 56(84) bytes of data.
From 10.0.0.7 icmp_seq=1 Destination Port Unreachable

--- 10.0.0.7 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
2.2.5.2、目的地址匹配
bash 复制代码
# 插入目的地址是0.7的允许访问,-I INPUT后面不加行号默认最前面插入
[root@ubuntu2404ser:~#] iptables -t filter -I INPUT -d 10.0.0.7 -j ACCEPT
[root@ubuntu2404ser:~#] iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 28581 packets, 38M bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        8   512 ACCEPT     0    --  *      *       0.0.0.0/0            10.0.0.7
2       80  6768 REJECT     0    --  *      *      !10.0.0.1             0.0.0.0/0            reject-with icmp-port-unreachable

[root@rocky9-6 ~]# ping 10.0.0.7 -c 1
PING 10.0.0.7 (10.0.0.7) 56(84) bytes of data.
64 bytes from 10.0.0.7: icmp_seq=1 ttl=64 time=0.525 ms

--- 10.0.0.7 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.525/0.525/0.525/0.000 ms
2.2.5.3、协议匹配
bash 复制代码
[root@ubuntu2404ser:~#] iptables -F
[root@ubuntu2404ser:~#] iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 28587 packets, 38M bytes)
num   pkts bytes target     prot opt in     out     source               destination

# 拒绝源地址0.6的主机icmp协议
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.6 -p icmp -j REJECT
[root@ubuntu2404ser:~#] iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 39031 packets, 53M bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 REJECT     1    --  *      *       10.0.0.6             0.0.0.0/0            reject-with icmp-port-unreachable

[root@rocky9-6 ~]# ping 10.0.0.7 -c 1
PING 10.0.0.7 (10.0.0.7) 56(84) bytes of data.
From 10.0.0.7 icmp_seq=1 Destination Port Unreachable

--- 10.0.0.7 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

# 其他协议不会与问题,如ssh
[root@rocky9-6 ~]# ssh root@10.0.0.7
The authenticity of host '10.0.0.7 (10.0.0.7)' can't be established.
ED25519 key fingerprint is SHA256:qfxGIdAzjwhotvmLYQbmSuHI11uN+3FXYzu/UNvbqUo.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.0.0.7' (ED25519) to the list of known hosts.
root@10.0.0.7's password:
2.2.6、扩展匹配
2.2.6.1、扩展基础
bash 复制代码
# 查看扩展条目总数
[root@ubuntu2404ser:~#] dpkg -L iptables | grep libxt_.*.so | wc -l
79

[root@ubuntu2404ser:~#] dpkg -L iptables | grep libxt_.*.so | head
/usr/lib/x86_64-linux-gnu/xtables/libxt_AUDIT.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_CHECKSUM.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_CLASSIFY.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_CONNMARK.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_CONNSECMARK.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_CT.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_DSCP.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_HMARK.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_IDLETIMER.so
/usr/lib/x86_64-linux-gnu/xtables/libxt_LED.so
2.2.6.2、显示扩展和隐示扩展

概念说明

  • 隐式扩展(implicit match) :指定 -p 协议 自动加载对应模块,不用写 -m xxx
  • 显式扩展(explicit match) :必须手动写 -m 模块名 才加载
类型 模块名称 触发方式 核心参数 简要说明
隐式扩展 tcp -p tcp --dport、--sport、--tcp-flags、--syn TCP 协议专用匹配
隐式扩展 udp -p udp --dport、--sport UDP 协议专用匹配
隐式扩展 icmp -p icmp --icmp-type ICMP 类型匹配(ping)
隐式扩展 icmpv6 -p icmpv6 --icmpv6-type IPv6 ICMP,ipv6tables
隐式扩展 sctp -p sctp --dport、--sport SCTP 协议端口
隐式扩展 dccp -p dccp --dport、--sport DCCP 协议端口
隐式扩展 ah -p ah --spi IPsec AH 安全参数索引
隐式扩展 esp -p esp --spi IPsec ESP 安全参数索引
显式扩展 conntrack -m conntrack --ctstate 连接状态 NEW/ESTABLISHED/RELATED/INVALID,推荐替代 state
显式扩展 state -m state --state 旧版连接状态模块,conntrack 子集,不推荐新部署
显式扩展 multiport -m multiport --dports / --sports 多离散端口一次性匹配
显式扩展 iprange -m iprange --src-range / --dst-range 连续 IP 区间(非 CIDR 网段)
显式扩展 mac -m mac --mac-source 源 MAC 地址匹配,仅限同二层
显式扩展 recent -m recent --set/--update/--hitcount IP 访问计数、防暴力破解
显式扩展 limit -m limit --limit、--limit-burst 令牌桶速率匹配
显式扩展 time -m time --timestart、--weekdays 按时间匹配包
显式扩展 string -m string --algo、--string 报文载荷字符串匹配
显式扩展 mark -m mark --mark 匹配 fwmark 标记
显式扩展 owner -m owner --uid-owner、--gid-owner 本机进程 UID/GID,仅 OUTPUT 链
显式扩展 length -m length --length IP 报文长度匹配
显式扩展 ttl -m ttl --ttl-eq/gt/lt IP 头部 TTL 值匹配
显式扩展 pkttype -m pkttype --pkt-type 广播 / 组播 / 单播报文类型
2.2.6.3、tcp 议扩展解读
参数 别名 含义 写法示例
--dport --destination-port 匹配 TCP目的端口 --dport 22 --dport 1000:2000 --dport 1000:(1000~65535)
--sport --source-port 匹配 TCP源端口 --sport :1024(0~1024)
--tcp-flags mask comp - TCP 标志位匹配mask:要检查哪些标志comp:必须置 1的标志 --tcp-flags SYN,ACK,FIN,RST SYN
--syn - 简写,等价:--tcp-flags SYN,RST,ACK SYN 匹配TCP 新建连接的 SYN 包(第一次握手包)
--tcp-option - 匹配 TCP 选项字段编号 --tcp-option 8 匹配 MSS 选项
bash 复制代码
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.8 -p tcp --dport 21:23 -j REJECT
[root@ubuntu2404ser:~#] iptables -nvL INPUT --line-numbers
Chain INPUT (policy ACCEPT 610K packets, 869M bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        1    84 REJECT     1    --  *      *       10.0.0.6             0.0.0.0/0            reject-with icmp-port-unreachable
2        0     0 REJECT     6    --  *      *       10.0.0.8             0.0.0.0/0            tcp dpts:21:23 reject-with icmp-port-unreachable


[root@rocky10-8 ~]# hostname -i
10.0.0.8
[root@rocky10-8 ~]# ssh root@10.0.0.7
ssh: connect to host 10.0.0.7 port 22: Connection refused
2.2.6.4、多端口与多IP匹配
参数 简写 含义
--destination-ports --dports 匹配目的端口(最常用)
--source-ports --sports 匹配源端口
--ports - 源端口 或 目的端口匹配列表端口(很少用)
bash 复制代码
# 1. 多端口
[root@ubuntu2404ser:~#] iptables -F
[root@ubuntu2404ser:~#] iptables -t filter -A INPUT -s 10.0.0.6 -p tcp -m multiport --dports 22,80,443 -j REJECT
[root@ubuntu2404ser:~#] iptables -nvL INPUT
Chain INPUT (policy ACCEPT 737K packets, 1050M bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 REJECT     6    --  *      *       10.0.0.6             0.0.0.0/0            multiport dports 22,80,443 reject-with icmp-port-unreachable
参数 含义
--src-range 匹配源 IP范围
--dst-range 匹配目的 IP范围
bash 复制代码
# 2. 多IP
[root@ubuntu2404ser:~#] apt install nginx

[root@ubuntu2404ser:~#] iptables -A INPUT -m iprange --src-range 10.0.0.6-10.0.0.8 -p tcp --dport 80 -j REJECT
[root@ubuntu2404ser:~#] iptables -nvL INPUT
Chain INPUT (policy ACCEPT 737K packets, 1050M bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 REJECT     6    --  *      *       10.0.0.6             0.0.0.0/0            multiport dports 22,80,443 reject-with icmp-port-unreachable
    0     0 REJECT     6    --  *      *       0.0.0.0/0            0.0.0.0/0            source IP range 10.0.0.6-10.0.0.8 tcp dpt:80 reject-with icmp-port-unreachable


[root@rocky10-8 ~]# curl 10.0.0.7
curl: (7) Failed to connect to 10.0.0.7 port 80 after 0 ms: Could not connect to server

2.3、SNAT转换

2.3.1、前提准备

给0.7新增一个仅主机网卡

bash 复制代码
# --0.8主机准备
[root@rocky10-8 ~]# dnf install nginx

[root@rocky10-8 ~]# systemctl restart nginx.service
[root@rocky10-8 ~]# systemctl status nginx.service
[root@rocky10-8 ~]# cd /usr/share/nginx/html
[root@rocky10-8 html]# ls
icons  index.html  nginx-logo.png  poweredby.png  system_noindex_logo.png
[root@rocky10-8 ~]# echo "rocky10 192.168.8.8" > /usr/share/nginx/html/index.html
[root@rocky10-8 html]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@rocky10-8 html]# systemctl reload nginx.service
[root@rocky10-8 html]# curl localhost
rocky10 192.168.8.8
# 网卡改为仅主机
bash 复制代码
# --0.7主机准备
[root@ubuntu24-7:~#] ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/ether 00:0c:29:70:b8:54 brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    inet 10.0.0.7/24 brd 10.0.0.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe70:b854/64 scope link
       valid_lft forever preferred_lft forever
3: ens37: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:0c:29:70:b8:5e brd ff:ff:ff:ff:ff:ff
    altname enp2s5
[root@ubuntu24-7:~#] cd /etc/netplan/
[root@ubuntu24-7:/etc/netplan#] ls
50-cloud-init.yaml
[root@ubuntu24-7:/etc/netplan#] vim 50-cloud-init.yaml
[root@ubuntu24-7:/etc/netplan#] cat 50-cloud-init.yaml
network:
  version: 2
  ethernets:
    ens33:
      addresses:
      - "10.0.0.7/24"
      nameservers:
        addresses:
        - 223.5.5.5
        - 223.6.6.6
        search: []
      routes:
      - to: "default"
        via: "10.0.0.2"
    ens37:
      addresses:
      - "192.168.8.7/24"
[root@ubuntu24-7:/etc/netplan#] netplan apply
[root@ubuntu24-7:/etc/netplan#] ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/ether 00:0c:29:70:b8:54 brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    inet 10.0.0.7/24 brd 10.0.0.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe70:b854/64 scope link
       valid_lft forever preferred_lft forever
3: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/ether 00:0c:29:70:b8:5e brd ff:ff:ff:ff:ff:ff
    altname enp2s5
    inet 192.168.8.7/24 brd 192.168.8.255 scope global ens37
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe70:b85e/64 scope link
       valid_lft forever preferred_lft forever
[root@ubuntu24-7:~#] sysctl -w "net.ipv4.ip_forward=1"
net.ipv4.ip_forward = 1
bash 复制代码
# --0.6主机准备
[root@rocky9-6 ~]# hostname -i
10.0.0.6
[root@rocky9-6 ~]# ip route del default
[root@rocky9-6 ~]# ip route add default via 10.0.0.7
[root@rocky9-6 ~]# ip route list
default via 10.0.0.7 dev ens160
10.0.0.0/24 dev ens160 proto kernel scope link src 10.0.0.6 metric 100
2.3.2、SNAT原理与配置
bash 复制代码
SNAT:Source Network Address Translation 源地址转换
链:nat 表 → POSTROUTING(重点!)
作用:修改数据包的源 IP,用于内网主机访问外网,把内网私网 IP 替换成网关公网 IP。
属于 target 动作,不是匹配扩展模块。

iptables -t nat -A POSTROUTING -s 源网段 -o 出口网卡 -j SNAT --to-source 转换后的IP
2.3.3、SNAT基础配置
bash 复制代码
# 创建源地址是10.0.0网段的,目的地址不是10.0.0网段的,SNAT转换为192.168.8.7
[root@ubuntu24-7:~#] iptables -t nat -A POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j SNAT --to-source 192.168.8.7
[root@ubuntu24-7:~#] iptables -t nat -nvL POSTROUTING --line-numbers
Chain POSTROUTING (policy ACCEPT 1 packets, 76 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 SNAT       0    --  *      *       10.0.0.0/24         !10.0.0.0/24          to:192.168.8.7

----------
# 测试
[root@rocky10-8 ~]# tcpdump -nn icmp
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens160, link-type EN10MB (Ethernet), snapshot length 262144 bytes

[root@rocky9-6 ~]# ping 192.168.8.8 -c 1
PING 192.168.8.8 (192.168.8.8) 56(84) bytes of data.
64 bytes from 192.168.8.8: icmp_seq=1 ttl=63 time=1.25 ms

--- 192.168.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.245/1.245/1.245/0.000 ms

[root@rocky10-8 ~]# tcpdump -nn icmp
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens160, link-type EN10MB (Ethernet), snapshot length 262144 bytes
15:15:47.822094 IP 192.168.8.7 > 192.168.8.8: ICMP echo request, id 18, seq 1, length 64
15:15:47.822135 IP 192.168.8.8 > 192.168.8.7: ICMP echo reply, id 18, seq 1, length 64
# 关于观察到是8.7和8.8在互相访问

[root@rocky9-6 ~]# curl 192.168.8.8
rocky10 192.168.8.8
2.3.4、多地址转换
bash 复制代码
# 修改
[root@ubuntu24-7:~#] iptables -t nat -R POSTROUTING 1 -s 10.0.0.0/24 ! -d 10.0.0.0/24 -o ens37 -j SNAT --to-source 192.168.8.123-192.168.8.244
[root@ubuntu24-7:~#] iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 3 packets, 217 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 SNAT       0    --  *      ens37   10.0.0.0/24         !10.0.0.0/24          to:192.168.8.123-192.168.8.244

[root@rocky9-6 ~]# curl 192.168.8.8
#没有返回信息阻塞中

[root@rocky10-8 ~]# tcpdump -nn 'tcp port 80'
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens160, link-type EN10MB (Ethernet), snapshot length 262144 bytes
15:26:54.231344 IP 192.168.8.211.42756 > 192.168.8.8.80: Flags [S], seq 2781043554, win 64240, options [mss 1460,sackOK,TS val 1971705369 ecr 0,nop,wscale 7], length 0
15:26:55.278381 IP 192.168.8.211.42756 > 192.168.8.8.80: Flags [S], seq 2781043554, win 64240, options [mss 1460,sackOK,TS val 1971706416 ecr 0,nop,wscale 7], length 0
2.3.4、多端口转换
bash 复制代码
[root@ubuntu24-7:~#] iptables -t nat -R POSTROUTING 1 -s 10.0.0.0/24 ! -d 10.0.0.0/24 -o ens37 -p tcp --dport 80 -j SNAT --to-source 192.168.8.7:12345
[root@ubuntu24-7:~#] iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 6 packets, 445 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 SNAT       6    --  *      ens37   10.0.0.0/24         !10.0.0.0/24          tcp dpt:80 to:192.168.8.7:12345
[root@ubuntu24-7:~#]

[root@rocky9-6 ~]# curl 192.168.8.8
rocky10 192.168.8.8

[root@rocky10-8 ~]# tcpdump -nn 'tcp port 80'
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens160, link-type EN10MB (Ethernet), snapshot length 262144 bytes
15:32:18.658821 IP 192.168.8.7.12345 > 192.168.8.8.80: Flags [S], seq 1346938351, win 64240, options [mss 1460,sackOK,TS val 1972029797 ecr 0,nop,wscale 7], length 0
15:32:18.658869 IP 192.168.8.8.80 > 192.168.8.7.12345: Flags [S.], seq 1588357966, ack 1346938352, win 65160, options [mss 1460,sackOK,TS val 1333005092 ecr 1972029797,nop,wscale 7], length 0
15:32:18.660345 IP 192.168.8.7.12345 > 192.168.8.8.80: Flags [.], ack 1, win 502, options [nop,nop,TS val 1972029798 ecr 1333005092], length 0
# 可以观察到请求报文端口是12345
2.3.5、协议转换
bash 复制代码
[root@ubuntu24-7:~#] iptables -t nat -R POSTROUTING 1 -s 10.0.0.0/24 ! -d 10.0.0.0/24 -o ens37 -p icmp -j SNAT --to-source 192.168.8.7:32768
[root@ubuntu24-7:~#] iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 6 packets, 445 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 SNAT       1    --  *      ens37   10.0.0.0/24         !10.0.0.0/24          to:192.168.8.7:32768

[root@rocky9-6 ~]# ping 192.168.8.8 -c 1
PING 192.168.8.8 (192.168.8.8) 56(84) bytes of data.
64 bytes from 192.168.8.8: icmp_seq=1 ttl=63 time=1.25 ms

--- 192.168.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.246/1.246/1.246/0.000 ms

[root@rocky10-8 ~]# tcpdump -nn icmp
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens160, link-type EN10MB (Ethernet), snapshot length 262144 bytes
15:34:30.396849 IP 192.168.8.7 > 192.168.8.8: ICMP echo request, id 32768, seq 1, length 64
15:34:30.396887 IP 192.168.8.8 > 192.168.8.7: ICMP echo reply, id 32768, seq 1, length 64
2.3.6、MASQUERADE

MASQUERADE 属于 nat 表 POSTROUTING 的 Target,是动态版本的 SNAT,不需要指定IP地址

复制代码
iptables -t nat -A POSTROUTING -s 内网网段 -o 出口网卡 -j MASQUERADE
bash 复制代码
[root@ubuntu24-7:~#] iptables -t nat -R POSTROUTING 1 -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j MASQUERADE
[root@ubuntu24-7:~#] iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 8 packets, 597 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 MASQUERADE  0    --  *      *       10.0.0.0/24         !10.0.0.0/24

[root@rocky9-6 ~]# ping 192.168.8.8 -c 1
PING 192.168.8.8 (192.168.8.8) 56(84) bytes of data.
64 bytes from 192.168.8.8: icmp_seq=1 ttl=63 time=1.05 ms

[root@rocky10-8 ~]# tcpdump -nn icmp
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens160, link-type EN10MB (Ethernet), snapshot length 262144 bytes
15:40:23.797831 IP 192.168.8.7 > 192.168.8.8: ICMP echo request, id 20, seq 1, length 64
15:40:23.797867 IP 192.168.8.8 > 192.168.8.7: ICMP echo reply, id 20, seq 1, length 64

2.4、DNAT转换

2.4.1、前提准备
bash 复制代码
[root@rocky9-6 ~]# ip route del default
[root@rocky9-6 ~]# ip route list
10.0.0.0/24 dev ens160 proto kernel scope link src 10.0.0.6 metric 100


[root@rocky10-8 ~]# ip route add default via 192.168.8.7
[root@rocky10-8 ~]# ip route list
default via 192.168.8.7 dev ens160
192.168.8.0/24 dev ens160 proto kernel scope link src 192.168.8.8 metric 100

[root@ubuntu24-7:~#] netstat -tnlp | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1340/nginx: master
tcp6       0      0 :::80                   :::*                    LISTEN      1340/nginx: master
[root@ubuntu24-7:~#] systemctl disable --now nginx.service
Synchronizing state of nginx.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
Executing: /usr/lib/systemd/systemd-sysv-install disable nginx
Removed "/etc/systemd/system/multi-user.target.wants/nginx.service".
[root@ubuntu24-7:~#] netstat -tnlp | grep 80
2.4.1、DNAT配置
bash 复制代码
[root@ubuntu24-7:~#] iptables -t nat -A PREROUTING -d 10.0.0.7 -p tcp --dport 80 -j DNAT --to-destination 192.168.8.8:80
[root@ubuntu24-7:~#] iptables -t nat -A PREROUTING -d 10.0.0.7 -p tcp --dport 8080 -j DNAT --to-destination 192.168.8.8:80
[root@ubuntu24-7:~#] iptables -t nat -nvL PREROUTING --line-numbers
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 DNAT       6    --  *      *       0.0.0.0/0            10.0.0.7             tcp dpt:80 to:192.168.8.8:80
2        0     0 DNAT       6    --  *      *       0.0.0.0/0            10.0.0.7             tcp dpt:8080 to:192.168.8.8:80

[root@rocky9-6 ~]# curl 10.0.0.7:8080
rocky10 192.168.8.8
[root@rocky9-6 ~]# curl 10.0.0.7:80
rocky10 192.168.8.8


[root@rocky10-8 ~]# tcpdump -nn 'tcp port 80'
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens160, link-type EN10MB (Ethernet), snapshot length 262144 bytes
15:52:49.156373 IP 192.168.8.7.40624 > 192.168.8.8.80: Flags [S], seq 1518178487, win 64240, options [mss 1460,sackOK,TS val 3835494592 ecr 0,nop,wscale 7], length 0
15:52:49.156413 IP 192.168.8.8.80 > 192.168.8.7.40624: Flags [S.], seq 1348421734, ack 1518178488, win 65160, options [mss 1460,sackOK,TS val 1334235590 ecr 3835494592,nop,wscale 7], length 0
15:52:49.157966 IP 192.168.8.7.40624 > 192.168.8.8.80: Flags [.], ack 1, win 502, options [nop,nop,TS val 3835494593 ecr 1334235590], length 0
2.4.3、多目标操作
bash 复制代码
[root@rocky10-8 ~]# vim /etc/nginx/nginx.conf
[root@rocky10-8 ~]# grep -Ev '^$|#' /etc/nginx/nginx.conf | grep -A 6 'server {'
    server {
        listen       81;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;
    }
    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;
        include /etc/nginx/default.d/*.conf;
    }
[root@rocky10-8 ~]# nginx -t
nginx: [warn] conflicting server name "_" on [::]:80, ignored
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@rocky10-8 ~]# systemctl reload nginx.service
[root@rocky10-8 ~]# netstat -tnlp | grep nginx
tcp        0      0 0.0.0.0:81              0.0.0.0:*               LISTEN      3268/nginx: master
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3268/nginx: master

[root@ubuntu24-7:~#] iptables -t nat -A PREROUTING -d 10.0.0.7 -p tcp --dport 81 -j DNAT --to-destination 192.168.8.8:81
[root@ubuntu24-7:~#] iptables -t nat -nvL PREROUTING --line-numbers                                  Chain PREROUTING (policy ACCEPT 5 packets, 674 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        1    60 DNAT       6    --  *      *       0.0.0.0/0            10.0.0.7             tcp dpt:80 to:192.168.8.8:80
2        1    60 DNAT       6    --  *      *       0.0.0.0/0            10.0.0.7             tcp dpt:8080 to:192.168.8.8:80
3        0     0 DNAT       6    --  *      *       0.0.0.0/0            10.0.0.7             tcp dpt:81 to:192.168.8.8:81

[root@rocky9-6 ~]# curl 10.0.0.7:81
rocky10 192.168.8.8

2.5、nftables /nft 快速入门

nftables 是 iptables 的下一代,Linux 内核 3.13+ 引入;Ubuntu20.04+/Rocky8+ 默认支持,用来替代 iptables、ip6tables、arptables、ebtables 。 命令行工具:nft

2.5.1、核心概念(和 iptables 对比理解)

iptables:表 → 链 → 规则,内置固定表 (filter/nat/mangle/raw),内置固定链

nftables:表 (table) → 链 (chain) → 规则 (rule)

链的 type + hook + priority(nft 最核心)

链必须指定:

  1. type:filter / nat / route
  2. hook:挂载在内核网络栈哪个点(对应 iptables 的链)
  3. priority:优先级(数字,越小越早执行)
nft hook 等价 iptables 链
prerouting PREROUTING
input INPUT
forward FORWARD
output OUTPUT
postrouting POSTROUTING
2.5.2、基础命令
bash 复制代码
nft 动作 chain <家族> <表名> <链名> <{ 规则细节 }>
常见动作:
	list 查看
	add 创建
	delete 删除
	flush 清空
bash 复制代码
# 1. 查看
[root@ubuntu24-7:~#] nft list ruleset
# Warning: table ip nat is managed by iptables-nft, do not touch!
table ip nat {
        chain POSTROUTING {
                type nat hook postrouting priority srcnat; policy accept;
                ip saddr 10.0.0.0/24 ip daddr != 10.0.0.0/24 counter packets 12 bytes 862 masquerade
        }

        chain PREROUTING {
                type nat hook prerouting priority dstnat; policy accept;
                ip daddr 10.0.0.7 tcp dport 80 counter packets 1 bytes 60 dnat to 192.168.8.8:80
                ip daddr 10.0.0.7 tcp dport 8080 counter packets 1 bytes 60 dnat to 192.168.8.8:80
                ip daddr 10.0.0.7 tcp dport 81 counter packets 1 bytes 60 dnat to 192.168.8.8:81
        }
}

# 2. 创建表
[root@ubuntu24-7:~#] nft list ruleset
[root@ubuntu24-7:~#] nft add table inet myfw
[root@ubuntu24-7:~#] nft list ruleset
table inet myfw {
}
[root@ubuntu24-7:~#] nft list table inet myfw
table inet myfw {
}

# 3. 删除表
[root@ubuntu24-7:~#] nft delete table inet myfw
[root@ubuntu24-7:~#] nft list ruleset


# 4. 创建链
[root@ubuntu24-7:~#] nft list ruleset
[root@ubuntu24-7:~#] nft add table inet myfw
# 创建链
[root@ubuntu24-7:~#] nft add chain inet myfw hehe { type filter hook input priority 0 \; policy accept \; }
[root@ubuntu24-7:~#] nft list ruleset
table inet myfw {
        chain hehe {
                type filter hook input priority filter; policy accept;
        }
}
[root@ubuntu24-7:~#]

# 5. 清空与删除链
# 清空
[root@ubuntu24-7:~#] nft flush chain inet myfw hehe
[root@ubuntu24-7:~#] nft list chain inet myfw hehe
table inet myfw {
        chain hehe {
                type filter hook input priority filter; policy accept;
        }
}
# 删除
[root@ubuntu24-7:~#] nft delete chain inet myfw hehe
[root@ubuntu24-7:~#] nft list ruleset
table inet myfw {
}
2.5.3、添加规则
bash 复制代码
# 创建表
[root@ubuntu24-7:~#] nft add table inet myfw
# 创建链
[root@ubuntu24-7:~#] nft add chain inet myfw input '{ type filter hook input priority 0; policy accept; }'
# 创建规则
[root@ubuntu24-7:~#] nft add rule inet myfw input ip saddr 10.0.0.6 drop
# 查看规则
[root@ubuntu24-7:~#] nft list chain inet myfw input
table inet myfw {
        chain input {
                type filter hook input priority filter; policy accept;
                ip saddr 10.0.0.6 drop
        }
}
# 查看规则显示行号,行号是递增的
[root@ubuntu24-7:~#] nft -a list chain inet myfw input
table inet myfw {
        chain input { # handle 2
                type filter hook input priority filter; policy accept;
                ip saddr 10.0.0.6 drop # handle 3
        }
}

[root@ubuntu24-7:~#] nft add rule inet myfw input tcp dport 22 accept
[root@ubuntu24-7:~#] nft -a list chain inet myfw input
table inet myfw {
        chain input { # handle 2
                type filter hook input priority filter; policy accept;
                ip saddr 10.0.0.6 drop # handle 3
                tcp dport 22 accept # handle 4
        }
}
2.5.4、删除规则
bash 复制代码
# 不能像iptables一样删除
[root@ubuntu24-7:~#] nft delete rule inet myfw input '{ ip saddr 10.0.0.6 drop }'
Error: syntax error, unexpected '{', expecting handle
delete rule inet myfw input { ip saddr 10.0.0.6 drop }
 
 # 需要按照行号删除
[root@ubuntu24-7:~#] nft delete rule inet myfw input handle 3
[root@ubuntu24-7:~#] nft -a list chain inet myfw input
table inet myfw {
        chain input { # handle 2
                type filter hook input priority filter; policy accept;
                tcp dport 22 accept # handle 4
        }
}
2.5.5、插入规则
bash 复制代码
# insert插入 默认第一行,行号与位置有没有相关
[root@ubuntu24-7:~#] nft insert rule inet myfw input ip saddr 10.0.0.6 drop
[root@ubuntu24-7:~#] nft -a list chain inet myfw input
table inet myfw {
        chain input { # handle 2
                type filter hook input priority filter; policy accept;
                ip saddr 10.0.0.6 drop # handle 5
                tcp dport 22 accept # handle 4
        }
}

# 指定行插入
[root@ubuntu24-7:~#] nft insert rule inet myfw input position 5 tcp dport 6633 accept
[root@ubuntu24-7:~#] nft -a list chain inet myfw input
table inet myfw {
        chain input { # handle 2
                type filter hook input priority filter; policy accept;
                tcp dport 6633 accept # handle 6
                ip saddr 10.0.0.6 drop # handle 5
                tcp dport 22 accept # handle 4
        }
}
[root@ubuntu24-7:~#]
2.5.6、替换规则
bash 复制代码
[root@ubuntu24-7:~#] nft replace rule inet myfw input handle 6 ip saddr 10.0.0.100 drop
[root@ubuntu24-7:~#] nft -a list chain inet myfw input
table inet myfw {
        chain input { # handle 2
                type filter hook input priority filter; policy accept;
                ip saddr 10.0.0.100 drop # handle 6
                ip saddr 10.0.0.6 drop # handle 5
                tcp dport 22 accept # handle 4
        }
}
[root@ubuntu24-7:~#]
2.5.7、清空规则
bash 复制代码
[root@ubuntu24-7:~#] nft flush chain inet myfw input
[root@ubuntu24-7:~#] nft -a list chain inet myfw input
table inet myfw {
        chain input { # handle 2
                type filter hook input priority filter; policy accept;
        }
}

三、服务安全加固

3.1、常见服务端口

服务 默认端口 风险等级 风险简述 推荐访问策略
SSH 22/TCP 🟥 高危 远程服务器管理入口;暴力密码爆破、密钥泄露、漏洞提权,拿下即服务器权限 ✅ 禁止公网直接开放;公网访问走跳板机 / 堡垒机 / VPN;内网做 IP 白名单;禁用密码登录,仅密钥;改非默认端口只是防扫描,不是安全手段
Telnet 23/TCP 🟥 极高危 明文传输!账号密码裸跑,中间人直接抓包拿密码;无加密,早已淘汰 ❌ 生产环境禁止使用,全部替换 SSH;仅隔离内网调试临时用,绝对不能上公网
Nginx 80(TCP) / 443(TCP) 🟧 中危 80:HTTP 明文;443:HTTPS 加密;风险不在端口本身,在于后端 Web 代码、路径穿越、注入、Web 漏洞、CC/DDoS ✅ 80/443 是业务端口,可对公网;80 强制跳转 443;WAF 防护、限制速率、关闭不必要 HTTP 方法;及时更新 nginx 版本
MySQL 3306/TCP 🟥 高危 数据库端口;弱口令爆破、未授权访问、注入、拖库、写入 shell;拿到库后业务数据全部泄露 ✅ 禁止公网开放;仅内网 / 应用服务器访问,IP 白名单;禁止 root 远程;开启 SSL 加密连接;复杂密码
Redis 6379/TCP 🟥 高危 经典高危端口!很多默认无密码;可写入 ssh 密钥、写 crontab 反弹 shell、写 webshell 直接拿下服务器 ✅ 禁止公网开放;内网 IP 白名单;设置密码;禁止危险命令(CONFIG、FLUSHALL 等);尽量不绑定 0.0.0.0,绑定 127.0.0.1

3.2、环境准备

bash 复制代码
[root@ubuntu24-19:~#] cat onekey_install_ruoyi_ubuntu24.sh
#!/bin/bash
# *************************************
# * 功能: Shell一键部署单机版Ruoyi-vue
# * 作者: 马哥教育王老师
# * 版本: xxxx-xx-xx
# *************************************
# set -euo pipefail

# ====================== 全局自定义变量 ======================
MYSQL_ROOT_PWD="Root@2026"
RUOYI_DB="ry_vue"
RUOYI_USER="ruoyi"
RUOYI_PWD="Ruoyi@123"
REDIS_PWD="Redis@2026"
APP_PORT=8080
WEB_DOMAIN="ruoyi.magedu.com"
BASE_DIR="/data/ruoyi"
SOURCE_DIR="/root/RuoYi-Vue"
RUOYI_SERVICE="/etc/systemd/system/ruoyi-admin.service"
# ===========================================================

# 日志打印函数
log_info() {
    echo -e "\033[32m===== $1 =====\033[0m"
}

# 1. 系统更新 & 基础工具安装
func_sys_init() {
    log_info "系统更新并安装基础工具 git curl"
    apt update -y
    apt install -y git curl
}

# 2. 安装 JDK17 并配置全局 JAVA_HOME
func_install_jdk() {
    log_info "安装 JDK17"
    apt install openjdk-17-jdk -y
    echo "export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64" >> /etc/profile
    echo "export PATH=\$JAVA_HOME/bin:\$PATH" >> /etc/profile
    source /etc/profile
}

# 3. Maven 安装 + 阿里镜像加速
func_install_maven() {
    log_info "安装 Maven 并配置阿里云镜像"
    apt install maven -y
    mkdir -p /root/.m2
    cat > /root/.m2/settings.xml <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<settings>
  <mirrors>
    <mirror>
      <id>aliyun</id>
      <mirrorOf>central</mirrorOf>
      <url>https://maven.aliyun.com/repository/public</url>
    </mirror>
  </mirrors>
</settings>
EOF
}

# 4. Node20 + npm 淘宝源
func_install_node() {
    log_info "安装 Node20 前端打包环境"
    curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
    apt install nodejs -y
    npm config set registry https://registry.npmmirror.com
}

# 5. Nginx 安装,清理默认站点
func_install_nginx() {
    log_info "安装 Nginx"
    apt install nginx -y
    systemctl enable --now nginx
    rm -f /etc/nginx/sites-enabled/default
    mkdir -p /etc/nginx/conf.d
}

# 6. Redis 单机本地仅127.0.0.1访问
func_install_redis() {
    log_info "安装并配置本地 Redis"
    apt install redis-server -y
    sed -i 's/^bind .*/bind 127.0.0.1/' /etc/redis/redis.conf
    sed -i '/^requirepass /d' /etc/redis/redis.conf
    sed -i '/# requirepass/a\requirepass "'${REDIS_PWD}'"' /etc/redis/redis.conf
    sed -i 's/^protected-mode .*/protected-mode yes/' /etc/redis/redis.conf
    systemctl restart redis-server
}

# 7. MySQL8 单机安装 + root初始化
func_install_mysql() {
    log_info "安装 MySQL8 单机服务"
    apt install mysql-server -y
    systemctl enable --now mysql
    mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PWD}';FLUSH PRIVILEGES;"
}

# 8. 创建若依数据库、业务账号
func_init_mysql_db() {
    log_info "初始化若依数据库与业务账号"
    mysql -uroot -p${MYSQL_ROOT_PWD} -e "
CREATE DATABASE IF NOT EXISTS ${RUOYI_DB} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS '${RUOYI_USER}'@'localhost' IDENTIFIED BY '${RUOYI_PWD}';
GRANT ALL ON ${RUOYI_DB}.* TO '${RUOYI_USER}'@'localhost';
FLUSH PRIVILEGES;" 2>/dev/null
}

# 9. 拉取源码 & 导入初始化SQL
func_get_source_and_import_sql() {
    log_info "拉取 RuoYi-Vue 源码"
    cd /root
    [ ! -d "RuoYi-Vue" ] && git clone https://gitee.com/y_project/RuoYi-Vue.git
    cd ${SOURCE_DIR}

    log_info "导入系统初始化SQL"
    mysql -uroot -p${MYSQL_ROOT_PWD} ${RUOYI_DB} < sql/ry_*.sql
}

# 10. 仅修改配置连接参数(sed替换,不覆盖完整yml)
func_modify_config() {
    log_info "修改数据库、Redis连接配置(仅替换参数,保留原有全部配置)"
    cd ${SOURCE_DIR}

    # ========== application-druid.yml 修改本地MySQL ==========
    DRUID_YML="ruoyi-admin/src/main/resources/application-druid.yml"
    sed -i "s|url: jdbc:mysql://.*:3306/.*?|url: jdbc:mysql://127.0.0.1:3306/${RUOYI_DB}?|" ${DRUID_YML}
        sed -i 's|useSSL=true|useSSL=false\&allowPublicKeyRetrieval=true|' ${DRUID_YML}
    sed -i "/master:/,/password:/s|        username: .*|        username: ${RUOYI_USER}|" ${DRUID_YML}
    sed -i "/master:/,/slave:/s|        password: .*|        password: ${RUOYI_PWD}|" ${DRUID_YML}

    # ========== application.yml 修改Redis、上传路径、服务端口 ==========
    APP_YML="ruoyi-admin/src/main/resources/application.yml"
    sed -i "s|profile: .*|profile: ${BASE_DIR}/uploadPath|g" ${APP_YML}
    sed -i "s/host: .*/host: 127.0.0.1/g" ${APP_YML}
    sed -i '/redis:/,/timeout:/s/\s*password:.*/      password: '"${REDIS_PWD}"'/' ${APP_YML}
}

# 11. Maven打包后端,部署Jar包
func_build_backend() {
    log_info "Maven打包后端项目"
    cd ${SOURCE_DIR}
    mvn clean package -Dmaven.test.skip=true

    log_info "迁移Jar至部署目录"
    mkdir -p ${BASE_DIR}/server ${BASE_DIR}/uploadPath
    cp ruoyi-admin/target/ruoyi-admin.jar ${BASE_DIR}/server/
}

# 12. 前端打包,部署静态资源
func_build_frontend() {
    log_info "前端打包生产静态资源"
        cd ${SOURCE_DIR}
        git checkout -b ruoyi-3.9.2 tags/v3.9.2
    cd ${SOURCE_DIR}/ruoyi-ui
    npm install
    npm run build:prod

    log_info "部署前端dist目录"
    mkdir -p ${BASE_DIR}/web
    cp -r dist ${BASE_DIR}/web/
}

# 13. 创建后端 systemd 托管服务
func_create_systemd() {
    log_info "创建 ruoyi-admin systemd 服务"
    cat > "${RUOYI_SERVICE}" <<EOF
[Unit]
Description=RuoYi-Vue Backend Admin Service
After=network.target mysql.service redis-server.service

[Service]
User=root
WorkingDirectory=${BASE_DIR}/server
ExecStart=/usr/lib/jvm/java-17-openjdk-amd64/bin/java -jar ruoyi-admin.jar
SuccessExitStatus=143
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF
    systemctl daemon-reload
    systemctl enable --now ruoyi-admin
}

# 14. Nginx站点反向代理配置
func_config_nginx() {
    log_info "生成 Nginx 若依站点配置"
    cat > /etc/nginx/conf.d/ruoyi.conf <<EOF
server {
    listen 80;
    server_name ${WEB_DOMAIN};
    root ${BASE_DIR}/web/dist;
    index index.html;

    location / {
        try_files \$uri \$uri/ /index.html;
    }
    location ^~ /prod-api/ {
        proxy_pass http://127.0.0.1:${APP_PORT}/;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
    }
    location /profile/ {
        proxy_pass http://127.0.0.1:${APP_PORT}/profile/;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
    }
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 1d;
        add_header Cache-Control "public";
    }
}
EOF
    nginx -t
    systemctl reload nginx
}

# 15. 部署完成提示
func_finish_tips() {
    log_info "==================== RuoYi-Vue 单机部署全部完成 ===================="
    echo "后端服务端口:${APP_PORT}"
    echo "前端访问地址:http://${WEB_DOMAIN}"
    echo "后端实时日志:journalctl -u ruoyi-admin -f"
    echo "重启后端服务:systemctl restart ruoyi-admin"
    echo "MySQL数据库:${RUOYI_DB} 账号:${RUOYI_USER} 密码:${RUOYI_PWD}"
    echo "Redis本地连接密码:${REDIS_PWD}"
        echo "清理环境的话,可以执行如下命令"
        echo "apt purge nginx* redis-* mysql-* -y"
        echo "rm -rf /data/ruoyi ${RUOYI_SERVICE} ${SOURCE_DIR}"
}

# ===================== 主执行流程 =====================
main() {
    func_sys_init
    func_install_jdk
    func_install_maven
    func_install_node
    func_install_nginx
    func_install_redis
    func_install_mysql
    func_init_mysql_db
    func_get_source_and_import_sql
    func_modify_config
    func_build_backend
    func_build_frontend
    func_create_systemd
    func_config_nginx
    func_finish_tips
}

# 启动入口
main
[root@ubuntu24-19:~#]
main[root@ubuntu24-19:~#] cat update_actuator_ruoyi_ubuntu24.sh
#!/bin/bash
# *************************************
# * 功能: Shell脚本开放Actuator功能
# * 作者: 马哥教育王老师
# * 版本: 2026-09-06
# *************************************


# set -e

# 定义环境变量
POM_FILE="./RuoYi-Vue/ruoyi-admin/pom.xml"
YML_FILE="./RuoYi-Vue/ruoyi-admin/src/main/resources/application.yml"
SECURITY_JAVA="./RuoYi-Vue/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java"

# 1 添加 spring‑boot‑starter‑actuator 依赖 "
actuator_status=$(grep -q "spring-boot-starter-actuator" "${POM_FILE}")
if [ "$actuator_status" == "" ] ;then
    cat >> /tmp/actuator_dep.xml <<'EOF'
        <!-- Spring Boot Actuator 监控依赖 -->
        <!-- 提供生产级别的应用监控和管理功能,包括健康检查、指标收集、环境信息等端点 -->
        <!-- 版本由 spring-boot-starter-parent 统一管理,无需显式指定 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
EOF
    # 将依赖插入到dependencies闭合标签前
    sed -i '/<\/dependencies>/e cat /tmp/actuator_dep.xml' "${POM_FILE}"
    rm -f /tmp/actuator_dep.xml
fi


# 2 写入management独立端口配置 ====="
manager_status=$(grep -q "^management:" "${YML_FILE}")
if [ "$manager_status" == "" ] ;then
    cat >> "${YML_FILE}" <<'EOF'

# ========= Actuator监控配置(独立端口8091,仅本机访问) =========
management:
  endpoints:
    web:
      base-path: /actuator        # 默认Actuator端点的访问路径前缀
      exposure:
        include: '*'               # 暴露所有端点,推荐改为health,info,metrics
  endpoint:
    health:
      show-details: always         # 健康检查显示详情
  server:
    port: 8091                     # actuator单独端口,不能和ruoyi的server.port重复
    address: 127.0.0.1             # 只允许本机访问
EOF
fi


# 3 修改SecurityConfig.java放行 /actuator/**"
code_status=$(grep -q 'requestMatchers("/actuator/\*\*").permitAll()' "${SECURITY_JAVA}")
if [ "$code_status" == "" ] ;then
    # 在现有requestMatchers放行块内部插入 .requestMatchers("/actuator/**").permitAll()
    # 匹配已有匿名放行的行,在该行后面插入actuator放行规则
    sed -i '/druid/a\                        .requestMatchers("/actuator/**").permitAll()' "${SECURITY_JAVA}"
fi

echo -e "完成Ruoyi-vue开放actuator 监控功能 "
echo "后续操作:"
echo "重新打包 mvn clean package -DskipTests"
echo "启动测试 java -jar ruoyi-admin/target/ruoyi-admin.jar"
echo "启动后访问:curl -s http://127.0.0.1:8091/actuator/metrics"


[root@ubuntu24-19:~#] /bin/bash onekey_install_ruoyi_ubuntu24.sh
[root@ubuntu24-19:~#] /bin/bash update_actuator_ruoyi_ubuntu24.sh

3.3、MySQL安全加固

bash 复制代码
[root@ubuntu24-19:~#] netstat -tnlp | grep -E 'mysql|redis|ssh|nginx|java'
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      1125/redis-server 1
tcp        0      0 127.0.0.1:33060         0.0.0.0:*               LISTEN      1193/mysqld
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      1578/sshd: root@pts
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      1193/mysqld
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1160/nginx: master
tcp6       0      0 :::8080                 :::*                    LISTEN      1256/java
tcp6       0      0 ::1:6010                :::*                    LISTEN      1578/sshd: root@pts

# 配置监听端口
[root@ubuntu24-19:~#] vim /etc/mysql/mysql.conf.d/mysqld.cnf
[root@ubuntu24-19:~#] grep -E -A 1 "^bind-address" /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address            = 127.0.0.1,10.0.0.19
mysqlx-bind-address     = 127.0.0.1,10.0.0.19
[root@ubuntu24-19:~#] systemctl restart mysql.service

[root@ubuntu24-19:~#] mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.46-0ubuntu0.24.04.4 (Ubuntu)

Copyright (c) 2000, 2026, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select Host,User from mysql.user;
+-----------+------------------+
| Host      | User             |
+-----------+------------------+
| localhost | debian-sys-maint |
| localhost | mysql.infoschema |
| localhost | mysql.session    |
| localhost | mysql.sys        |
| localhost | root             |
| localhost | ruoyi            |
+-----------+------------------+
6 rows in set (0.00 sec)
# 修改密码
mysql> alter user root@localhost identified by 'Xyx@1234';
Query OK, 0 rows affected (0.01 sec)
# 只能本机登录
mysql> REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'ruoyi'@'localhost';
Query OK, 0 rows affected (0.00 sec)
# 修改用户对指定库表权限
mysql> GRANT SELECT,INSERT,UPDATE,DELETE ON ry_vue.* TO 'ruoyi'@'localhost';
Query OK, 0 rows affected (0.01 sec)
# 创建用户指定网段可以连接
mysql> CREATE USER IF NOT EXISTS 'ruoyi_dev'@'10.0.0.%' IDENTIFIED BY 'Ruoyi@123';
Query OK, 0 rows affected (0.03 sec)
# 修改用户对指定库表权限
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,ALTER,INDEX ON ry_vue.* TO 'ruoyi_dev'@'10.0.0.%';
Query OK, 0 rows affected (0.01 sec)
# 刷新配置
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

mysql>exit;

3.4、Redis安全加固

bash 复制代码
[root@ubuntu24-19:~#] vim /etc/redis/redis.conf
[root@ubuntu24-19:~#] grep -E '10.0.0.19|^protected-mode|Redis@2026|^rename-command' /etc/redis/redis.conf
bind 127.0.0.1 10.0.0.19	# 监听地址
protected-mode yes		#开启保护模式
requirepass "Redis@2026"	# 认证密码
# 禁用敏感词
rename-command FLUSHALL ""	
rename-command FLUSHDB ""
rename-command DEBUG ""
rename-command KEYS "KEYS_123456"
rename-command CONFIG "CONFIG_123456"
[root@ubuntu24-19:~#] systemctl restart redis

# 密码认证登录,敏感命令取消
[root@ubuntu24-19:~#] redis-cli -a Redis@2026
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> KEYS_123456 *
 1) "sys_config:sys.account.registerUser"
 2) "sys_dict:sys_job_group"
 3) "sys_dict:sys_oper_type"
 4) "sys_dict:sys_yes_no"
 5) "sys_config:sys.user.initPassword"
 6) "sys_dict:sys_notice_type"
 7) "sys_dict:sys_notice_status"
 8) "sys_dict:sys_show_hide"
 9) "sys_config:sys.account.initPasswordModify"
10) "sys_config:sys.account.captchaEnabled"
11) "sys_dict:sys_normal_disable"
12) "sys_dict:sys_common_status"
13) "sys_config:sys.index.sideTheme"
14) "sys_config:sys.index.skinName"
15) "sys_dict:sys_user_sex"
16) "sys_dict:sys_job_status"
17) "sys_config:sys.account.chrtype"
18) "sys_config:sys.login.blackIPList"
19) "sys_config:sys.account.passwordValidateDays"
127.0.0.1:6379> KEYS *
(error) ERR unknown command 'KEYS', with args beginning with: '*'

3.5、Nginx加固

Nginx 默认开启版本号回显、开启目录浏览功能。攻击者可通过响应头获取 Nginx 具体版本,针对性搜索版本漏洞.

bash 复制代码
[root@ubuntu24-19:~#] curl -I 10.0.0.19
HTTP/1.1 200 OK
Server: nginx/1.24.0 (Ubuntu)
Date: Wed, 21 Oct 2026 08:03:32 GMT
Content-Type: text/html
Content-Length: 12759
Last-Modified: Wed, 21 Oct 2026 03:47:11 GMT
Connection: keep-alive
ETag: "6ad835bf-31d7"
Accept-Ranges: bytes
----------------------
[root@ubuntu24-19:~#] cat > /etc/nginx/conf.d/security.conf <<'EOF'
server_tokens off;
autoindex off;
EOF
[root@ubuntu24-19:~#] chown -R www-data:www-data /data/ruoyi/web
[root@ubuntu24-19:~#] find /data/ruoyi/web -type d -exec chmod 755 {} \;
[root@ubuntu24-19:~#] find /data/ruoyi/web -type f -exec chmod 644 {} \;
[root@ubuntu24-19:~#] nginx -t && systemctl reload nginx.service
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@ubuntu24-19:~#]

-----------------------

[root@ubuntu24-19:~#] curl -I 10.0.0.19
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 21 Oct 2026 08:10:29 GMT
Content-Type: text/html
Content-Length: 12759
Last-Modified: Wed, 21 Oct 2026 03:47:11 GMT
Connection: keep-alive
ETag: "6ad835bf-31d7"
Accept-Ranges: bytes

3.6、Actuator安全加固

生产环境仅保留健康检查端点用于监控告警,关闭所有敏感信息端点。

bash 复制代码
[root@ubuntu24-19:~#] cd RuoYi-Vue/
[root@ubuntu24-19:~/RuoYi-Vue#] vim ruoyi-admin/src/main/resources/application.yml
[root@ubuntu24-19:~/RuoYi-Vue#] grep -E -C 5 'base-path' ruoyi-admin/src/main/resources/application.yml

# ========= Actuator监控配置(独立端口8091,仅本机访问) =========
management:
  endpoints:
    web:
      base-path: /actuator        # 默认Actuator端点的访问路径前缀
      exposure:
        include: 'health,metrics'               # 暴露所有端点,推荐改为health,info,metrics
  endpoint:
    health:
      show-details: always         # 健康检查显示详情

[root@ubuntu24-19:~/RuoYi-Vue#] mvn clean package -DskipTests
[root@ubuntu24-19:~/RuoYi-Vue#] cp ruoyi-admin/target/ruoyi-admin.jar /data/ruoyi/server/
[root@ubuntu24-19:~/RuoYi-Vue#] systemctl restart ruoyi-admin.service
[root@ubuntu24-19:~/RuoYi-Vue#] mvn clean package ^C
[root@ubuntu24-19:~/RuoYi-Vue#] systemctl status ruoyi-admin.service
● ruoyi-admin.service - RuoYi-Vue Backend Admin Service
     Loaded: loaded (/etc/systemd/system/ruoyi-admin.service; enabled; preset: enabled)
     Active: active (running) since Wed 2026-10-21 08:19:04 UTC; 2min 25s ago
   Main PID: 3007 (java)
      Tasks: 252 (limit: 4545)
     Memory: 855.4M (peak: 860.2M)
        CPU: 1min 57.797s
     CGroup: /system.slice/ruoyi-admin.service
             └─3007 /usr/lib/jvm/java-17-openjdk-amd64/bin/java -jar ruoyi-admin.jar

[root@ubuntu24-19:~/RuoYi-Vue#] cd
[root@ubuntu24-19:~#] curl -I 10.0.0.19
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 21 Oct 2026 08:21:51 GMT
Content-Type: text/html
Content-Length: 12759
Last-Modified: Wed, 21 Oct 2026 03:47:11 GMT
Connection: keep-alive
ETag: "6ad835bf-31d7"
Accept-Ranges: bytes

3.6、Actuator安全加固

生产环境仅保留健康检查端点用于监控告警,关闭所有敏感信息端点。

bash 复制代码
[root@ubuntu24-19:~#] cd RuoYi-Vue/
[root@ubuntu24-19:~/RuoYi-Vue#] vim ruoyi-admin/src/main/resources/application.yml
[root@ubuntu24-19:~/RuoYi-Vue#] grep -E -C 5 'base-path' ruoyi-admin/src/main/resources/application.yml

# ========= Actuator监控配置(独立端口8091,仅本机访问) =========
management:
  endpoints:
    web:
      base-path: /actuator        # 默认Actuator端点的访问路径前缀
      exposure:
        include: 'health,metrics'               # 暴露所有端点,推荐改为health,info,metrics
  endpoint:
    health:
      show-details: always         # 健康检查显示详情

[root@ubuntu24-19:~/RuoYi-Vue#] mvn clean package -DskipTests
[root@ubuntu24-19:~/RuoYi-Vue#] cp ruoyi-admin/target/ruoyi-admin.jar /data/ruoyi/server/
[root@ubuntu24-19:~/RuoYi-Vue#] systemctl restart ruoyi-admin.service
[root@ubuntu24-19:~/RuoYi-Vue#] mvn clean package ^C
[root@ubuntu24-19:~/RuoYi-Vue#] systemctl status ruoyi-admin.service
● ruoyi-admin.service - RuoYi-Vue Backend Admin Service
     Loaded: loaded (/etc/systemd/system/ruoyi-admin.service; enabled; preset: enabled)
     Active: active (running) since Wed 2026-10-21 08:19:04 UTC; 2min 25s ago
   Main PID: 3007 (java)
      Tasks: 252 (limit: 4545)
     Memory: 855.4M (peak: 860.2M)
        CPU: 1min 57.797s
     CGroup: /system.slice/ruoyi-admin.service
             └─3007 /usr/lib/jvm/java-17-openjdk-amd64/bin/java -jar ruoyi-admin.jar

[root@ubuntu24-19:~/RuoYi-Vue#] cd
[root@ubuntu24-19:~#] curl -I 10.0.0.19
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 21 Oct 2026 08:21:51 GMT
Content-Type: text/html
Content-Length: 12759
Last-Modified: Wed, 21 Oct 2026 03:47:11 GMT
Connection: keep-alive
ETag: "6ad835bf-31d7"
Accept-Ranges: bytes
相关推荐
li星野8 分钟前
【学习记录】k-Wave 时间步长、CFL 稳定性与参数实验全解析
学习
禁默24 分钟前
启元 Q1 二次开发实践:Ubuntu 部署与仿真验证,从 PrimeConsole 到 ROS 2 Humble + RViz
linux·运维·ubuntu
skywalk81631 小时前
把 去也网站 从 Ubuntu 搬到 FreeBSD:一次 Service Jail + nginx 的部署实录
linux·运维·nginx·ubuntu·freebsd
风骏时光牛马2 小时前
生成一个移动端标题,只需要一个标题,不需要其他的任何文本。
前端
IT_陈寒3 小时前
Redis雪崩把我坑惨了,这是5年经验的教训
前端·人工智能·后端
SameX3 小时前
HarmonyOS ArkUI List 的侧滑删除 用 ListItem 的 swipeAction + endIcon 的做法
前端
心祭丫丫3 小时前
【每天一个 Python 小案例17】Python 实现通讯录
开发语言·人工智能·笔记·python·学习
爱莉希雅&&&3 小时前
GitLab 完整学习笔记
linux·运维·服务器
风笙9783 小时前
[文件系统]文件系统挂载与卸载详解
linux