Ubuntu服务器装好之后能跑起来只是第一步,真正的考验在于日常使用中资源会不会突然吃紧、日志会不会悄悄占满磁盘、SSH端口会不会被人盯上。很多运维事故不是配置有多复杂,而是基础细节没人管。下面直接讲日常最该做的几件事,从资源监控、自动清理、内核参数、防火墙到SSH加固,每一条都给出可落地的操作。

先解决磁盘被日志和旧内核塞满的问题

Ubuntu长期运行后,/var/log目录和旧内核是磁盘空间的两大隐形杀手。特别是/var/log/journal,systemd日志默认持续增长,如果不限制大小,几个月就能吃掉几个GB。先用一条命令查看当前占用:

journalctl --disk-usage

如果占用过高,直接修改/etc/systemd/journald.conf,取消注释并设置:

SystemMaxUse=500M
SystemMaxFileSize=100M
MaxRetentionSec=2week

保存后执行systemctl restart systemd-journald生效。这个操作能把日志控制在固定范围内,避免磁盘被写满导致服务异常。

旧内核同样需要定期清理。Ubuntu升级内核后不会自动删除旧版本,/boot分区很容易被占满。查看当前已安装的内核:

dpkg --list | grep linux-image

确认当前运行内核版本用uname -r,然后手动删除旧内核:

sudo apt-get purge linux-image-旧版本号

更稳妥的做法是安装byobu工具,里面包含purge-old-kernels脚本,可以自动保留最近两个内核并清理其余版本:

sudo apt install byobu
sudo purge-old-kernels --keep 2

建议把这个清理动作加入每月例行维护清单,避免/boot满后导致系统无法正常升级。

内存与CPU异常排查要直接看关键指标

服务器变慢时不要急着重启,先用top或htop看整体负载。重点看load average三个数值是否长期超过CPU核心数,如果超过说明有进程在排队。再用free -h看内存,注意available列才是真正可用的内存,不要被used列吓到,Linux会把空闲内存拿去做缓存。

如果发现某个进程占用CPU或内存异常,用以下命令定位具体线程:

ps aux --sort=-%mem | head -20
ps aux --sort=-%cpu | head -20

对于MySQL或PostgreSQL这类数据库,不要只看进程本身,还要检查慢查询日志。Ubuntu默认可能没开慢查询,建议在数据库配置中开启并设置合理阈值,比如MySQL在/etc/mysql/mysql.conf.d/mysqld.cnf中加入:

slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 2

重启数据库后定期分析慢日志,能提前发现索引缺失或SQL写法问题,比等到CPU被打满再处理有效得多。

自动化安全更新与无人值守升级

很多安全事件是因为补丁没及时打。Ubuntu有unattended-upgrades工具可以自动安装安全更新,不需要人工干预。先安装:

sudo apt install unattended-upgrades

然后编辑/etc/apt/apt.conf.d/50unattended-upgrades,确保安全更新源被启用:

Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}-security";
    "${distro_id}ESMApps:${distro_codename}-apps-security";
    "${distro_id}ESM:${distro_codename}-infra-security";
};

再启用自动升级定时任务:

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

选择“是”即可。这个工具只会安装安全更新,不会升级大版本或引入不兼容变更,适合生产环境。建议同时配置邮件通知,在配置文件中设置Unattended-Upgrade::Mail为管理员邮箱,这样每次自动更新后都能收到报告。

防火墙策略要精细到端口和来源IP

UFW是Ubuntu上最直接的防火墙工具,但很多人的用法只停留在ufw allow 22/tcp这种粗粒度规则。实际生产环境应该限制来源IP,比如只允许公司出口IP访问SSH:

sudo ufw allow from 203.0.113.10 to any port 22 proto tcp

如果必须对公网开放Web端口,至少把80和443单独放行,不要用ufw allow 1:65535这种危险操作。查看当前规则用ufw status numbered,删除规则用ufw delete 编号。另外注意UFW默认会允许所有出站流量,入站默认拒绝,这个策略本身是安全的,但如果有特殊需求要显式配置。

对于有大量动态IP需要访问的场景,可以考虑结合fail2ban做动态封禁。安装fail2ban后,在/etc/fail2ban/jail.local中配置SSH防护:

[sshd]
enabled = true
port = 22
maxretry = 3
bantime = 3600
findtime = 600

这样连续3次密码错误就封禁该IP一小时,能有效阻挡暴力破解。fail2ban还支持Nginx、Apache、MySQL等多种服务的日志分析,建议至少对SSH和Web服务启用。

SSH加固不只是改端口和禁root

改SSH端口能减少大部分自动化扫描,但更关键的是禁用密码登录、强制使用密钥。编辑/etc/ssh/sshd_config:

Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers deploy

重启SSH服务前务必确认已经把自己的公钥加到~/.ssh/authorized_keys,否则会被锁在门外。AllowUsers白名单比DenyUsers更安全,只允许指定用户登录。另外建议设置LoginGraceTime 30和MaxAuthTries 3,降低暴力尝试的成功率。

还有一个常被忽略的点:SSH版本信息泄露。默认配置下连接SSH会显示Ubuntu版本,攻击者可以针对特定版本漏洞发起攻击。在sshd_config中加入:

DebianBanner no

虽然不能完全隐藏,但能减少一部分自动化工具的指纹识别。

系统资源限制与内核参数调优

默认的文件描述符限制在并发高的服务上会成为瓶颈。查看当前限制:

ulimit -n

如果只有1024,Nginx或数据库在高并发下会报too many open files错误。修改/etc/security/limits.conf:

* soft nofile 65535
* hard nofile 65535

同时修改/etc/systemd/system.conf中的DefaultLimitNOFILE=65535,重启后生效。对于运行Docker的服务器,这个参数尤其重要,容器内的进程也会继承宿主机的限制。

内核网络参数方面,如果服务器作为反向代理或负载均衡,建议调整TCP连接复用和超时时间。编辑/etc/sysctl.d/99-network.conf:

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_max_syn_backlog = 8192
net.core.somaxconn = 8192

执行sysctl -p /etc/sysctl.d/99-network.conf生效。这些参数能加快TIME_WAIT状态的回收,提升短连接场景下的吞吐能力。但注意不要盲目照搬网上的“万能优化参数”,不同业务模型需要的调优方向不同,比如长连接为主的服务反而要增大keepalive时间。

日志轮转与集中管理

除了systemd日志,应用日志也要配置轮转。Ubuntu自带的logrotate默认每周轮转一次,但有些应用日志增长很快,需要单独配置。在/etc/logrotate.d/下创建应用配置文件,例如针对Nginx:

/var/log/nginx/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        systemctl reload nginx > /dev/null 2>&1
    endscript
}

这样每天轮转一次,保留14天,压缩旧日志,轮转后自动重载Nginx。对于多台服务器的场景,建议把关键日志集中到一台日志服务器,可以用rsyslog转发或直接使用 Loki、Elasticsearch 等方案。集中管理的好处是出问题时不用逐台登录服务器翻日志。

定期备份与恢复演练

运维优化做得再好,没有备份都是空谈。Ubuntu服务器至少要做到数据库每日备份、配置文件定期备份。数据库备份可以用mysqldump或pg_dump配合cron定时执行:

0 3 * * * /usr/bin/mysqldump --single-transaction --quick --databases appdb | gzip > /backup/mysql/appdb_$(date +\%F).sql.gz

配置文件备份更简单,把/etc目录下修改过的文件用git管理,或者定期打包:

tar czf /backup/etc_$(date +\%F).tar.gz /etc/nginx /etc/mysql /etc/systemd/system

备份做完一定要定期做恢复演练,验证备份文件真的能还原。很多团队直到出事故才发现备份文件损坏或恢复流程不完整。建议每季度至少做一次全量恢复测试,把备份还原到测试环境并验证数据完整性。

监控告警不能只靠人肉盯

日常运维中很多问题如果能提前收到告警,就不会发展成事故。Ubuntu上可以部署轻量级监控工具,比如Netdata、Prometheus配合Node Exporter,或者直接使用云服务商自带的监控。至少要监控磁盘使用率、CPU负载、内存可用量、服务存活状态这几个核心指标。

告警阈值要设置得合理,磁盘使用率超过80%告警,超过90%严重告警。CPU负载持续超过核心数2倍告警。内存可用量低于总内存10%告警。告警方式可以用邮件、企业微信或钉钉机器人,关键是告警信息要包含主机名、指标值、持续时间,方便快速定位。

另外建议配置服务自动拉起机制。对于关键服务,在systemd unit文件中加入:

[Service]
Restart=always
RestartSec=5
StartLimitIntervalSec=60
StartLimitBurst=3

这样服务异常退出后会自动重启,连续失败3次后停止尝试,避免无限重启循环。配合监控告警,能在服务自动恢复的同时通知运维人员介入排查根因。

Ubuntu服务器的日常运维优化没有银弹,核心是把磁盘、内存、CPU、网络、安全这几个维度都纳入常规检查,把能自动化的操作自动化,把需要人工判断的指标通过告警及时暴露出来。安全防护方面,最小化暴露面、强制密钥认证、及时打补丁这三件事做到位,就能挡住绝大多数攻击。