[PR #2506] [CLOSED] Add server-managed split tunneling rules #2830

Closed
opened 2026-10-14 21:05:34 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/amnezia-vpn/amnezia-client/pull/2506
Author: @nik65
Created: 4/21/2026
Status: ❌ Closed

Base: dev ← Head: feat/server-managed-split-tunnel


📝 Commits (10+)

  • 19d1c0b feat: add server-managed routing rules sync
  • 7a81128 Fix managed split tunnel rule sync
  • 529379c Fix split tunneling QML row delegate indexing
  • 9ecd306 Merge branch 'amnezia-vpn:dev' into feat/server-managed-split-tunnel
  • da1a0f5 Merge remote-tracking branch 'upstream/dev' into feat/server-managed-split-tunnel
  • fcd4cb9 Fix CI signing guards and import server routing rules
  • 296fa19 Merge upstream dev into server-managed split tunnel
  • b50d6fb Merge remote-tracking branch 'upstream/dev' into feat/server-managed-split-tunnel
  • 0467504 Merge remote-tracking branch 'upstream/dev' into feat/server-managed-split-tunnel
  • 69888d2 Merge remote-tracking branch 'upstream/dev' into feat/server-managed-split-tunnel

📊 Changes

130 files changed (+12346 additions, -1542 deletions)

View changed files

📝 .github/actions/apple-install-cert/action.yml (+5 -0)
📝 .github/actions/apple-setup-provisioning-profile/action.yml (+8 -1)
➕ .github/upstream-release-freeze.json (+13 -0)
➖ .github/workflows/deploy.yml (+0 -923)
➖ .github/workflows/tag-deploy.yml (+0 -150)
➖ .github/workflows/tag-upload.yml (+0 -41)
📝 .gitignore (+16 -3)
📝 CMakeLists.txt (+6 -2)
📝 client/CMakeLists.txt (+15 -0)
📝 client/amneziaApplication.cpp (+22 -1)
📝 client/amneziaApplication.h (+3 -0)
📝 client/android/AndroidManifest.xml (+2 -1)
📝 client/android/build.gradle.kts (+23 -0)
📝 client/android/res/xml/qtprovider_paths.xml (+1 -0)
📝 client/android/src/org/amnezia/vpn/AmneziaActivity.kt (+94 -7)
📝 client/android/src/org/amnezia/vpn/qt/QtAndroidController.kt (+7 -4)
📝 client/cmake/android.cmake (+44 -1)
📝 client/cmake/sources.cmake (+2 -0)
📝 client/core/controllers/api/newsController.cpp (+2 -1)
📝 client/core/controllers/api/servicesCatalogController.cpp (+1 -2)

...and 80 more files

📄 Description

Summary

This PR adds server-managed routing rules for site-based split tunneling.

A server admin can now configure a list of domains, IP addresses, and CIDR subnets that should not be accessed through the VPN for users of a specific server. The setting is available under:

Settings -> Servers -> Server -> Services -> Server routing rules

The placement is intentional: these rules are server policy, not just a local device preference. The rules are published for the VPN containers installed on that server, synced by clients that connect to that server, and shown in the existing Site-based split tunneling UI as locked managed entries.

The feature is scoped to the existing bypass mode: "Addresses from the list should not be accessed via VPN". It does not add a server-managed allowlist/"only these through VPN" mode.

Motivation

There are repeated requests around sharing, centralizing, and scaling split-tunneling rules.

The closest request is Discussion #1960, which describes this almost directly: a server admin defines one or more split-tunneling site lists and applies them to server users, while clients may still keep their own local blacklists/whitelists with priority rules.

Related requests and reports point to the same missing layer:

  • #2449 asks for sharing split-tunneling settings between users.
  • #1039 asks for easier import and automatic updating of large site lists instead of manual JSON-only management.
  • #1423 is an umbrella issue for improving site-based split tunneling and consolidating duplicates.
  • #2109 and Discussion #2418 describe the need to organize large domain/IP lists instead of forcing users to manage everything manually in one flat local list.
  • #1607, Discussion #1939, and #1750 show that domain/subdomain/IP resolution behavior is a recurring pain point.
  • #1623 asks for excluding networks/subnets from tunneling.
  • #2248 shows the practical impact of very large CIDR lists on connection behavior.
  • Discussion #2033 asks for whitelist-style routing behavior and clearer routing control.

This PR does not attempt to solve every split-tunneling runtime issue on every platform. It adds the missing configuration and distribution layer: a server-managed ruleset that can be maintained by the server admin and applied consistently by clients using that server.

User-visible behavior

Server admins get a new Server routing rules service entry next to other server-level services.

From that page an admin can:

  • add domains, IP addresses, and CIDR subnets to the server-managed bypass list;
  • import and export the list using the same JSON shape as regular site split tunneling;
  • publish the rules for clients of that server;
  • optionally force site-based split tunneling for clients that have it disabled.

Client behavior:

  • managed rules apply only while using the server where they are configured;
  • managed entries are displayed in the normal Site-based split tunneling list;
  • managed entries are locked/non-editable and visually separated from local user entries;
  • local user entries remain editable and are not overwritten;
  • clients using the opposite mode, "Only the sites listed here will be accessed through the VPN", keep their current behavior and are not switched automatically.

Force toggle behavior:

  • if site split tunneling is disabled locally, the client enables bypass mode and applies the server-managed list;
  • if the client already uses bypass mode, the server-managed list is merged with the local list;
  • if the client already uses the opposite allowlist mode, the server-managed bypass list is not forced into that mode.

Implementation details

  • Adds server-managed routing rule storage to the settings/config layer.
  • Publishes a rules.json payload for installed VPN containers, instead of publishing only for one default container.
  • Adds client sync on connect, retry on failed/invalid sync, and a daily refresh interval for successful syncs.
  • Keeps the rules sync endpoint reachable when split tunneling is active, so clients can refresh rules through the connected VPN path.
  • Adds strict payload validation and limits for downloaded rules before persisting them locally.
  • Supports domains, IP addresses, and CIDR subnets in managed rules.
  • Preserves stored IP/CIDR data on import when it is already present in the exported JSON, and resolves missing domain data when rules are saved/imported.
  • Handles server config updates so stale local managed rules are not kept forever after the server-side list is changed or cleared.
  • Adds the QML page, services model entry, navigation, managed-sites model, and translations for the new UI.

Compatibility

Older clients ignore the new managed-rules data and continue to use their existing local split-tunneling settings. They will still connect normally; they simply will not fetch, display, or apply server-managed routing rules until upgraded.

Existing local split-tunneling lists are preserved. Managed rules are merged into the effective routing list for the active server and are not copied into unrelated server profiles.

Plain WireGuard/export-style flows are kept separate from the server-managed sync path, so ordinary config export should continue to work without requiring these new fields.

Scope / non-goals

This PR intentionally keeps the server-managed UI to bypass rules only: addresses from the managed list should not be accessed via VPN.

It does not add:

  • a server-managed "only these addresses through VPN" mode;
  • per-user server-side rule assignment;
  • wildcard/regex rule syntax;
  • a full subscription/update system for external third-party lists;
  • a complete rewrite of platform-specific split-tunneling implementations.

Those can be considered separately. This PR focuses on the shared admin-managed ruleset and the client sync/apply pipeline.

Validation

Local validation performed on Windows:

  • cmake --build deploy\build_64 --config Release --target AmneziaVPN --parallel
  • git diff --check

Android validation:

  • C++ sources compiled for arm64-v8a.
  • Gradle debug build completed successfully.
  • The CMake apk target still exits at the known androiddeployqt expected-APK-path step after Gradle reports BUILD SUCCESSFUL.

Commit breakdown

  • 42bb69cc feat: add server-managed routing rules sync
  • 126a6f37 feat(ui): add server routing rules settings
  • acf4c26d chore(i18n): update server routing rules translations

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/amnezia-vpn/amnezia-client/pull/2506 **Author:** [@nik65](https://github.com/nik65) **Created:** 4/21/2026 **Status:** ❌ Closed **Base:** `dev` ← **Head:** `feat/server-managed-split-tunnel` --- ### 📝 Commits (10+) - [`19d1c0b`](https://github.com/amnezia-vpn/amnezia-client/commit/19d1c0be919b416be4ba14cf5146cf6440ed9613) feat: add server-managed routing rules sync - [`7a81128`](https://github.com/amnezia-vpn/amnezia-client/commit/7a8112833fe58d57914d709cc89a48c6d42a3029) Fix managed split tunnel rule sync - [`529379c`](https://github.com/amnezia-vpn/amnezia-client/commit/529379cf5af2c843b7136f2185317f6fee6c92f7) Fix split tunneling QML row delegate indexing - [`9ecd306`](https://github.com/amnezia-vpn/amnezia-client/commit/9ecd30646f1ca260132696ec4d1a4c59bceed728) Merge branch 'amnezia-vpn:dev' into feat/server-managed-split-tunnel - [`da1a0f5`](https://github.com/amnezia-vpn/amnezia-client/commit/da1a0f5c877cbd0782bbd35997216d2204a7d316) Merge remote-tracking branch 'upstream/dev' into feat/server-managed-split-tunnel - [`fcd4cb9`](https://github.com/amnezia-vpn/amnezia-client/commit/fcd4cb98e3248cf2cde9d68c96254dca72a7bd6a) Fix CI signing guards and import server routing rules - [`296fa19`](https://github.com/amnezia-vpn/amnezia-client/commit/296fa19d9c005c5daaea2bdf95986b7e15df62b0) Merge upstream dev into server-managed split tunnel - [`b50d6fb`](https://github.com/amnezia-vpn/amnezia-client/commit/b50d6fbdfe74e892b99797f53115137c7af4efc8) Merge remote-tracking branch 'upstream/dev' into feat/server-managed-split-tunnel - [`0467504`](https://github.com/amnezia-vpn/amnezia-client/commit/04675045180a55b4126ffe69ee4c639884d82365) Merge remote-tracking branch 'upstream/dev' into feat/server-managed-split-tunnel - [`69888d2`](https://github.com/amnezia-vpn/amnezia-client/commit/69888d2f3d28c51bebdf2b1296884ceeec38d84a) Merge remote-tracking branch 'upstream/dev' into feat/server-managed-split-tunnel ### 📊 Changes **130 files changed** (+12346 additions, -1542 deletions) <details> <summary>View changed files</summary> 📝 `.github/actions/apple-install-cert/action.yml` (+5 -0) 📝 `.github/actions/apple-setup-provisioning-profile/action.yml` (+8 -1) ➕ `.github/upstream-release-freeze.json` (+13 -0) ➖ `.github/workflows/deploy.yml` (+0 -923) ➖ `.github/workflows/tag-deploy.yml` (+0 -150) ➖ `.github/workflows/tag-upload.yml` (+0 -41) 📝 `.gitignore` (+16 -3) 📝 `CMakeLists.txt` (+6 -2) 📝 `client/CMakeLists.txt` (+15 -0) 📝 `client/amneziaApplication.cpp` (+22 -1) 📝 `client/amneziaApplication.h` (+3 -0) 📝 `client/android/AndroidManifest.xml` (+2 -1) 📝 `client/android/build.gradle.kts` (+23 -0) 📝 `client/android/res/xml/qtprovider_paths.xml` (+1 -0) 📝 `client/android/src/org/amnezia/vpn/AmneziaActivity.kt` (+94 -7) 📝 `client/android/src/org/amnezia/vpn/qt/QtAndroidController.kt` (+7 -4) 📝 `client/cmake/android.cmake` (+44 -1) 📝 `client/cmake/sources.cmake` (+2 -0) 📝 `client/core/controllers/api/newsController.cpp` (+2 -1) 📝 `client/core/controllers/api/servicesCatalogController.cpp` (+1 -2) _...and 80 more files_ </details> ### 📄 Description ## Summary This PR adds server-managed routing rules for site-based split tunneling. A server admin can now configure a list of domains, IP addresses, and CIDR subnets that should **not** be accessed through the VPN for users of a specific server. The setting is available under: `Settings -> Servers -> Server -> Services -> Server routing rules` The placement is intentional: these rules are server policy, not just a local device preference. The rules are published for the VPN containers installed on that server, synced by clients that connect to that server, and shown in the existing Site-based split tunneling UI as locked managed entries. The feature is scoped to the existing bypass mode: **"Addresses from the list should not be accessed via VPN"**. It does not add a server-managed allowlist/"only these through VPN" mode. ## Motivation There are repeated requests around sharing, centralizing, and scaling split-tunneling rules. The closest request is Discussion #1960, which describes this almost directly: a server admin defines one or more split-tunneling site lists and applies them to server users, while clients may still keep their own local blacklists/whitelists with priority rules. Related requests and reports point to the same missing layer: - #2449 asks for sharing split-tunneling settings between users. - #1039 asks for easier import and automatic updating of large site lists instead of manual JSON-only management. - #1423 is an umbrella issue for improving site-based split tunneling and consolidating duplicates. - #2109 and Discussion #2418 describe the need to organize large domain/IP lists instead of forcing users to manage everything manually in one flat local list. - #1607, Discussion #1939, and #1750 show that domain/subdomain/IP resolution behavior is a recurring pain point. - #1623 asks for excluding networks/subnets from tunneling. - #2248 shows the practical impact of very large CIDR lists on connection behavior. - Discussion #2033 asks for whitelist-style routing behavior and clearer routing control. This PR does not attempt to solve every split-tunneling runtime issue on every platform. It adds the missing configuration and distribution layer: a server-managed ruleset that can be maintained by the server admin and applied consistently by clients using that server. ## User-visible behavior Server admins get a new **Server routing rules** service entry next to other server-level services. From that page an admin can: - add domains, IP addresses, and CIDR subnets to the server-managed bypass list; - import and export the list using the same JSON shape as regular site split tunneling; - publish the rules for clients of that server; - optionally force site-based split tunneling for clients that have it disabled. Client behavior: - managed rules apply only while using the server where they are configured; - managed entries are displayed in the normal Site-based split tunneling list; - managed entries are locked/non-editable and visually separated from local user entries; - local user entries remain editable and are not overwritten; - clients using the opposite mode, "Only the sites listed here will be accessed through the VPN", keep their current behavior and are not switched automatically. Force toggle behavior: - if site split tunneling is disabled locally, the client enables bypass mode and applies the server-managed list; - if the client already uses bypass mode, the server-managed list is merged with the local list; - if the client already uses the opposite allowlist mode, the server-managed bypass list is not forced into that mode. ## Implementation details - Adds server-managed routing rule storage to the settings/config layer. - Publishes a `rules.json` payload for installed VPN containers, instead of publishing only for one default container. - Adds client sync on connect, retry on failed/invalid sync, and a daily refresh interval for successful syncs. - Keeps the rules sync endpoint reachable when split tunneling is active, so clients can refresh rules through the connected VPN path. - Adds strict payload validation and limits for downloaded rules before persisting them locally. - Supports domains, IP addresses, and CIDR subnets in managed rules. - Preserves stored IP/CIDR data on import when it is already present in the exported JSON, and resolves missing domain data when rules are saved/imported. - Handles server config updates so stale local managed rules are not kept forever after the server-side list is changed or cleared. - Adds the QML page, services model entry, navigation, managed-sites model, and translations for the new UI. ## Compatibility Older clients ignore the new managed-rules data and continue to use their existing local split-tunneling settings. They will still connect normally; they simply will not fetch, display, or apply server-managed routing rules until upgraded. Existing local split-tunneling lists are preserved. Managed rules are merged into the effective routing list for the active server and are not copied into unrelated server profiles. Plain WireGuard/export-style flows are kept separate from the server-managed sync path, so ordinary config export should continue to work without requiring these new fields. ## Scope / non-goals This PR intentionally keeps the server-managed UI to bypass rules only: addresses from the managed list should not be accessed via VPN. It does not add: - a server-managed "only these addresses through VPN" mode; - per-user server-side rule assignment; - wildcard/regex rule syntax; - a full subscription/update system for external third-party lists; - a complete rewrite of platform-specific split-tunneling implementations. Those can be considered separately. This PR focuses on the shared admin-managed ruleset and the client sync/apply pipeline. ## Validation Local validation performed on Windows: - `cmake --build deploy\build_64 --config Release --target AmneziaVPN --parallel` - `git diff --check` Android validation: - C++ sources compiled for `arm64-v8a`. - Gradle debug build completed successfully. - The CMake `apk` target still exits at the known `androiddeployqt` expected-APK-path step after Gradle reports `BUILD SUCCESSFUL`. ## Commit breakdown - `42bb69cc` feat: add server-managed routing rules sync - `126a6f37` feat(ui): add server routing rules settings - `acf4c26d` chore(i18n): update server routing rules translations --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-14 21:05:34 +00:00
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
amnezia-vpn/amnezia-client#2830
No description provided.