Ubuntu服务器上线后最容易出问题的往往不是复杂的架构,而是那些看似基础却容易被忽略的默认配置。新手拿到一台全新VPS或云主机,通常第一件事就是创建用户、装软件、开端口,但很多安全隐患和运维坑就埋在这个阶段。下面直接讲具体问题和解决方法,不绕弯子。
不要长期用root账户通过SSH登录
很多镜像默认允许root密码登录,这是最大的风险点之一。攻击者会不断扫描22端口并尝试爆破root密码。正确做法是创建一个普通用户,并授予其sudo权限,然后禁止root直接SSH登录。创建用户后执行:
sudo adduser deploy sudo usermod -aG sudo deploy
接着修改SSH配置文件:
sudo nano /etc/ssh/sshd_config
找到PermitRootLogin这一行,将其值改为no。如果存在PasswordAuthentication,建议在配置好密钥登录后也改为no。修改后重启SSH服务:
sudo systemctl restart ssh
以后所有管理操作都通过deploy用户登录,需要权限时用sudo执行。这样即使普通账户被爆破,攻击者还需要再突破sudo密码,多一层防护。
SSH密钥登录比密码登录更可靠,但别把私钥到处放
密码可以被暴力破解,而密钥几乎不可能。在本地电脑生成密钥对:
ssh-keygen -t ed25519 -C "your-email@example.com"
将公钥复制到服务器:
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@服务器IP
完成后测试密钥登录,确认没问题再关闭密码登录。私钥文件id_ed25519必须妥善保管,不要上传到任何网盘或代码仓库。如果需要在多台设备上登录,每台设备单独生成密钥并添加公钥,不要复用同一个私钥。另外建议给私钥设置passphrase,即使私钥泄露也还有一层保护。
防火墙默认策略要设置成拒绝所有入站,只放行必要端口
Ubuntu自带的UFW可以快速配置防火墙。新手常犯的错误是只开放了22、80、443端口,却没有启用防火墙,或者默认策略是允许所有入站。正确流程是:
sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow 22/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable
如果SSH端口改成了非22端口,记得放行对应端口,否则启用防火墙后会立即断开连接。启用前可以用ufw status numbered查看规则,确认SSH端口在放行列表中。对于数据库端口如3306、5432、6379,除非有明确的外部访问需求,否则不要开放。如果必须开放,至少限制来源IP。
修改SSH默认端口能减少大量噪音,但不能替代其他安全措施
将SSH端口从22改为一个不常用的高位端口,比如2222或更高,可以显著减少自动扫描和爆破日志。修改sshd_config中的Port参数:
Port 2222
同时更新防火墙规则,删除22端口放行,添加新端口。修改后重启SSH服务。注意不要只改端口而忘记更新防火墙,否则会被锁在服务器外。另外,修改端口并不能阻止定向攻击,它只是过滤掉了大部分无差别扫描。密钥登录和禁用root仍然是必须做的。
自动安全更新要开启,但生产环境建议分阶段更新
Ubuntu的unattended-upgrades可以自动安装安全补丁,对于新手来说能避免很多已知漏洞被利用。安装并启用:
sudo apt install unattended-upgrades sudo dpkg-reconfigure --priority=low unattended-upgrades
这会自动安装安全更新。但如果你运行的是生产服务,完全自动更新可能导致服务意外重启或依赖冲突。折中方案是只自动安装安全更新,不自动安装普通更新,并设置更新时间为业务低峰期。配置文件在/etc/apt/apt.conf.d/50unattended-upgrades,可以指定允许更新的仓库和包类型。
fail2ban是防爆破的基础工具,但配置不当会误伤自己
fail2ban监控日志,对多次失败尝试的IP进行临时封禁。安装:
sudo apt install fail2ban
默认配置对SSH有效,但封禁阈值和封禁时间需要根据情况调整。在/etc/fail2ban/jail.local中创建自定义配置:
[sshd] enabled = true port = 2222 maxretry = 3 bantime = 3600 findtime = 600
这里port要改成你实际的SSH端口。maxretry设得太低容易因为自己输错密码被误封,设得太高又起不到防护作用。bantime建议至少1小时。如果自己有固定IP,可以加入ignoreip白名单,避免误封。
用户权限和文件权限要最小化,不要图省事用chmod 777
很多新手遇到权限问题就直接chmod 777,这会让所有用户都能读写执行该文件或目录,极其危险。Web目录、配置目录尤其要注意。正确的做法是分析到底哪个用户需要什么权限。例如Nginx或Apache运行用户通常是www-data,网站文件的所有者可以是deploy,组设置为www-data,目录权限755,文件权限644,需要写入的目录如uploads或cache设置为775,并确保组为www-data。使用chown和chmod精确控制:
sudo chown -R deploy:www-data /var/www/example.com
sudo find /var/www/example.com -type d -exec chmod 755 {} \;
sudo find /var/www/example.com -type f -exec chmod 644 {} \;
sudo chmod 775 /var/www/example.com/storage
这样既保证了Web服务能读取,又避免了任意用户可写。
数据库不要监听公网地址,默认账户必须设置强密码
MySQL、PostgreSQL、Redis等数据库默认只监听本地地址,但有些教程会教人改成0.0.0.0方便远程管理,这是非常危险的操作。如果确实需要远程连接数据库,使用SSH隧道转发,而不是直接开放数据库端口。例如本地通过SSH隧道连接服务器上的MySQL:
ssh -L 3307:127.0.0.1:3306 deploy@服务器IP
然后本地连接127.0.0.1:3307即可。对于Redis,如果必须远程访问,至少设置requirepass强密码,并绑定内网IP。但更推荐的做法是完全不暴露数据库端口。
定期备份是最后的防线,但要验证备份真的能恢复
很多新手配置了备份任务就以为高枕无忧,结果真出问题时发现备份文件损坏或恢复流程不通。备份至少包含数据库和网站文件。可以用cron定时执行备份脚本,例如每天凌晨备份MySQL:
0 3 * * * /usr/bin/mysqldump -u root -p'密码' --all-databases | gzip > /backup/db_$(date +\%F).sql.gz
网站文件用tar打包:
0 4 * * * tar -czf /backup/www_$(date +\%F).tar.gz /var/www/example.com
备份文件要同步到异地存储,不能只放在同一台服务器上。可以用rsync同步到另一台机器或对象存储。更重要的是定期做恢复演练,找一个测试环境把备份还原出来,确认数据完整可用。否则备份只是心理安慰。
日志监控不能只看错误日志,要关注异常访问模式
很多新手只在服务出问题时才去看日志,平时完全不关注。实际上日志里藏着大量攻击迹象。建议安装logwatch或使用简单的命令定期检查。例如查看SSH登录失败记录:
sudo grep "Failed password" /var/log/auth.log | tail -20
查看Nginx访问日志中状态码分布:
sudo awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
如果发现大量404请求集中在某个路径,可能是扫描器在探测漏洞。大量500错误则可能服务本身有问题。可以配置logrotate确保日志不会占满磁盘,同时设置简单的告警,比如用cron脚本检测日志中特定关键词并发送邮件。
软件源和镜像要选对,避免下载到被篡改的包
Ubuntu默认软件源在国外,国内访问速度慢且不稳定。但不要随意使用网上找到的第三方镜像源,尤其是那些没有官方背书的。建议使用Ubuntu官方提供的镜像列表,选择国内知名镜像站,例如阿里云、腾讯云、华为云等。修改/etc/apt/sources.list时,先备份原文件,再替换为镜像地址。更新源后执行apt update和apt upgrade。注意不要混用不同版本的源,比如20.04的系统不要添加22.04的源,否则会导致依赖混乱。
服务器时间要同步,否则证书验证和日志时间都会出问题
时间不同步会导致HTTPS证书验证失败、日志时间错乱、分布式系统数据不一致等问题。Ubuntu默认安装了systemd-timesyncd,但有时没有启用。检查状态:
timedatectl status
如果NTP服务未激活,执行:
sudo timedatectl set-ntp true
对于需要更高精度时间同步的场景,可以安装chrony替代。确保时区设置正确:
sudo timedatectl set-timezone Asia/Shanghai
时间同步虽然简单,但经常被忽略,出问题时排查起来很费劲。
不要随意运行网上找到的一键脚本,先看懂它做了什么
很多新手为了省事,直接复制粘贴网上的一键安装脚本,比如装宝塔、装Docker、装各种面板。这些脚本可能包含恶意代码,或者会修改系统配置导致后续难以维护。即使脚本本身没问题,它也可能安装了过多不需要的组件,增加攻击面。建议尽量使用官方文档的安装方式,如果必须用脚本,先打开脚本内容,逐行看它下载了什么、执行了什么、修改了哪些文件。对于不明来源的脚本,可以在隔离环境中测试后再用到生产服务器。
定期检查服务器资源使用情况,防止磁盘被日志或缓存占满
磁盘满会导致数据库无法写入、服务崩溃。定期用df -h查看磁盘使用率,用du -sh /var/log/*查看日志目录大小。配置logrotate限制日志保留数量和大小。对于Docker环境,容器日志也可能迅速占满磁盘,需要配置日志驱动限制单个容器日志大小。另外,/tmp目录可能积累大量临时文件,可以设置定期清理。内存方面,用free -h和top查看是否有进程异常占用。如果发现内存持续增长,可能是内存泄漏,需要进一步排查具体进程。
总结一下核心原则:最小权限、最小暴露、持续验证。每个服务只给必要的权限,每个端口只在必要时开放,每个备份都要验证可恢复。新手最容易犯的错就是图省事,但省事的代价往往是服务器被入侵或数据丢失。把这些基础配置做好,能避开90%以上的常见问题。
