GNU General Public License v3.0

技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

深度技术分析:hartwork/sandwine

项目背景与痛点

在 Linux 环境下,由于软件生态的差异,某些专为 Windows 设计的应用可能无法直接运行。SandWine 项目正是为了填补这一痛点而生。通过利用 Wine 桥接工具与 bwrap/bubblewrap 隔离技术,它能够为 Windows 应用程序提供一个简易的命令行启动器。这样一来,用户能够在 Linux 环境中流畅运行 Windows 应用,极大拓宽了用户的应用生态,同时也确保了运行时环境的安全性与隔离性。

核心技术揭秘

技术架构与实现原理

项目采用了 Wine 作为 Windows 应用的桥接器,通过在系统层面的适配,允许 Windows 应用程序在 Linux 环境下正常运行。通过 bwrap/bubblewrap 技术,这些应用被置于隔离的执行环境中,防止意外数据泄露及系统损害。

以下是对 SandWine 核心数据流的一个简单架构图:

graph TD A[用户执行命令] --> B[解析命令行参数] B --> C{"参数是否正确"} C -->|"是"| D[使用 Wine 启动 Windows 应用] C -->|"否"| E[输出错误提示] D --> F[bwrap 隔离环境] F --> G[应用运行] G --> H[应用输出] H --> I[用户交互]

关键技术栈与设计模式

SandWine 项目的技术栈主要依赖于现有的稳定技术栈,包括 Wine 桥接工具以及 bwrap/bubblewrap 隔离技术。这种方式使得项目开发能够专注于增强易用性,简化配置流程,而无需从底层开始构筑技术栈。

在设计模式上,展现出基于社区成熟方案和开源工具组合的集约化设计思想,通过命令行工具封装了 Wine 和 bwrap 的复杂性,使最终用户能够直接通过简单命令调用现有应用,提高用户接受度和应用性。

功能亮点与差异

独特设计与优势

相较于同类竞品,SandWine 项目的主要优势在于其轻量级和易用性。它不对用户提供复杂的配置选项,而是直接封装了 Wine 和 bwrap 的具体配置,用户只需简单的命令行操作即可使用。这种设计可以显著降低用户入门成本,同时也便于大规模部署。

应用场景与落地建议

生产环境中使用 SandWine 时需注意以下几点:

  • 权限管理:需要注意对 bwrap 的权限配置,确保除了必要文件外,不要泄露更多系统信息。
  • 兼容性测试:并非所有 Windows 应用都可以无缝运行,对于企业环境而言,需要进行充分的兼容性测试。
  • 性能调优:不同应用可能运行效率不一,根据具体应用进行 Wine 和 bwrap 的调优也是必要步骤。

综合评价

SandWine 提供了一种轻量高效且易于使用的方式,让用户能够在 Linux 环境中运行 Windows 应用。其优势在于设计简洁明了,但同时也存在兼容性问题和系统管理不当的风险。对于需要紧密整合 Windows 和 Linux 应用的用户而言,无疑是一个值得尝试的工具。

关于

GitHub 原始描述(英文)

:wine_glass: Command-line tool to run Windows apps with Wine and bwrap/bubblewrap isolation on Linux

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

语言占比

Python

Release

README

pre-commit Run the test suite Run pre-commit

sandwine_threat_model.png

What is sandwine?

sandwine is a command-line tool to run Windows applications on GNU/Linux that offers more isolation than raw Wine and more convenience than raw bubblewrap. It uses Wine and bubblewrap (>=0.8.0), it does not replace them. sandwine is Software Libre written in Python 3, and is licensed under the “GPL v3 or later” license.

Installation

# pip3 install sandwine

Git development

git clone https://github.com/hartwork/sandwine
cd sandwine
python3 -m venv venv/
source venv/bin/activate
pip3 install .

Usage Examples

Install Winamp 5.66: no networking, no X11, no sound, no access to ~/* files

# cd ~/Downloads/
# sha256sum -c <(echo 'ac70a0c8a2928c91400b9ac3774b331f1d700f3486bab674dbd09da6b31fe130  winamp566_full_en-us.exe')
# WINEDEBUG=-all sandwine --dotwine winamp/:rw ./winamp566_full_en-us.exe /S /D='C:\Program' 'Files' '(x86)\Winamp' '5.66'

(The weird quoting in /D='C:\Program' 'Files' '(x86)\Winamp' '5.66' is documented behavior for NSIS.)

Run installed Winamp: with sound, with nested X11, no networking, no ~/* file access

# sandwine --pulseaudio --x11 --dotwine winamp/:rw --pass ~/Music/:ro --configure -- winamp

Argument --configure will bring up winecfg prior to Winamp so that you have a chance at unchecking these two boxes:

  • Graphics:
    • Allow the window manage to *decorate* the windows
    • Allow the window manage to *control* the windows

If Winamp crashes right after showing the main window, run it once more, there is some Wine bug at work here.

Run Games (3D applications) with modern stack (Wayland)

sandwine --dotwine ~/.wine-games:rw --pass /path/to/Games/folder:rw --wayland --pulseaudio "/path/to/Games/folder/Start.exe"

--dotwine ~/.wine-games:rw is needed to specify persistent Wineprefix. Needed for saves to be stored.

--pass /path/to/Games/folder:rw is used if your Games sit in system storage path. If your games are located in Wineprefix like “~/.wine/drive_c/Games”, you don’t need this parameter.

Optional: --nvidia-gpu to enable access to Nvidia GPU.

Optional: --raw-input to enable access to controllers (gamepads).

Run Geiss Screensaver: with sound, with host X11 (careful!), no networking, no ~/* file access

sandwine --host-x11-danger-danger --pulseaudio --retry -- ./geiss.scr /S

--host-x11-danger-danger make sandwine talk to the host X11 server, which would expose you to keyloggers so please re-visit your threat model before using --host-x11-danger-danger.

--retry is used to start programs a second time that consistently crash from graphics issues in a fresh Wine environment the first but not the second time. Potentially a bug in Wine, needs more investigation.

PS: The Geiss Screensaver has its GitHub home at https://github.com/geissomatik/geiss .

Run wget: with networking, no X11, no sound, no access to ~/* files

# sandwine --network --no-wine -- wget -S -O/dev/null https://blog.hartwork.org/

Argument --no-wine is mostly intended for debugging, but is needed here to invoke non-Wine wget.

Under the Hood

sandwine aims to protect against Windows applications that:

  • read and leak personal files through/to the Internet
  • read and leak keystrokes from other running applications (related post)
  • modify/destroy personal files
  • modify/destroy system files

To achieve that, by default the launched application:

  • Sees no files in ${HOME} and/or /home/ (but a tmpfs where written data lives in RAM and is being discarded on process termination, unless you pass --pass PATH:{ro,rw} for a related directory)
  • Does not have access to the internet (unless you pass --network)
  • Does not have access to your local X11 server (unless you enable some form of X11 integration, ideally nested X11)
  • Does not have access to your local Wayland display server (unless you pass --wayland)
  • Does not have access to your sound card (unless you pass --pulseaudio and/or --pipewire)
  • Does not have access to your GPU card (unless you pass --nvidia-gpu)
  • Does not have access to /dev/input (unless you pass --raw-input)
  • Does not have access to /dev/dri (unless you pass --nvidia-gpu, --wayland, or enable X11 support some way)

So what is shared with the application by default then?

What is Exposed by Default?

Files

Path Content
/ new tmpfs
/bin read-only bind mount
/dev new devtmpfs
/dev/ntsync bind mount with device access
/etc read-only bind mount
${HOME} new tmpfs
${HOME}/.wine new tmpfs
/lib read-only bind mount
/lib32 read-only bind mount
/lib64 read-only bind mount
/proc new procfs
/sys read-only bind mount
/tmp new tmpfs
/usr read-only bind mount

Environment Variables

  • ${DISPLAY}
  • ${HOME}
  • ${HOSTNAME} (with random 12-hex-digits value)
  • ${PATH} (with known-unavailable entries removed)
  • ${TERM}
  • ${USER}
  • ${WINEDEBUG}
  • ${WINEDLLOVERRIDES}
  • ${wineserver} (lowercase, with the path to command wineserver)

sandwine features include:

  • A focus on security, usability, transparency
  • Support for nested X11 provided by:
    • X2Go nxagent (seamless)
    • Xephyr
    • Xnest
    • Xpra (experimental, careful!)
    • Xvfb (invisible)
  • Support for Wayland
  • Support for PulseAudio
  • Support for PipeWire
  • Support for /etc/resolv.conf provided by:
    • NetworkManager
    • systemd-resolved
  • Support for Nvidia GPUs
  • Support for NTsync

Threat Model and Known Limitations

  • If your life depends on the sandbox, please consider using a virtual machine rather than sandwine, e.g. because your username is exposed to the running application and depending on your threat model, that may be too much already.
  • sandwine is not intended for use with known-malicious software, viruses, malware.
  • sandwine has not seen any known external security audits, yet.
  • sandwine relies on bubblewrap for its security, so it can only be as secure as bubblewrap.
  • sandwine does not limit the set of syscalls that the application can do. bubblewrap supports arguments --seccomp and --add-seccomp-fd to go further on that end, but sandwine does not use them so far.
  • sandwine does not keep the application from using loads of RAM, CPU time and/or disk space. If your concerns include denial of service, you need protection beyond sandwine.
  • sandwine relies on sane file permissions in the places that are shared read-only. If you have files in e.g. /etc that contain credentials but are readable by unprivileged users, sandwine will do nothing to block that read access.
  • If the Windows application to be run expects a GNU/Linux environment and includes Linux Kernel exploit code, then that exploit is not likely to be stopped by sandwine.
  • If you manually allow the sandboxed application to communicate with an unsandboxed application and the latter executes commands for the former, then the sandbox cannot prevent privilege escalation. Think of a model like the Docker daemon where whoever can talk to the Docker daemon can become root. If you use sandwine with something like that, sandwine will have a problem.
  • Start-up time below 200ms is not a goal.

Reporting Vulnerabilities

If you think you found a vulnerability in sandwine, please reach out via e-mail so we can have a closer look and coordinate disclosure.


Sebastian Pipping, Berlin, 2023

评论

暂无评论