diff --git a/.cargo/config.toml b/.cargo/config.toml
index 75f6d91..cd566cd 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -2,11 +2,8 @@
RUST_TEST_THREADS = "1"
# macOS 26 (Tahoe) moved libc++ headers inside the SDK; Apple clang 17 no longer
-# finds them at the old search path. This causes boring-sys's cmake step to fail
-# when building with --features stealth. Setting CXXFLAGS and SDKROOT here makes
-# them visible to all build scripts (including boring-sys's) so cmake can locate
-# the headers. force=false lets CI or developers override via their shell env.
-# Non-macOS platforms ignore SDKROOT; the -isystem path is silently skipped if
-# it doesn't exist. See: https://github.com/h4ckf0r0day/obscura/issues/136
-CXXFLAGS = { value = "-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1", force = false }
-SDKROOT = { value = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk", force = false }
+# finds them at the old search path. Scope the workaround to Apple targets so a
+# Linux stealth build never inherits a macOS SDK include flag. cc-rs recognizes
+# the target-suffixed CXXFLAGS variables below. See issue #136.
+CXXFLAGS_aarch64_apple_darwin = { value = "-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1", force = false }
+CXXFLAGS_x86_64_apple_darwin = { value = "-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1", force = false }
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index cf439dc..74955da 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -50,41 +50,90 @@ jobs:
with:
targets: ${{ matrix.target }}
- - name: Build
+ - name: Install stealth build dependencies (Linux)
+ if: runner.os == 'Linux'
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y cmake clang libclang-dev llvm-dev
+
+ - name: Configure libclang (macOS)
+ if: runner.os == 'macOS'
+ shell: bash
+ run: |
+ SDK_PATH="$(xcrun --show-sdk-path)"
+ echo "SDKROOT=$SDK_PATH" >> "$GITHUB_ENV"
+ echo "CXXFLAGS=-isystem $SDK_PATH/usr/include/c++/v1" >> "$GITHUB_ENV"
+ echo "LIBCLANG_PATH=$(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib" >> "$GITHUB_ENV"
+
+ - name: Configure libclang (Windows)
+ if: runner.os == 'Windows'
+ shell: pwsh
+ run: |
+ "LIBCLANG_PATH=C:\Program Files\LLVM\bin" | Out-File -FilePath $env:GITHUB_ENV -Append
+
+ - name: Build default release binary
run: cargo build --release --target ${{ matrix.target }}
- - name: Build stealth
- run: cargo build --release --target ${{ matrix.target }} --features stealth
- continue-on-error: true
+ - name: Stage default release binary
+ shell: bash
+ run: |
+ BIN_DIR=target/${{ matrix.target }}/release
+ mkdir -p dist/default
+ if [ -f "$BIN_DIR/obscura.exe" ]; then
+ cp "$BIN_DIR/obscura.exe" "$BIN_DIR/obscura-worker.exe" dist/default/
+ else
+ cp "$BIN_DIR/obscura" "$BIN_DIR/obscura-worker" dist/default/
+ fi
- - name: Smoke test (V8 snapshot)
+ # Build and package stealth separately so the default download keeps its
+ # lower RSS while the advertised wreq/BoringSSL variant cannot silently
+ # fall back to a non-stealth binary.
+ - name: Build stealth release binary
+ run: cargo build --release --target ${{ matrix.target }} --features stealth
+
+ - name: Stage stealth release binary
+ shell: bash
+ run: |
+ BIN_DIR=target/${{ matrix.target }}/release
+ mkdir -p dist/stealth
+ if [ -f "$BIN_DIR/obscura.exe" ]; then
+ cp "$BIN_DIR/obscura.exe" "$BIN_DIR/obscura-worker.exe" dist/stealth/
+ else
+ cp "$BIN_DIR/obscura" "$BIN_DIR/obscura-worker" dist/stealth/
+ fi
+
+ - name: Smoke test release binaries (V8 snapshot)
# Run the V8 path once so a release never ships a binary that crashes at
# isolate init from a mismatched snapshot (issue #290). The data: URL
# keeps it offline. Every target here is native, so the runner can
- # execute what it just built.
+ # execute both variants it just built.
shell: bash
run: |
- BIN=target/${{ matrix.target }}/release/obscura
- [ -f "$BIN.exe" ] && BIN="$BIN.exe"
- "$BIN" fetch "data:text/html,
ok" --eval "1+1"
+ for VARIANT in default stealth; do
+ BIN=dist/$VARIANT/obscura
+ [ -f "$BIN.exe" ] && BIN="$BIN.exe"
+ "$BIN" fetch "data:text/html,ok" --eval "1+1"
+ done
- name: Package (Unix)
if: runner.os != 'Windows'
run: |
- cd target/${{ matrix.target }}/release
- tar czf ../../../${{ matrix.name }}.tar.gz obscura obscura-worker
- cd ../../..
+ tar czf ${{ matrix.name }}.tar.gz -C dist/default obscura obscura-worker
+ tar czf ${{ matrix.name }}-stealth.tar.gz -C dist/stealth obscura obscura-worker
- name: Package (Windows)
if: runner.os == 'Windows'
run: |
- cd target/${{ matrix.target }}/release
- 7z a ../../../${{ matrix.name }}.zip obscura.exe obscura-worker.exe
- cd ../../..
+ cd dist/default
+ 7z a ../../${{ matrix.name }}.zip obscura.exe obscura-worker.exe
+ cd ../stealth
+ 7z a ../../${{ matrix.name }}-stealth.zip obscura.exe obscura-worker.exe
- name: Upload
uses: softprops/action-gh-release@v2
with:
files: |
${{ matrix.name }}.tar.gz
+ ${{ matrix.name }}-stealth.tar.gz
${{ matrix.name }}.zip
+ ${{ matrix.name }}-stealth.zip
diff --git a/README.md b/README.md
index c4d0bfd..4e0992c 100644
--- a/README.md
+++ b/README.md
@@ -169,6 +169,10 @@ No Chrome, no Node.js, no dependencies. Release archives include both
`obscura` and `obscura-worker`; keep them in the same directory for the
parallel `scrape` command.
+Default archive names contain the lean binary. Archives ending in
+`-stealth.tar.gz` or `-stealth.zip` additionally include the wreq/BoringSSL
+transport used for TLS impersonation.
+
Linux release builds target Ubuntu 22.04 so the downloaded binary remains
usable on common LTS servers with glibc 2.35+.
@@ -192,6 +196,14 @@ cargo build --release --features stealth
```
Requires Rust 1.75+ ([rustup.rs](https://rustup.rs)). First build takes ~5 min (V8 compiles from source, cached after).
+The stealth build also compiles BoringSSL and generates bindings, so it needs
+CMake, Clang, and the libclang/LLVM development libraries. On Ubuntu/Debian:
+
+```bash
+sudo apt-get install build-essential cmake clang libclang-dev llvm-dev
+```
+
+The default build does not require these additional stealth dependencies.
## Quick Start
diff --git a/docs/Build-from-source.md b/docs/Build-from-source.md
index 84be00c..db31e3c 100644
--- a/docs/Build-from-source.md
+++ b/docs/Build-from-source.md
@@ -24,6 +24,19 @@ cargo build --release --features stealth
Adds TLS fingerprint randomization and the tracker blocklist. See [Configure stealth and proxies](Configure-stealth-and-proxies.md).
+The stealth feature builds BoringSSL and generates Rust bindings. In addition
+to the default requirements, install CMake, Clang, and the libclang/LLVM
+development libraries. On Ubuntu/Debian:
+
+```bash
+sudo apt-get install build-essential cmake clang libclang-dev llvm-dev
+```
+
+On macOS, install the Xcode Command Line Tools and CMake. On Windows, install
+the Visual Studio C++ Build Tools, CMake, and LLVM/Clang. Ensure the directory
+containing `libclang` is available through `LIBCLANG_PATH` if bindgen cannot
+locate it automatically.
+
## OpenSSL on older systems
If the build fails on the vendored OpenSSL with an AVX-512 assembler error (common on older VPS hosts):
diff --git a/docs/Configure-stealth-and-proxies.md b/docs/Configure-stealth-and-proxies.md
index 26a08ae..1bc222a 100644
--- a/docs/Configure-stealth-and-proxies.md
+++ b/docs/Configure-stealth-and-proxies.md
@@ -15,7 +15,10 @@ What `--stealth` changes:
- Loads a tracker blocklist that drops requests to known analytics and fingerprinting endpoints.
- Bundles webpki roots instead of relying on the system store.
-Requires a build that includes the stealth feature. Release binaries on the Releases page include it. To build it yourself:
+Requires a build that includes the stealth feature. The Releases page provides
+explicitly named `-stealth` archives alongside the lean default archives, so
+users who do not need wreq/BoringSSL do not pay its binary-size or RSS cost. To
+build the stealth variant yourself:
```bash
cargo build --release --features stealth
diff --git a/docs/Installation.md b/docs/Installation.md
index 87e3988..54624a6 100644
--- a/docs/Installation.md
+++ b/docs/Installation.md
@@ -59,6 +59,10 @@ See [Build from source](Build-from-source.md).
- `obscura`: CLI and CDP server.
- `obscura-worker`: helper for the parallel `scrape` command. Keep both in the same directory.
+The standard archive names contain the lean default build. Choose the matching
+archive with a `-stealth` suffix when you need the wreq/BoringSSL transport for
+TLS impersonation.
+
## Smoke test
```bash