在云主机或物理服务器上部署Debian时,很多人习惯性地勾选所有组件,或者直接使用云厂商提供的全量镜像。系统上线后,你会发现后台运行着蓝牙服务、打印服务、图形库甚至一些你永远用不到的设备驱动。每一个多余的软件包,每一个监听在端口上的默认服务,都是攻击者眼中的突破口。最小化安装不是一种洁癖,而是Linux服务器安全加固的第一步,也是最有效的一步。它能从源头上缩减攻击面,让那些依赖特定服务或库文件的漏洞直接失去立足之地。
安装时只选“标准系统工具”Debian安装程序在tasksel环节会列出多个软件集合,包括桌面环境、Web服务器、打印服务器、SSH服务器等。很多人担心后续操作不便,会勾选“Debian desktop environment”或者“LXDE”之类的图形界面。对于服务器而言,这完全是多余的。图形界面不仅占用磁盘空间,还会引入X11、窗口管理器、字体渲染引擎等大量组件,这些组件历史上爆出过不少本地提权漏洞和远程代码执行漏洞。
正确的做法是:在tasksel界面只勾选“standard system utilities”,其他所有选项全部取消。这个选项包含了一组基础命令行工具,比如less、nano、wget、curl、rsync等,足够你完成后续配置。如果你连这些都觉得多余,甚至可以按Tab键切到“Continue”直接跳过,获得一个近乎裸机的系统。安装完成后,系统中运行的服务数量会降到最低,默认监听端口几乎为零。
手动控制OpenSSH的安装时机很多人在tasksel阶段会勾选“SSH server”,这样安装完成后系统自动启动sshd。问题在于,此时你的系统可能还没有完成防火墙配置、没有禁用密码登录、没有修改默认端口。从系统上线到完成加固的这段时间窗口,扫描机器人可能已经通过密码爆破攻破了root账户。
更安全的做法是:安装时不勾选SSH服务,系统装完后通过本地控制台或带外管理登录,先配置好iptables或nftables规则,只允许特定IP访问22端口,然后手动安装openssh-server。安装后立即编辑/etc/ssh/sshd_config,设置PermitRootLogin no、PasswordAuthentication no、使用密钥认证,最后再启动sshd服务。这样你的SSH服务从一开始就处于加固状态,不存在暴露期。
用debootstrap构建真正的最小化系统如果你对“最小化”有极致追求,标准安装程序可能还不够彻底。debootstrap是Debian官方提供的工具,可以在一个空目录中直接构建出最小的Debian基础系统。用这个方法装出来的系统,连内核都需要手动安装,包的数量可以控制在200个以内。
操作流程大致如下:先用任意Linux Live环境启动服务器,分区并挂载到/mnt,然后执行:
debootstrap --arch amd64 bookworm /mnt http://deb.debian.org/debian
这会下载并解压约150个基础包,包括apt、dpkg、coreutils等。之后chroot进入新系统,安装内核、引导加载程序、配置网络。整个过程你拥有完全的控制权,系统中不会有任何你不知情的软件。这种方式特别适合需要长期运行、对稳定性要求极高的生产环境,因为你可以精确复现系统状态,也便于做安全审计。
清理不必要的内核模块和固件即使你选择了最小化安装,Debian默认内核仍然会加载大量硬件驱动模块。对于运行在KVM、VMware或Xen上的虚拟机来说,蓝牙驱动、Wi-Fi驱动、红外驱动、声音驱动都是完全无用的。这些内核模块虽然不直接监听网络端口,但它们增加了内核的攻击面。历史上,蓝牙协议栈和Wi-Fi驱动层都曾出现过严重漏洞,即使你没有对应的物理硬件,恶意代码如果被加载进内核,理论上仍可能触发这些模块中的缺陷。
你可以通过blacklist机制禁用它们。在/etc/modprobe.d/目录下创建blacklist-unused.conf文件,内容如下:
blacklist bluetooth blacklist btusb blacklist soundcore blacklist snd blacklist iwlmvm blacklist iwlwifi blacklist cfg80211
对于虚拟机,还可以进一步禁用virtio之外的所有存储和网络驱动模块。重启后用lsmod查看已加载模块,你会发现内核变得非常干净。这不仅减少攻击面,还能略微降低内存占用和内核处理开销。
裁剪systemd服务单元Debian默认使用systemd作为初始化系统。最小化安装后,systemd仍然会启动一些你可能不需要的服务单元。执行systemctl list-units --type=service --state=running可以查看所有运行中的服务。常见的多余服务包括:
systemd-timesyncd.service——如果你打算用chrony或ntpd做时间同步,这个可以禁用。
systemd-resolved.service——如果你使用静态DNS配置或运行自己的解析器,这个可以禁用。
systemd-networkd.service——如果你用ifupdown或NetworkManager管理网络,这个可以禁用。
apt-daily-upgrade.service和apt-daily.service——这两个定时任务会不定期触发apt更新检查,在需要严格控制出站网络连接的环境中应该禁用。
禁用方法很简单:systemctl disable --now 服务名。对于定时器,还需要用systemctl disable apt-daily.timer来彻底关闭。每禁用一个服务前,确认它在你当前网络架构中确实不需要。这样处理下来,一个基础Debian服务器后台运行的服务可以控制在10个以内。
精确控制安装包的依赖深度apt安装软件时默认会拉入“推荐”级别的依赖包。这意味着你只想装一个轻量级工具,结果附带进来一整套文档生成器、字体包、邮件发送程序。这些间接依赖可能引入你完全意想不到的网络服务或解析库。
在/etc/apt/apt.conf.d/目录下创建00norecommends文件,写入:
APT::Install-Recommends "false"; APT::Install-Suggests "false";
这样apt只会安装“必需”级别的依赖,包的数量大幅减少。如果你已经安装了一些带推荐依赖的包,可以用deborphan和apt-get autoremove来清理孤儿包。定期运行deborphan -s可以列出所有不再被任何包依赖的共享库,结合aptitude的交互式界面,你可以精细地审视系统中每一个包存在的必要性。
移除编译工具和开发库生产服务器上不应该保留gcc、make、linux-headers这类编译工具。攻击者一旦通过Web应用漏洞获得低权限shell,第一件事就是检查系统是否有编译器。如果有,他们可以直接在目标机器上编译提权exp或后门程序。没有编译器,攻击者就必须寻找其他方式上传预编译的二进制文件,增加了攻击难度和暴露风险。
最小化安装完成后,执行dpkg -l | grep -E 'gcc|make|build-essential|linux-headers'检查是否存在这些包。通常最小化安装不会包含它们,但如果你在后续配置中不小心引入了,务必用apt purge彻底移除。同时检查/usr/bin/下是否存在gcc、cc、g++等可执行文件。
利用AppArmor或SELinux做强制访问控制减少软件包是缩小攻击面的第一步,但剩下的服务仍然可能被攻破。Debian默认集成AppArmor,最小化安装后这个框架已经在运行,只是很多配置文件需要手动启用。执行aa-status可以看到当前加载的策略。对于你保留的服务,比如Nginx、MySQL、bind9等,Debian官方提供了对应的AppArmor配置文件,存放在/etc/apparmor.d/目录下。
用aa-enforce /etc/apparmor.d/usr.sbin.nginx这样的命令将服务置于强制模式。这样即使Nginx进程被远程代码执行,攻击者也受限于AppArmor定义的访问规则,无法随意读取/etc/shadow或执行/bin/bash。这是一种纵深防御思路:先通过最小化安装减少组件,再通过强制访问控制限制已运行组件的权限范围。
网络层面的最小化最小化安装的服务器,网络栈本身也可以做减法。Debian默认内核编译了IPv6支持,如果你的网络环境完全基于IPv4,可以在/etc/sysctl.conf中添加net.ipv6.conf.all.disable_ipv6 = 1来关闭IPv6协议栈。这不仅减少攻击面,还能避免一些IPv6相关的路由泄露问题。
另外,检查系统中是否存在监听0.0.0.0的服务。用ss -tlnp和ss -ulnp查看所有TCP和UDP监听端口。如果你发现某个服务监听在0.0.0.0,而它只需要被本机访问,就修改其配置让它只监听127.0.0.1。比如MySQL如果只需要被本地PHP调用,就在my.cnf中设置bind-address = 127.0.0.1。每减少一个对外暴露的端口,扫描器发现你的概率就降低一分。
日志和审计的轻量化最小化安装并不意味着放弃可观测性。rsyslog默认会安装并运行,但它会监听本地socket接收日志,本身不暴露网络端口,风险很低。如果你需要更轻量的方案,可以考虑用busybox的syslogd替代rsyslog,或者直接依赖systemd-journald。journald默认只将日志存储在/run/log/journal目录下,重启后清空,适合不需要长期存储日志的场景。
auditd审计框架在最小化安装中通常不会默认安装,如果你不需要内核级别的系统调用审计,就不要主动安装它。auditd会记录大量内核事件,不仅消耗CPU和磁盘,其自身也曾出现过本地提权漏洞。只在有合规要求时才部署,并且严格控制审计规则的范围。
定期用debsums做完整性校验最小化安装完成后,系统中每一个文件都来自Debian官方仓库。你可以安装debsums工具,它会根据/var/lib/dpkg/info/目录下的MD5校验和,逐一比对系统中每个包的文件是否被篡改。首次运行debsums -c会列出所有校验失败的文件,正常情况下应该只有配置文件发生变化。将这个检查加入cron定时任务,可以在第一时间发现后门或rootkit对系统二进制文件的替换。
结合rkhunter或chkrootkit这类工具做补充扫描,但要注意这些工具本身也会引入额外的Perl或Python依赖。如果你追求极致精简,debsums加上手动检查/etc/passwd、/etc/shadow、/etc/crontab等关键文件的变更就足够了。
最小化安装不是一次性操作,而是一种持续维护的理念。每次用apt安装新软件前,问自己这个包是否真的必要。定期审视系统中运行的服务、监听的端口、已加载的内核模块。Debian的包管理系统给了你极高的可控性,利用好这份可控性,你的服务器从一开始就站在了更高的安全起点上。
