一台 Linux 服务器从购买到正式对外提供服务,中间有一个容易被忽视却至关重要的环节——安全加固。很多运维事故的根源并非复杂的 0day 漏洞,而是基础配置的疏忽:SSH 允许密码登录、数据库端口对公网开放、Web 应用缺乏输入过滤。本文围绕 Linux 服务器上线前的基础安全加固展开,同时延伸讨论 Web 层最常见的两类攻击——XSS 与 SQL 注入——以及对应的防御思路和编码实践。
一、SSH 加固:关闭最容易被爆破的入口
SSH 是服务器管理的生命线,也是攻击者最先扫描的目标。默认配置下,SSH 允许 root 用户通过密码登录,这给了暴力破解工具极大的可乘之机。
核心加固措施:
- 禁用 root 直接登录:在
/etc/ssh/sshd_config中设置PermitRootLogin no,改为使用普通用户登录后再su或sudo提权。 - 启用密钥认证,关闭密码认证:设置
PasswordAuthentication no和PubkeyAuthentication yes。密钥认证的暴力破解难度远高于密码。 - 修改默认端口:虽然安全界对此有争议,但将 22 端口改为非标准端口可以过滤掉大量自动化扫描。
- 限制登录来源:通过
AllowUsers或防火墙规则只允许特定 IP 段访问 SSH。 - 配置 fail2ban:自动封禁多次登录失败的 IP,有效遏制持续爆破。
修改完配置后,务必先保持当前 SSH 会话不关闭,另开一个终端验证新配置可以正常登录,再重启 sshd 服务。
二、系统层面:最小化攻击面
服务器上运行的服务越多,潜在漏洞就越多。加固的基本原则是“不需要的,就关掉”。
- 关闭无用服务:检查
systemctl list-unit-files和netstat -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.hash、document.URL等来源读取数据并直接插入 DOM,不经过服务器。
前端防御的核心原则是“永远不信任用户输入”:
- 输出编码:根据输出位置(HTML 正文、属性、URL、JavaScript)使用对应的编码方式。例如在 HTML 中,将
<转为<,>转为>。现代前端框架如 React、Vue 默认对插值进行转义,但dangerouslySetInnerHTML和v-html会绕过保护,需格外谨慎。 - 使用 CSP(内容安全策略):通过 HTTP 头
Content-Security-Policy限制脚本来源,禁止内联脚本执行,即使注入成功也难以运行。 - 输入验证与过滤:对用户输入做白名单校验,但过滤不能替代输出编码。
- 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 防线


朋友圈点赞图在线生成源码