Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f9ab623
security(linux): pre-release hardening from the vulnerability assessment
Anof-cyber Oct 20, 2026
801de95
docs(linux): remove the audit notes from the repository
Anof-cyber Oct 20, 2026
20271c4
test(windows): real-traffic end-to-end test in the Windows workflow (…
Anof-cyber Oct 20, 2026
ecc4e02
test(windows): commit the end-to-end HTTP proxy helper (*.py was igno…
Anof-cyber Oct 20, 2026
c4a1689
test(windows): e2e - patch Nexus for UDP ASSOCIATE, and only count a …
Anof-cyber Oct 20, 2026
82dcdaf
test(windows): e2e - UDP checks match what Nexus and nslookup really …
Anof-cyber Oct 20, 2026
547c1c5
test(windows): e2e - rule matching, ports, ranges, order, failures an…
Anof-cyber Oct 20, 2026
1f9b3d0
test(windows): e2e - real installer, service, Live Connections counte…
Anof-cyber Oct 20, 2026
de11442
test(windows): e2e service - keep one-line answers an array, app clos…
Anof-cyber Oct 20, 2026
174aa19
test(windows): e2e service - logging checks match the real semantics …
Anof-cyber Oct 20, 2026
a6bf22d
test(windows): e2e service - dedup check uses one process
Anof-cyber Oct 20, 2026
364cb18
test(windows): e2e service - use a curl option that exists
Anof-cyber Oct 20, 2026
ee065e1
build(linux): self-contained binaries, nothing to install except GTK3…
Anof-cyber Oct 20, 2026
6931655
feat(linux/gui): one Action choice per rule, per-proxy DNS only, logo…
Anof-cyber Oct 20, 2026
0172c6c
fix(linux): a connection reset mid-transfer no longer kills the proce…
Anof-cyber Oct 20, 2026
797b98e
feat(linux): ship a launcher entry and icon so the desktop shows the …
Anof-cyber Oct 20, 2026
f3efa85
fix(linux): UDP session eviction freed a session a worker was still s…
Anof-cyber Oct 20, 2026
75126ac
fix(linux): UDP sender check by user instead of descriptor scans; tes…
Anof-cyber Oct 20, 2026
42fe97a
feat(linux/gui): Profile is a menu of its own, like the Windows app, …
Anof-cyber Oct 20, 2026
c77538d
feat(linux/gui): menu bar like the Windows app (Proxy, Profile, Setti…
Anof-cyber Oct 20, 2026
fd341f9
test(linux/gui): opt-in screenshot scenario (PB_SCREENSHOT_DIR) used …
Anof-cyber Oct 20, 2026
e34cec0
feat(linux): ProxyBridge service (root) and an unprivileged window th…
Anof-cyber Oct 20, 2026
8ef7fed
feat(linux): installer sets up the service and the group; CI and docs…
Anof-cyber Oct 20, 2026
9ac074e
fix(linux/gui): a window whose service restarted starts the engine ag…
Anof-cyber Oct 20, 2026
bf7a769
test(linux): gui_service restores the system state first, whatever a …
Anof-cyber Oct 20, 2026
57cf847
fix(linux): security review of the service and installer
Anof-cyber Oct 21, 2026
aaa84e6
fix(linux/gui): an upgrade from 3.2.x or the Linux beta keeps its set…
Anof-cyber Oct 21, 2026
74b3ab8
test(linux): e2e_lifecycle reaches the library as an unprivileged use…
Anof-cyber Oct 21, 2026
d421c26
test(linux): e2e_exempt counts proxy requests by port; e2e_logging wa…
Anof-cyber Oct 21, 2026
acf3955
chore(linux): version 4.0.0
Anof-cyber Oct 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions .github/workflows/build-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,11 @@ jobs:
build-essential \
gcc \
make \
bzip2 \
clang \
linux-tools-common \
linux-tools-generic \
libbpf-dev \
libelf-dev \
zlib1g-dev \
libgtk-3-dev \
pkg-config
shell: bash
Expand Down Expand Up @@ -151,17 +150,21 @@ jobs:
run: |
set -e
out="$PWD/Linux/output"
run_in() { # image, install command
# The library and the command line program must run in a bare image with nothing installed; only the GUI needs GTK3.
run_in() { # image, command that installs GTK3 for the GUI check
echo "::group::$1"
docker run --rm -v "$out:/out:ro" "$1" sh -c "$2 >/dev/null 2>&1 &&
LD_LIBRARY_PATH=/out /out/ProxyBridge --help | grep -q -- '--profile' && echo 'CLI starts' &&
missing=\$(LD_LIBRARY_PATH=/out ldd /out/ProxyBridge /out/libproxybridge.so /out/ProxyBridgeGUI 2>&1 | grep 'not found' || true) &&
if [ -n \"\$missing\" ]; then echo \"missing: \$missing\"; exit 1; fi && echo 'all libraries resolve'"
docker run --rm -v "$out:/out:ro" "$1" sh -c "
/out/ProxyBridge --help | grep -q -- '--profile' && echo 'CLI starts with nothing installed' &&
missing=\$(ldd /out/ProxyBridge /out/libproxybridge.so 2>&1 | grep 'not found' || true) &&
if [ -n \"\$missing\" ]; then echo \"missing: \$missing\"; exit 1; fi && echo 'CLI and library: all libraries resolve' &&
$2 >/dev/null 2>&1 &&
missing=\$(LD_LIBRARY_PATH=/out ldd /out/ProxyBridgeGUI 2>&1 | grep 'not found' || true) &&
if [ -n \"\$missing\" ]; then echo \"missing: \$missing\"; exit 1; fi && echo 'GUI: all libraries resolve with GTK3'"
echo "::endgroup::"
}
run_in ubuntu:22.04 "apt-get update && apt-get install -y libelf1 zlib1g libgtk-3-0"
run_in debian:12 "apt-get update && apt-get install -y libelf1 zlib1g libgtk-3-0"
run_in fedora:40 "dnf install -y elfutils-libelf zlib gtk3"
run_in ubuntu:22.04 "apt-get update && apt-get install -y libgtk-3-0"
run_in debian:12 "apt-get update && apt-get install -y libgtk-3-0"
run_in fedora:40 "dnf install -y gtk3"
shell: bash

- name: Verify the build left the source tree clean
Expand All @@ -187,18 +190,19 @@ jobs:
uname -r
ls /sys/kernel/btf/vmlinux && mount | grep -q "type cgroup2" || { echo "kernel lacks BTF or cgroup2: skipping"; exit 0; }
fail=0
for t in e2e e2e_rules e2e_domains e2e_security e2e_profile e2e_parity e2e_cli e2e_faults e2e_udp e2e_rules_diff e2e_logging e2e_exempt e2e_lifecycle api_live; do
for t in e2e e2e_rules e2e_domains e2e_security e2e_profile e2e_parity e2e_cli e2e_faults e2e_udp e2e_rules_diff e2e_logging e2e_exempt e2e_lifecycle api_live e2e_daemon e2e_service; do
echo "::group::$t"
sudo env PB_DIR="$PWD/Linux/output" BPFTOOL="$BPFTOOL" bash "Linux/tests/$t.sh" || fail=1
echo "::endgroup::"
done
echo "::group::e2e_checker"
env PB_DIR="$PWD/Linux/output" bash Linux/tests/e2e_checker.sh || fail=1
echo "::endgroup::"
for t in gui_headless gui_ui; do
for t in gui_headless gui_ui gui_service; do
echo "::group::$t"
if command -v broadwayd > /dev/null; then
if [ "$t" = gui_headless ]; then sudo env BPFTOOL="$BPFTOOL" bash Linux/tests/gui_headless.sh "$PWD/Linux/output/ProxyBridgeGUI" "$PWD/Linux/output" || fail=1
elif [ "$t" = gui_service ]; then sudo env BPFTOOL="$BPFTOOL" bash Linux/tests/gui_service.sh "$PWD/Linux/output" || fail=1
else sudo env BPFTOOL="$BPFTOOL" bash Linux/tests/gui_ui.sh "$PWD/Linux/output" || fail=1; fi
else echo "broadwayd not available: skipped"; fi
echo "::endgroup::"
Expand Down
41 changes: 41 additions & 0 deletions .github/workflows/build-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,47 @@ jobs:
.\compile.ps1 -NoSign
shell: pwsh

# The unit tests above use made-up data. This step runs the REAL engine and WinDivert driver (through the CLI) with a
# real SOCKS5 proxy (Nexus Proxy), a small real HTTP proxy and real requests to real servers, and checks that traffic
# goes where the rules say. It loads a kernel driver, so it only runs here on the disposable runner (the script
# refuses to run elsewhere). Best effort for now: it depends on the internet and on the hosted runner allowing the
# driver, so a failure is reported without failing the build. See Windows\tests\e2e\run_e2e.ps1.
- name: Real-traffic end-to-end tests (best effort)
continue-on-error: true
timeout-minutes: 25
run: |
cd Windows
.\tests\e2e\run_e2e.ps1 -PbDir .\output
shell: pwsh

# The same idea for the parts around the engine: it runs the real installer, the ProxyBridge Service, the app's own
# client code (Live Connections, pause, logging switches, rule changes, permissions), the real app and the real
# uninstaller. It installs ProxyBridge on the runner, so it runs after the step above. Best effort, same reasons.
# See Windows\tests\e2e\run_e2e_service.ps1.
- name: Real-traffic end-to-end tests, installer and service (best effort)
continue-on-error: true
timeout-minutes: 25
run: |
cd Windows
.\tests\e2e\run_e2e_service.ps1 -PbDir .\output
shell: pwsh

- name: Upload end-to-end logs
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: ProxyBridge-E2E-Logs-${{ github.sha }}
path: |
Windows/tests/e2e/out/*.log
Windows/tests/e2e/out/*.err
Windows/tests/e2e/out/*.out
Windows/tests/e2e/out/*.pbprofile
Windows/tests/e2e/out_service/*.log
Windows/tests/e2e/out_service/*.err
Windows/tests/e2e/out_service/*.out
if-no-files-found: ignore
retention-days: 7

- name: Upload artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,10 @@ jobs:
make \
clang \
curl \
bzip2 \
linux-tools-common \
linux-tools-generic \
libbpf-dev \
libelf-dev \
zlib1g-dev \
libgtk-3-dev \
pkg-config
shell: bash
Expand Down
15 changes: 10 additions & 5 deletions .github/workflows/release-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,11 @@ jobs:
build-essential \
gcc \
make \
bzip2 \
clang \
linux-tools-common \
linux-tools-generic \
libbpf-dev \
libelf-dev \
zlib1g-dev \
libgtk-3-dev \
pkg-config
shell: bash
Expand Down Expand Up @@ -114,7 +113,6 @@ jobs:

- name: Create release archive
run: |
VERSION="${{ steps.version.outputs.version }}"
ARCHIVE_NAME="ProxyBridge-Linux-v${VERSION}.tar.gz"

echo "Creating archive: $ARCHIVE_NAME"
Expand All @@ -127,7 +125,12 @@ jobs:

# Move archive to root for upload
mv "../$ARCHIVE_NAME" "../../$ARCHIVE_NAME"
cd ../..
sha256sum "$ARCHIVE_NAME" > "$ARCHIVE_NAME.sha256"
cat "$ARCHIVE_NAME.sha256"
shell: bash
env:
VERSION: ${{ steps.version.outputs.version }}

- name: List release files
run: |
Expand All @@ -144,7 +147,7 @@ jobs:

- name: Upload archive to release
run: |
gh release upload "$TAG" ProxyBridge-Linux-v*.tar.gz --clobber
gh release upload "$TAG" ProxyBridge-Linux-v*.tar.gz ProxyBridge-Linux-v*.tar.gz.sha256 --clobber
shell: bash
env:
GH_TOKEN: ${{ github.token }}
Expand All @@ -154,5 +157,7 @@ jobs:
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: ProxyBridge-Linux-Release-${{ steps.version.outputs.version }}
path: ProxyBridge-Linux-*.tar.gz
path: |
ProxyBridge-Linux-*.tar.gz
ProxyBridge-Linux-*.tar.gz.sha256
retention-days: 90
3 changes: 1 addition & 2 deletions .github/workflows/sonarqube.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,10 @@ jobs:
make \
clang \
curl \
bzip2 \
linux-tools-common \
linux-tools-generic \
libbpf-dev \
libelf-dev \
zlib1g-dev \
libgtk-3-dev \
pkg-config
shell: bash
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,9 @@ Windows/**/*.obj
Windows/gui/*.res
Windows/**/*.res
Windows/tests/out/

Windows/tests/e2e/out/
Windows/tests/e2e/out_service/

# the end-to-end test helper is a script we ship
!Windows/tests/e2e/*.py
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ request, before the build. **Please add or update a test when you change behavio
case in `test_engine.c`, a profile-format change in `test_profile.c`, or a new window feature in `test_rules_ui.c` /
`test_main_ui.c`.

**Real-traffic end-to-end test:** `Windows/tests/e2e/run_e2e.ps1` is the opposite of the unit tests: it runs the real engine and WinDivert driver (through `ProxyBridge_CLI.exe`) with a real SOCKS5 proxy (Nexus Proxy), a small HTTP proxy and real requests to real servers, and checks that traffic goes where the rules say (SOCKS5, HTTP proxy, login, Direct, Block, domain and CIDR rules, UDP, an HTTPS download with a checksum). Because it loads a kernel driver and redirects the machine's traffic, it runs only on the CI runner (the `Build Windows` workflow, best effort, logs in the `ProxyBridge-E2E-Logs` artifact) and refuses to run anywhere else unless you pass `-IKnowThisLoadsTheKernelDriver` on a throw-away VM.

**Project Structure:**
- `Windows/src/` - C library core (ProxyBridge.c, ProxyBridge.h)
- `ProxyBridge.c` - Main packet interception logic
Expand Down
Loading
Loading