拿到一台全新的Ubuntu云服务器,默认状态下的安全防护几乎等于裸奔。最常见的攻击不是针对你个人,而是自动化扫描脚本在互联网上地毯式搜索弱口令和漏洞。不做任何加固直接部署业务,快则几分钟,慢则几小时,就会被植入挖矿木马或被当成跳板。下面这份清单按照操作优先级排列,每一条都是实战中验证过的必要步骤。
锁定SSH访问:改端口只是第一步默认的22端口是扫描器重点关照对象。修改SSH端口能过滤掉90%以上的自动化攻击噪音,但这只是障眼法,核心在于密钥认证和权限控制。先别急着改端口,确保密钥登录可用,否则把自己锁在服务器外面就麻烦了。
在本地生成密钥对:
ssh-keygen -t ed25519 -C "your-server-name"
将公钥上传到服务器:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your-server-ip
确认密钥可以正常登录后,编辑SSH配置文件:
sudo nano /etc/ssh/sshd_config
修改以下关键参数。Port改为一个高位端口号,比如22222或更高,避免与其他服务冲突。PermitRootLogin设为no,禁止root直接登录,这是最基础也是最重要的防线。PasswordAuthentication设为no,彻底关闭密码认证,只允许密钥登录。PubkeyAuthentication设为yes,确保密钥认证开启。AuthorizedKeysFile指向正确的公钥存储位置。AllowUsers指定仅允许特定用户登录,这是白名单机制,比黑名单安全得多。
修改完成后重启SSH服务:
sudo systemctl restart sshd
保持当前终端窗口不要断开,另开一个新终端测试新端口和密钥是否能正常登录。确认无误后再关闭旧连接。如果出现问题,旧窗口还保留着会话可以回滚配置。
防火墙策略:从零信任开始构建Ubuntu默认的ufw工具本质上是iptables的友好封装。原则很简单:先拒绝所有入站流量,再按需开放端口。这比默认允许再逐个封禁要安全得多。
sudo ufw default deny incoming sudo ufw default allow outgoing
开放修改后的SSH端口:
sudo ufw allow 22222/tcp
如果运行Web服务,开放HTTP和HTTPS:
sudo ufw allow 80/tcp sudo ufw allow 443/tcp
确认规则无误后启用防火墙:
sudo ufw enable
用sudo ufw status verbose查看当前规则列表,确保每个开放的端口都有明确用途。生产环境里每多开一个端口,就多一个潜在攻击面。定期审查规则,关掉不再使用的端口。
系统更新自动化与内核安全刚上线的系统可能存在已知漏洞,第一时间更新所有软件包:
sudo apt update && sudo apt upgrade -y
建议安装无人值守更新,让安全补丁自动安装,避免人为遗忘:
sudo apt install unattended-upgrades sudo dpkg-reconfigure --priority=low unattended-upgrades
编辑/etc/apt/apt.conf.d/50unattended-upgrades,确认安全更新源已启用。重点勾选“${distro_id}:${distro_codename}-security”这一行。可以设置自动清理旧内核,防止/boot分区被占满。
内核参数也需要调优。编辑/etc/sysctl.conf或创建/etc/sysctl.d/99-security.conf,加入以下内容:
# 防止SYN洪水攻击 net.ipv4.tcp_syncookies = 1 # 禁止IP源路由 net.ipv4.conf.all.accept_source_route = 0 # 忽略ICMP重定向 net.ipv4.conf.all.accept_redirects = 0 # 启用反向路径过滤 net.ipv4.conf.all.rp_filter = 1
执行sudo sysctl -p使其生效。这些参数能防御常见的网络层攻击手法。
用户权限与审计体系创建一个普通用户用于日常操作,而不是直接用root。这个用户需要sudo权限来执行管理命令:
sudo adduser yourusername sudo usermod -aG sudo yourusername
检查/etc/sudoers文件,确保只有必要的用户拥有sudo权限。可以用visudo命令安全地编辑该文件。建议开启sudo操作日志记录,在/etc/sudoers中添加:
Defaults logfile="/var/log/sudo.log"
这样每次sudo操作都会被记录下来,事后审计有据可查。
检查系统中是否存在无密码的用户账户:
sudo awk -F: '($2 == "") {print $1}' /etc/shadow
如果有输出,说明存在空密码账户,必须立即设置密码或禁用该账户。
Fail2ban:动态防御的必备工具防火墙是静态规则,Fail2ban提供动态响应能力。它监控日志文件,发现暴力破解行为后自动封禁攻击IP。安装很简单:
sudo apt install fail2ban -y
创建本地配置文件覆盖默认设置:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
编辑jail.local,重点配置SSH防护。在[sshd]段落下设置:enabled = true,port改为你修改后的SSH端口号,maxretry设为3,bantime设为3600或更长,findtime设为600。这意味着10分钟内失败3次就封禁1小时。可以根据实际情况调整,但不要把maxretry设得太大,3次足够正常用户纠正输入错误了。
重启服务并设置开机自启:
sudo systemctl enable fail2ban sudo systemctl restart fail2ban
用sudo fail2ban-client status sshd查看封禁状态。如果看到封禁列表里有IP,说明已经在发挥作用了。
禁用不必要的服务和进程最小化原则:只运行业务必需的服务。列出所有监听端口:
sudo ss -tlnp
仔细审查每个监听的服务。常见的可以关闭的服务包括:avahi-daemon(零配置网络服务,服务器环境用不到)、cups(打印服务)、rpcbind(远程过程调用,NFS才需要)。关闭方式:
sudo systemctl disable --now servicename
同时检查开机自启项:
sudo systemctl list-unit-files --state=enabled
禁用不需要的自启服务,减少攻击面也节省系统资源。
日志审计与入侵检测安全加固不是一次性工作,持续的监控才能及时发现异常。首先确认rsyslog服务正常运行:
sudo systemctl status rsyslog
安装logwatch可以生成每日日志摘要报告:
sudo apt install logwatch -y
配置邮件发送报告,或者手动查看:
sudo logwatch --detail High --range today
对于更高要求的环境,可以考虑安装AIDE做文件完整性检查:
sudo apt install aide -y sudo aideinit
AIDE会建立文件系统快照,检测关键系统文件是否被篡改。初始化后记得将数据库移到安全位置。
还有一个容易被忽略的点:检查crontab中是否有异常定时任务。攻击者常在crontab中植入持久化脚本:
sudo ls -la /var/spool/cron/crontabs sudo cat /etc/crontab
逐条审查,不认识的条目要追查到底。
应用层安全配置如果服务器运行数据库,务必修改默认端口并设置强密码。MySQL或PostgreSQL安装后应立即执行安全脚本:
sudo mysql_secure_installation
移除匿名用户、禁止远程root登录、删除测试数据库。对于Redis这类内存数据库,务必设置requirepass密码,并绑定到127.0.0.1,禁止外部访问。
Web应用层面,检查Nginx或Apache的配置,隐藏版本号信息。Nginx在http块中添加server_tokens off;Apache在配置中设置ServerTokens Prod和ServerSignature Off。这些信息虽然不算致命漏洞,但减少信息泄露能提高攻击者的侦察成本。
如果使用PHP,务必检查php.ini中的关键配置:expose_php = Off,disable_functions中根据需求加入exec、shell_exec、system等危险函数,allow_url_fopen和allow_url_include设为Off。
备份策略:最后一道防线安全措施再完善也无法保证100%安全,备份是最后的保险。至少要做到关键配置文件的定期备份。可以写一个简单的备份脚本,把/etc/ssh/sshd_config、/etc/ufw/、/etc/fail2ban/、/etc/sysctl.conf等配置文件打包,配合crontab定时执行,推送到远程存储或其他服务器。
数据库备份同样重要,mysqldump或pg_dump配合cron定时任务,保留最近7天的备份文件。备份文件本身也要注意权限设置,600权限仅root可读。
以上步骤执行完毕后,建议做一次全面的安全检查。用sudo netstat -tlnp再次确认监听端口,用sudo last查看登录记录,用sudo faillog -a查看失败登录尝试。每一项都正常,这台Ubuntu服务器才算达到了基本的安全基线。安全是一个持续的过程,保持更新、定期审查、关注安全公告,这些习惯比任何一次性配置都重要。
