Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
bbf26e4
feat(linux): replace iptables/NFQUEUE with an eBPF cgroup datapath
Anof-cyber Oct 14, 2026
da8e8fa
feat(linux/cli): multiple proxies, per-rule proxy and domain rules
Anof-cyber Oct 14, 2026
e3fea87
feat(linux/gui): proxy manager, profiles and per-rule proxy
Anof-cyber Oct 14, 2026
23e94ab
test(linux): end-to-end, scale and benchmark suites
Anof-cyber Oct 14, 2026
d3f2bec
docs(linux): describe the eBPF design; update dependencies and ignores
Anof-cyber Oct 14, 2026
ec50a20
build(linux): build out of tree so only output/ receives final files
Anof-cyber Oct 14, 2026
aef0708
ci(linux): install clang, bpftool and libbpf; run the unit tests
Anof-cyber Oct 14, 2026
f4e7daf
ci(linux): build the Linux-ebpf branch and verify the new build output
Anof-cyber Oct 14, 2026
9a366b0
ci(linux): get a real bpftool on Ubuntu runners
Anof-cyber Oct 14, 2026
e0e691a
test(linux): isolate the relay DNS tests; add watchdogs and CI timeouts
Anof-cyber Oct 14, 2026
2aac5bf
test(linux): make the relay tests robust on slow, shared CPUs
Anof-cyber Oct 14, 2026
78863ae
test(linux): report why relay_connect fails in the relay tests
Anof-cyber Oct 14, 2026
dfa5d4e
test(linux): accept a reset during connect() as "closed by the relay"
Anof-cyber Oct 14, 2026
8019f00
test(linux): end-to-end suite against Nexus Proxy (real SOCKS5 forwar…
Anof-cyber Oct 14, 2026
29a01c0
docs(linux): the minimum kernel is 5.11, not 5.8
Anof-cyber Oct 14, 2026
5cedb7b
fix(linux): bind the relay hand-off to the client address, exempt loc…
Anof-cyber Oct 14, 2026
caace65
fix(linux/relay): source-address check, leak audit, cheaper UDP path,…
Anof-cyber Oct 14, 2026
a89668d
fix(linux/cli): keep proxy credentials out of the process list; use t…
Anof-cyber Oct 14, 2026
6c8e87a
refactor(linux/gui): fix the exit leak, share helpers, move the rules…
Anof-cyber Oct 14, 2026
bdeb458
test(linux): security, churn and exemption tests; document the securi…
Anof-cyber Oct 14, 2026
6ee21fd
build(linux): hardened, portable build; fix GLIBC_2.38 requirement (#…
Anof-cyber Oct 14, 2026
3552375
feat(linux/gui): event pipeline, status bar, async start/stop, leak f…
Anof-cyber Oct 14, 2026
6c63fea
ci(linux): new build dependencies, portability job on older distros, …
Anof-cyber Oct 14, 2026
a036bd0
chore(linux): version 4.0.0-Beta
Anof-cyber Oct 14, 2026
9854864
chore(linux): drop the obsolete crash-cleanup hint from the install s…
Anof-cyber Oct 14, 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
121 changes: 113 additions & 8 deletions .github/workflows/build-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ permissions:

on:
push:
branches: [ master, dev ]
branches: [ master, dev, Linux-ebpf ]
pull_request:
branches: [ master, dev ]
branches: [ master, dev, Linux-ebpf ]
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
actions: read
Expand All @@ -28,12 +29,27 @@ jobs:
build-essential \
gcc \
make \
libnetfilter-queue-dev \
libnfnetlink-dev \
clang \
linux-tools-common \
linux-tools-generic \
libbpf-dev \
libelf-dev \
zlib1g-dev \
libgtk-3-dev \
pkg-config
shell: bash

- name: Locate bpftool
# On Ubuntu "bpftool" is only a virtual package; the real binary ships in linux-tools-* and is not on PATH
# for the runner's cloud kernel, so find it explicitly.
run: |
shopt -s nullglob
candidates=(/usr/lib/linux-tools/*/bpftool)
[ ${#candidates[@]} -gt 0 ] || { echo "bpftool binary not found"; ls /usr/lib/linux-tools 2>&1 || true; exit 1; }
echo "BPFTOOL=${candidates[0]}" >> "$GITHUB_ENV"
"${candidates[0]}" version | head -1
shell: bash

- name: Verify dependencies
run: |
echo "=== Checking GCC ==="
Expand All @@ -48,15 +64,30 @@ jobs:
echo "=== Checking GTK3 ==="
pkg-config --modversion gtk+-3.0
echo ""
echo "=== Checking libnetfilter_queue ==="
pkg-config --modversion libnetfilter_queue || echo "Package info not available, but headers should be present"
echo "=== Checking clang (eBPF compiler) ==="
clang --version | head -1
echo ""
echo "=== Checking bpftool (skeleton generator) ==="
"$BPFTOOL" version | head -1
echo ""
echo "=== Checking libbpf ==="
pkg-config --modversion libbpf
shell: bash

- name: Unit tests (rule engine, DNS parser, relay)
timeout-minutes: 15
run: |
cd Linux/src
make test-rules BUILD_DIR="$RUNNER_TEMP/pb-tests"
cd tests
TMPDIR="$RUNNER_TEMP" ./run_relay_test.sh plain
shell: bash

- name: Build project
run: |
cd Linux
chmod +x build.sh
./build.sh
WERROR=1 ./build.sh
shell: bash

- name: Verify build output
Expand Down Expand Up @@ -84,8 +115,82 @@ jobs:
echo "✓ GUI built successfully"
file Linux/output/ProxyBridgeGUI
else
echo "⚠ GUI build skipped (GTK3 not available or build failed)"
echo "✗ GUI build failed (GTK3 is installed on this runner)"
exit 1
fi
shell: bash

- name: Smoke test the built binaries
run: |
cd Linux/output
# capture output first: `cmd | grep -q` can fail under pipefail when grep exits early (SIGPIPE)
help_out="$(LD_LIBRARY_PATH="$PWD" ./ProxyBridge --help)"
grep -q -- "--proxy" <<<"$help_out" && echo "✓ CLI runs and shows its help"
cli_deps="$(LD_LIBRARY_PATH="$PWD" ldd ./ProxyBridge)"
grep -q libproxybridge <<<"$cli_deps" && echo "✓ CLI links libproxybridge.so"
# the GUI must carry an $ORIGIN runpath so it finds the library in its own directory
gui_dyn="$(readelf -d ./ProxyBridgeGUI)"
grep -q 'RUNPATH.*\$ORIGIN' <<<"$gui_dyn" && echo "✓ GUI runpath is \$ORIGIN"
# the library must export the public API
exports="$(nm -D libproxybridge.so)"
for sym in ProxyBridge_Start ProxyBridge_Stop ProxyBridge_AddRule ProxyBridge_AddProxy ProxyBridge_ValidateRule; do
grep -q " T $sym" <<<"$exports" || { echo "✗ missing export $sym"; exit 1; }
done
echo "✓ public API exported"
# no iptables/NFQUEUE dependency may come back
lib_deps="$(ldd libproxybridge.so)"
if grep -qi netfilter <<<"$lib_deps"; then echo "✗ libnetfilter dependency is back"; exit 1; fi
echo "✓ no libnetfilter dependency"
shell: bash

- name: Portability - run the binaries on older distributions (issue 146)
# BIND_NOW makes the loader resolve every glibc symbol at start-up, so a clean --help run in these images proves the
# binaries do not need a newer glibc than Ubuntu 22.04 / Debian 12 / RHEL 9 era systems provide.
run: |
set -e
out="$PWD/Linux/output"
run_in() { # image, install command
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 -- '--proxy' && 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'"
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"
shell: bash

- name: Verify the build left the source tree clean
run: |
# build.sh compiles in a temp directory: no untracked or ignored file may appear outside Linux/output/
status="$(git status --porcelain --ignored)"
dirty="$(grep -E '^(\?\?|!!)' <<<"$status" | grep -v 'Linux/output' || true)"
if [ -n "$dirty" ]; then
echo "✗ build left files outside Linux/output:"
echo "$dirty"
exit 1
fi
echo "✓ source tree clean (only Linux/output/ was written)"
shell: bash

- name: End-to-end tests with the real kernel datapath (best effort)
# Needs root, cgroup v2 and a BTF kernel. GitHub-hosted runners usually have them, but this is not guaranteed,
# so a failure here is reported without failing the build.
continue-on-error: true
timeout-minutes: 15
run: |
sudo apt-get install -y dnsutils >/dev/null
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 api_live; do
echo "::group::$t"
sudo env PB_DIR="$PWD/Linux/output" BPFTOOL="$BPFTOOL" bash "Linux/tests/$t.sh" || fail=1
echo "::endgroup::"
done
exit $fail
shell: bash

- name: Upload artifacts
Expand Down
20 changes: 18 additions & 2 deletions .github/workflows/release-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ permissions:
jobs:
build-and-release:
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: write
actions: read
Expand All @@ -27,12 +28,27 @@ jobs:
build-essential \
gcc \
make \
libnetfilter-queue-dev \
libnfnetlink-dev \
clang \
linux-tools-common \
linux-tools-generic \
libbpf-dev \
libelf-dev \
zlib1g-dev \
libgtk-3-dev \
pkg-config
shell: bash

- name: Locate bpftool
# On Ubuntu "bpftool" is only a virtual package; the real binary ships in linux-tools-* and is not on PATH
# for the runner's cloud kernel, so find it explicitly.
run: |
shopt -s nullglob
candidates=(/usr/lib/linux-tools/*/bpftool)
[ ${#candidates[@]} -gt 0 ] || { echo "bpftool binary not found"; ls /usr/lib/linux-tools 2>&1 || true; exit 1; }
echo "BPFTOOL=${candidates[0]}" >> "$GITHUB_ENV"
"${candidates[0]}" version | head -1
shell: bash

- name: Build project
run: |
cd Linux
Expand Down
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,28 @@ Linux/cli/main.o
Linux/cli/proxybridge-cli
Linux/src/libproxybridge.so
Linux/src/ProxyBridge.o
Linux/src/*.o
Linux/src/proxybridge.skel.h
Linux/src/bpf/*.o
Linux/cli/ProxyBridge
Linux/gui/*.o
Linux/gui/ProxyBridgeGUI
Linux/ProxyBridgeGUI
Linux/src/tests/rules_test
Linux/src/dns_test
Linux/src/rules_test
Linux/src/tests/dns_test
Linux/**/*.o
Linux/**/*.skel.h
Linux/**/vmlinux.h
Linux/gui/tests/config_test
Linux/src/tests/relay_test
Linux/src/tests/relay_test_*
Linux/tests/hookbench
Linux/tests/thrbench
Linux/tests/api_live_test
Linux/**/__pycache__/
!Linux/tests/*.py
Android/**
iOS/**
# Windows build intermediates (MSVC import lib / export file / objects)
Expand Down
Loading
Loading