Linux添加Swap交换分区,解决内存不足问题
前言
服务器内存不够用了?MySQL 启动就报内存不足?或者运行着运行着就被 OOM Killer 杀进程了?这时候除了加内存条,还有个应急办法——加 Swap 交换分区。Swap 就是把磁盘的一部分当内存用,虽然慢,但能救急。本文就讲一下怎么在 Linux 下添加 Swap 交换分区。
什么是 Swap
Swap 交换分区,就是把磁盘的一部分空间当作内存来用。当物理内存不够的时候,系统会把不常用的内存数据换到磁盘上,腾出物理内存给正在用的进程。
注意: Swap 只是应急方案,不能当内存用。磁盘比内存慢几百倍,如果频繁使用 Swap,系统会非常卡。
第一步:查看当前 Swap 情况
先看看现在有没有 Swap,多大:
free -h
输出示例:
total used free shared buff/cache available
Mem: 1.8Gi 1.2Gi 200Mi 50Mi 400Mi 300Mi
Swap: 0B 0B 0B
上面的例子里 Swap 是 0B,说明没有配置 Swap。
也可以看:
swapon -s
第二步:创建 Swap 文件
我们用文件的方式创建 Swap,比分区方式灵活,随时可以删。
1. 创建一个 2G 的 Swap 文件
dd if=/dev/zero of=/swapfile bs=1M count=2048
参数说明:
if=/dev/zero:输入源,零设备of=/swapfile:输出文件bs=1M:块大小1Mcount=2048:2048块,也就是2G
2. 设置文件权限
chmod 600 /swapfile
必须设置成 600,不然系统不认。
3. 格式化成 Swap
mkswap /swapfile
输出会显示:
Setting up swapspace version 1, size = 2097151 KiB
no label, UUID=xxxx-xxxx
第三步:启用 Swap
swapon /swapfile
查看是否启用成功:
free -h
现在应该能看到 Swap 那行有数值了。
第四步:配置开机自动挂载
写入 /etc/fstab,重启后自动启用。
vi /etc/fstab
在最后一行添加:
/swapfile swap swap defaults 0 0
第五步:调整 Swap 使用优先级
Linux 默认是尽量用物理内存,Swap 只用在内存不够的时候。这个策略一般不用改。
如果想调整 Swap 的使用倾向,可以改 /etc/sysctl.conf:
vm.swappiness = 10
swappiness 值范围是 0~100:
0:尽量不用 Swap100:积极使用 Swap10:推荐值,内存不够才用 Swap
改完执行:
sysctl -p
常见操作
查看 Swap 使用情况
swapon -s
关闭 Swap
swapoff /swapfile
删除 Swap
swapoff /swapfile
rm /swapfile
然后把 /etc/fstab 里那行也删掉。
实际应用场景
场景1:MySQL 启动报内存不足
MySQL 启动的时候需要加载很多数据到内存,如果内存不够会直接启动失败。加个 Swap 就能启动了。
场景2:临时跑大任务
有时候要临时跑个大任务,内存不够,加个 Swap 救急。
场景3:防止 OOM Killer 杀进程
内存不够的时候,系统会用 OOM Killer 杀掉占内存最多的进程。加个 Swap 能缓冲一下,避免直接被杀。
常见坑
坑1:Swap 文件权限不对
创建完 Swap 文件之后忘了 chmod 600,结果 swapon 报错。
解决: 一定要先设置权限:
chmod 600 /swapfile
坑2:/etc/fstab 写错了
和挂载硬盘一样,/etc/fstab 写错了重启会进不去系统。
解决: 改完先执行 swapon -a 测试一下。
坑3:Swap 太大了影响性能
Swap 不是越大越好。如果 Swap 用得很频繁,系统会非常卡,因为磁盘比内存慢几百倍。
建议: Swap 大小设成物理内存的 0.5~2 倍就够了。比如 2G 内存,Swap 设 2~4G 就行。
坑4:SSD 上放 Swap 还好,机械硬盘上放 Swap 很卡
如果是机械硬盘,频繁读写 Swap 会非常卡。SSD 还好一点。
总结
添加 Swap 的完整流程:
- dd 创建 Swap 文件
- chmod 600 设置权限
- mkswap 格式化
- swapon 启用
- 写 /etc/fstab 开机自动挂载
- 调整 swappiness 优先级
Swap 只是应急方案,真正解决内存不足还是要加物理内存。但应急的时候,Swap 确实能救一命。
遇到问题加QQ23979811 协助处理
Linux查看磁盘I/O性能,iostat命令详解
前言
服务器变慢了,CPU不高、内存也够,但就是卡。这时候就要看看是不是磁盘I/O瓶颈了。很多时候系统慢不是CPU不够,而是磁盘读写太慢,CPU一直在等磁盘。iostat 就是专门用来查看磁盘I/O性能的工具,配合 vmstat 一起用,能快速定位I/O问题。本文就详细讲一下 iostat 命令的使用。
安装 iostat
CentOS7 默认可能没装 iostat,先装一下:
yum install sysstat -y
iostat 属于 sysstat 包,装完就有了。
基本用法
直接输入:
iostat
输出示例:
Linux 3.10.0-1160.el7.x86_64 (localhost) 10/05/2026 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
5.00 0.00 2.00 1.00 0.00 92.00
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 10.00 50.00 100.00 500000 1000000
输出详解
CPU 部分
avg-cpu: %user %nice %system %iowait %steal %idle
5.00 0.00 2.00 1.00 0.00 92.00
| 列 | 含义 |
|---|---|
%user |
用户态CPU占用 |
%nice |
改变过优先级的进程占用 |
%system |
内核态CPU占用 |
%iowait |
等待磁盘I/O的CPU占比(重点看这个) |
%steal |
被虚拟机偷走的CPU |
%idle |
空闲CPU |
重点看 %iowait: 如果这个值很高(比如超过20%),说明磁盘I/O是瓶颈,CPU大部分时间在等磁盘读写。
磁盘部分
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 10.00 50.00 100.00 500000 1000000
| 列 | 含义 |
|---|---|
Device |
设备名 |
tps |
每秒传输次数(IOPS) |
kB_read/s |
每秒读取的数据量 |
kB_wrtn/s |
每秒写入的数据量 |
kB_read |
总共读取的数据量 |
kB_wrtn |
总共写入的数据量 |
实时监控
每2秒刷新一次
iostat 2
按 Ctrl+C 退出。
每2秒刷新一次,总共刷新5次
iostat 2 5
只看磁盘部分,不看CPU
iostat -d 2
更详细的磁盘统计
显示扩展统计信息
iostat -x
输出会多出很多列,这才是真正分析磁盘性能的关键:
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 5.00 1.00 9.00 50.00 100.00 30.00 0.10 5.00 2.00 6.00 1.00 1.00
重点列说明:
| 列 | 含义 | 判断标准 |
|---|---|---|
await |
平均I/O等待时间(毫秒) | 超过20ms就要注意,超过100ms说明磁盘很慢 |
svctm |
平均I/O服务时间(毫秒) | 越小越好 |
%util |
磁盘利用率 | 接近100%说明磁盘跑满了 |
avgqu-sz |
平均I/O队列长度 | 越大说明排队越严重 |
最重要的两个指标:
%util:如果接近100%,说明磁盘已经跑满了await:如果很大,说明每次I/O等待时间很长,磁盘很慢
常用参数组合
实时监控磁盘性能
iostat -x 2
每2秒刷新一次,显示扩展信息。
只看某个磁盘
iostat -x sda 2
以MB为单位显示
iostat -m
显示设备映射关系
iostat -N
实际排查案例
案例1:系统变慢,怀疑磁盘I/O
vmstat 1
看 wa 列,如果很高(超过20%),说明磁盘I/O是瓶颈。
然后用 iostat 详细看:
iostat -x 2
看 %util 是不是接近100%,await 是不是很大。
案例2:哪个磁盘跑得最忙
iostat -x 2
看 %util 列,哪个磁盘的 %util 最高,就是哪个磁盘是瓶颈。
案例3:读写比例
iostat -x 2
看 r/s 和 w/s,是读多还是写多,针对性优化。
常见坑
坑1:%util 100% 就以为磁盘坏了
%util 100% 说明磁盘在处理I/O请求,但不一定是磁盘性能不行。可能是I/O请求量太大,也可能是磁盘确实慢。要结合 await 一起看。
坑2:只看 tps 不看 await
tps 高不一定是问题,要看每次I/O的等待时间 await。如果 await 很小,说明磁盘处理得很快,tps高也没关系。
坑3:把 iowait 当成CPU问题
%iowait 高说明CPU在等磁盘,不是CPU不够用。这时候加CPU没用,要优化磁盘I/O。
总结
查看磁盘I/O性能的核心命令:
- iostat:快速看磁盘整体读写情况
- iostat -x 2:实时监控,重点看
%util和await - vmstat 1:看
wa列,确认是不是I/O瓶颈
记住两个关键指标:
%util接近100%:磁盘跑满了await超过20ms:磁盘响应慢了
遇到问题加QQ23979811 协助处理
Linux crontab定时任务不执行常见原因与排查
前言
配置好了 crontab 定时任务,时间也写对了,但到点就是不执行?这是很多新手都会遇到的坑。crontab 不执行的原因五花八门,从最基础的语法错误到环境变量问题,再到 SELinux 拦截,排查起来很费时间。本文把常见的 crontab 不执行原因都整理出来,按排查顺序一步步来,基本能解决 90% 的问题。
第一步:确认 crond 服务是否运行
最基础也是最容易忽略的——定时任务服务本身有没有启动。
systemctl status crond
如果显示 inactive (dead),说明服务没启动,先启动它:
systemctl start crond
systemctl enable crond
CentOS7 上定时服务叫 crond,Debian/Ubuntu 上叫 cron,别搞混了。
第二步:检查 crontab 语法是否正确
1. 查看当前用户的定时任务
crontab -l
2. crontab 时间格式
* * * * * 命令
- - - - -
| | | | |
| | | | ----- 星期几 (0 - 7) (0和7都是周日)
| | | ------- 月份 (1 - 12)
| | --------- 日期 (1 - 31)
| ----------- 小时 (0 - 23)
------------- 分钟 (0 - 59)
3. 常见语法错误
错误1:分钟写在最前面
# 错误:每天9点执行(错的)
0 9 * * * /root/backup.sh
# 正确:每天9点执行
0 9 * * * /root/backup.sh
等等,这个其实是对的。真正容易错的是:
错误2:命令路径用了相对路径
# 错误:crontab 里找不到 mysql 命令
0 9 * * * mysql -u root -p123456 dbname < /root/backup.sql
# 正确:用绝对路径
0 9 * * * /usr/bin/mysql -u root -p123456 dbname < /root/backup.sql
crontab 的环境变量和你手动登录时不一样! 它的 PATH 很精简,很多命令找不到。所以要么用绝对路径,要么在脚本里先 source 环境变量。
第三步:检查脚本本身有没有执行权限
很多人写了脚本,但忘了加执行权限:
ls -l /root/backup.sh
如果没有 x 权限,加上:
chmod +x /root/backup.sh
第四步:检查脚本内容有没有问题
1. 脚本里用了相对路径
# 错误:相对路径在 crontab 里会出问题
cd /var/www/html
tar -zcf backup.tar.gz .
# 正确:用绝对路径
cd /var/www/html
tar -zcf /root/backup.tar.gz .
2. 脚本里用了交互式命令
比如 read、ssh 需要交互输入的命令,在 crontab 里是跑不了的,因为没有终端。
3. 脚本开头没写 shebang
# 正确的 shebang
#!/bin/bash
如果脚本没有 shebang,或者 shebang 写错了,执行就会失败。
第五步:检查日志
crontab 的执行日志默认在 /var/log/cron 里:
tail -100 /var/log/cron
如果日志里显示任务被执行了,但结果不对,那就是脚本本身的问题。
如果日志里压根没有这个任务的记录,那就是 crontab 服务本身的问题或者任务格式不对。
第六步:检查环境变量问题
这是最隐蔽的坑。你手动跑脚本没问题,但 crontab 里就是不行,十有八九是环境变量的问题。
排查方法:在脚本开头加上环境变量
#!/bin/bash
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
或者直接在 crontab 里指定:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
0 9 * * * /root/backup.sh
第七步:检查 SELinux 是不是拦截了
如果 SELinux 开着,可能会拦截 crontab 的操作。查看日志:
tail -100 /var/log/audit/audit.log | grep crontab
如果看到 denied 字样,就是 SELinux 拦截了。
第八步:检查邮箱通知
crontab 默认会把执行结果(包括错误信息)发到执行用户的邮箱里:
mail
或者看 /var/spool/mail/root 文件:
tail -100 /var/spool/mail/root
这里面通常会有具体的错误信息,是排查的好帮手。
常见坑
坑1:环境变量缺失
这是最常见的坑。你手动跑脚本能成,crontab 里就不行,因为 crontab 的环境变量和你登录 shell 的不一样。
解决: 在脚本开头加上 export PATH=...,或者所有命令都用绝对路径。
坑2:脚本没有执行权限
写完脚本忘了 chmod +x,crontab 当然跑不了。
坑3:重定向丢了
crontab 默认会把输出发到邮箱,如果你不想收邮件,可以重定向:
0 9 * * * /root/backup.sh > /dev/null 2>&1
> /dev/null 是丢弃标准输出,2>&1 是把错误输出也重定向到标准输出。
坑4:时间格式写错了
比如把 * * * * * 写成了 * * * *,少了一个字段,直接就不执行。
坑5:用户写错了
你用 root 用户写的 crontab,但实际是别的用户需要跑,当然不执行。用 crontab -u 用户名 -l 查看对应用户的任务。
总结
crontab 不执行的排查顺序:
- 先确认 crond 服务启动了没
- 检查 crontab 语法格式对不对
- 脚本有没有执行权限
- 脚本里的命令是不是都用了绝对路径
- 看
/var/log/cron日志有没有执行记录 - 看
/var/spool/mail/root有没有错误信息 - 检查 SELinux 是不是拦截了
按这个顺序排查,基本都能找到原因。记住 crontab 的环境变量和你手动登录时不一样,所有命令都用绝对路径,能避免 80% 的问题。
遇到问题加QQ23979811 协助处理
Linux磁盘占用100%怎么排查,大文件查找清理方法
前言
服务器跑着跑着突然网站打不开了,SSH 也反应变慢,一查磁盘使用率 100%。这是运维中非常常见的问题。磁盘满了不仅影响服务正常运行,还可能导致数据丢失、日志写不进去等严重后果。本文就手把手教你怎么快速定位磁盘占用大的文件,以及怎么安全清理。
第一步:查看整体磁盘使用情况
先用 df 命令看看哪个分区满了:
df -h
参数说明:
-h:以人类可读的方式显示(G、M)
输出示例:
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 38G 2.0G 95% /
devtmpfs 7.8G 0 7.8G 0% /dev
tmpfs 7.8G 0 7.8G 0% /dev/shm
tmpfs 7.8G 480M 7.8G 6% /run
tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup
看 Use% 那一列,如果哪个分区到了 100% 或者 90% 以上,那就是问题所在。比如上面 /dev/vda1 用了 95%,根分区快满了。
第二步:定位哪个目录占用最大
知道哪个分区满了,接下来找是哪个目录占了最多空间。用 du 命令:
1. 查看根目录下各目录的大小
du -sh /* 2>/dev/null
参数说明:
-s:只显示总计,不显示每个子目录-h:人类可读格式2>/dev/null:忽略权限不足的报错信息
输出示例:
0 /bin
100M /boot
...
15G /home
20G /var
3G /usr
从输出可以看出 /var 目录占了 20G,是大头。
2. 继续往下查 /var 目录
du -sh /var/* 2>/dev/null | sort -rh | head -10
参数说明:
sort -rh:按大小倒序排列head -10:只显示前10个最大的
输出示例:
15G /var/log
3G /var/lib
1G /var/cache
...
继续往下查,直到找到具体是哪个文件最大。
第三步:查找最大的单个文件
如果目录太大不好定位,直接找整个系统里最大的文件:
1. 查找大于100M的文件
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | awk '{print $5, $9}'
参数说明:
-type f:只找文件,不找目录-size +100M:找大于100M的文件2>/dev/null:忽略权限报错
2. 按大小排序显示前20个最大文件
find / -type f -size +10M -exec ls -lh {} \; 2>/dev/null | sort -k5 -rh | head -20
这样就能列出系统里最大的20个文件,一目了然。
常见的磁盘占用大户
根据经验,Linux 磁盘占用大通常是这几个地方:
1. 日志文件(/var/log)
这是最常见的。服务跑久了日志文件会越来越大,尤其是:
- Nginx 访问日志、错误日志
- MySQL 慢查询日志、错误日志
- 系统日志 messages、syslog
排查方法:
du -sh /var/log/* | sort -rh | head -10
2. 已删除但仍被进程占用的文件
有时候你删掉了大文件,但磁盘空间没释放,因为还有进程在占用这个文件的句柄。
排查方法:
lsof | grep deleted
如果看到很多 deleted 状态的文件,说明有进程占用着已删除的文件。重启对应的进程就能释放空间。
3. 缓存文件(/var/cache)
yum 下载的缓存包、APT 的缓存都在这里,时间久了会积累很多。
清理方法:
yum clean all
4. Docker 镜像和容器
如果用了 Docker,镜像、容器、日志都会占很多空间。
排查方法:
docker system df
清理方法:
docker system prune -a
安全清理方法
找到大文件后,不要直接 rm -rf 删了就完事,要注意安全:
1. 日志文件:清空而不是删除
如果是日志文件,不要删文件本身,而是清空内容:
> /var/log/nginx/access.log
或者:
echo "" > /var/log/nginx/access.log
这样文件还在,但内容清空了,不会影响正在写入的进程。
2. 大文件:先确认再删除
删之前一定要确认这个文件是不是真的不需要了:
ls -lh /path/to/file
head -20 /path/to/file # 看看内容是什么
确认没问题再删:
rm -f /path/to/file
3. 已删除但被占用的文件
如果删掉文件后空间没释放,找到占用的进程并重启:
lsof | grep deleted
# 找到对应的 PID,重启服务
systemctl restart nginx
常见坑
坑1:用 du 查到的大小和 df 不一致
有时候 df 显示磁盘满了,但 du -sh /* 加起来远没到那个数。这通常是因为:
- 有已删除但仍被进程占用的文件
- 挂载点下还有其他挂载
解决: 用 lsof | grep deleted 找被占用的已删除文件,重启对应进程释放空间。
坑2:删了文件空间没释放
这就是上面说的坑——文件被进程占用着,虽然删了但空间没释放。必须重启进程才能释放。
坑3:直接删日志文件导致服务异常
很多人直接 rm -f /var/log/nginx/access.log,结果 Nginx 还在往这个已经不存在的文件里写,日志就丢了。正确做法是清空内容而不是删除文件:> /var/log/nginx/access.log。
总结
排查磁盘占用的标准流程:
df -h看哪个分区满了du -sh /* | sort -rh找最大的目录find / -type f -size +100M找最大的文件- 确认文件用途后再清理
- 日志文件清空内容,不要直接删文件
日常运维建议配置 logrotate 自动切割日志,避免日志越积越大。
遇到问题加QQ23979811 协助处理
Linux查看服务器开放端口,netstat和ss命令使用教程
前言
部署完网站后,经常需要确认某个端口是否真的开放了,或者排查服务有没有正常监听。Linux 下最常用的两个工具就是 netstat 和 ss。netstat 是老经典,几乎所有系统都自带;ss 是 iproute2 套件里的新工具,性能更好、信息更全。本文把这两个命令的常用用法都整理出来,新手照着抄就行。
netstat 命令用法
1. 查看所有监听端口
netstat -tlnp
参数说明:
-t:只显示 TCP 连接-l:只显示监听状态的端口-n:以数字形式显示端口号,不做域名解析-p:显示占用端口的进程名和 PID
输出示例:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1234/sshd
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 5678/nginx
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 5678/nginx
2. 查看 UDP 端口
netstat -ulnp
把 -t 换成 -u 就是查看 UDP 端口。
3. 查看所有端口(TCP+UDP)
netstat -tulnp
4. 查看指定端口是否被占用
netstat -tlnp | grep 80
如果 80 端口被占用,会输出对应的进程信息。
5. 查看所有网络连接(不只是监听)
netstat -an
-a 表示显示所有连接,不只是监听状态的。
ss 命令用法
ss 是 netstat 的替代品,在服务器上性能更好,尤其是连接数很多的时候。
1. 查看所有监听端口
ss -tlnp
参数和 netstat 基本一样:
-t:TCP-l:监听状态-n:数字形式-p:显示进程
2. 查看 UDP 端口
ss -ulnp
3. 查看所有端口(TCP+UDP)
ss -tulnp
4. 查看指定端口
ss -tlnp | grep 443
5. 查看所有已建立的连接
ss -tn state established
可以用来统计当前服务器有多少个活跃连接。
6. 查看某个IP的连接
ss -tn dst 192.168.1.100
查看和 192.168.1.100 之间的所有连接。
两个命令的区别
| 对比项 | netstat | ss |
|---|---|---|
| 性能 | 连接数多的时候很慢 | 非常快 |
| 来源 | net-tools 包 | iproute2 包 |
| 兼容性 | 几乎所有 Linux 都有 | 新系统默认自带 |
| 功能 | 基础网络查询 | 更丰富的过滤功能 |
建议: 日常排查用 ss 更高效,老系统上找不到 ss 再用 netstat。
常见坑
坑1:看不到进程信息
执行 netstat -tlnp 或 ss -tlnp 时,如果看不到 PID/Program name 那一列,说明你不是 root 用户。加上 sudo 再执行:
sudo netstat -tlnp
sudo ss -tlnp
坑2:端口显示是 :: 而不是 0.0.0.0
0.0.0.0:80 表示监听所有 IPv4 地址的 80 端口;:::80 表示监听所有 IPv6 地址的 80 端口(同时也兼容 IPv4)。这两种都能从外网访问,不用担心。
坑3:查不到端口但服务明明启动了
检查一下服务是不是只监听了 127.0.0.1。如果 Local Address 显示的是 127.0.0.1:80,那外网是访问不了的,只能本机访问。需要修改服务配置监听 0.0.0.0。
总结
查看 Linux 开放端口记住这几个核心命令就够了:
- 常用查看:
ss -tlnp或netstat -tlnp - 查指定端口:
ss -tlnp | grep 端口号 - 查UDP端口:
ss -ulnp
日常排查优先用 ss,速度快信息全;老系统没 ss 再用 netstat。
遇到问题加QQ23979811 协助处理
Linux 服务器安全加固:10个必须做的基础配置
前言
刚装完的 Linux 服务器就像没锁门的房子,任何人都能进来。本文整理了 10 个最基础但最重要的安全加固配置,帮你把门锁上。
1. 修改 SSH 端口,禁止 root 登录
默认 22 端口是黑客扫描的首选目标,改个端口能挡掉 90% 的自动扫描。
# 编辑 sshd 配置
vi /etc/ssh/sshd_config
# 修改端口
Port 22222
# 禁止 root 登录
PermitRootLogin no
# 重启 sshd
systemctl restart sshd
注意:改完端口后,记得在防火墙和安全组里放行新端口,否则你自己也进不去了。
2. 使用 SSH 密钥登录,禁用密码登录
密码再复杂也扛不住暴力破解,密钥登录才是正道。
# 本地生成密钥对(在你自己的电脑上执行)
ssh-keygen -t ed25519 -C "your_email@example.com"
# 把公钥传到服务器
ssh-copy-id -p 22222 user@your_server_ip
# 服务器上禁用密码登录
vi /etc/ssh/sshd_config
PasswordAuthentication no
3. 配置防火墙,只开必要端口
# 只开 SSH、HTTP、HTTPS
ufw default deny incoming
ufw default allow outgoing
ufw allow 22222/tcp # SSH
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw enable
4. 自动安全更新
# Ubuntu/Debian
apt install unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades
# CentOS/RHEL
dnf install dnf-automatic
systemctl enable --now dnf-automatic.timer
5. 创建普通用户,配置 sudo
永远不要用 root 跑日常操作,创建一个普通用户,需要时用 sudo 提权。
# 创建用户
adduser deploy
# 加入 sudo 组
usermod -aG sudo deploy
6. 禁用不必要的服务
# 查看正在运行的服务
systemctl list-unit-files --type=service --state=enabled
# 禁用不需要的服务
systemctl disable --now avahi-daemon
systemctl disable --now cups
7. 配置 fail2ban 防暴力破解
apt install fail2ban
# 配置 sshd 防护
vi /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 22222
maxretry = 3
bantime = 3600
systemctl restart fail2ban
8. 设置密码策略
# 编辑 pwquality 配置
vi /etc/security/pwquality.conf
minlen = 12 # 最小长度
dcredit = -1 # 至少1个数字
ucredit = -1 # 至少1个大写字母
lcredit = -1 # 至少1个小写字母
ocredit = -1 # 至少1个特殊字符
9. 监控日志,定期检查
# 查看登录失败记录
grep "Failed password" /var/log/auth.log
# 查看当前登录用户
w
# 查看最近登录记录
last -n 20
10. 定期备份,备份再备份
安全加固做得再好,也不如有一份能快速恢复的备份。
# 简单的文件备份脚本
tar -czf backup_$(date +%Y%m%d).tar.gz /var/www/
把备份文件同步到异地存储,别只放在同一台服务器上。
总结
这 10 条配置不需要高深的技术,但每一条都能实实在在地降低服务器被攻破的风险。建议新服务器装好后,第一件事就是把这 10 条全部过一遍。
安全不是一次性的工作,而是一个持续的过程。定期更新系统、监控日志、检查异常,才能真正把服务器守好。