拿到一台全新的Ubuntu服务器,默认配置在公网上裸奔,无异于把家门钥匙挂在门把手上。22端口被扫、root账户被暴力破解,这些都是分分钟会发生的事。安全加固不是可选项,而是上线前的必做动作。下面这套流程,从基础到进阶,每一步都直接告诉你该敲什么命令、改什么配置,照着做就能把一台“毛坯房”变成“安全屋”。

第一步:系统更新与自动安全补丁

系统漏洞是最大的攻击面。拿到服务器的第一件事,就是打上所有补丁,并开启自动安全更新。别相信自己的记忆力,让系统自己处理关键补丁。

先手动更新现有包列表并升级:

sudo apt update && sudo apt upgrade -y

如果内核升级了,重启一下让新内核生效:

sudo reboot

接下来配置无人值守的安全更新。安装 unattended-upgrades 包:

sudo apt install unattended-upgrades -y

启用自动更新,选择“Yes”:

sudo dpkg-reconfigure --priority=low unattended-upgrades

更精细的控制需要编辑配置文件。打开 /etc/apt/apt.conf.d/50unattended-upgrades,确保安全更新源没有被注释。通常只需要把 security 那一行的注释去掉。同时建议开启自动清理旧内核,防止 /boot 分区被塞满。找到 Unattended-Upgrade::Remove-Unused-Kernel-Packages 和 Unattended-Upgrade::Remove-New-Unused-Dependencies 这两项,都设为 true。最后,通过修改 /etc/apt/apt.conf.d/20auto-upgrades 文件,可以设置更新周期,内容如下:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";

这样系统每天都会检查并安装安全更新,省心又安全。

用户与权限管理:告别root登录

root用户权限过大,一旦被破解,整个系统就沦陷了。必须禁止root直接SSH登录,并创建一个普通用户来执行日常管理任务,通过sudo提权。

如果你还没创建普通用户,现在创建:

sudo adduser your_new_username

系统会提示设置密码和其他信息,密码务必复杂。接着把该用户加入sudo组:

sudo usermod -aG sudo your_new_username

验证一下新用户能否正常使用sudo。用新用户登录后,执行以下命令,如果能返回root权限的列表,就说明成功了:

sudo -l

现在禁止root SSH登录。编辑SSH配置文件:

sudo nano /etc/ssh/sshd_config

找到 PermitRootLogin 这一行,把值改为 no。如果前面有 # 号,先删除 # 号取消注释。同时,为了进一步限制爆破,可以顺便把密码登录也禁掉,只允许密钥登录。找到 PasswordAuthentication,设为 no。修改后的关键配置如下:

PermitRootLogin no
PasswordAuthentication no

保存文件后,重启SSH服务使配置生效:

sudo systemctl restart sshd

千万别急着关掉当前的root会话窗口。另开一个新终端,用新用户测试能否成功登录并执行sudo命令。确认无误后,再关闭root会话。这一步出错就只能进VNC救援了。

SSH安全加固:换个门牌号并配上钥匙

默认的22端口是自动化扫描脚本的最爱。把SSH端口改成一个高位端口,能过滤掉90%以上的噪音攻击。同时,强制使用密钥对登录,从根本上杜绝密码爆破。

先在本地电脑生成SSH密钥对(如果已有可跳过):

ssh-keygen -t ed25519 -C "your_email@example.com"

ed25519算法比RSA更安全、更快。生成后,把公钥复制到服务器。在本地终端执行:

ssh-copy-id -i ~/.ssh/id_ed25519.pub your_new_username@your_server_ip

这会自动把公钥追加到服务器的 ~/.ssh/authorized_keys 文件中,并设置好正确的权限。现在用密钥登录测试一下,应该不需要输入密码了。

确认密钥登录没问题后,修改SSH端口。再次编辑 /etc/ssh/sshd_config:

sudo nano /etc/ssh/sshd_config

找到 #Port 22,去掉注释,把22改成一个你记得住的、介于1024到65535之间的端口号,比如 49221。同时,确保 PubkeyAuthentication 设为 yes,ChallengeResponseAuthentication 和 UsePAM 中的密码认证相关选项都已禁用。一个强化的SSH配置片段如下:

Port 49221
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
UsePAM yes
AllowUsers your_new_username

AllowUsers 这一行是白名单机制,只有列出的用户才能SSH登录,这是最后一道防线。修改完保存,重启SSH服务:

sudo systemctl restart sshd

同样,不要关闭当前窗口,另开终端用新端口和密钥测试连接:

ssh -p 49221 your_new_username@your_server_ip

成功后,你的SSH服务已经相当坚固了。

配置防火墙:打造精准的流量过滤网

Ubuntu默认的防火墙工具是ufw,它简化了iptables的复杂操作。原则是“默认拒绝所有入站,只放行必要服务”。

先设置默认策略:

sudo ufw default deny incoming
sudo ufw default allow outgoing

然后放行你需要的服务。用你自定义的SSH端口替换下面的数字,千万别直接放行22,否则端口改了等于没改:

sudo ufw allow 49221/tcp

如果你运行了Web服务,还需要放行HTTP和HTTPS:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

检查一下规则列表,确认无误:

sudo ufw show added

最后启用防火墙:

sudo ufw enable

系统会提示可能中断当前连接,因为我们已经把新SSH端口加入了白名单,所以输入 y 确认即可。用 sudo ufw status verbose 可以随时查看详细的运行状态和规则编号。

入侵防御:用Fail2ban挡住暴力破解

防火墙设好了,但那些对着SSH端口不断尝试的机器人怎么办?Fail2ban会监控日志,一旦某个IP在短时间内多次认证失败,就自动用防火墙把它临时或永久封禁。

安装Fail2ban:

sudo apt install fail2ban -y

Fail2ban的默认配置可能会监听过时的端口,我们需要为它创建一个本地配置来适应我们的自定义SSH端口。复制默认的jail配置文件:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

编辑这个本地文件:

sudo nano /etc/fail2ban/jail.local

找到 [sshd] 部分,修改或添加 port 参数为你自定义的端口。同时可以设置封禁时间和重试次数。一个典型的配置如下:

[sshd]
enabled = true
port = 49221
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600

这段配置的意思是:在600秒内,如果有IP对端口49221尝试SSH登录失败3次,就封禁该IP 3600秒(1小时)。保存后,启动并设置开机自启:

sudo systemctl enable fail2ban
sudo systemctl start fail2ban

用 sudo fail2ban-client status sshd 可以查看SSH监狱的拦截情况,看到当前封禁的IP列表会让你很有安全感。

系统审计与高级访问控制

基础防护做完,还需要一双眼睛盯着系统内部的一举一动。auditd是Linux内核级的审计系统,能记录文件访问、系统调用等底层事件。而AppArmor是Ubuntu自带的强制访问控制系统,能为程序划定能力边界。

安装并启用auditd:

sudo apt install auditd -y
sudo systemctl enable auditd
sudo systemctl start auditd

一个非常实用的审计规则是监控 /etc/passwd 和 /etc/shadow 的写入事件,这通常是攻击者添加后门账户的迹象。添加规则:

sudo auditctl -w /etc/passwd -p wa -k passwd_changes
sudo auditctl -w /etc/shadow -p wa -k shadow_changes

为了让规则永久生效,需要写入规则文件:

sudo nano /etc/audit/rules.d/audit.rules

在文件中加入:

-w /etc/passwd -p wa -k passwd_changes
-w /etc/shadow -p wa -k shadow_changes

重启auditd服务。之后可以用 ausearch -k passwd_changes 命令来查询相关审计日志。

AppArmor的配置通常不需要从零开始写。先查看当前各进程的强制模式:

sudo aa-status

你会看到很多服务已经处于“enforce”模式。对于未受约束但暴露在外的服务,可以考虑为其生成或编写AppArmor配置文件。例如,一个自定义的Web应用,可以用 aa-genprof 工具来辅助生成配置,它会分析程序运行时的行为,让你选择允许或拒绝。这属于进阶操作,但即使只保持默认启用的AppArmor策略,也已经能有效限制很多常见服务的文件访问范围了。

文件完整性监控与日志管理

再坚固的防线也可能被突破,因此需要一套机制来及时发现入侵。AIDE(高级入侵检测环境)能对系统关键文件做哈希快照,任何篡改都会在比对时暴露。

安装AIDE:

sudo apt install aide -y

初始化数据库,这会为所有监控的文件生成基准哈希值:

sudo aideinit

这个过程需要几分钟。完成后,初始数据库会被复制到正式库中:

sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db

之后,定期运行检查命令,就能发现文件变动:

sudo aide.wrapper --check

可以把这个检查命令加入crontab,比如每天凌晨4点运行一次,并将结果发送到你的邮箱。编辑crontab:

sudo crontab -e

加入一行:

0 4 * * * /usr/bin/aide.wrapper --check | mail -s "AIDE Report for $(hostname)" your_email@example.com

日志是追溯攻击路径的唯一线索。确保 rsyslog 服务正常运行:

sudo systemctl status rsyslog

更推荐的做法是部署一个集中式日志收集工具,比如用rsyslog将日志远程转发到一台专门的日志服务器,防止攻击者在拿到root权限后清理本地日志。在 /etc/rsyslog.d/ 下创建一个转发配置,将所有日志通过TCP发送出去:

*.* @@remote_log_server_ip:514

这确保了即使服务器被完全控制,操作痕迹依然保留在远程日志系统中。

内核参数与网络层安全调优

最后,深入到内核参数,从网络栈层面强化抗攻击能力。编辑 /etc/sysctl.conf 文件,加入或修改以下参数:

# 开启TCP SYN Cookie保护,防御SYN Flood攻击
net.ipv4.tcp_syncookies = 1

# 禁用IP源路由,防止攻击者指定数据包路由
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0

# 开启反向路径过滤,防止IP欺骗
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# 忽略所有ICMP重定向
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0

# 不发送ICMP重定向
net.ipv4.conf.all.send_redirects = 0

# 记录可疑数据包(如火星地址)
net.ipv4.conf.all.log_martians = 1

保存后,用以下命令立即应用所有设置,无需重启:

sudo sysctl -p

这套组合拳打下来,你的Ubuntu服务器已经从一个脆弱的目标,变成了一个让攻击者头疼的硬骨头。安全是一个持续的过程,不是一次性项目。定期查看日志、保持更新习惯、遵循最小权限原则,这些动作需要融入日常运维中。现在,你可以稍微松口气,但保持警惕永远是正确的。