服务器内存耗尽与访问卡顿问题解决及防火墙安全配置全记录
服务器内存耗尽与访问卡顿问题解决及防火墙安全配置全记录
一、背景
某云服务器(CentOS 系统)运行期间突然出现访问卡顿现象,运维人员登录服务器后发现,系统响应迟缓,基础操作(如命令输入、文件查看)存在明显延迟。该服务器承载了业务服务与 SSH 运维入口,持续卡顿可能导致业务中断与运维受阻,需紧急排查并解决问题。同时,为防范后续类似问题(如恶意 IP 大量访问、端口被暴力占用),需配套配置防火墙规则,保障服务器稳定运行。
二、问题发现
运维人员通过top 命令查看系统资源占用情况,发现以下关键异常信息,明确了问题核心:
2.1 内存资源彻底耗尽
top 命令输出显示,服务器物理内存 8GB,已用 7.7GB,仅剩 100MB 左右空闲内存,可用内存(avail Mem)仅 5-8MB,且未配置 Swap 分区。内存耗尽后,系统无法为新进程分配内存,导致业务服务与系统进程争抢资源,引发卡顿。
KiB Mem : 8008372 total, 103392 free, 7750156 used, 154824 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 8440 avail Mem2.2 CPU 系统态占比过高,IO 阻塞严重
CPU 资源中,系统态(sy)占比高达 58%-90%,IO 等待(wa)占比 16%,空闲 CPU(id)仅 3.8%-24.6%。核心原因是内核内存回收进程(kswapd0)因内存耗尽疯狂工作,占用 67%-75% CPU,同时日志服务(systemd-journal、rsyslogd)与监控代理(argusagent)处于 IO 阻塞状态(D 状态),进一步加剧资源争抢。
%Cpu(s): 0.7 us, 89.7 sy, 0.0 ni, 3.8 id, 5.5 wa, 0.0 hi, 0.3 si, 0.0 st2.3 进程数量异常飙升
系统总进程数达 5785 个,远超正常服务器几百个进程的水平。大量睡眠进程持续占用内存,是内存耗尽的核心诱因之一,推测存在业务进程异常 fork 或监控进程故障。
Tasks: 5785 total, 2 running, 5783 sleeping, 0 stopped, 0 zombie2.4 恶意 IP 高频访问风险
排查过程中发现,存在特定 IP(如 117.143.56.54)频繁访问服务器的情况,若不加以限制,可能进一步占用服务器资源,加剧卡顿或引发安全风险。同时,SSH 端口(22 端口)若被大量并发连接占用,会导致运维人员无法正常登录。
三、问题处理
针对上述问题,采取“应急缓解+根源排查”的两步处理策略,先快速恢复服务器正常运行,再追溯问题根源。
3.1 应急缓解:核心排查与连接阻断命令介绍
在应急缓解阶段,需先通过关键命令定位资源占用与恶意连接情况,再执行阻断操作,快速遏制资源恶化趋势。以下是核心命令的功能、用法及作用说明:
3.1.1 top 命令:系统资源全景排查
该命令是排查系统资源占用的核心工具,可实时查看CPU、内存、进程的资源占用状态,帮助快速定位瓶颈。
top关键输出解读:
内存信息(KiB Mem/Swap):查看总内存、空闲内存、已用内存及Swap分区使用情况,判断是否存在内存耗尽;
CPU信息(%Cpu(s)):关注系统态(sy)、IO等待(wa)占比,若sy占比过高可能是内核进程异常,wa占比高则提示IO阻塞;
进程列表:查看高CPU、高内存占用的进程,定位异常进程(如kswapd0、异常业务进程)。
3.1.2 sudo ss -tn state established 命令:活跃连接排查
该命令用于查看服务器当前所有已建立的TCP连接,帮助了解连接分布情况,判断是否存在大量异常连接占用资源。
sudo ss -tn state established参数解读与作用:
-t:仅显示TCP协议连接;
-n:以数字形式显示IP和端口(不解析域名,提升查询速度);
state established:仅筛选已建立的连接(排除监听、关闭等状态的连接)。
通过该命令可快速排查是否存在某IP大量建立连接的情况,为后续精准阻断提供依据。
3.1.3 恶意IP连接阻断命令:精准终止异常连接
该命令是一套组合命令,核心功能是筛选出恶意IP(117.143.56.54)的所有已建立连接,提取对应进程PID并强制终止,彻底断开恶意连接。
sudo ss -tnp state established | grep 117.143.56.54 | awk -F'[,:]' '{for(i=1;i<=NF;i++){if($i~/pid=[0-9]+/){gsub("pid=","",$i);print $i}}}' | sort -u | xargs -r sudo kill -9命令拆解与作用:
sudo ss -tnp state established:获取所有已建立TCP连接的详细信息,包含进程PID(-p参数);
grep 117.143.56.54:筛选出与恶意IP相关的连接;
awk -F'[,:]' '{for(i=1;i<=NF;i++){if($i~/pid=[0-9]+/){gsub("pid=","",$i);print $i}}}':以逗号、冒号为分隔符,提取连接对应的进程PID,并去除“pid=”前缀;
sort -u:对PID去重,避免重复终止同一进程;
xargs -r sudo kill -9:将提取的PID作为参数,强制终止对应进程(-r参数确保无PID时不执行kill命令,避免报错)。
通过 ss 命令筛选恶意 IP(117.143.56.54)的所有连接,提取对应进程 PID 并强制杀死,断开现有连接。
3.2 根源排查:定位进程异常原因
应急缓解后,通过以下命令定位进程异常飙升的根源:
# 查看进程数最多的程序,定位异常进程
ps aux | awk '{print $11}' | sort | uniq -c | sort -nr | head -10经排查,发现是某业务脚本存在逻辑漏洞,导致无限创建子进程,后续对该脚本进行修复,避免问题复发。同时,检查 /var/log 磁盘空间,确认日志服务阻塞是因业务日志量暴增导致,清理旧日志后恢复正常。
3.3 阿里云安全组IP请求限制配置
除了服务器内部通过iptables配置限制外,阿里云安全组作为云端第一道防护屏障,可进一步设置IP请求限制,从网络入口拦截异常流量,减轻服务器处理压力。以下是具体配置步骤与说明:
3.3.1 核心作用
阿里云安全组通过控制入站/出站规则过滤网络流量,针对恶意IP或高频请求,可配置“IP黑名单”“端口访问频率限制”等规则,实现:1)直接阻断恶意IP的网络请求,无需服务器内核处理;2)限制单个IP对特定端口的访问频率/并发数,防范暴力攻击或流量冲击;3)与服务器内部iptables规则形成双层防护,提升安全性。
3.3.2 配置步骤
登录阿里云控制台:进入「云服务器ECS」-「网络与安全」-「安全组」,选择目标服务器所属的安全组,点击「配置规则」。
添加恶意IP拦截规则:在「入站规则」中点击「添加规则」,配置如下:规则方向:入站
授权策略:拒绝
协议类型:全部
端口范围:全部
授权对象:填写需拦截的恶意IP(如117.143.56.54),多个IP用逗号分隔,或填写IP段(如117.143.56.0/24)
优先级:设置为1-100(数值越小优先级越高,建议设为10,确保优先于允许规则生效)
配置IP访问频率限制(可选):若需限制单个IP对特定端口(如22、80)的访问频率,可通过「高级选项」配置:针对22端口(SSH):设置“单IP每秒最大请求数”为5-10,超出则临时阻断(阻断时长可按需设置);
针对80/443端口(业务端口):设置“单IP每分钟最大请求数”为100-200(根据业务量调整),避免单个IP高频访问占用资源。
保存规则:配置完成后点击「确定」,规则立即生效,无需重启服务器。
3.3.3 关键注意事项
规则优先级:拒绝规则优先级需高于允许规则,确保恶意IP拦截生效;
授权对象精准性:填写恶意IP时避免误填正常IP(如运维IP、业务合作方IP),可先通过服务器日志确认IP的恶意行为;
规则联动:安全组规则与服务器内部iptables规则不冲突,建议保持配置一致(如同时阻断117.143.56.54),形成双层防护;
动态调整:定期查看阿里云安全组日志(「安全组」-「日志查询」),分析异常流量,及时更新拦截IP或调整访问频率限制阈值。
四、限制方案:配置防火墙规则,防范后续风险
为避免恶意 IP 大量访问、端口被并发占用等问题,基于 iptables 配置针对性限制规则,实现“精准阻断+并发控制”。
4.1 永久阻断恶意 IP 入站连接
添加 iptables 规则,永久拒绝恶意 IP(117.143.56.54)的所有入站连接,从源头阻断其访问:
# 插入规则到 INPUT 链首,优先生效
sudo iptables -I INPUT -s 117.143.56.54 -j DROP4.2 限制 SSH 端口(22 端口)并发连接数
配置规则限制单个 IP 访问 22 端口的并发连接数不超过 30 个,保障运维通道畅通:
# 加载 connlimit 内核模块(确保规则生效)
modprobe xt_connlimit
# 限制 22 端口单 IP 并发 ≤30,超过则丢弃
sudo iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 30 --connlimit-mask 32 -j DROP4.3 可选:限制业务端口(80/443)并发连接
若服务器运行 Web 服务,可同步限制 80/443 端口的并发连接数,避免业务服务被压垮:
sudo iptables -I INPUT -p tcp -m multiport --dports 80,443 -m connlimit --connlimit-above 10 --connlimit-mask 32 -j DROP4.4 规则验证
执行以下命令确认规则添加成功,确保规则按预期排序(限制规则优先于其他规则):
sudo iptables -L INPUT -n --line-numbers正常输出示例(规则顺序正确):
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 #conn src/32 > 30
2 DROP all -- 117.143.56.54 0.0.0.0/0五、规则持久化:两种开机自启方案详解
默认情况下,iptables 规则仅存在于内存中,服务器重启后会丢失。为实现规则永久生效,提供两种方案:方案一为无需安装 iptables-services 的 rc.local 脚本方案(保留原有核心方案),方案二为标准的 iptables-services 服务方案,以下分别详细说明。
方案一:无需 iptables-services(原有核心方案)
该方案通过系统原生的 rc.local 脚本实现规则开机自动加载,无需安装任何额外软件包,适配所有 CentOS 系统,操作简单且无依赖风险。
5.1.1 核心原理
/etc/rc.d/rc.local 是系统开机最后执行的脚本文件,在该文件中添加 iptables-restore 命令,可实现开机时自动读取已保存的规则文件并加载到内核中,模拟 iptables-services 的核心功能。
5.1.2 操作步骤
步骤 1:保存现有规则到文件
将当前配置的所有 iptables 规则(含恶意IP阻断、端口并发限制)保存到 /etc/sysconfig/iptables 文件:
# 保存规则到配置文件
sudo iptables-save > /etc/sysconfig/iptables步骤 2:配置 rc.local 实现开机加载
编写一键配置脚本,确保 rc.local 有执行权限,并添加规则加载命令(避免重复添加):
#!/bin/bash
# 确保 rc.local 可执行(CentOS 7+ 默认可能无权限)
chmod +x /etc/rc.d/rc.local
# 备份原有 rc.local,避免误操作覆盖
cp /etc/rc.d/rc.local /etc/rc.d/rc.local.bak.$(date +%Y%m%d)
# 仅添加一次加载命令,防止重复执行
grep -q "iptables-restore < /etc/sysconfig/iptables" /etc/rc.d/rc.local || {
echo -e "\n# 开机自动加载 iptables 规则(无需 iptables-services)" >> /etc/rc.d/rc.local
echo "iptables-restore < /etc/sysconfig/iptables" >> /etc/rc.d/rc.local
}步骤 3:脚本执行与验证
# 赋予脚本执行权限
chmod +x iptables_auto_load.sh
# 执行脚本
sudo ./iptables_auto_load.sh
# 验证配置结果(查看 rc.local 中是否添加成功)
cat /etc/rc.d/rc.local | grep iptables-restore正常输出如下即配置成功:
# 开机自动加载 iptables 规则(无需 iptables-services)
iptables-restore < /etc/sysconfig/iptables5.1.3 核心优势
无依赖:无需安装任何额外软件包,使用系统原生工具即可实现;
操作简单:脚本包含备份和重复添加防护,可安全执行;
兼容性强:适配所有 CentOS 版本及其他 Linux 发行版。
方案二:iptables-services 服务方案(标准方案)
iptables-services 是官方提供的 iptables 规则管理服务,通过系统 systemctl 命令管理规则的保存、加载和开机自启,符合 Linux 服务管理规范,适用于追求标准化运维的场景。
5.2.1 核心原理
安装 iptables-services 后,系统会生成 iptables.service 服务单元,该服务默认读取 /etc/sysconfig/iptables 作为规则配置文件。通过 systemctl enable iptables 启用开机自启后,服务器重启时会自动启动该服务并加载规则。
5.2.2 操作步骤
步骤 1:关闭 firewalld 防火墙(关键前提)
firewalld 是 CentOS 7+ 默认防火墙,与 iptables 存在规则控制权冲突,需先关闭并禁用:
# 停止 firewalld 服务
sudo systemctl stop firewalld
# 禁止 firewalld 开机自启
sudo systemctl disable firewalld步骤 2:安装 iptables-services 包
# CentOS/RHEL 系统安装命令
sudo yum install iptables-services -y步骤 3:保存现有规则
使用 iptables-services 自带的保存命令,将当前规则写入 /etc/sysconfig/iptables:
sudo service iptables save步骤 4:启用并启动 iptables 服务
# 启用开机自启
sudo systemctl enable iptables
# 启动 iptables 服务(加载规则)
sudo systemctl start iptables
# 验证服务状态(输出 active (running) 即正常)
sudo systemctl status iptables步骤 5:验证规则持久化效果
# 重启服务器
sudo reboot
# 重启后验证规则是否加载
sudo iptables -L INPUT -n --line-numbers | grep -E "22|connlimit|117.143.56.54"能看到之前配置的 22 端口限制、恶意IP阻断规则,说明持久化生效。
5.2.3 风险点说明
- 与 firewalld 冲突风险:若未关闭 firewalld,启动 iptables 服务后,两种防火墙会争抢内核规则控制权,可能导致规则被覆盖、服务启动失败或网络异常;
- 依赖软件包风险:
iptables-services需通过 yum 安装,若服务器无法访问 yum 源(如内网隔离环境),则无法使用该方案;
- 依赖软件包风险:
- 命令兼容性风险:CentOS 7+ 中
service iptables save命令已被部分废弃,可能出现 “The service command supports only basic LSB actions” 报错,需改用iptables-save > /etc/sysconfig/iptables手动保存;
- 命令兼容性风险:CentOS 7+ 中
- 配置文件覆盖风险:
service iptables save会直接覆盖/etc/sysconfig/iptables原有内容,若之前手动修改过该文件,未备份可能导致配置丢失。
- 配置文件覆盖风险:
两种方案对比与选择建议
| 对比维度 | 方案一:rc.local 脚本 | 方案二:iptables-services |
|---|---|---|
| 依赖情况 | 无任何依赖 | 需安装 iptables-services 包 |
| 操作复杂度 | 低(脚本一键执行) | 中(需关闭 firewalld、安装服务) |
| 风险等级 | 低(仅修改 rc.local 脚本) | 中(存在服务冲突、配置覆盖风险) |
| 运维规范度 | 一般(非标准服务管理) | 高(符合 systemctl 服务管理规范) |
| 适用场景 | 内网隔离、无 yum 源、追求简单稳定的场景 | 标准化运维、有 yum 源、需通过服务管理规则的场景 |
| 选择建议:若服务器环境简单、无 yum 源或追求低风险,优先选择方案一;若需遵循标准化运维规范、便于通过服务批量管理多台服务器,可选择方案二(需严格规避上述风险点)。 |
重启服务器后,通过 sudo iptables -L INPUT -n --line-numbers | grep 22 确认规则已自动加载,实现永久生效。
六、总结与核心命令汇总
本次服务器卡顿问题的核心是“进程异常飙升导致内存耗尽”,叠加“无 Swap 分区加剧资源紧张”“恶意 IP 访问雪上加霜”。通过“应急资源释放+根源进程修复”快速恢复系统,再通过 iptables 配置“IP 阻断+端口并发限制”防范后续风险,最终通过规则持久化方案实现长期稳定,形成完整的问题解决闭环。
后续建议:1)定期检查业务进程运行状态,避免异常 fork;2)为服务器配置永久 Swap 分区,提升系统容错性;3)定期查看防火墙规则与系统日志,及时发现潜在安全风险。
6.1 核心命令汇总及注释
以下按“应急排查、恶意连接阻断、防火墙配置、规则持久化”场景分类,整理全文关键操作命令及详细注释,便于后续运维参考:
6.1.1 应急排查命令
# 1. 查看系统资源占用(CPU、内存、进程),定位瓶颈
top
# 注释:实时显示系统资源状态,重点关注 Mem/Swap 内存占用、%Cpu(s) 系统态/IO等待占比、高资源进程列表
# 2. 查看当前所有已建立的TCP连接,排查异常连接分布
sudo ss -tn state established
# 注释:-t仅显示TCP连接,-n以数字形式显示IP/端口(提速),筛选已建立连接,避免无关连接干扰
# 3. 查看进程数最多的程序,定位异常进程根源
ps aux | awk '{print $11}' | sort | uniq -c | sort -nr | head -10
# 注释:提取所有进程的程序名,去重统计数量,按数量降序排列,取前10个,快速定位异常fork的进程6.1.2 恶意连接阻断命令
# 精准终止恶意IP(117.143.56.54)的所有已建立连接对应的进程
sudo ss -tnp state established | grep 117.143.56.54 | awk -F'[,:]' '{for(i=1;i<=NF;i++){if($i~/pid=[0-9]+/){gsub("pid=","",$i);print $i}}}' | sort -u | xargs -r sudo kill -9
# 注释:
# 1. ss -tnp state established:获取已建立TCP连接详情,含进程PID(-p参数)
# 2. grep 117.143.56.54:筛选恶意IP相关连接
# 3. awk命令:以逗号/冒号为分隔符,提取连接对应的进程PID,去除"pid="前缀
# 4. sort -u:PID去重,避免重复终止同一进程
# 5. xargs -r sudo kill -9:将PID作为参数强制终止进程,-r确保无PID时不执行(避免报错)6.1.3 防火墙规则配置命令
# 1. 永久阻断恶意IP(117.143.56.54)所有入站连接(插入链首,优先生效)
sudo iptables -I INPUT -s 117.143.56.54 -j DROP
# 注释:-I INPUT插入规则到链首,-s指定恶意IP,-j DROP直接丢弃该IP所有请求
# 2. 加载connlimit内核模块(确保端口并发限制规则生效)
modprobe xt_connlimit
# 注释:iptables的connlimit模块默认可能未加载,需手动加载才能使用连接数限制功能
# 3. 限制22端口(SSH)单IP最大30个并发连接,超过则丢弃
sudo iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 30 --connlimit-mask 32 -j DROP
# 注释:
# -p tcp --dport 22:仅针对SSH的TCP连接
# -m connlimit:启用连接数限制模块
# --connlimit-above 30:并发连接数超过30个触发规则
# --connlimit-mask 32:按单个IPv4地址限制(而非IP段)
# -j DROP:超过限制的连接直接丢弃
# 4. (可选)限制80/443端口单IP最大10个并发连接
sudo iptables -I INPUT -p tcp -m multiport --dports 80,443 -m connlimit --connlimit-above 10 --connlimit-mask 32 -j DROP
# 注释:-m multiport --dports 80,443:同时针对多个业务端口
# 5. 验证iptables规则是否添加成功(显示规则行号、详情)
sudo iptables -L INPUT -n --line-numbers
# 注释:-L INPUT查看INPUT链规则,-n数字显示IP/端口,--line-numbers显示规则行号,便于后续修改/删除6.1.4 规则持久化命令(两种方案)
# 方案一:无需iptables-services(rc.local脚本方案)
# 1. 保存当前iptables规则到配置文件
sudo iptables-save > /etc/sysconfig/iptables
# 2. 赋予rc.local执行权限(CentOS 7+默认无权限)
chmod +x /etc/rc.d/rc.local
# 3. 备份原有rc.local(带日期后缀,便于回滚)
cp /etc/rc.d/rc.local /etc/rc.d/rc.local.bak.$(date +%Y%m%d)
# 4. 向rc.local添加开机加载规则命令(仅添加一次)
grep -q "iptables-restore < /etc/sysconfig/iptables" /etc/rc.d/rc.local || {
echo -e "\n# 开机自动加载iptables规则(无需iptables-services)" >> /etc/rc.d/rc.local
echo "iptables-restore < /etc/sysconfig/iptables" >> /etc/rc.d/rc.local
}
# 5. 验证rc.local配置结果
cat /etc/rc.d/rc.local | grep iptables-restore
# 方案二:iptables-services服务方案
# 1. 关闭并禁用firewalld(避免与iptables冲突)
sudo systemctl stop firewalld
sudo systemctl disable firewalld
# 2. 安装iptables-services包
sudo yum install iptables-services -y
# 3. 保存当前iptables规则到配置文件
sudo service iptables save
# 4. 启用并启动iptables服务(设置开机自启)
sudo systemctl enable iptables
sudo systemctl start iptables
# 5. 验证服务状态(确认正常运行)
sudo systemctl status iptables
# 6. 重启后验证规则是否加载
sudo reboot
sudo iptables -L INPUT -n --line-numbers | grep -E "22|connlimit|117.143.56.54"(注:文档部分内容可能由 AI 生成)
