Add native traffic inspection to Harbor Connect and Gateway

This commit is contained in:
2026-08-31 05:19:15 +03:00
parent 116686a138
commit 4d066cb879
62 changed files with 10975 additions and 220 deletions
+2 -2
View File
@@ -12,7 +12,7 @@ GATEWAY_IMAGE="${GATEWAY_IMAGE:-${IMAGE_NAME}:${IMAGE_TAG}}"
BASE_IMAGE="${BASE_IMAGE:-vpn-proxy-runtime-base:bookworm-slim}"
NODE_BUILD_IMAGE="${NODE_BUILD_IMAGE:-node:20.19-alpine}"
RUNTIME_BASE_SOURCE_IMAGE="${RUNTIME_BASE_SOURCE_IMAGE:-mirror.gcr.io/library/debian:bookworm-slim}"
SINGBOX_VERSION="${SINGBOX_VERSION:-1.13.18}"
SINGBOX_VERSION="${SINGBOX_VERSION:-1.14.0-rc.5}"
DOCKER_BUILD_PULL="${DOCKER_BUILD_PULL:-false}"
INSTALL_RUNTIME_DEPS="${INSTALL_RUNTIME_DEPS:-false}"
INSTALL_SINGBOX="${INSTALL_SINGBOX:-false}"
@@ -63,7 +63,7 @@ else
fi
echo "Building image on ${BUILD_HOST}"
BUILD_COMMAND="set -e; echo 'Docker context:' \$(docker context show 2>/dev/null || true); docker info 2>/dev/null | sed -n '/HTTP Proxy:/p;/HTTPS Proxy:/p;/Name:/p'; cd '${BUILD_PATH}'; if ! docker image inspect '${BASE_IMAGE}' >/dev/null 2>&1; then if [ '${AUTO_BUILD_RUNTIME_BASE}' = 'true' ]; then echo 'Runtime base image ${BASE_IMAGE} is missing on ${BUILD_HOST}; building it now.'; BASE_IMAGE='${RUNTIME_BASE_SOURCE_IMAGE}' RUNTIME_BASE_IMAGE='${BASE_IMAGE}' SINGBOX_VERSION='${SINGBOX_VERSION}' ./scripts/build-runtime-base.sh; else echo 'Runtime base image ${BASE_IMAGE} is missing on ${BUILD_HOST}.'; echo 'Seed it once with: ./scripts/build-runtime-base.sh'; exit 1; fi; fi; npm ci && npm run build:production && docker build --pull='${DOCKER_BUILD_PULL}' --build-arg NODE_BUILD_IMAGE='${NODE_BUILD_IMAGE}' --build-arg BASE_IMAGE='${BASE_IMAGE}' --build-arg SINGBOX_VERSION='${SINGBOX_VERSION}' --build-arg INSTALL_RUNTIME_DEPS='${INSTALL_RUNTIME_DEPS}' --build-arg INSTALL_SINGBOX='${INSTALL_SINGBOX}' -t '${GATEWAY_IMAGE}' ."
BUILD_COMMAND="set -e; echo 'Docker context:' \$(docker context show 2>/dev/null || true); docker info 2>/dev/null | sed -n '/HTTP Proxy:/p;/HTTPS Proxy:/p;/Name:/p'; cd '${BUILD_PATH}'; if ! docker image inspect '${BASE_IMAGE}' >/dev/null 2>&1 || ! docker run --rm '${BASE_IMAGE}' sh -lc \"command -v npm >/dev/null && sing-box version 2>&1 | grep -Fx 'sing-box version ${SINGBOX_VERSION}'\"; then if [ '${AUTO_BUILD_RUNTIME_BASE}' = 'true' ]; then echo 'Runtime base image ${BASE_IMAGE} is missing or does not contain sing-box ${SINGBOX_VERSION}; building it now.'; BASE_IMAGE='${RUNTIME_BASE_SOURCE_IMAGE}' RUNTIME_BASE_IMAGE='${BASE_IMAGE}' SINGBOX_VERSION='${SINGBOX_VERSION}' ./scripts/build-runtime-base.sh; else echo 'Runtime base image ${BASE_IMAGE} is missing or does not contain sing-box ${SINGBOX_VERSION} on ${BUILD_HOST}.'; echo 'Seed it once with: ./scripts/build-runtime-base.sh'; exit 1; fi; fi; docker run --rm '${BASE_IMAGE}' sh -lc \"command -v npm >/dev/null && sing-box version 2>&1 | grep -Fx 'sing-box version ${SINGBOX_VERSION}'\"; npm ci && npm run build:production && docker build --pull='${DOCKER_BUILD_PULL}' --build-arg NODE_BUILD_IMAGE='${NODE_BUILD_IMAGE}' --build-arg BASE_IMAGE='${BASE_IMAGE}' --build-arg SINGBOX_VERSION='${SINGBOX_VERSION}' --build-arg INSTALL_RUNTIME_DEPS='${INSTALL_RUNTIME_DEPS}' --build-arg INSTALL_SINGBOX='${INSTALL_SINGBOX}' -t '${GATEWAY_IMAGE}' . && docker run --rm --entrypoint sing-box '${GATEWAY_IMAGE}' version 2>&1 | grep -Fx 'sing-box version ${SINGBOX_VERSION}'"
if [ "${BUILD_HOST}" = "local" ]; then
bash -lc "${BUILD_COMMAND}"
else
+1 -1
View File
@@ -3,7 +3,7 @@ set -euo pipefail
BASE_IMAGE="${BASE_IMAGE:-mirror.gcr.io/library/debian:bookworm-slim}"
RUNTIME_BASE_IMAGE="${RUNTIME_BASE_IMAGE:-vpn-proxy-runtime-base:bookworm-slim}"
SINGBOX_VERSION="${SINGBOX_VERSION:-1.13.18}"
SINGBOX_VERSION="${SINGBOX_VERSION:-1.14.0-rc.5}"
APT_MIRROR="${APT_MIRROR:-http://mirror.yandex.ru/debian}"
APT_SECURITY_MIRROR="${APT_SECURITY_MIRROR:-http://mirror.yandex.ru/debian-security}"
HTTP_PROXY="${HTTP_PROXY:-$(docker info 2>/dev/null | awk -F': ' '/HTTP Proxy:/ {print $2; exit}')}"
+8 -1
View File
@@ -9,7 +9,8 @@ COMPOSE_FILE="docker-compose.client.yml"
DEFAULT_PROXY_PORT="8082"
REQUESTED_PROXY_PORT="${VPN_PROXY_CLIENT_PORT:-}"
REQUESTED_UI_PORT="${VPN_PROXY_CLIENT_UI_PORT:-${CLIENT_UI_PORT:-}}"
TARGET_SINGBOX_VERSION="${SINGBOX_VERSION:-1.13.18}"
TARGET_SINGBOX_VERSION="${SINGBOX_VERSION:-1.14.0-rc.5}"
TARGET_TRAFFIC_SOURCE="${SING_BOX_TRAFFIC_SOURCE:-native}"
CLIENT_CONTAINER_NAME="harbor-connect"
LEGACY_CLIENT_CONTAINER_NAME="vpn-proxy-client"
NETWORK_MONITOR_LABEL="com.dokril.harbor-connect.network"
@@ -290,6 +291,11 @@ need curl
need rsync
need tar
case "$TARGET_TRAFFIC_SOURCE" in
native|disabled) ;;
*) die "SING_BOX_TRAFFIC_SOURCE must be native or disabled" ;;
esac
docker compose version >/dev/null 2>&1 || die "Docker Compose plugin is required"
docker info >/dev/null 2>&1 || die "Docker Desktop is not running"
@@ -321,6 +327,7 @@ assert_ui_outside_proxy_range
set_env_value APP_MODE client
set_env_value SINGBOX_VERSION "$TARGET_SINGBOX_VERSION"
set_env_value SING_BOX_TRAFFIC_SOURCE "$TARGET_TRAFFIC_SOURCE"
set_env_value CLIENT_UI_PORT "$UI_PORT"
set_env_value CLIENT_PROXY_PORT "$PROXY_PORT"
set_env_value PROXY_PORT "$PROXY_PORT"
+7 -3
View File
@@ -19,6 +19,7 @@ const noRuntimeImpact = [
/^entrypoint\.client\.sh$/,
/^install\.sh$/,
/^scripts\/(?:check-import-boundaries\.mjs|clean-test-dist\.mjs|harbor-network-monitor\.sh|harbor-version\.mjs|install-macos-client\.sh)$/,
/^tools\/test-singbox-(?:client-rc|gateway-native-traffic|native-traffic)\.sh$/,
];
const foundation = [
/^\.dockerignore$/,
@@ -32,11 +33,14 @@ const foundation = [
/^tsconfig(?:\.[^.]+)?\.json$/,
];
const controlAndDataplane = [
/^buf\.gen\.yaml$/,
/^proto\//,
new RegExp(`^src/server/main${CODE_EXTENSION}`),
new RegExp(`^src/server/(?:config|gatewayRouting|singbox|singboxRuntime|version)${CODE_EXTENSION}`),
new RegExp(`^src/server/(?:config|gatewayNativeRuntime|gatewayRouting|singbox|singboxRuntime|version)${CODE_EXTENSION}`),
/^src\/server\/generated\//,
new RegExp(`^src/server/adapters/neighbors${CODE_EXTENSION}`),
new RegExp(`^src/server/services/(?:connectivityDiagnosticsService|deviceInventoryService|devicePolicyService|singboxSelectorService)${CODE_EXTENSION}`),
new RegExp(`^src/shared/(?:connectivityDiagnostics|errors)${CODE_EXTENSION}`),
new RegExp(`^src/server/services/(?:connectivityDiagnosticsService|deviceInventoryService|devicePolicyService|liveTrafficService|singboxSelectorService)${CODE_EXTENSION}`),
new RegExp(`^src/shared/(?:connectivityDiagnostics|errors|liveTraffic)${CODE_EXTENSION}`),
/^src\/server\/infrastructure\/dataplane\//,
];
const dataplane = [