服务器安全加固清单:Linux、Nginx 与 MySQL 实战指南

服务器安全不是装个防火墙就万事大吉的事。一个暴露在公网的 Linux 服务器,如果没有经过系统性的加固,从上线到被扫描器盯上可能只需要几个小时。这篇文章从 Linux 系统层、Nginx 中间层到 MySQL 数据层,给出一份可直接落地的安全加固清单,同时覆盖 XSS 和 SQL 注入这两个最常见的 Web 攻击面。

一、Linux 服务器安全加固清单

1. SSH 加固

SSH 是服务器最重要的入口,也是最常被暴力破解的目标。

  • 禁用 root 远程登录:在 /etc/ssh/sshd_config 中设置 PermitRootLogin no,日常操作使用普通用户 + sudo
  • 改用密钥认证:设置 PasswordAuthentication no,彻底关闭密码登录。配合 ssh-keygen 生成密钥对,公钥放到服务器的 ~/.ssh/authorized_keys
  • 修改默认端口:将 22 端口改为非标准端口(如 22022),能过滤掉绝大部分自动化扫描。
  • 限制登录来源:如果服务器只服务于特定 IP 段,用 AllowUsers 或防火墙规则限制来源。
  • 安装 fail2ban:自动封禁多次登录失败的 IP,配置简单且效果显著。

2. 防火墙与端口管理

遵循最小开放原则——只开放必要的端口。

# 使用 ufw 的典型配置
ufw default deny incoming
ufw default allow outgoing
ufw allow 22022/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

定期用 ss -tlnp 检查监听端口,关闭不需要的服务。很多安全事件源于一个被遗忘的测试端口。

3. 系统更新与权限

  • 开启自动安全更新:Ubuntu/Debian 用 unattended-upgrades,CentOS 用 yum-cron
  • 检查 SUID 文件:find / -perm -4000 -type f 2>/dev/null,确认没有异常提权入口。
  • 关键目录权限:/etc/shadow 应为 640/root 应为 700
  • 启用 SELinux 或 AppArmor,为服务提供额外的访问控制层。

4. 日志与监控

部署 auditd 记录关键系统调用,用 logwatch 或集中式日志方案(如 ELK)定期审查异常行为。至少确保 /var/log/auth.log 有人看——或者有工具帮你看。

二、Nginx 安全配置要点

Nginx 作为反向代理和 Web 服务器,是攻击者接触应用的第一层。

隐藏版本信息

server_tokens off;

避免在响应头和错误页面中暴露 Nginx 版本号,减少被针对性利用的可能。

安全响应头

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'" always;

其中 Content-Security-Policy(CSP)是防御 XSS 的重要补充手段,后文会展开。

限制请求与连接

limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;

location /api/ {
    limit_req zone=api burst=20 nodelay;
    limit_conn addr 10;
}

这能有效缓解暴力破解和简单的 CC 攻击。

其他关键项

  • 禁用不需要的 HTTP 方法:if ($request_method !~ ^(GET|HEAD|POST)$) { return 405; }
  • 禁止访问敏感文件:location ~ /\.(git|env|htaccess) { deny all; }
  • 上传目录禁止执行 PHP:location /uploads/ { location ~ \.php$ { deny all; } }

三、XSS 的常见方式与前端防御

XSS(跨站脚本攻击)的本质是攻击者让恶意脚本在受害者的浏览器中执行。常见类型有三种:

  1. 存储型 XSS:恶意脚本被存入数据库(如评论区),所有访问该页面的用户都会中招。危害最大。
  2. 反射型 XSS:恶意脚本通过 URL 参数传入,服务器直接回显在页面中。通常需要诱导用户点击特制链接。
  3. DOM 型 XSS:前端 JavaScript 直接从 location.hashdocument.URL 等来源取数据并插入 DOM,不经过服务器。

前端防御的核心原则

永远不信任用户输入,永远对输出进行编码。

具体做法:

  • 输出编码:将 < 转为 &lt;> 转为 &gt;" 转为 &quot;。根据输出上下文选择编码方式——HTML 内容、HTML 属性、JavaScript 字符串、URL 各自的编码规则不同。
  • 避免危险的 DOM 操作:用 textContent 替代 innerHTML,用 setAttribute 替代直接拼接属性。如果必须用 innerHTML,先经过 DOMPurify 等库净化。
  • CSP 作为纵深防御:通过 Content-Security-Policy 头限制脚本来源,禁止内联脚本执行。即使编码出现疏漏,CSP 也能阻断大部分 XSS 利用。
  • Cookie 加 HttpOnly:让 JavaScript 无法读取会话 Cookie,即使 XSS 成功也无法直接窃取会话。

四、MySQL 防止 SQL 注入的几种写法

SQL 注入的根源是将用户输入拼接进 SQL 语句。防御的核心是让数据和指令分离。

1. 参数化查询(首选)

// PDO 预处理
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => $email]);
# Python + MySQL Connector
cursor.execute("SELECT * FROM users WHERE email = %s", (email,))

参数化查询让数据库驱动负责转义和类型处理,是防御 SQL 注入最可靠的方式。

2. 使用 ORM

Laravel 的 Eloquent、Django ORM、SQLAlchemy 等默认使用参数化查询,只要不手写原生 SQL 拼接,基本不会引入注入漏洞。

# Django ORM 自动参数化
User.objects.filter(email=email)

3. 输入验证与白名单

对于无法参数化的场景(如动态表名、排序字段),使用严格白名单:

$allowed = ['name', 'created_at', 'email'];
$orderBy = in_array($_GET['sort'], $allowed) ? $_GET['sort'] : 'name';

4. 最小权限原则

应用连接数据库的账号不应拥有 DROPFILEGRANT 等权限。只授予必要的 SELECTINSERTUPDATEDELETE,并且只限于特定数据库。

5. 额外加固

  • 关闭 local_infile,防止通过 LOAD DATA LOCAL 读取服务器文件。
  • 开启慢查询日志,监测异常查询模式。
  • 使用 WAF(如 ModSecurity)作为补充层,但绝不能替代代码层的参数化查询。

结语

安全加固是一个持续的过程,不是一次性的配置任务。Linux 层控制入口,Nginx 层过滤流量,应用层防御 XSS 和 SQL 注入,数据库层限制权限——每一层都不完美,但叠加起来能大幅提高攻击成本。建议将上述清单转化为自动化脚本或配置管理工具(如 Ansible)中的检查项,定期审计,持续更新。

未经允许不得转载:任鹏个人博客 » 服务器安全加固清单:Linux、Nginx 与 MySQL 实战指南

赞 (0) 打赏

评论 0

取消
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏