Ubuntu系统中snap应用默认采用严格的沙盒隔离机制,每个snap包都运行在独立的confinement环境中,与宿主系统和其他应用之间有明确的权限边界。但经典模式(classic confinement)会直接打破这种隔离,让snap应用获得与传统deb安装包几乎同等的系统访问权限,这意味着一旦经典模式的snap应用存在漏洞或被恶意利用,攻击者可以直接访问你的文件系统、网络接口甚至硬件设备。核心问题就在于:很多用户在安装snap时根本不知道自己装的是经典模式还是严格模式,也不清楚如何检查和限制权限。
要搞清楚这个风险,首先得理解snap的三种confinement级别。严格模式(strict)是默认的,应用只能访问自己的沙盒空间和明确声明的接口;经典模式(classic)则完全放开,应用可以访问整个系统;还有一种开发模式(devmode),主要用于调试,权限同样很宽泛。Ubuntu从20.x版本开始大力推行snap作为默认安装方式,Firefox、Chromium、VS Code等主流软件都被打包成snap分发,其中不少采用了经典模式。这就是风险的根源所在。
snap权限隔离的核心机制是什么snap的安全架构基于AppArmor、cgroups、seccomp和命名空间这四项Linux内核安全技术的组合。每个snap包在安装时会自动生成一套AppArmor策略文件,限制该应用能打开哪些文件、能发起哪些系统调用、能访问哪些网络资源。这些策略是自动生成的,但并不完美,因为自动生成意味着策略可能过于宽松或者过于严格导致功能异常。
具体来说,snap应用的权限通过"接口"(interface)来管理。常见的接口包括home、network、network-bind、removable-media、camera、audio-playback等。每个接口对应一种系统资源的访问能力。你可以通过snap的连接和断开操作来动态管理这些权限。比如一个严格模式的snap应用如果需要访问你的家目录,必须显式连接home接口,否则它只能访问自己沙盒内的~/snap目录。
# 查看已安装snap应用的confinement级别 snap list --all | grep classic # 查看某个snap应用的具体权限 snap info <应用名> # 查看当前所有的接口连接情况 snap connections
上面这些命令是日常管理snap权限的基础工具。特别是snap connections这条命令,它会列出所有已建立的接口连接,包括哪个snap通过哪个接口连接到了哪个插槽(slot),一目了然。很多安全隐患就藏在这些连接关系里。
经典模式为什么危险:具体风险场景分析经典模式的snap应用绕过了所有沙盒限制,直接以普通用户或root身份运行。这带来几个具体风险。第一,文件系统完全暴露。经典模式的snap可以读取/etc下的配置文件、/home下的用户数据、甚至/root目录。如果这个应用被植入后门或者存在远程代码执行漏洞,攻击者就能直接拿到你的敏感文件。
第二,网络权限不受控。严格模式的snap如果需要网络访问,必须连接network接口,而且流量可以被监控。经典模式的snap直接使用宿主系统的网络栈,没有任何额外限制,它可以监听任意端口、发起任意连接、甚至抓取本地网络流量。
第三,硬件访问无屏障。经典模式的snap可以直接访问USB设备、摄像头、麦克风、蓝牙适配器等硬件。一个恶意的经典模式snap可以在后台持续录音录像而你毫无察觉。
第四,权限提升风险。虽然snap应用默认不以root运行,但经典模式下如果应用本身有setuid二进制文件或者利用了内核漏洞,提权路径比严格模式短得多。严格模式下即使应用被攻破,攻击者也被困在沙盒里,而经典模式下沙盒根本不存在。
如何检查你的系统中哪些snap是经典模式这是最实用的一步。打开终端,执行以下命令:
# 列出所有使用经典confinement的snap包
snap list --all | awk '/classic/ {print $1, $3}'
# 更详细的查看方式
snap info --verbose <应用名> | grep confinement
在Ubuntu 22.04及以后的版本中,你可能会发现chromium、firefox、vlc、code等常见应用都是经典模式。这不是偶然的,因为这些应用需要访问用户文件、播放媒体、使用硬件加速等功能,严格模式的接口限制无法满足需求,所以开发者选择了经典模式。但这并不意味着你必须接受这种风险。
针对经典模式snap的具体防护策略第一招:能换deb就换deb。对于Firefox和Chromium这类浏览器,Ubuntu其实同时提供了deb版本和snap版本。如果你对安全要求高,直接用deb版本,通过apt安装,传统的AppArmor策略虽然也不完美,但至少你可以用aa-status和aa-genprof等工具手动调整策略。对于Chromium,可以添加Mozilla的PPA来获取deb版本:
sudo add-apt-repository ppa:mozillateam/ppa sudo apt install chromium-browser
第二招:手动限制经典模式snap的接口。即使是经典模式,你仍然可以断开某些不必要的接口连接。比如一个经典模式的办公软件不需要访问摄像头,你可以断开camera接口:
# 断开某个snap的特定接口 sudo snap disconnect <应用名>:camera sudo snap disconnect <应用名>:removable-media # 查看断开后的效果 snap connections <应用名>
第三招:使用AppArmor手动加固。对于经典模式的snap,你可以在/etc/apparmor.d/目录下创建自定义策略文件,进一步限制其行为。虽然snap自带的AppArmor策略在经典模式下基本失效,但你可以叠加自定义规则。这需要一定的AppArmor知识,但效果显著。
第四招:监控snap应用的行为。使用strace、auditd或者系统自带的snap审计日志来监控经典模式snap的系统调用和文件访问。auditd可以设置规则追踪特定snap进程的所有文件操作:
# 添加audit规则监控某个snap应用的文件访问 sudo auditctl -w /home -p rw -k snap_monitor sudo ausearch -k snap_monitorUbuntu官方对snap安全的态度与争议
需要客观指出的是,Ubuntu团队一直强调snap的安全性,认为自动生成的AppArmor策略加上严格模式的隔离已经足够安全。但社区中有大量安全研究人员和资深Linux用户持不同意见。核心争议点在于:自动生成的策略覆盖面不够全面,很多边缘场景没有被正确限制;经典模式的大量使用实际上削弱了snap的安全优势;snap的更新机制是自动且不可控的,用户无法选择不更新,这意味着一个原本安全的snap可能在某次更新后引入新的权限或漏洞。
从实际案例来看,2023年曾有安全研究人员发现某些经典模式的snap应用在更新后新增了不必要的接口连接,而用户完全不知情。这说明snap的权限管理在实践中存在透明度不足的问题。作为用户,你不能完全依赖snap自身的安全声明,必须主动检查和管理。
企业环境和服务器场景的特殊考量在服务器环境中,snap的使用需要更加谨慎。Ubuntu Server默认不会预装太多snap应用,但如果你通过snap安装了Docker、LXD或者其他服务,一定要确认它们的confinement级别。特别是LXD,它使用经典模式,因为它需要管理整个系统的容器和网络。这意味着LXD snap如果被攻破,整个服务器都会沦陷。
企业用户的建议是:生产环境尽量避免使用snap,尤其是经典模式的snap。如果必须使用,应该建立定期审计机制,用脚本批量检查所有snap的confinement级别和接口连接状态,纳入安全合规检查流程。
总结:平衡便利性与安全性的实用建议snap的权限隔离机制本身是好的设计,严格模式确实提供了比传统deb包更强的默认安全保障。但经典模式的广泛使用让这个优势大打折扣。作为Ubuntu用户,你需要做到三点:第一,定期运行snap list --all检查哪些应用是经典模式;第二,对于不需要经典权限的应用,考虑切换到deb版本或者手动断开多余接口;第三,保持系统更新但同时关注snap的变更日志,了解每次更新带来了什么权限变化。安全不是一劳永逸的事情,而是持续管理的过程。Ubuntu给了你工具,但用不用、怎么用,决定权在你手里。
