Linux 服务器上线前的基础安全加固清单:从 SSH 到 Web 防线

一台 Linux 服务器从购买到正式对外提供服务,中间有一个容易被忽视却至关重要的环节——安全加固。很多运维事故的根源并非复杂的 0day 漏洞,而是基础配置的疏忽:SSH 允许密码登录、数据库端口对公网开放、Web 应用缺乏输入过滤。本文围绕 Linux 服务器上线前的基础安全加固展开,同时延伸讨论 Web 层最常见的两类攻击——XSS 与 SQL 注入——以及对应的防御思路和编码实践。

一、SSH 加固:关闭最容易被爆破的入口

SSH 是服务器管理的生命线,也是攻击者最先扫描的目标。默认配置下,SSH 允许 root 用户通过密码登录,这给了暴力破解工具极大的可乘之机。

核心加固措施:

  • 禁用 root 直接登录:在 /etc/ssh/sshd_config 中设置 PermitRootLogin no,改为使用普通用户登录后再 susudo 提权。
  • 启用密钥认证,关闭密码认证:设置 PasswordAuthentication noPubkeyAuthentication yes。密钥认证的暴力破解难度远高于密码。
  • 修改默认端口:虽然安全界对此有争议,但将 22 端口改为非标准端口可以过滤掉大量自动化扫描。
  • 限制登录来源:通过 AllowUsers 或防火墙规则只允许特定 IP 段访问 SSH。
  • 配置 fail2ban:自动封禁多次登录失败的 IP,有效遏制持续爆破。

修改完配置后,务必先保持当前 SSH 会话不关闭,另开一个终端验证新配置可以正常登录,再重启 sshd 服务。

二、系统层面:最小化攻击面

服务器上运行的服务越多,潜在漏洞就越多。加固的基本原则是“不需要的,就关掉”。

  • 关闭无用服务:检查 systemctl list-unit-filesnetstat -tulnp,停用并禁用不需要的端口监听服务。
  • 防火墙白名单策略:使用 iptables、nftables 或 ufw,默认拒绝所有入站流量,只放行必要的端口(如 80、443、SSH 端口)。数据库端口 3306、Redis 端口 6379 绝不应直接暴露在公网。
  • 及时更新系统补丁:配置 unattended-upgrades 或定期手动执行 apt upgrade / yum update,修补已知内核和软件漏洞。
  • 账号与权限管理:删除或锁定不必要的默认账号,确保每个服务使用独立的低权限系统用户运行,避免一个服务被攻破后波及全局。

三、Web 层防线:XSS 与 SQL 注入的防御

服务器加固解决了“门锁”问题,但 Web 应用本身的漏洞才是攻击者最常利用的通道。以下聚焦两类最典型的 Web 攻击。

XSS 的常见方式与前端防御

XSS(跨站脚本攻击)的本质是攻击者将恶意脚本注入到网页中,当其他用户浏览该页面时脚本在其浏览器中执行。常见方式包括:

  • 反射型 XSS:恶意脚本作为请求参数发送给服务器,服务器未经处理直接“反射”回页面。典型场景是搜索框、错误提示页。
  • 存储型 XSS:恶意内容被存入数据库(如评论、用户昵称),所有访问该页面的用户都会触发。危害最大。
  • DOM 型 XSS:完全在前端发生,JavaScript 从 location.hashdocument.URL 等来源读取数据并直接插入 DOM,不经过服务器。

前端防御的核心原则是“永远不信任用户输入”:

  1. 输出编码:根据输出位置(HTML 正文、属性、URL、JavaScript)使用对应的编码方式。例如在 HTML 中,将 < 转为 &lt;> 转为 &gt;。现代前端框架如 React、Vue 默认对插值进行转义,但 dangerouslySetInnerHTMLv-html 会绕过保护,需格外谨慎。
  2. 使用 CSP(内容安全策略):通过 HTTP 头 Content-Security-Policy 限制脚本来源,禁止内联脚本执行,即使注入成功也难以运行。
  3. 输入验证与过滤:对用户输入做白名单校验,但过滤不能替代输出编码。
  4. Cookie 设置 HttpOnly:防止 JavaScript 通过 document.cookie 读取会话凭证,降低 XSS 得手后的危害。

MySQL 防止 SQL 注入的几种写法

SQL 注入的根源是将用户输入拼接进 SQL 语句。以下是几种安全的写法,按推荐程度排列:

1. 预处理语句(Prepared Statements)——首选方案

$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ? AND status = ?");
$stmt->execute([$email, $status]);

参数与 SQL 结构分离,数据库先编译语句模板,再传入数据,从根本上杜绝注入。Java 的 PreparedStatement、Python 的 cursor.execute(sql, params) 同理。

2. 使用 ORM 框架的参数绑定

Laravel 的 Eloquent、Django ORM、Hibernate 等框架默认使用参数绑定,只要不手动拼接原生 SQL,安全性有保障。

3. 存储过程(需注意内部实现)

存储过程本身不天然防注入,如果内部仍用 CONCAT 拼接参数,同样存在风险。只有在存储过程内部也使用参数化查询时才安全。

4. 最小权限原则

为 Web 应用连接数据库的账号只授予必要的权限(如只读账号不给 DELETE、DROP),即使注入成功,攻击者能造成的破坏也有限。

需要避免的错误写法:

// 危险:直接拼接
$sql = "SELECT * FROM users WHERE id = " . $_GET['id'];
// 危险:手动转义不完整
$sql = "SELECT * FROM users WHERE name = '" . addslashes($name) . "'";

addslashes 在特定字符集下仍可被绕过,不应作为主要防御手段。

四、上线前的检查清单

将以上内容汇总为一份可执行的清单:

  • SSH 禁用 root 登录、禁用密码认证、启用密钥
  • 配置防火墙,仅开放必要端口
  • 数据库、Redis 等中间件不暴露公网
  • 系统补丁已更新,无用服务已关闭
  • Web 应用所有输出点已做编码处理
  • 配置了合理的 CSP 响应头
  • 所有 SQL 查询使用参数化写法
  • 数据库账号遵循最小权限原则
  • 部署了 fail2ban 或类似入侵检测工具
  • 日志记录与监控已就位

安全加固不是一次性的任务,而是持续的过程。上线前的这轮基础加固能挡掉绝大多数自动化攻击和低水平入侵,为后续更精细的安全运营争取时间和空间。

未经允许不得转载:任鹏个人博客 » Linux 服务器上线前的基础安全加固清单:从 SSH 到 Web 防线

赞 (0) 打赏

评论 0

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

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

支付宝扫一扫打赏

微信扫一扫打赏