Ubuntu服务器默认安装后并不处于最佳安全状态,很多攻击并非利用零日漏洞,而是针对配置疏忽、默认服务暴露和权限设置不当。安全优化的进阶思路不是堆砌工具,而是从攻击面收敛、内核参数、访问控制、审计追踪四个维度建立纵深。下面直接进入具体操作层面,不讨论基础的开防火墙、改SSH端口这类常识,重点讲容易被忽略但实际防护价值很高的配置。
限制内核暴露的信息与模块加载攻击者进入系统后第一件事通常是收集内核版本和已加载模块,以便寻找对应exploit。可以通过sysctl限制内核信息泄露。编辑/etc/sysctl.d/99-security.conf,加入以下参数:
kernel.kptr_restrict = 2 kernel.dmesg_restrict = 1 kernel.unprivileged_bpf_disabled = 1 kernel.yama.ptrace_scope = 2
kptr_restrict=2会隐藏内核指针地址,dmesg_restrict=1阻止非root用户读取内核日志,unprivileged_bpf_disabled=1关闭非特权用户的BPF访问,防止利用BPF进行权限提升。ptrace_scope=2则限制ptrace附加进程的能力,有效阻断进程注入类攻击。执行sysctl --system立即生效。另外建议在/etc/modprobe.d/blacklist.conf中禁用不常用的高危模块,例如usb-storage、firewire-core、thunderbolt,如果服务器不涉及相关硬件,直接禁止加载能减少本地物理攻击面。
用AppArmor强制进程行为边界很多管理员启用了UFW就觉得安全了,但防火墙只解决网络层,进程被攻破后的行为控制要靠强制访问控制。Ubuntu自带AppArmor,默认只对部分服务启用。查看当前状态用aa-status,你会发现很多关键服务处于unconfined状态。对于Nginx、MySQL这类高频攻击目标,建议手动编写或启用额外profile。以Nginx为例,安装apparmor-profiles包后,将usr.sbin.nginx profile从/usr/share/apparmor/extra-profiles/复制到/etc/apparmor.d/,根据实际路径修改后执行apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx。配置时要特别注意日志目录和临时目录的写权限,否则服务会异常。AppArmor的complain模式可以先用来测试,确认无阻断后再切换enforce。这个步骤虽然初期调试耗时,但一旦生效,即使Nginx被远程代码执行,攻击者也无法读取/etc/shadow或写入系统目录。
审计关键系统调用与文件访问没有审计的安全优化是盲目的。安装auditd后,不要只监控/etc/passwd这类基础文件。真正有价值的是监控系统调用层面的异常行为。在/etc/audit/rules.d/security.rules中添加以下规则:
-a always,exit -F arch=b64 -S execve -F euid=0 -k root_exec -a always,exit -F arch=b64 -S open -F dir=/etc -F success=1 -k etc_access -a always,exit -F arch=b64 -S connect -F a1=AF_INET -k network_connect -a always,exit -F arch=b64 -S ptrace -k ptrace_attempt
第一条记录所有root权限的进程执行,第二条记录对/etc目录的成功读取,第三条记录所有IPv4网络连接,第四条记录任何ptrace尝试。这些规则产生的日志量可控,但能覆盖大部分入侵后的横向移动和提权行为。用ausearch -k root_exec --start today可以快速检索当天所有root执行的命令。配合audispd将日志转发到远程集中日志服务器,防止攻击者本地清除痕迹。
SSH进阶加固:从端口到证书与限制改端口和禁root登录是基础,但还不够。建议在/etc/ssh/sshd_config中做以下调整:
PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys AllowUsers deploy opsuser MaxAuthTries 3 LoginGraceTime 30 ClientAliveInterval 300 ClientAliveCountMax 2
关键点在于PasswordAuthentication no强制密钥登录,AllowUsers白名单只允许特定用户SSH。如果团队人数多,可以用AllowGroups代替。另外建议开启SSH证书签名登录,用ssh-keygen -s ca_key -I user_id -n username -V +52w user_key.pub生成用户证书,服务器配置TrustedUserCAKeys指向CA公钥。这样即使某个开发者的私钥泄露,证书过期后也无法登录,且吊销只需在服务器端配置RevokedKeys。这种方式比单纯管理authorized_keys文件更可控,尤其适合多服务器环境。
文件系统与权限的隐藏风险很多人检查/var/www的权限,却忽略了/tmp、/var/tmp和/dev/shm这三个可写目录。攻击者提权后往往在这些目录放置恶意脚本或二进制。建议在/etc/fstab中为这些挂载点添加noexec,nosuid选项:
tmpfs /dev/shm tmpfs defaults,noexec,nosuid,nodev 0 0 /tmp /var/tmp none rw,noexec,nosuid,nodev,bind 0 0
注意/tmp绑定到/var/tmp需要确保/var/tmp存在且为空。noexec会阻止这些目录下的二进制执行,nosuid禁止setuid位生效,nodev禁止设备文件。这能有效阻断大量依赖临时目录的提权脚本和webshell执行。如果某些应用确实需要在/tmp下执行代码,可以单独为其创建子目录并挂载exec选项,但绝大多数生产环境不需要。
内核网络层防欺骗与异常包处理除了常规的net.ipv4.conf.all.rp_filter=1防IP欺骗,还应关注以下参数:
net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_syn_backlog = 4096 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 2 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.icmp_ignore_bogus_error_responses = 1
accept_redirects=0防止攻击者通过ICMP重定向篡改路由表,accept_source_route=0禁用源路由选项,这两项在云环境中尤其重要。tcp_syncookies=1开启SYN Cookie防护,配合synack_retries降低到2,能显著缓解SYN Flood的影响,同时避免正常连接被大量半开连接拖垮。icmp_echo_ignore_broadcasts=1防止服务器被用作Smurf攻击的反射器。
定时任务与启动项的完整性监控攻击者持久化最常用的手段是写入crontab、systemd timer或修改启动脚本。建议用inotify或auditd监控这些路径的变化。更实际的做法是定期用脚本比对关键目录的文件哈希。创建一个简单的监控脚本,用sha256sum计算/etc/cron.d、/etc/cron.daily、/etc/systemd/system、/etc/rc.local等目录下所有文件的哈希,与基线文件比对,发现变化立即告警。将脚本放入/etc/cron.daily每日执行。同时检查所有用户的crontab,用for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l 2>/dev/null; done列出全部任务,人工审核是否有异常条目。很多挖矿木马就藏在某个低权限用户的crontab里。
利用systemd安全选项限制服务权限对于自己部署的服务,不要用root直接运行。systemd提供了丰富的安全加固指令,可以在service文件中直接使用。例如:
[Service] User=appuser Group=appgroup NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=true ReadWritePaths=/var/log/myapp CapabilityBoundingSet=CAP_NET_BIND_SERVICE RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX SystemCallFilter=@system-service
NoNewPrivileges=true阻止进程通过setuid或capabilities提权,PrivateTmp=true为服务提供独立的/tmp目录,ProtectSystem=strict将整个文件系统设为只读,只有ReadWritePaths指定的路径可写。CapabilityBoundingSet限制进程的能力集,如果服务不需要绑定低端口,甚至可以去掉CAP_NET_BIND_SERVICE。SystemCallFilter通过白名单限制允许的系统调用,@system-service集合已经排除了大量危险调用。这些选项比传统的chroot或容器更轻量,但防护效果显著,尤其适合数据库、缓存、消息队列这类中间件。
日志完整性保护与远程转发本地日志再详细,如果攻击者拿到root权限后可以随意修改,审计就失去意义。除了常规的rsyslog远程转发,建议使用journald的持久化和转发功能。在/etc/systemd/journald.conf中设置Storage=persistent,并配置ForwardToSyslog=yes将日志同时发送到rsyslog,再由rsyslog通过TCP或RELP协议转发到远程日志服务器。对于高安全要求的环境,可以部署auditbeat或filebeat将日志实时推送到集中平台,并开启日志完整性校验。关键是日志传输通道要独立于业务网络,至少使用单独的VLAN或管理网段,这样即使业务网段被攻破,日志链路仍然不受影响。
定期自动化安全审计手动检查总有遗漏,建议将安全审计自动化。安装lynis和debsecan,lynis是系统级安全审计工具,能检查数百项配置并给出建议;debsecan专门检查已安装软件包中是否存在已知CVE漏洞。将两者放入每周定时任务,输出结果通过邮件或消息推送发送给管理员。lynis audit system --quick可以快速扫描,debsecan --format detail输出可读的漏洞列表。另外使用unattended-upgrades自动安装安全更新,但只启用security源,避免自动更新引入不兼容的版本变更。在/etc/apt/apt.conf.d/50unattended-upgrades中配置Unattended-Upgrade::Allowed-Origins只包含Ubuntu安全源,并设置自动重启相关服务的策略。
安全优化不是一次性的配置,而是持续的过程。上述措施覆盖了内核、进程、网络、文件系统、审计五个层面,每一项都针对真实攻击场景中的具体环节。建议按优先级逐步实施,每完成一项就验证服务是否正常运行,避免因安全配置导致业务中断。最终目标不是让服务器绝对不可攻破,而是大幅提高攻击成本,让攻击者在尝试过程中暴露痕迹,为检测和响应争取时间。
