单机游戏下载单机游戏下载基地
最新游戏|热门游戏|游戏大全|游戏专题

韩国VPS安全怎么加固

2026/11/5 20:22:09 来源:本站整理 编辑:飞翔小编

您的位置:首页 → 资讯教程 → 软件教程 → 韩国VPS安全怎么加固

【飞翔导读】买韩国VPS回来第一件事不是装面板,而是关掉所有不必要的入口。这篇按真实排查顺序讲加固:用产品库里的真实配置算出加固前后的成本差、给出可以直接照着验收的数字阈值、说明什么情况下不该按这套流程做、以及四类人各自的落地清单,让你读完就知道该买哪一档、该怎么配。

一、先算账:一套加固流程到底要花多少钱

韩国VPS的安全加固本身不花钱,花钱的是加固前被入侵后的重建成本,以及你为了防住攻击而多买的配置。先把这笔账算清楚,再谈怎么配。

看产品库里真实在售的机型:云途香港 DS.ES.C 是每月 700 美元、64GB 内存、800GB SSD、2000Mbps 端口、40000GB 月流量;同系列的 HK.DS.S 是每月 800 美元、128GB 内存、6000GB 存储、2000Mbps、40000GB 流量。两者的内存单价分别是 10.94 美元/GB 和 6.25 美元/GB,硬盘单价分别是 0.875 美元/GB 和 0.133 美元/GB。

换算成加固这件事上:

算账维度 具体算法 结果
单台月成本 700 美元/月 ÷ 1 台 700 美元
每 GB 内存成本 700 ÷ 64 10.94 美元/GB
每 GB 硬盘成本 700 ÷ 800 0.875 美元/GB
每 TB 流量成本 700 ÷ (40000÷1024) 17.92 美元/TB
超流量重购单价 产品库 traffic_reset_price 字段值为 500,超流量按次重购 每次重购 500(美元计)
一年安全重建成本 700 × 12 ÷ 2 次重建 4200 美元

查 justg 在售套餐与库存

这行数字才是重点:一年 4200 美元的重建成本,换来的是不到一小时的人工加固。 一台机器被挖矿或植入后门后,重装系统、清数据、重配业务、重新验证,这个过程通常要花掉几小时到半天,而且清不干净的概率不低。

第二个更实用的算法是:加固投入对比攻击收益。 一次典型的 SSH 暴力破解,成功后攻击者会在你的机器上做什么?挂挖矿、塞 SSH 公钥、架设代理。挖矿是最常见的变现方式,因为它不需要你的机器有业务价值,只要 CPU 一直开着就能自动产生收益。所以加固的第一优先级永远是 CPU 消耗异常。

第三个算法决定你该买哪一档配置:算你的加固盲区。 一台 1GB 内存的机器,装完 fail2ban 加 auditd 加 AIDE 之后,常驻内存大约在 200MB 上下,安全工具链本身就要吃掉五分之一的内存。1GB 内存跑加固套件会很吃力,更别说还要跑业务。 这就是为什么产品库最低档的 RosCloud-01(每月 19.99 美元、1GB 内存)不适合承载需要完整加固的生产环境。

第四个算法:把加固成本摊进带宽预算。 以云途 HK.DS.S 为例,2000Mbps 端口加 40000GB 月流量,单价 20.48 美元/TB。一次成功的劫持,机器消耗的流量由你的账单承担。 挖矿程序的挖矿池通信流量不大,但代理类的会大量吃流量。假设被架代理后每月额外跑掉 2000GB 流量,按 20.48 美元/TB 算就是 40 美元。这笔钱不多,但它证明了一件事:机器被入侵后,账单异常是一个有效的告警信号。

二、验收阈值:加固完必须跑通的六个数字

网上大部分加固文章只说「要改 SSH 端口」「要装 fail2ban」,但读完你还是不知道做到什么程度算合格。这一节给的是可以直接抄进检查脚本的阈值。

阈值一:SSH 密码认证必须为 no,且实测有效。

# 查最终生效配置(比读配置文件可靠,Include 片段会覆盖)
sudo sshd -T | grep -E "^(passwordauthentication|permitrootlogin|pubkeyauthentication|maxauthtries|logingracetime|maxstartups)"

# 阈值:passwordauthentication no
# 阈值:maxauthtries 3
# 阈值:logingracetime 20
# 阈值:maxstartups 10:30:60

实测方式:从另一台机器用密码方式尝试登录,必须失败。

# 预期结果:Permission denied (publickey),不是提示输入密码
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no root@你的服务器IP

阈值二:fail2ban 必须真的在解析日志。

# 阈值:fail2ban-regex 的匹配数必须 > 0,匹配数为 0 等于没装
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

# 阈值:当前 jail 状态必须是 running,不是 ERROR
sudo fail2ban-client status

# 阈值:10 分钟窗口内 5 次失败即封禁,封禁时长 86400 秒
sudo fail2ban-client status sshd

阈值三:对外开放的端口数量必须与业务清单一致。

# 列出所有对外监听的端口
sudo ss -tulnp | grep -E "0\.0\.0\.0|::"

# 阈值:对外监听端口数量 ≤ 4(SSH + 80 + 443 + 1 个管理端口)
# 阈值:3306 / 6379 / 27017 等数据库端口不得出现在对外列表里

这一条是最容易失败的阈值。 很多人装完 ufw 就以为端口关了,但 ufw 只管 iptables 的 INPUT 链,如果数据库服务本身绑定在 0.0.0.0,而 ufw 的规则又写错了,端口照样在外面。判定标准是 ss 的输出,不是 ufw 的输出。

# 数据库必须只监听回环
sudo ss -tlnp | grep 3306
# 阈值:输出只出现 127.0.0.1:3306,出现 0.0.0.0:3306 即为不合格

阈值四:待更新的安全包数量必须为 0。

# 阈值:apt list --upgradable 里不能有带 -security 后缀的包
apt list --upgradable 2>/dev/null | grep -c security
# 阈值:结果为 0

阈值五:CPU 空闲占用必须低于 15%,且没有任何非系统目录的进程。

# 阈值:top 的 Cpu(s) 空闲行,idle 必须 ≥ 85%
top -bn1 | grep "Cpu(s)"

# 阈值:任何进程的 exe 落在 /tmp、/dev/shm、/var/tmp 的一律视为异常
for p in /proc/[0-9]*; do
  exe=$(readlink "$p/exe" 2>/dev/null)
  case "$exe" in */tmp/*|*/dev/shm/*|*/var/tmp/*) echo "VIOLATION: $p -> $exe";; esac
done

阈值六:必须存在一份可用的异地备份,且最近一次恢复演练在 30 天内。

# 阈值:restic check 返回无错误
restic -r sftp:user@backup:/var/backups/myvps check

# 阈值:restore 到临时目录后文件数与源一致
restic -r sftp:user@backup:/var/backups/myvps restore latest --target /tmp/restore-test
ls /tmp/restore-test

vpckr 官网机型与实时报价

这六个阈值可以全部写成一个脚本,每周自动跑一次,输出 PASS/FAIL 清单。 这比每天手动检查成本低得多,而且有记录可查。

三、第一步:改 SSH 是整套加固里性价比最高的一环

五分钟的 SSH 加固能挡掉绝大部分自动化攻击。 你开通实例后,扫描器在几小时内就会扫到你的 22 端口,这是必然事件,不是意外。

顺序不能错:先配密钥、确认能登进去,再关密码,最后才重启服务。

# 1. 生成密钥(ed25519 比 RSA 更短更快)
ssh-keygen -t ed25519 -C "my-kr-vps"

# 2. 首次用密码登录并上传公钥
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@你的服务器IP

# 3. 确认公钥已在位
cat ~/.ssh/authorized_keys

改配置。

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo nano /etc/ssh/sshd_config
PermitRootLogin prohibit-password
PasswordAuthentication no
KbdInteractiveAuthentication no
Port 10022
AllowUsers root deploy
LoginGraceTime 20
MaxAuthTries 3
MaxStartups 10:30:60

MaxStartups 10:30:60 的含义是:未认证连接达到 10 个开始丢弃,超过 30 个时随机丢弃 60%。这个参数直接限制了攻击者能同时维持的爆破连接数,是真正的技术性门槛。

改端口到底防什么,必须说清楚。 现在的扫描器是一把扫 1 到 65535 全端口的,改端口不会让机器从扫描里消失,几小时内照样会被扫到。改端口真正的作用只有两个:一是让没有针对性配置的自动化工具漏掉你,二是大幅减少日志噪音——改完后你的 auth.log 里每天几千条失败尝试会变成几十条,真实攻击反而更容易被看见。

更有效的替代方案是限制来源 IP,前提是你有固定出口 IP:

curl -s https://api.ipify.org    # 先确认自己的公网出口
# /etc/ssh/sshd_config.d/allow.conf
AllowUsers [email protected].*
AllowUsers [email protected]

这个方案比改端口强得多,因为它是从访问控制层面直接拒绝。但家宽 IP 会变,用云主机做跳板机的话跳板机本身要先加固好。

排查 SSH 问题永远先跑 sudo sshd -T。 配置文件可能有多个片段互相覆盖,最终生效的未必是你改的那份,sshd -T 打印的是合并后的真实配置,比翻文件快十倍。

自锁是这一步最大的风险。 预防办法有三条:一是改配置前先在另一个终端建一条保活长连接;二是改完不要立刻关掉当前会话,开新窗口测试能登上再关旧的;三是确认云厂商的 VNC 或网页控制台可用——这是前提,不是可选项。

# 保活会话
ssh -o ServerAliveInterval 60 root@你的服务器IP

# 改完先测语法再重启
sudo sshd -t && sudo systemctl restart ssh
sudo ss -tlnp | grep 10022

注意 Ubuntu 24.04 起服务名从 ssh 变成了 sshd。 不确定就先查:systemctl list-units | grep ssh。

如果真的锁在外面了,按顺序恢复:控制台登录,然后 sudo sshd -t 查语法,再查防火墙规则,最后查公钥权限。

chmod 700 /root/.ssh
chmod 600 /root/.ssh/authorized_keys
sudo sshd -T | grep -i authorizedkeysfile

顺手删掉用不上的账号并查一遍 UID。 每个多余的带 shell 账号都是爆破目标,隐藏后门的常见手法是建一个 UID 0 或 UID 1000 的账号冒充正常用户:

grep -vE "(nologin|false)" /etc/passwd
cut -d: -f3 /etc/passwd | sort | uniq -d   # 重复 UID
awk -F: '$3 == 0 {print $1}' /etc/passwd   # 所有 root 等价账号

密钥本身也要保护,别把私钥裸放在服务器上。 私钥应该只存在于你自己的电脑上,服务器上只放公钥。很多人的失误是把 id_ed25519 整个传到了服务器上,等于把钥匙和锁一起交给了别人。

给私钥加 passphrase,这样即使私钥文件泄露,攻击者也无法直接使用。

# 生成时设置 passphrase
ssh-keygen -t ed25519 -C "my-kr-vps"

# 日常使用用 ssh-agent 缓存,避免每次输 passphrase
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

再给 SSH 加上连接数上限,防止攻击者用大量并发连接耗尽你的进程数。 很多 VPS 的默认 SSH 配置没有这一条,攻击者用几百个并发连接就能把机器的进程表占满,让你的正常运维连不上。

# /etc/ssh/sshd_config.d/limits.conf
MaxSessions 10
ClientAliveInterval 300
ClientAliveCountMax 2

查看 zji 当前月价与库存

ClientAliveInterval 300 加 ClientAliveCountMax 2 的意思是:客户端连续 600 秒没有任何响应,服务端就断开这条连接。 这能清理掉大量半开连接,这些连接平时看着无害,但会持续占用文件描述符和进程槽位。

四、第二步:防火墙只放行业务必需的端口

VPS 默认状态下所有端口对外敞开。数据库 3306、Redis 6379、面板端口只要有一个暴露,就是现成的入侵入口。

sudo apt update && sudo apt install ufw

# 顺序不能反:先加规则,再启用
sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 10022/tcp     # SSH(改过端口就用这个)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

sudo ufw enable
sudo ufw status verbose

「只允许特定网段访问管理端口」这个用法很多人不知道:

# 只允许办公网访问 SSH
sudo ufw allow from 203.0.113.0/24 to any port 10022 proto tcp

# 只允许容器网段访问数据库
sudo ufw allow from 172.16.0.0/16 to any port 3306 proto tcp

但更好的做法是让数据库根本不监听公网。

# /etc/mysql/mysql.conf.d/mysqld.cnf
[ mysqld ]
bind-address = 127.0.0.1
# /etc/redis/redis.conf
bind 127.0.0.1 -::1
protected-mode yes
requirepass 你的强密码
sudo systemctl restart redis-server
sudo ss -tlnp | grep -E "3306|6379"
# 阈值:只出现 127.0.0.1

Redis 是最容易被忽视的入口。 它默认不带密码,一旦暴露在公网,几分钟内就会被写入 SSH 公钥或挖矿程序,直接拿下 root。

每个季度做一次「实际在监听什么」的检查。 很多人几个月前跑过临时测试服务,之后忘了还开着:

sudo ss -tulnp
sudo ss -tulnp | grep -E "0\.0\.0\.0|::"
sudo lsof -i -P -n | grep LISTEN

看到不认识的进程,查它的真实路径:

ps aux | grep -v grep | grep -E "defunct|\./"
ls -l /proc/$(pgrep -f 可疑进程名 | head -1)/exe
cat /proc/$(pgrep -f 可疑进程名 | head -1)/cmdline | tr '\0' ' '

查看 恒创科技 当前月价与库存

正常的进程路径在 /usr/bin、/usr/sbin、/bin;路径在 /tmp、/dev/shm、/var/tmp 或者文件名是一串乱码,那就是恶意程序。

五、第三步:fail2ban 自动封禁与无人值守补丁

手工封 IP 追不上扫描器速度。fail2ban 的机制是监控日志,发现某 IP 在统计周期内失败次数超阈值就加进封禁列表。

sudo apt install fail2ban fail2ban-systemd
sudo cp /etc/fail2ban/jail.local /etc/fail2ban/jail.local.bak
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
bantime = 86400
findtime = 600
maxretry = 5
ignoreip = 127.0.0.1/8 ::1
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 604800

[sshd]
enabled = true
port = 10022
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
bantime = 86400

bantime.increment = true 值得单独说:开启后被反复尝试封禁的 IP,封禁时长按 factor 递增——第一次 1 天,第二次 2 天,第三次 4 天,最长 7 天。这对付换 IP 试探的分布式攻击特别有效。bantime.maxtime = 604800 则保证不会变成永久封禁,你不必手动解封。

sudo systemctl enable --now fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 1.2.3.4

装完必须验证它在解析日志,而不是静默空转。

# 阈值:匹配数必须 > 0
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

# 从另一台机器故意输错密码 6 次
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no root@你的服务器IP
# 然后回来确认封禁列表
sudo fail2ban-client status sshd

fail2ban-regex 是最实用的自检命令,它直接告诉你扫了多少行、匹配了多少行。匹配数为 0 说明 filter 和你的日志格式对不上,fail2ban 装了等于没装。

再给 Web 服务加 jail,并开 recidive 抓换号回来的攻击者:

[nginx-http-auth]
enabled = true
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3

[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
maxretry = 3
bantime = 604800

补丁策略:只自动打安全更新,不自动做版本升级。

sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
# /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "7";

APT::Periodic::Unattended-Upgrade "1" 是关键的一行。 很多人装了 unattended-upgrades 却没开这个开关,结果它什么都没干。改完要重启服务才生效:

sudo systemctl restart unattended-upgrades
sudo systemctl list-timers | grep -i unattended

限定「只打安全补丁」,需要配置 origins 列表:

# 发行版代号用 lsb_release -cs 查,下面以 Ubuntu 24.04 (noble) 为例
Unattended-Upgrade::Allowed-Origins {
        "ubuntu:noble-security";
        "ubuntuESMApps:noble-apps-security";
        "ubuntuESM:noble-infra-security";
};

这个取舍很重要。 PHP 从 8.1 跳到 8.3 这种大版本变化必须人工确认,跳过去可能让你的网站直接报错;安全补丁则基本无副作用。生产服务器上,稳定性比新特性重要。

改完必须验证它真的更新了,很多机器上无人值守更新会静默失败:

sudo tail -30 /var/log/unattended-upgrades/unattended-upgrades.log
apt list --upgradable | wc -l

WordPress 站点要单独管插件,插件漏洞比核心漏洞多:

wp plugin list --update=available --format=table
0 3 * * * cd /var/www/html && wp core update --quiet && wp plugin update --all --quiet

最后是删掉不用的软件,每一份多装的软件都是潜在漏洞面:

apt-mark showmanual
apt-get autoremove --dry-run

再补一条很多人会忽略的:数据库的默认账号。 MySQL 和 PostgreSQL 安装完都会带一个默认超级用户,它的密码在安装时通常是随机生成或干脆是空的。如果这个账号的密码为空或者你从没改过,它就是一个挂在数据库端口上的后门。

# MySQL 检查有哪些用户、哪些没有密码
sudo mysql -e "SELECT user, host, authentication_string FROM mysql.user;"

# PostgreSQL 检查
sudo -u postgres psql -c "\du"

# 删掉不需要的默认账号
sudo mysql -e "DROP USER 'test'@'%';"

同时确认数据库服务没有绑定到公网网卡。 前面说过 bind-address = 127.0.0.1 是最有效的一层,但很多人改完没有重启,或者改错了配置文件位置。

# 找出 MySQL 真正读取的配置文件位置
sudo mysqld --verbose --help 2>/dev/null | grep -A1 "Default options are read from"

# 确认最终生效的绑定地址
sudo mysql -e "SHOW VARIABLES LIKE 'bind_address';"

这个检查能排掉一大类低级失误。 确认结果是 127.0.0.1 才对,如果显示 0.0.0.0 或者 *,说明绑定没生效。

还有一个容易被忽略的入口:面板自带的数据库管理端口。 宝塔、1Panel、aaPanel 这类面板为了方便管理,会开一个数据库管理端口(常见是 888、33060 之类),这个端口在装防火墙时最容易被漏掉,因为它不写在你部署的任何服务配置里。

# 把所有对外监听的端口和进程一行行列出来,逐个对照你的业务清单
sudo ss -tulnp | grep -E "0\.0\.0\.0|::" | awk '{print $1, $5, $7}'

# 如果确认某个面板端口用不上,直接停掉对应服务
sudo systemctl stop mysql && sudo systemctl disable mysql

停掉比屏蔽更好。 一个不运行的服务不占端口、不占内存、不产生补丁面,比加一条防火墙规则干净得多。「不用的服务就不装」永远是安全的第一原则,加固只是补救。

配置防火墙时还有一条经常被忽略的规则:限制出站。 默认的 ufw 策略是允许所有出站连接,也就是你的机器可以主动连接任意地址。这条规则在机器被入侵后是致命的,因为攻击者需要把你的机器连到他的 C2 服务器才能远程控制,而你的机器不主动连出去,他就只能等。

# 危险做法:完全禁止出站
# sudo ufw default deny outgoing
# 后果:apt 装不了包、证书续不了、监控系统上报不了

# 正确做法:允许常用出站,其余拒绝
sudo ufw allow out to 8.8.8.8/32
sudo ufw allow out to 151.101.0.0/16

查看 hostkvm 当前月价与库存

但不建议一上来就禁出站。 更稳妥的做法是保持默认允许,但在监控里盯住异常出站连接——第二节阈值五里那个 /proc 检查就是配套的。

六、第四步:入侵迹象排查,怎么知道自己有没有被入侵

加固是预防,这一步是确认预防有没有效。VPS 被入侵后通常不立刻发作,而是潜伏几天到几周,等到被当作跳板或矿机才暴露。主动排查比等它发作便宜得多。

先明确判断标准,分三档:

档次 典型迹象 该做什么
可疑 陌生 cron 项、陌生 systemd 服务、异常对外连接 逐条核对,确认来源,删掉来路不明的
明确 陌生账号、webshell、异常 sudo 免密记录 立即备份数据,准备重装
确证 挖矿进程、文件校验失败、C2 连接 直接重装,不要试图清理

查 vollcloud 在售套餐与库存

关键原则:一旦落到「明确」这一档,就不要清理,直接重装。 清理后门的成本远高于重装一次,而漏掉一个后门意味着重装也白搭。

第一组:账号和登录记录。

# 所有 UID 0 的账号
awk -F: '$3 == 0 {print $1" (uid=0)"}' /etc/passwd

# UID 1000 以上且有 shell 的账号,和你自己的清单对比,多出来的都要查
awk -F: '$3 >= 1000 && $7 !~ /nologin|false/ {print $1, $3, $7}' /etc/passwd

# 最近的成功登录
last -n 30

# 失败的密码尝试按 IP 统计
sudo grep "Failed password" /var/log/auth.log | awk '{print $9}' | sort | uniq -c | sort -rn | head -20

# 成功但用了密码的方式(说明有人在用密码登进来)
sudo grep "Accepted password" /var/log/auth.log | tail -20

第二组:计划任务,攻击者藏身的地方。

sudo crontab -l -u root
for u in $(cut -f1 -d: /etc/passwd); do sudo crontab -l -u $u 2>/dev/null; done

ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/
sudo systemctl list-timers --all

# 常见隐藏方式
sudo grep -R "curl\|wget\|base64\|/dev/shm\|nc " /etc/cron* 2>/dev/null

现代恶意程序更爱注册成 systemd 服务而不是 cron:

systemctl list-unit-files --type=service | grep enabled
ls -la /etc/systemd/system/*.service
sudo grep -R "ExecStart" /etc/systemd/system/*.service 2>/dev/null | grep -vE "/usr/bin|/usr/sbin|/bin/|/usr/lib"

第三组:进程和异常文件。

# 挖矿程序会霸榜
ps aux --sort=-%cpu | head -15
ps aux --sort=-%mem | head -15

# 跑在临时目录里的进程
for p in /proc/[0-9]*; do
  exe=$(readlink "$p/exe" 2>/dev/null)
  case "$exe" in */tmp/*|*/dev/shm/*|*/var/tmp/*) echo "SUSPICIOUS: $p -> $exe";; esac
done

# 挖矿通常会下载大文件
sudo du -sh /tmp /var/tmp /dev/shm 2>/dev/null
sudo find / -xdev -type f -size +100M -exec ls -lh {} \; 2>/dev/null | head -20

第四组:网络连接,C2 连接是最容易确认的证据。

sudo ss -tunap | grep ESTAB
sudo ss -tunap | grep -v "127.0.0.1\|::1\|你的服务器IP"

# 路由表有没有被加恶意的路由
ip route
ip rule

第五组:文件完整性。

# 最近 7 天被改过的系统配置文件
sudo find /etc /usr/bin /usr/sbin -mtime -7 -type f 2>/dev/null

# 校验系统文件(Debian/Ubuntu 用 dpkg,CentOS 系用 rpm)
sudo dpkg -V
sudo rpm -Va | grep -E "^5"

rpm -Va 输出的第五列是校验结果,5 代表 MD5 不匹配,也就是这个文件被改过,这是入侵最直接的证据之一。

第六组:shell 启动脚本里的后门。

sudo grep -nE "curl|wget|base64|nc |/dev/tcp" /root/.bashrc /root/.profile /etc/profile /etc/bash.bashrc 2>/dev/null
sudo grep -E "base64|curl.*\|.*sh|wget.*\|.*sh|nc -e|/dev/tcp" /root/.bash_history 2>/dev/null | tail -20

第七组:sudo 权限有没有被篡改。 攻击者进来后最想做的一件事就是给自己加免密 sudo:

sudo grep -R "NOPASSWD" /etc/sudoers /etc/sudoers.d/ 2>/dev/null

输出必须逐条核对。 你自己配的那几条应该记得,别人加的就该问清楚是谁加的。

这七项加起来十分钟左右,建议每月跑一次。 关键不是每次手工看,而是把输出存下来做基线,之后 diff,新增的行就是变化点:

sudo { cat /etc/passwd; ss -tulnp; systemctl list-unit-files --type=service; crontab -l; } > ~/baseline_$(date +%F).txt

# 下次检查
sudo ss -tulnp > /tmp/now.txt
sudo ss -tulnp | diff - ~/baseline_2026-11-05.txt

七、Web 服务的攻击面:PHP 站点最容易出事的地方

很多 VPS 被入侵,起点不是 SSH,而是跑在上面的网站,尤其是 WordPress。

改任何配置之前先做摸底,看你的网站到底被怎么打。 这一步能告诉你该优先堵哪个口:

# 访问最多的路径
sudo awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# 404 最多的请求(针对不存在路径的探测)
sudo awk '$9 == 404 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# 针对敏感文件的探测
sudo grep -E "\.env|\.git|wp-config|composer\.(json|lock)|\.sql|\.bak" /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20

# 打到登录接口的 POST 尝试
sudo awk '$6 == "POST" && $7 ~ /wp-login|admin|login|xmlrpc/ {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

最后一条命令的输出如果集中在一个 IP 上,那就是正在爆破你的后台。 这比读十篇安全文章都直接。

关掉 XML-RPC,禁掉 wp-content 下的 PHP 执行:

location ~* ^/xmlrpc\.php$ {
    deny all;
}

location ~* wp-config\.php\.(bak|old|save|swp|orig)$ {
    deny all;
}

location ~* ^/wp-content/.*\.php$ {
    deny all;
}

autoindex off;

PHP 配置层面有几个必做项:

; /etc/php/8.2/fpm/php.ini
open_basedir = /var/www/html:/tmp:/var/www
disable_functions = exec,passthru,shell_exec,system,popen,proc_open,pcntl_exec
display_errors = Off
log_errors = On
error_log = /var/log/php/error.log
expose_php = Off
upload_max_filesize = 20M
post_max_size = 22M

open_basedir 是防 webshell 横向扩散最有效的一道锁。 webshell 最典型的行为就是去读 /etc/passwd、去读别的站点的配置文件,open_basedir 会直接把它挡掉。

sudo systemctl restart php8.2-fpm

安全响应头成本几乎为零:

add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

server {
    listen 80;
    server_name 你的域名;
    return 301 https://$host$request_uri;
}

includeSubDomains 要谨慎加,它会影响所有子域名,如果你有子域名还没上 HTTPS,加了会导致它们无法访问。不确定就先不加。

TLS 配置:

# /etc/nginx/snippets/ssl-options.conf
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;

ssl_protocols 里绝对不要留 TLSv1 和 TLSv1.1,留着只是给扫描器送漏洞报告。ssl_session_cache 能显著改善性能,访客第二次连接时省掉一次完整握手往返。

证书续期必须验证,这是最常见的静默故障:

sudo certbot renew --dry-run
sudo systemctl status certbot.timer

Let's Encrypt 证书只有 90 天有效期,续期失败站点直接不可用。 很多手动装的 certbot 只装了包没装定时器。

再加一条限速规则做双保险:

查看 kdatacenter 当前月价与库存

limit_req_zone $binary_remote_addr zone=wp_limit:10m rate=5r/m;

location ~* /wp-login\.php {
    limit_req zone=wp_limit burst=5 nodelay;
}

八、Webshell 检测与文件完整性监控

前面几节是预防,这一节是发现。webshell 的特点是:文件被上传到某个目录,权限改成可执行,然后通过 HTTP 请求触发。

手工排查可疑的 PHP 文件:

# 最近 7 天新增或修改的 PHP 文件
sudo find /var/www -name "*.php" -mtime -7 -exec ls -la {} \; 2>/dev/null | head -30

# 含常见恶意函数的小文件(webshell 特征)
sudo grep -rlE "eval\s*\(|assert\s*\(|base64_decode\s*\(|system\s*\(|passthru\s*\(|shell_exec\s*\(|preg_replace\s*\(.*\/e" /var/www --include="*.php" 2>/dev/null

# 图片目录里的 PHP 文件(最常见的藏身处)
sudo find /var/www -path "*/uploads/*" -name "*.php" -o -path "*/images/*" -name "*.php" 2>/dev/null

部署 AIDE 做完整性监控,这是最省事的长期方案。

sudo apt install aide
sudo aideinit
# Debian/Ubuntu 会生成 /var/lib/aide/aide.db.new
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
sudo systemctl enable --now aide-check.timer
sudo aide --check

Tripwire 是替代方案,配置更简单:

sudo apt install tripwire
sudo tripwire-init
sudo tripwire --local-options

再补一条日志集中化,攻击者拿到 root 后第一件事就是清日志,日志必须有机器之外的副本。

# /etc/rsyslog.d/remote.conf
*.* @203.0.113.10:514

或者用 auditd 记录所有 sudo 操作:

sudo auditctl -w /usr/bin/sudo -p x -k sudo_exec
sudo ausearch -k sudo_exec -i | tail -50

这个记录的价值在于它能回答「谁在什么时候用了 sudo」,而这个信息在事后往往查不到,普通日志会被轮转清掉,auditd 的记录相对独立。

持久化规则,让 auditd 重启后不丢:

# /etc/audit/rules.d/audit.rules
-w /etc/passwd -p wa -k identity_change
-w /etc/shadow -p wa -k shadow_change
-w /etc/sudoers -p wa -k sudoers_change
-w /usr/bin/sudo -p x -k sudo_exec
-w /var/www -p wa -k webdir_change
-w /etc/ssh/sshd_config -p wa -k sshd_config_change
-w /etc/crontab -p wa -k cron_change

sudo augenrules --load
sudo auditctl -l

webdir_change 会记录网站目录里每一次文件写入。如果哪天发现一个可疑的 PHP 文件,这条记录能精确告诉你它是什么时候、怎么被写进来的。

再补一个很多人没做的:给关键二进制挂不可变属性。

sudo chattr +i /usr/bin/sshd
sudo chattr +i /usr/bin/passwd
sudo chattr +i /usr/bin/sudo
# 需要更新时先解除
sudo chattr -i /usr/bin/sshd

但 chattr +i 有代价:它会让正常的软件包升级失败,也会让你自己改配置时报错。建议只对最关键的几个二进制文件用,并把解除锁定的步骤写进运维手册。

内核参数加固,能直接挡掉一大类常见攻击:

# /etc/sysctl.d/99-hardening.conf
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

sudo sysctl --system

查 racknerd 在售套餐与库存

注意不要顺手加上 net.ipv4.icmp_echo_ignore_all = 1,禁 ping 会让你自己的排查变得很麻烦。

九、什么情况下不该按这套流程做

这一节比前面所有命令都重要。 加固是通用的,但有些约束会让这套流程的收益大幅下降甚至变成负担。以下判断只依据公开的机房位置、线路类型、计费方式和 IP 资源,不涉及对任何商家的评价。

场景一:你只有一台机器,且主要靠 SSH 密码登录,没有密钥可用。

强行关掉密码登录会直接锁死你。替代方案:保留密码登录,装 fail2ban 并把 maxretry 设为 3,同时把 SSH 端口从 22 改到高端口。 这样虽然安全性不如密钥,但比什么都不做强得多,而且不会把你锁在外面。

场景二:你的机器是按小时计费的临时开发机,跑完就删。

完整加固要花一到两小时,而机器生命周期只有几小时。替代方案:只做三件事,改端口、装 ufw 只放行 22 和 80/443、装 fail2ban。 这三步加起来十分钟,能覆盖绝大部分扫描噪声。

场景三:你的机器跑的是实时音视频或游戏服务端,客户端需要直接连进来。

这种情况下「只放行业务端口」的原则不适用,因为业务端口本身就是给公网用的。替代方案:把防护重心从主机层转到网络层,用带清洗能力的线路,针对你的业务端口做限速和连接数限制,而不是做全端口封锁。

场景四:你要跑的负载本身需要高内存,而你的配置档位内存不足。

安全工具链的常驻开销是实打实的。产品库最低档的 RosCloud-01 是每月 19.99 美元、1GB 内存、20GB 硬盘、500Mbps、1024GB 流量,1GB 内存跑完 fail2ban 加 auditd 加 AIDE 之后留给业务的空间不到 500MB。替代方案:选内存更大的档位,而不是硬塞。 云途 HK.DS.P 是每月 750 美元、64GB 内存、1024GB SSD、2000Mbps、40000GB 流量,内存单价 11.72 美元/GB,硬盘单价 0.732 美元/GB,流量单价 19.2 美元/TB;云途 DS.ES.C 每月 700 美元、64GB 内存、800GB SSD、流量单价 17.92 美元/TB,流量单价更低,适合流量消耗大的场景。

场景五:你的业务依赖固定 IP 白名单,机器要频繁更换。

加固配置每次重装都要重做,加密备份的恢复流程也要跟着变。替代方案:机器上不存业务数据,只做反向代理或转发层,数据放在有持久盘的对象存储上。 这样换机器时的数据迁移成本接近零。

场景六:你判断机器已经确认被入侵。

查 spinservers 在售套餐与库存

这时候做加固是错的,应该直接重装。 花两小时加固一台已经被植入后门的机器,不如花二十分钟重装。

按你的情况,下一步该看哪家

上面讲的是判断标准,但多数人最后还是想问一句「那我该买谁」。按你的实际情况对照下面几条,直接去看对应的机型页比继续比价更快:

价格与库存以商家页面当日显示为准,下单前建议先确认退款窗口与是否支持按月付费。

十、结论:四类人各自该怎么做

第一类:个人用户,只有 1 台机器跑个人博客或小站。

你的合理默认值是按月付费的最低配置即可,不要买年付,年付在被入侵后你要赔进去更多沉没成本。做四件事:改 SSH 端口到 10022、生成 ed25519 密钥并关掉密码登录、ufw 只放行 22/80/443、装 fail2ban 且用 fail2ban-regex 验证它真的在跑。验收看第二节的阈值三:对外监听端口数量不超过 4。 升级配置的时机很明确:当你的监控发现内存谷值超过 70% 或待更新安全包数不为 0 时再升。

第二类:做外贸或跨境电商的公司站,跑在 2 台以上机器上。

你需要的是可追溯而不是不可访问。给每台机器配独立的 fail2ban jail、开全量 auditd 审计、把每台机器的基线文件定期 diff、备份做异地加密。验收看第二节的阈值六:最近一次恢复演练在 30 天内。 配置档位上流量单价是关键指标,按 17.92 美元/TB 的档位比 20.48 美元/TB 的档位在相同流量消耗下成本更低。

第三类:做 API 服务或数据处理的后端团队。

你们的暴露面是 API 端口而不是 SSH,所以加固重点要放在限流和异常检测上,而不只是关入口。做法是 Nginx 侧对 API 路径配 limit_req、对异常状态码配告警、数据库只监听回环、Redis 强制密码且只监听回环。验收看第二节的阈值五:CPU 空闲必须达到 85% 以上,且没有进程跑在临时目录里。 对这类场景来说,一台机器上跑多台实例加独立审计,比多开几台低配更省。

第四类:托管客户服务器的运维团队。

客户服务器不能直接禁 root 也不能限制来源 IP,因为你的客户要能登进去。正确做法是每个客户一个独立系统账号并用 sudo 提权、每个客户一条独立的 fail2ban jail、按客户隔离目录权限、全量 auditd 记录所有 sudo。核心原则是可追溯而不是不可访问。 这种模式下配置档位要留余量,因为多客户共享一台机器时,单个客户的流量峰值会挤占其他人的配额,内存单价高但资源隔离好的档位反而更合适。

通用的一句话收尾:加固的成本是一个小时,收益是把「被入侵后重建」的概率从「迟早」变成「小概率」。但别把它当成买了保险就万事大吉,配置一台机器之前先花十分钟确认云厂商控制台可用,这是所有加固操作的前提条件,不是可选项。

zenlayer 官网机型与实时报价

关于本文提到的所有具体配置:文中引用的价格与配置均来自渠道库快照(2026-11-05 22:39 抓取),以官网当日显示为准;没有给出结构化套餐数据的商家,本文不涉及具体报价,请以下单页为准。文中所有安全命令都是通用操作,是否适合你的具体环境需要你自己判断后再执行。

飞翔声明:飞翔网登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。

评论:0 次

阅读本文后您有什么感想? 已有 人给出评价!

  • 0 喜欢
  • 0 高兴
  • 0 鬼脸
  • 0 呵呵
  • 0 无聊
  • 0 伤心

相关新闻

网友评论

评分
★
★
★
★
★
力荐
选择头像:
10
999+人评分
★★★★★
★★★★
★★★
★★
★
查看更多 >

魔兽世界Dota式击杀音效插件PVPSound

点击进入 立即下载

关于飞翔 | 联系我们 | 大事记 | 下载帮助(?) | 广告联系 | 版权声明 | 网站地图 | 友情链接

Copyright 2010-2025 单机游戏下载 (R) 版权所有 飞翔下载所有游戏及软件下载资源来源互联网,并由网友上传分享。如有侵权,请来电来函告之。
飞翔忠告:抵制不良色情、反动、暴力游戏 合理安排游戏时间 享受健康生活 鄂公网安备:42011102003115号 【鄂ICP备17000818号-1】