一、概述
1.1 背景介绍
在互联网环境中,服务器每天都面临着各种安全威胁。某天凌晨,你可能会收到告警:服务器遭受SSH暴力破解攻击,短短几分钟内就有上千次登录尝试;或者发现某个Web应用被入侵,攻击者通过漏洞获取了root权限,植入了挖矿程序。这些安全事件不仅会影响业务正常运行,还可能导致数据泄露、经济损失,甚至法律责任。
安全加固不是一次性的工作,而是一个持续的过程。很多运维工程师在服务器上线时,往往只做了最基础的配置,比如改个SSH端口、设置个防火墙规则,就认为安全工作完成了。实际上,这远远不够。攻击者的手段在不断进化,从简单的密码爆破,到利用0day漏洞,再到社会工程学攻击,防不胜防。
本文将从实战角度出发,介绍Linux服务器安全加固的核心技术:SSH安全配置、防火墙规则管理、用户权限控制。这些技术经过大量生产环境验证,能够有效抵御90%以上的常见攻击。更重要的是,这些加固措施不会对正常业务造成影响,可以放心在生产环境中实施。
1.2 技术特点
纵深防御策略:不依赖单一防护手段,而是构建多层防御体系。即使某一层被突破,其他层仍能提供保护。SSH层面限制登录方式和来源,防火墙层面控制网络访问,权限层面实施最小权限原则,三者相互配合,形成完整的安全防护网。
实用性与安全性平衡:安全加固不能影响正常运维工作。本文介绍的方法都经过实践验证,既能有效提升安全性,又不会给日常运维带来过多负担。比如,使用密钥认证替代密码登录,既更安全又更方便;配置sudo权限,既限制了root直接登录,又保证了管理员能够执行必要的操作。
可审计可追溯:所有的安全配置都会产生日志,便于事后审计和问题排查。通过分析登录日志、sudo日志、防火墙日志,可以及时发现异常行为,追溯安全事件的来龙去脉。这对于满足合规要求和安全事件响应都非常重要。
1.3 适用场景
场景一:电商平台Web服务器防护电商平台的Web服务器是攻击者的重点目标,因为这里存储着大量用户数据和交易信息。常见的攻击手段包括:SSH暴力破解、Web应用漏洞利用、DDoS攻击等。安全加固的重点是:禁用密码登录,只允许密钥认证;配置防火墙只开放必要端口(80、443);使用fail2ban自动封禁暴力破解IP;配置应用用户权限,避免使用root运行Web服务。通过这些措施,可以大幅降低被入侵的风险。
场景二:API服务器访问控制API服务器通常需要对外提供服务,但又不能完全开放。典型的需求是:只允许特定IP访问SSH;API接口只对合作伙伴开放;限制单个IP的请求频率,防止恶意调用。安全加固的重点是:使用防火墙白名单机制,只允许可信IP访问SSH;配置应用层防火墙(如nginx的limit_req模块)限制API调用频率;使用iptables的recent模块实现动态限流;配置详细的访问日志,便于审计和问题排查。
场景三:数据库服务器隔离防护数据库服务器存储着核心业务数据,安全要求最高。通常部署在内网,不直接对外提供服务。安全加固的重点是:完全禁止外网访问,只允许应用服务器连接;SSH只允许跳板机访问;数据库用户权限严格控制,应用只能访问特定数据库;启用审计日志,记录所有数据库操作;定期备份,防止数据丢失。通过网络隔离+访问控制+审计日志的组合,确保数据库安全。
1.4 环境要求
| | |
|---|
| CentOS 7+/Ubuntu 18.04+/Debian 10+ | |
| | |
| | |
| | |
| | |
二、详细步骤
2.1 SSH安全加固
2.1.1 生成和配置SSH密钥
密钥认证比密码认证安全得多,密钥长度通常是2048位或4096位,暴力破解几乎不可能。
在本地生成SSH密钥:
# 生成RSA密钥对(推荐4096位)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# 或者生成更安全的ED25519密钥
ssh-keygen -t ed25519 -C "your_email@example.com"
# 按提示操作:
# 1. 指定密钥保存位置(默认~/.ssh/id_rsa)
# 2. 设置密钥密码(可选,但建议设置)
将公钥上传到服务器:
# 方法一:使用ssh-copy-id(推荐)
ssh-copy-id -i ~/.ssh/id_rsa.pub user@server_ip
# 方法二:手动复制
cat ~/.ssh/id_rsa.pub | ssh user@server_ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# 方法三:直接在服务器上操作
# 登录服务器后执行:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
vim ~/.ssh/authorized_keys # 粘贴公钥内容
chmod 600 ~/.ssh/authorized_keys
验证密钥登录:
# 测试密钥登录
ssh -i ~/.ssh/id_rsa user@server_ip
# 如果能成功登录,说明密钥配置正确
2.1.2 修改SSH配置文件
配置SSH服务器,禁用不安全的登录方式。
# 备份原配置文件
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# 编辑配置文件
sudo vim /etc/ssh/sshd_config
关键配置项:
# 修改SSH端口(避免自动化扫描)
Port 22022
# 禁止root直接登录
PermitRootLogin no
# 禁用密码认证,只允许密钥登录
PasswordAuthentication no
PubkeyAuthentication yes
# 禁用空密码登录
PermitEmptyPasswords no
# 禁用基于主机的认证
HostbasedAuthentication no
# 限制登录用户(可选)
AllowUsers deploy admin
# 设置登录超时时间
LoginGraceTime 60
# 限制最大认证尝试次数
MaxAuthTries 3
# 禁用X11转发(如果不需要)
X11Forwarding no
# 启用严格模式(检查文件权限)
StrictModes yes
# 设置日志级别
LogLevel VERBOSE
重启SSH服务:
# 先测试配置文件语法
sudo sshd -t
# 如果没有错误,重启SSH服务
sudo systemctl restart sshd
# 重要:重启前保持当前SSH连接,新开一个终端测试
# 确保能正常登录后再关闭旧连接
实战经验:修改SSH端口后,防火墙规则也要相应调整。建议先在防火墙中开放新端口,测试成功后再关闭22端口,避免把自己锁在外面。
2.1.3 配置fail2ban防暴力破解
fail2ban可以自动监控日志,发现暴力破解行为后自动封禁IP。
安装fail2ban:
# Ubuntu/Debian
sudo apt update
sudo apt install -y fail2ban
# CentOS/RHEL
sudo yum install -y epel-release
sudo yum install -y fail2ban
# 启动服务
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
配置fail2ban:
# 创建本地配置文件
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo vim /etc/fail2ban/jail.local
关键配置:
[DEFAULT]
# 封禁时间(秒),默认10分钟
bantime = 3600
# 查找时间窗口(秒)
findtime = 600
# 在findtime内失败maxretry次就封禁
maxretry = 3
# 忽略的IP(白名单)
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
[sshd]
enabled = true
port = 22022
logpath = /var/log/auth.log
maxretry = 3
bantime = 7200
验证fail2ban运行状态:
# 查看fail2ban状态
sudo systemctl status fail2ban
# 查看SSH监控状态
sudo fail2ban-client status sshd
# 查看被封禁的IP
sudo fail2ban-client get sshd banned
2.2 防火墙配置
2.2.1 使用iptables配置防火墙
iptables是Linux最常用的防火墙工具,功能强大且灵活。
基础防火墙规则:
# 清空现有规则(谨慎操作)
sudo iptables -F
sudo iptables -X
# 设置默认策略(默认拒绝所有)
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
# 允许本地回环
sudo iptables -A INPUT -i lo -j ACCEPT
# 允许已建立的连接
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许SSH(注意端口号)
sudo iptables -A INPUT -p tcp --dport 22022 -j ACCEPT
# 允许HTTP和HTTPS
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 允许ping(可选)
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# 保存规则
sudo iptables-save > /etc/iptables/rules.v4
限制SSH访问来源:
# 只允许特定IP访问SSH
sudo iptables -A INPUT -p tcp -s 192.168.1.100 --dport 22022 -j ACCEPT
sudo iptables -A INPUT -p tcp -s 10.0.0.0/8 --dport 22022 -j ACCEPT
# 拒绝其他IP的SSH访问
sudo iptables -A INPUT -p tcp --dport 22022 -j DROP
防止SYN flood攻击:
# 限制SYN包速率
sudo iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
sudo iptables -A INPUT -p tcp --syn -j DROP
2.2.2 使用firewalld配置防火墙(CentOS/RHEL)
firewalld是CentOS 7+的默认防火墙工具,比iptables更易用。
# 启动firewalld
sudo systemctl start firewalld
sudo systemctl enable firewalld
# 查看当前状态
sudo firewall-cmd --state
# 查看默认区域
sudo firewall-cmd --get-default-zone
# 查看活动区域
sudo firewall-cmd --get-active-zones
配置防火墙规则:
# 添加服务
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
# 添加自定义端口
sudo firewall-cmd --permanent --add-port=22022/tcp
# 删除默认SSH端口
sudo firewall-cmd --permanent --remove-service=ssh
# 限制SSH访问来源
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="22022" protocol="tcp" accept'
# 重载配置
sudo firewall-cmd --reload
# 查看所有规则
sudo firewall-cmd --list-all
2.3 用户权限管理
2.3.1 创建普通用户并配置sudo权限
避免直接使用root账户,通过sudo授予必要的管理权限。
创建用户:
# 创建新用户
sudo useradd -m -s /bin/bash deploy
# 设置密码
sudo passwd deploy
# 或者创建用户时指定更多信息
sudo useradd -m -s /bin/bash -c "Deploy User" -G wheel deploy
配置sudo权限:
# 编辑sudoers文件(推荐使用visudo)
sudo visudo
# 或者创建独立的配置文件
sudo vim /etc/sudoers.d/deploy
sudo配置示例:
# 允许用户执行所有命令(需要密码)
deploy ALL=(ALL:ALL) ALL
# 允许用户执行所有命令(无需密码,不推荐)
deploy ALL=(ALL:ALL) NOPASSWD: ALL
# 只允许特定命令
deploy ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx
# 允许用户组
%admin ALL=(ALL:ALL) ALL
验证sudo权限:
# 切换到新用户
su - deploy
# 测试sudo权限
sudo whoami # 应该输出root
2.3.2 配置密码策略
强制使用强密码,定期更换密码。
安装密码质量检查工具:
# Ubuntu/Debian
sudo apt install -y libpam-pwquality
# CentOS/RHEL
sudo yum install -y libpwquality
配置密码策略:
# 编辑PAM配置
sudo vim /etc/security/pwquality.conf
密码策略配置:
# 最小密码长度
minlen = 12
# 至少包含一个小写字母
lcredit = -1
# 至少包含一个大写字母
ucredit = -1
# 至少包含一个数字
dcredit = -1
# 至少包含一个特殊字符
ocredit = -1
# 新密码中至少有3个字符与旧密码不同
difok = 3
# 密码不能包含用户名
usercheck = 1
配置密码过期策略:
# 编辑登录配置
sudo vim /etc/login.defs
# 密码最长使用天数
PASS_MAX_DAYS 90
# 密码最短使用天数
PASS_MIN_DAYS 7
# 密码过期前警告天数
PASS_WARN_AGE 14
三、示例代码和配置
3.1 安全加固一键脚本
#!/bin/bash
# 文件名:security_hardening.sh
# 功能:Linux服务器安全加固自动化脚本
set -e
echo"========================================="
echo"Linux服务器安全加固脚本"
echo"时间:$(date '+%Y-%m-%d %H:%M:%S')"
echo"========================================="
# 1. 备份重要配置文件
echo"[1/6] 备份配置文件..."
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d)
sudo cp /etc/sudoers /etc/sudoers.bak.$(date +%Y%m%d)
# 2. 配置SSH安全
echo"[2/6] 配置SSH安全..."
sudo sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sudo sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/^#*Port.*/Port 22022/' /etc/ssh/sshd_config
# 3. 安装fail2ban
echo"[3/6] 安装fail2ban..."
ifcommand -v apt &> /dev/null; then
sudo apt update && sudo apt install -y fail2ban
elifcommand -v yum &> /dev/null; then
sudo yum install -y epel-release && sudo yum install -y fail2ban
fi
# 4. 配置防火墙
echo"[4/6] 配置防火墙..."
ifcommand -v firewall-cmd &> /dev/null; then
sudo firewall-cmd --permanent --add-port=22022/tcp
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
else
sudo iptables -A INPUT -p tcp --dport 22022 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
fi
# 5. 配置密码策略
echo"[5/6] 配置密码策略..."
sudo sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs
sudo sed -i 's/^PASS_MIN_DAYS.*/PASS_MIN_DAYS 7/' /etc/login.defs
# 6. 重启服务
echo"[6/6] 重启相关服务..."
sudo systemctl restart sshd
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
echo"========================================="
echo"安全加固完成!"
echo"注意:SSH端口已改为22022"
echo"请确保防火墙已开放该端口"
echo"========================================="
3.2 实际应用案例
案例一:电商平台SSH暴力破解防护
场景描述:某电商平台的Web服务器,运维人员发现auth.log中有大量失败的SSH登录尝试,来自全球各地的IP,每分钟数千次,典型的暴力破解攻击。
诊断过程:
# 查看失败的登录尝试
sudo grep "Failed password" /var/log/auth.log | tail -20
# 统计攻击来源IP
sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
# 输出示例:
# 1523 185.220.101.45
# 892 103.99.0.122
# 654 198.98.51.189
解决方案:
# 1. 立即配置fail2ban
sudo apt install -y fail2ban
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
# 2. 配置更严格的封禁策略
sudo vim /etc/fail2ban/jail.local
# [sshd]
# enabled = true
# maxretry = 3
# bantime = 86400 # 封禁24小时
# findtime = 600
# 3. 禁用密码登录
sudo vim /etc/ssh/sshd_config
# PasswordAuthentication no
# 4. 重启SSH服务
sudo systemctl restart sshd
# 5. 验证效果
sudo fail2ban-client status sshd
优化效果:
四、最佳实践和注意事项
4.1 最佳实践
4.1.1 SSH安全最佳实践
使用密钥认证:
限制访问来源:
# 在sshd_config中限制允许登录的用户
AllowUsers deploy@192.168.1.* admin@10.0.0.*
# 或者使用防火墙限制
sudo iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 22022 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22022 -j DROP
启用双因素认证(可选):
# 安装Google Authenticator
sudo apt install -y libpam-google-authenticator
# 配置PAM
sudo vim /etc/pam.d/sshd
# 添加:auth required pam_google_authenticator.so
# 配置SSH
sudo vim /etc/ssh/sshd_config
# ChallengeResponseAuthentication yes
4.1.2 防火墙最佳实践
默认拒绝策略:
分层防护:
# 网络层:限制IP访问
sudo iptables -A INPUT -s 10.0.0.0/8 -j ACCEPT
# 传输层:限制端口访问
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 应用层:使用nginx限流
# limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
日志和监控:
# 启用防火墙日志
sudo iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: "
# 查看被拒绝的连接
sudo tail -f /var/log/syslog | grep "IPTables-Dropped"
4.2 注意事项
4.2.1 配置变更注意事项
修改SSH配置前的准备:
防火墙配置注意事项:
- 使用
iptables-save保存规则,避免重启后丢失
4.2.2 常见错误
| | |
|---|
| | |
| | chmod 600 ~/.ssh/authorized_keys |
| | |
| | |
| | |
五、故障排查和监控
5.1 安全日志分析
SSH登录日志:
# 查看成功的登录
sudo grep "Accepted" /var/log/auth.log
# 查看失败的登录
sudo grep "Failed" /var/log/auth.log
# 统计登录尝试最多的IP
sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
sudo操作日志:
# 查看sudo操作记录
sudo grep "sudo" /var/log/auth.log
# 查看特定用户的sudo操作
sudo grep "sudo.*deploy" /var/log/auth.log
防火墙日志:
# 查看被拒绝的连接
sudo grep "DPT" /var/log/syslog | tail -20
# 统计被拒绝最多的源IP
sudo grep "SRC" /var/log/syslog | awk '{print $9}' | cut -d= -f2 | sort | uniq -c | sort -rn | head -10
5.2 安全监控指标
建议监控的关键安全指标:
六、总结
6.1 技术要点回顾
- SSH安全核心:禁用密码登录,使用密钥认证;修改默认端口;配置fail2ban自动封禁;限制登录用户和来源IP
- 防火墙配置核心:采用默认拒绝策略;只开放必要端口;使用白名单限制访问来源;启用日志记录
- 权限管理核心:禁止root直接登录;使用sudo授权;配置强密码策略;实施最小权限原则;启用操作审计
6.2 进阶学习方向
6.3 参考资料
- NIST Cybersecurity Framework - 网络安全框架
- Linux Security - Linux内核安全文档
附录
A. 安全检查清单
# SSH安全检查
□ 已禁用root登录
□ 已禁用密码认证
□ 已修改默认端口
□ 已配置fail2ban
□ 已限制登录用户
# 防火墙检查
□ 已启用防火墙
□ 已配置默认拒绝策略
□ 只开放必要端口
□ 已配置访问来源限制
# 用户权限检查
□ 已创建普通管理员账户
□ 已配置sudo权限
□ 已设置密码策略
□ 已启用操作审计
# 日志监控检查
□ 已配置日志记录
□ 已设置日志轮转
□ 已配置安全告警
B. 常用安全命令
# 查看当前登录用户
w
who
# 查看登录历史
last
lastb # 失败的登录
# 查看用户列表
cat /etc/passwd
# 查看sudo权限
sudo -l
# 查看开放端口
sudo netstat -tulnp
sudo ss -tulnp
# 查看防火墙规则
sudo iptables -L -n -v
sudo firewall-cmd --list-all
# 查看fail2ban状态
sudo fail2ban-client status
C. 术语表
| | |
|---|
| | |
| | |
| | |
| | |
| | |
| | |
| Two-Factor Authentication | |