搜索全站
安装部署 16 分钟阅读

网站上线前的安全基线配置:账号、端口、防火墙与备份清单

新服务器上线前必须做的 8 项安全基线:SSH 密钥登录、改端口禁 root、防火墙最小化放行、fail2ban 防爆破、文件权限、数据库隔离、自动更新与离线备份,附可直接执行的命令。

U
UFO_PF 2017-01-24 · 阅读 16 分钟
网站 安装部署
阅读提示
本文约 6,095 字,预计阅读 16 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:公网服务器存活时间以分钟计

一台新开的云服务器,只要公网 IP 一生效,来自全球的自动化扫描就开始敲门了。这不是夸张——把 SSH 开在 22 端口、密码强度一般的机器,通常在几小时内就会出现在爆破日志里,运气不好几天内就会被植入挖矿程序。

WordPress 站点因为市场份额高,是扫描器的重点关照对象:/wp-login.php 的暴力破解、/xmlrpc.php 的 pingback 放大攻击、插件目录的已知漏洞探测,几乎每分钟都在发生。很多站长觉得”我就是个小博客,没人会攻击我”——实际上自动化扫描不挑目标,它只挑漏洞。上线前的这几项基线配置总共花不到一小时,却能挡掉 95% 以上的自动化攻击。

原理分析:攻击面来自哪里

服务器的安全风险可以拆成四层:

第一层:远程登录入口(SSH)。 默认 22 端口 + root 用户 + 密码登录,是最经典的组合风险。攻击者用密码字典不断尝试,一旦命中就是最高权限。

第二层:端口暴露面。 每一台服务器默认可能开放 22(SSH)、3306(MySQL)、6379(Redis)、80/443(Web)等端口。其中 3306 和 6379 绝对不应该对公网开放——Redis 未授权访问是最常见的一键沦陷方式,攻击者可以直接写入 SSH 公钥或 crontab。

第三层:Web 应用层。 WordPress 的攻击面集中在登录页、XML-RPC、插件与主题漏洞、以及文件权限。其中 xmlrpc.php 的 system.multicall 方法可以在一次请求里尝试上千个密码,绕过常规的登录失败次数限制。

第四层:数据可恢复性。 前面三层都被突破的情况下(勒索、误操作、云厂商故障),唯一能救你的是备份。而”备份在同一台机器上”等于没备份。

防护优先级应该是:先堵住入口(SSH、端口),再加固应用(权限、XML-RPC),最后保证可恢复(异地备份)。不要反过来,很多人花大量时间装安全插件,却把 3306 端口开着。

保姆级实操:上线前逐项执行

步骤 1:创建普通用户并配置 SSH 密钥登录。 全程用密钥,禁用密码登录。

# 本地机器生成密钥对(一路回车即可,或加 -C 备注)
ssh-keygen -t ed25519 -C "admin@mimangfei"

# 把公钥传到服务器(这是唯一需要输一次密码的时候)
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@你的IP

# 登录服务器后创建日常使用的普通用户
adduser webadmin
usermod -aG sudo webadmin

# 把 root 下已授权的公钥复制给新用户
mkdir -p /home/webadmin/.ssh
cp /root/.ssh/authorized_keys /home/webadmin/.ssh/
chown -R webadmin:webadmin /home/webadmin/.ssh
chmod 700 /home/webadmin/.ssh
chmod 600 /home/webadmin/.ssh/authorized_keys

用新用户新开一个终端窗口验证密钥登录成功之后,再继续下一步。 这一步不做完就禁用密码登录,会把自己锁在门外。

步骤 2:修改 SSH 配置,禁用密码与 root 登录。

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo nano /etc/ssh/sshd_config

关键项改成这样:

# /etc/ssh/sshd_config
Port 22922                 # 改成 1024-65535 之间的自定义端口,避开扫描器
PermitRootLogin no         # 禁止 root 直接登录
PasswordAuthentication no  # 禁用密码登录,只允许密钥
PubkeyAuthentication yes
PermitEmptyPasswords no
ChallengeResponseAuthentication no
UsePAM no
MaxAuthTries 3             # 单次连接最多尝试 3 次
LoginGraceTime 30
AllowUsers webadmin        # 白名单,只允许指定用户登录

改完后 不要直接重启 sshd,先检查语法,并保持一个已登录的会话不断开:

sudo sshd -t && echo "配置正确"     # 无输出即无错误
sudo systemctl restart sshd          # Ubuntu 上是 ssh,CentOS 是 sshd

新开终端用新端口测试能连上之后,再关掉旧会话。

步骤 3:配置防火墙,只放行必要端口。

# Ubuntu / Debian 用 ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22922/tcp comment 'SSH'
sudo ufw allow 80/tcp  comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw --force enable
sudo ufw status verbose
# CentOS / Rocky / AlmaLinux 用 firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --permanent --add-port=22922/tcp
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

注意:还要在云厂商控制台的”安全组”里同步放行。 云安全组是独立于系统防火墙的一层,两层都放行才通;反过来,只在云控制台开放而系统防火墙没开,也一样连不上。安全组务必检查是否误开了 3306、6379、22 对 0.0.0.0/0。

步骤 4:安装 fail2ban 拦截暴力破解。

sudo apt install -y fail2ban       # CentOS: sudo yum install -y fail2ban

sudo tee /etc/fail2ban/jail.local > /dev/null <<'EOF'
[DEFAULT]
bantime  = 3600
findtime = 600
maxretry = 3
ignoreip = 127.0.0.1/8

[sshd]
enabled  = true
port     = 22922
filter   = sshd
logpath  = /var/log/auth.log      # CentOS 改为 /var/log/secure
maxretry = 3

[nginx-http-auth]
enabled = true

[wordpress-login]
enabled  = true
port     = http,https
filter   = wordpress-login
logpath  = /var/log/nginx/access.log
maxretry = 5
EOF

# 为 WordPress 登录创建过滤规则
sudo tee /etc/fail2ban/filter.d/wordpress-login.conf > /dev/null <<'EOF'
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php.* 200
            ^<HOST> .* "POST /xmlrpc.php.* 200
ignoreregex =
EOF

sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

步骤 5:收紧 WordPress 文件权限与配置。 目录 755、文件 644,wp-config.php 收到 600,并且禁止 Web 访问敏感文件:

# 在站点根目录执行(把 www-data 换成你的 Web 用户,LNMP 一键包常是 www)
sudo find /var/www/html -type d -exec chmod 755 {} \;
sudo find /var/www/html -type f -exec chmod 644 {} \;
sudo chmod 600 /var/www/html/wp-config.php
sudo chown -R www-data:www-data /var/www/html
# Nginx:禁止访问敏感文件
location ~* /(?:wp-config\.php|readme\.html|readme\.txt|wp-config-sample\.php) {
    deny all;
}

# 关闭 XML-RPC,挡住 pingback 放大与 system.multicall 爆破
location = /xmlrpc.php {
    deny all;
}

# 禁止在上传目录执行 PHP(防图片马 getshell)
location ~* /uploads/.*\.php$ {
    deny all;
}

步骤 6:数据库安全加固。 创建专用数据库用户,只给必要权限,不要用 root 用户连 WordPress:

-- 登录 MySQL 后执行,把密码换成强随机密码
CREATE DATABASE wp_site DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY '换成强随机密码';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, INDEX
      ON wp_site.* TO 'wp_user'@'localhost';
FLUSH PRIVILEGES;

确认 MySQL 只监听本地:

sudo grep -rn "bind-address" /etc/mysql/ 2>/dev/null
# 应为 bind-address = 127.0.0.1,云安全组里绝不能放行 3306
sudo ss -lntp | grep 3306
# 正常应显示 127.0.0.1:3306,出现 0.0.0.0:3306 说明对公网开放了,必须改

步骤 7:开启系统自动安全更新。

sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades   # 交互界面选 Yes
sudo systemctl enable --now unattended-upgrades

步骤 8:配置异地自动备份。 备份脚本放到另一台机器或对象存储,网站数据备份策略 里有完整的落地方案。最低要求是:每日一次全量、保留 7 天、备份文件不存放在本机 Web 目录。

常见踩坑

  1. 改了 SSH 端口就重启,没先开新会话验证。 sshd 配置写错会直接断开且连不回去,只能走云控制台的 VNC 救援。正确做法是:sshd -t 检查语法 → 保留当前会话 → 新开终端测试 → 成功后再关旧会话。
  2. 只配了系统防火墙,忘了云安全组。 表现为”配置都对但连不上”,或者”以为关了其实公网还能扫到 3306″。两层都要查。
  3. Redis / Memcached 监听 0.0.0.0。 用 ss -lntp 检查,必须是 127.0.0.1。未授权 Redis 是”一键沦陷”级漏洞。
  4. wp-config.php 权限 644 且允许 Web 访问。 数据库账号密码直接暴露。
  5. 装了一堆安全插件却不更新核心。 漏洞统计里,过时核心与过时插件的占比远高于”没装安全插件”。
  6. 密钥文件权限太开放导致 SSH 拒绝使用。 本地私钥必须是 600:chmod 600 ~/.ssh/id_ed25519,否则报错 Permissions 0644 for 'id_ed25519' are too open。
  7. 案例:一台被植入挖矿程序的新服务器。 客户买了服务器后只装了宝塔面板,用了默认的 8888 端口和弱密码,也没改 SSH 默认配置。三天后 CPU 长期 100%,用 top 看到一个名为 kworkerds 的进程占满 CPU,crontab -l 里多了一条从境外地址下载脚本的定时任务。这个案例的教训是:宝塔、WDCP 等面板的入口端口本身就是攻击面,要么改掉默认端口 + 强密码 + IP 白名单,要么用完就关掉面板服务(bt stop)。另外,定期执行 crontab -l、ls /tmp、ss -lntp 这三条命令,能最快发现异常。

总结

安全基线的判断标准是”最小化暴露 + 可恢复”。执行顺序:密钥登录 → 禁 root 改端口 → 防火墙与安全组双层收紧 → fail2ban 拦爆破 → 文件权限与 Nginx 屏蔽 → 数据库专用账号 → 自动更新 → 异地备份。全部做完之后,用 ss -lntp 确认对外只开放 80、443 和自定义 SSH 端口,就算达标。上线后还要持续做 网站监控与告警搭建,配置 CPU 异常与登录失败告警;SSL 证书申请与部署 也是安全基线的一部分——全站 HTTPS 能防止中间人劫持登录凭证。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。