Prepare release v1.2.28

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
MaxFan
2026-05-17 19:34:10 +03:30
parent dfe623dd99
commit d9a2a3b7d2
6 changed files with 157 additions and 11 deletions
+3 -3
View File
@@ -21,9 +21,9 @@
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
<NeutralLanguage>fa-IR</NeutralLanguage>
<!-- Version Management -->
<Version>1.2.27</Version>
<AssemblyVersion>1.2.27.0</AssemblyVersion>
<FileVersion>1.2.27.0</FileVersion>
<Version>1.2.28</Version>
<AssemblyVersion>1.2.28.0</AssemblyVersion>
<FileVersion>1.2.28.0</FileVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
@@ -5,6 +5,8 @@ namespace AppTunnel.Services;
public partial class TrafficRouterService
{
private bool _vpnServerPhysicalRouteAdded;
public bool IsFullRouteEnabled => _fullRouteEnabled;
public bool SetFullRouteEnabled(bool enabled)
@@ -17,9 +19,19 @@ public partial class TrafficRouterService
if (!AddVpnServerPhysicalRoute())
Logger.Warning("[FULL-ROUTE] Could not pin VPN server to the physical gateway; enabling full-route may fail.");
if (!TryRunRouteCommand($"add 0.0.0.0 mask 0.0.0.0 0.0.0.0 IF {_vpnInterfaceIndex} METRIC 1", out var stderr))
RemoveFullRouteDefault();
var gateway = GetVpnRouteGateway();
var added = TryRunRouteCommand($"add 0.0.0.0 mask 0.0.0.0 {gateway} IF {_vpnInterfaceIndex} METRIC 1", out var stderr);
if (!added && gateway != "0.0.0.0")
{
Logger.Warning($"[FULL-ROUTE] Failed to add VPN default route via {gateway}; retrying on-link gateway. stderr={stderr.Trim()}");
added = TryRunRouteCommand($"add 0.0.0.0 mask 0.0.0.0 0.0.0.0 IF {_vpnInterfaceIndex} METRIC 1", out stderr);
}
if (!added)
{
Logger.Warning($"[FULL-ROUTE] Failed to add VPN default route: {stderr}");
RemoveVpnServerPhysicalRoute();
return false;
}
@@ -32,6 +44,7 @@ public partial class TrafficRouterService
RemoveExcludedDirectRoutes();
RemoveFullRouteDefault();
RemoveVpnServerPhysicalRoute();
_fullRouteEnabled = false;
MarkPolicyTransitionGrace(TimeSpan.FromSeconds(25));
CleanupRoutesForCurrentMode(dropStaleNat: true);
@@ -42,15 +55,28 @@ public partial class TrafficRouterService
private bool AddVpnServerPhysicalRoute()
{
_vpnServerPhysicalRouteAdded = false;
if (string.IsNullOrWhiteSpace(_vpnServerIp) || _vpnServerIp == "0.0.0.0")
return false;
if (string.IsNullOrWhiteSpace(_physicalGatewayIp) || _physicalInterfaceIndex <= 0)
return false;
TryRunRouteCommand($"delete {_vpnServerIp}", out _);
return TryRunRouteCommand(
var added = TryRunRouteCommand(
$"add {_vpnServerIp} mask 255.255.255.255 {_physicalGatewayIp} IF {_physicalInterfaceIndex} METRIC 1",
out _);
_vpnServerPhysicalRouteAdded = added;
return added;
}
private void RemoveVpnServerPhysicalRoute()
{
if (!_vpnServerPhysicalRouteAdded)
return;
if (!string.IsNullOrWhiteSpace(_vpnServerIp) && _vpnServerIp != "0.0.0.0")
TryRunRouteCommand($"delete {_vpnServerIp}", out _);
_vpnServerPhysicalRouteAdded = false;
}
private void RemoveFullRouteDefault()
@@ -59,6 +85,9 @@ public partial class TrafficRouterService
RemoveDefaultRouteOnVpn();
}
private string GetVpnRouteGateway()
=> string.IsNullOrWhiteSpace(_vpnGatewayIp) ? "0.0.0.0" : _vpnGatewayIp;
/// <summary>
/// Remove default routes (0.0.0.0/0) on the VPN interface so only
/// explicitly added /32 host routes use the tunnel. Without this,
@@ -357,7 +386,7 @@ public partial class TrafficRouterService
/// </summary>
private bool TryAddRouteViaCommandLine(IPAddress dstIp)
{
var gateway = string.IsNullOrWhiteSpace(_vpnGatewayIp) ? "0.0.0.0" : _vpnGatewayIp;
var gateway = GetVpnRouteGateway();
var ok = TryRunRouteCommand($"add {dstIp} mask 255.255.255.255 {gateway} IF {_vpnInterfaceIndex} METRIC 1", out var stderr);
if (!ok && Interlocked.Read(ref _statRoutesFailed) <= 10)
Logger.Warning($"[ROUTE!] route.exe add {dstIp} via {gateway} stderr='{stderr.Trim()}'");
+14 -3
View File
@@ -157,7 +157,7 @@
<StackPanel>
<TextBlock Text="۱. پروفایل" FontSize="12" FontWeight="SemiBold"
Foreground="{StaticResource TextPrimaryBrush}"/>
<TextBlock Text="نوع اتصال را انتخاب کنید: L2TP، V2Ray/Xray یا اوپن‌وی‌پی‌ان. برای اسپلیت اوپن‌وی‌پی‌ان، نسخه Community لازم است؛ فایل .ovpn را انتخاب کنید و نام کاربری/رمز را در TunnelX وارد کنید."
<TextBlock Text="نوع اتصال را انتخاب کنید: L2TP، V2Ray/Xray، SOCKS5/HTTP Proxy یا اوپن‌وی‌پی‌ان. برای اسپلیت اوپن‌وی‌پی‌ان، نسخه Community لازم است؛ فایل .ovpn را انتخاب کنید و نام کاربری/رمز را در TunnelX وارد کنید."
FontSize="10" TextWrapping="Wrap"
Foreground="{StaticResource TextSecondaryBrush}" Margin="0,5,0,0"/>
</StackPanel>
@@ -222,6 +222,17 @@
Foreground="{StaticResource TextSecondaryBrush}"
Margin="0,4,0,10"/>
<TextBlock Text="SOCKS5 / HTTP Proxy"
FontSize="12"
FontWeight="SemiBold"
Foreground="{StaticResource TextPrimaryBrush}"/>
<TextBlock Text="اگر پراکسی خارجی آماده دارید، آدرس سرور، پورت و در صورت نیاز نام کاربری/رمز را در پروفایل پراکسی وارد کنید. این حالت با SOCKS5 داخلی روی 127.0.0.1 تفاوت دارد."
FontSize="11"
LineHeight="18"
TextWrapping="Wrap"
Foreground="{StaticResource TextSecondaryBrush}"
Margin="0,4,0,10"/>
<TextBlock Text="OpenVPN"
FontSize="12"
FontWeight="SemiBold"
@@ -308,7 +319,7 @@
<TextBlock Style="{StaticResource SectionHeader}" Text="SOCKS5 داخلی"/>
<TextBlock TextWrapping="Wrap" FontSize="11" LineHeight="19"
Foreground="{StaticResource TextSecondaryBrush}">
پروکسی داخلی روی 127.0.0.1 اجرا می‌شود. پورت را قبل از اتصال انتخاب کنید؛ پورت‌های سیستم، رزرو و پورت‌های رایج توسعه محدود شده‌اند.
پروکسی داخلی روی 127.0.0.1 اجرا می‌شود و برای ابزارهایی است که آدرس پراکسی محلی می‌خواهند. پورت را قبل از اتصال انتخاب کنید؛ پورت‌های سیستم، رزرو و پورت‌های رایج توسعه محدود شده‌اند.
</TextBlock>
<Border Background="#11FFFFFF" CornerRadius="6" Padding="8" Margin="0,8,0,0">
<TextBlock Text="127.0.0.1:1080"
@@ -337,7 +348,7 @@ Leak باید صفر باشد. DNS نشان می‌دهد درخواست‌ها
<TextBlock Style="{StaticResource SectionHeader}" Text="عیب‌یابی سریع"/>
<Expander Header="اتصال برقرار نمی‌شود" Foreground="{StaticResource TextPrimaryBrush}" Margin="0,4,0,0">
<TextBlock Text="دسترسی Administrator، فایروال، پورت SOCKS5 و صحت کانفیگ را بررسی کنید. در کانفیگ‌های xhttp، هسته باید Xray باشد."
<TextBlock Text="دسترسی Administrator، فایروال، پورت SOCKS5، اطلاعات پراکسی و صحت کانفیگ را بررسی کنید. در کانفیگ‌های xhttp، هسته باید Xray باشد."
TextWrapping="Wrap" FontSize="11" LineHeight="19"
Foreground="{StaticResource TextSecondaryBrush}" Margin="0,8,0,0"/>
</Expander>
+12
View File
@@ -6,6 +6,18 @@
### فارسی
## 1.2.28 - 2026-05-17
### English
- Fixed Full Route default-route installation by preferring the VPN gateway, retrying with an on-link gateway when needed, and cleaning up the pinned physical route to the tunnel server when Full Route is disabled.
- Updated English/Persian README and in-app Help content for the new SOCKS/Proxy profile flow, connection types, routing notes, local data, and troubleshooting guidance.
### فارسی
- نصب default route در حالت Full Route اصلاح شد؛ ابتدا gateway تونل استفاده می‌شود، در صورت نیاز با gateway روی‌لینک دوباره تلاش می‌شود، و route فیزیکی ثابت‌شده برای سرور تونل هنگام خاموش شدن Full Route پاک‌سازی می‌شود.
- README فارسی/انگلیسی و محتوای راهنمای داخل برنامه برای جریان جدید SOCKS/Proxy، نوع‌های اتصال، نکته‌های مسیر، داده‌های محلی و عیب‌یابی به‌روز شد.
## 1.2.27 - 2026-05-17
### English
+47
View File
@@ -14,22 +14,69 @@
- <span dir="ltr">Split tunneling</span> بر اساس برنامه‌های انتخاب‌شده در ویندوز
- حالت <span dir="ltr">Full-route</span> برای تونل کردن کل سیستم
- پشتیبانی از پروفایل‌های <span dir="ltr">L2TP/IPsec</span> ویندوز
- پشتیبانی از جریان‌های <span dir="ltr">V2Ray</span> بر پایه <span dir="ltr">Xray-core</span> و <span dir="ltr">sing-box</span>
- پشتیبانی از پروفایل‌های اختصاصی <span dir="ltr">SOCKS5/HTTP Proxy</span> با سرور، پورت، نام کاربری و رمز عبور جداگانه
- پشتیبانی از <span dir="ltr">OpenVPN Community</span> با فایل‌های <span dir="ltr">`.ovpn`</span> برای <span dir="ltr">Split tunneling</span> برنامه‌های انتخاب‌شده
- پروکسی <span dir="ltr">SOCKS5</span> محلی روی <span dir="ltr">`127.0.0.1`</span> برای ابزارهایی که تنظیم پروکسی داخلی دارند
- تغییر مسیر <span dir="ltr">DNS</span>، مسدودسازی <span dir="ltr">IPv6</span>، محافظ نشت، عیب‌یابی <span dir="ltr">route</span> و تاریخچه مصرف تونل
- مدیریت چند پروفایل، کپی/ویرایش کانفیگ‌ها، تست سرور، تشخیص <span dir="ltr">IP</span> خروجی و اعلان بروزرسانی
- رابط کاربری فارسی‌محور برای ویندوز
## شروع سریع
1. آخرین فایل <span dir="ltr">standalone</span> را از بخش <span dir="ltr">GitHub Releases</span> دانلود کنید.
2. برنامه را با دسترسی <span dir="ltr">Administrator</span> اجرا کنید؛ قابلیت‌های تغییر مسیر، <span dir="ltr">WinDivert</span> و مدیریت ترافیک به سطح دسترسی بالا نیاز دارند.
3. از تب اتصال، یک کانفیگ جدید بسازید یا کانفیگ موجود را انتخاب کنید.
4. نوع اتصال را انتخاب کنید: <span dir="ltr">L2TP/IPsec</span>، <span dir="ltr">V2Ray/Xray</span>، <span dir="ltr">SOCKS5/HTTP Proxy</span> یا <span dir="ltr">OpenVPN</span>.
5. قبل از اتصال، تست سرور را اجرا کنید و سپس برنامه‌هایی را که باید از تونل عبور کنند در تب برنامه‌ها فعال کنید.
6. در صورت نیاز، مقصدهای لزومی یا استثنا را اضافه کنید و بعد از اتصال کارت سلامت ترافیک، <span dir="ltr">DNS</span>، <span dir="ltr">IPv6</span> و <span dir="ltr">Route</span> را بررسی کنید.
## انواع اتصال
### <span dir="ltr">L2TP/IPsec</span>
برای اتصال‌های <span dir="ltr">L2TP/IPsec</span>، آدرس سرور، نام کاربری، رمز عبور و <span dir="ltr">Pre-Shared Key</span> را وارد کنید. <span dir="ltr">TunnelX</span> اتصال ویندوز را ایجاد می‌کند و سپس مسیرها را بر اساس حالت انتخابی یا <span dir="ltr">Full-route</span> مدیریت می‌کند.
### <span dir="ltr">V2Ray / Xray</span>
لینک یا کانفیگ <span dir="ltr">V2Ray/Xray</span> را در پروفایل وارد کنید. برنامه برای کانفیگ‌های معمول از <span dir="ltr">sing-box</span> استفاده می‌کند و برای کانفیگ‌هایی که به قابلیت‌های خاص <span dir="ltr">Xray</span> مثل <span dir="ltr">xhttp</span> نیاز دارند، <span dir="ltr">Xray-core</span> را انتخاب می‌کند.
### <span dir="ltr">SOCKS5/HTTP Proxy</span>
اگر از پراکسی آماده استفاده می‌کنید، نوع پروفایل <span dir="ltr">SOCKS5/HTTP Proxy</span> را انتخاب کنید و سرور، پورت و در صورت نیاز نام کاربری و رمز عبور را وارد کنید. این حالت برای عبور برنامه‌های انتخاب‌شده از یک پراکسی خارجی مناسب است و با پراکسی محلی <span dir="ltr">`127.0.0.1`</span> تفاوت دارد.
## پشتیبانی از <span dir="ltr">OpenVPN</span>
<span dir="ltr">TunnelX</span> می‌تواند نسخه نصب‌شده <span dir="ltr">OpenVPN Community</span> و فایل انتخابی <span dir="ltr">`.ovpn`</span> کاربر را اجرا کند و سپس سیاست <span dir="ltr">Split tunneling</span> خودش را اعمال کند؛ یعنی فقط برنامه‌ها و مقصدهای انتخاب‌شده از تونل <span dir="ltr">OpenVPN</span> عبور می‌کنند.
<span dir="ltr">OpenVPN</span> همراه <span dir="ltr">TunnelX</span> توزیع نمی‌شود. برای این حالت باید <span dir="ltr">OpenVPN Community</span> را جداگانه نصب کنید، فایل <span dir="ltr">`.ovpn`</span> را در <span dir="ltr">TunnelX</span> انتخاب کنید و در صورت نیاز نام کاربری و رمز عبور <span dir="ltr">OpenVPN</span> را داخل برنامه وارد کنید. نصب بودن <span dir="ltr">OpenVPN Connect</span> به‌تنهایی برای این حالت کافی نیست، چون آن برنامه مسیرها و <span dir="ltr">DNS</span> را با کلاینت خودش مدیریت می‌کند.
<span dir="ltr">TunnelX</span> برای سازگاری با <span dir="ltr">Split tunneling</span>، تنظیمات مسیر و <span dir="ltr">DNS</span> تحمیلی فایل <span dir="ltr">`.ovpn`</span> را کنترل می‌کند و در صورت تغییر <span dir="ltr">IP</span> تونل، <span dir="ltr">gateway</span>، <span dir="ltr">interface</span> یا مقصد ریموت هنگام <span dir="ltr">reconnect</span>، مسیر‌دهی داخلی خودش را دوباره راه‌اندازی می‌کند.
## نکته‌های مسیر و دامنه
قانون‌های <span dir="ltr">Include</span> و <span dir="ltr">Exclude</span> هم خود دامنه واردشده و هم زیردامنه‌های آن را پوشش می‌دهند. برای نمونه، افزودن <span dir="ltr">`githubusercontent.com`</span> پس از resolve شدن <span dir="ltr">DNS</span> شامل <span dir="ltr">`raw.githubusercontent.com`</span> هم می‌شود. اگر یک کلاینت <span dir="ltr">HTTPS</span> در مرحله بررسی <span dir="ltr">certificate revocation</span> خطا داد، ممکن است میزبان‌های <span dir="ltr">OCSP/CRL</span> آن از مسیر انتخابی قابل دسترسی نباشند؛ در این حالت خود برنامه دانلودکننده یا دامنه‌های revocation مربوطه را هم در لیست لزومی قرار دهید.
- مقصدهای استثناشده حتی برای برنامه‌های انتخاب‌شده مستقیم می‌مانند.
- مقصدهای لزومی حتی اگر برنامه مربوطه انتخاب نشده باشد از تونل عبور می‌کنند.
- برای برنامه‌های <span dir="ltr">Store/MSIX</span>، <span dir="ltr">WebView2</span> یا برنامه‌های چندپردازشی، برنامه را باز نگه دارید و فهرست برنامه‌ها را دوباره بارگذاری کنید.
- اگر <span dir="ltr">Full-route</span> روشن باشد، کل ترافیک سیستم از تونل عبور می‌کند و قانون‌های مستقیم/استثنا همچنان برای نگه داشتن مقصدهای خاص روی مسیر عادی کاربرد دارند.
## تنظیمات و داده‌های محلی
پروفایل‌ها، برنامه‌های انتخاب‌شده، مقصدهای لزومی/استثنا، تاریخچه اتصال و لاگ‌ها روی دستگاه کاربر نگهداری می‌شوند و معمولاً در مسیر <span dir="ltr">`%LOCALAPPDATA%\TunnelX`</span> یا کنار برنامه قرار می‌گیرند. <span dir="ltr">TunnelX</span> عمداً تحلیل آماری یا <span dir="ltr">telemetry</span> برای نگهدارنده ارسال نمی‌کند.
لاگ‌ها ممکن است شامل نام پردازش‌ها، نام دامنه‌ها، آدرس‌های <span dir="ltr">IP</span>، پورت‌ها و وضعیت اتصال باشند. قبل از ارسال عمومی لاگ در <span dir="ltr">GitHub Issues</span>، اطلاعات حساس مثل آدرس سرور خصوصی، کلیدها، <span dir="ltr">UUID</span>، رمزها و endpointهای شخصی را حذف کنید.
## عیب‌یابی سریع
- اگر اتصال برقرار نمی‌شود، اجرای برنامه با دسترسی <span dir="ltr">Administrator</span>، فایروال، درستی کانفیگ، پورت‌های پراکسی و نصب بودن پیش‌نیازهای مربوط به همان نوع اتصال را بررسی کنید.
- اگر ترافیک یک برنامه از تونل عبور نمی‌کند، برنامه را در تب برنامه‌ها فعال کنید، برنامه را باز نگه دارید و فهرست برنامه‌ها را دوباره بارگذاری کنید.
- اگر فقط یک سایت یا دامنه باید از تونل عبور کند، آن را به مقصدهای لزومی اضافه کنید؛ اگر باید مستقیم بماند، آن را به استثناها اضافه کنید.
- اگر خطای <span dir="ltr">DNS</span> یا <span dir="ltr">IPv6</span> می‌بینید، کارت سلامت بعد از اتصال را بررسی کنید و در صورت نیاز یک‌بار قطع و وصل کنید تا مسیرها و قانون‌های <span dir="ltr">DNS</span> دوباره ساخته شوند.
- اگر از <span dir="ltr">OpenVPN</span> استفاده می‌کنید و اتصال طولانی می‌شود، فایل <span dir="ltr">`.ovpn`</span>، نام کاربری/رمز و نصب بودن <span dir="ltr">OpenVPN Community</span> را بررسی کنید.
## تصاویر برنامه
| داشبورد اتصال | تنظیم پروفایل و سرور |
+49 -2
View File
@@ -8,22 +8,69 @@ TunnelX is a free and open-source Windows split-tunneling client built by **MaxF
- App-based split tunneling for selected Windows processes
- Full-route mode for whole-system tunneling
- Windows L2TP/IPsec profile support
- Xray-core / sing-box based V2Ray workflows
- Dedicated SOCKS5/HTTP Proxy profiles with separate server, port, username, and password fields
- OpenVPN Community support via user-provided `.ovpn` files for app-based split tunneling
- Local SOCKS5 proxy for tools that need `127.0.0.1`
- DNS redirect, IPv6 blocking, leak guard, route diagnostics, and traffic history
- Multiple profiles, duplicate/edit flows, server tests, public exit IP detection, and release update checks
- Persian-first Windows desktop UI
## Quick Start
1. Download the latest standalone release from GitHub Releases.
2. Run TunnelX as Administrator. Route management, WinDivert, and packet interception require elevated privileges.
3. Create a new profile or select an existing profile from the connection tab.
4. Choose the connection type: L2TP/IPsec, V2Ray/Xray, SOCKS5/HTTP Proxy, or OpenVPN.
5. Test the server, then enable the Windows apps that should use the tunnel.
6. Add include or exclude destinations when needed, connect, and check the traffic health cards for DNS, IPv6, leaks, and route status.
## Connection Types
### L2TP/IPsec
Enter the server address, username, password, and pre-shared key. TunnelX creates the Windows VPN connection and manages routes according to the selected-app policy or full-route mode.
### V2Ray / Xray
Paste a V2Ray/Xray link or JSON config into the profile. TunnelX uses sing-box for regular configs and switches to Xray-core for configs that require Xray-specific behavior such as `xhttp`.
### SOCKS5/HTTP Proxy
Use a SOCKS5/HTTP Proxy profile when you already have an external proxy endpoint. Enter the proxy server, port, and optional credentials. This is different from the local `127.0.0.1` SOCKS5 proxy, which is exposed after connection for tools that need a local proxy address.
## OpenVPN
TunnelX can run an installed **OpenVPN Community** `openvpn.exe` with a user-selected `.ovpn` profile, then apply its own split-tunneling policy so only selected apps and included destinations use the OpenVPN tunnel.
OpenVPN is not bundled with TunnelX. Install OpenVPN Community separately, select the `.ovpn` file in TunnelX, and enter the OpenVPN username/password if the server requires credentials. OpenVPN Connect alone is not enough for this mode because it manages routes and DNS through its own client.
For split-tunnel compatibility, TunnelX prepares the OpenVPN config by controlling pushed route and DNS behavior. If OpenVPN reconnects and changes the tunnel IP, gateway, interface, or remote endpoint, TunnelX restarts its packet routing with the new values.
## Routing Notes
Destination include/exclude rules match both the entered domain and its subdomains. For example, adding `githubusercontent.com` also covers `raw.githubusercontent.com` after DNS resolves it. Some HTTPS clients may still fail during certificate revocation checks if their OCSP/CRL hosts are not reachable through the selected route; add the downloader app or the relevant revocation domains to the include list when that happens.
- Excluded destinations stay direct even for selected apps.
- Included destinations use the tunnel even when the matching app is not selected.
- For Store/MSIX, WebView2, or multi-process apps, keep the app open and refresh the app list.
- In full-route mode, the whole system uses the tunnel; direct/exclude rules are still useful for keeping specific destinations on the normal route.
## Local Data and Logs
Profiles, selected apps, include/exclude destinations, connection history, and logs are stored on the user's Windows machine, typically under `%LOCALAPPDATA%\TunnelX` or next to the app depending on the feature. TunnelX does not intentionally send analytics or telemetry to the maintainer.
Logs can contain process names, hostnames, IP addresses, ports, and connection state. Before posting logs publicly, remove server credentials, UUIDs, private keys, private endpoints, and other sensitive data.
## Troubleshooting
- If connection fails, check Administrator privileges, firewall rules, config validity, proxy ports, and prerequisites for the selected connection type.
- If an app does not use the tunnel, enable it in the apps tab, keep it running, and refresh the app list.
- If only one site or domain should use the tunnel, add it to include destinations. If it should stay direct, add it to exclusions.
- If DNS or IPv6 status looks wrong, check the health cards after connection and reconnect once to rebuild routes and DNS rules.
- For OpenVPN connection delays, verify the `.ovpn` file, credentials, and OpenVPN Community installation.
## Screenshots
| Connection dashboard | Profile and server setup |
@@ -36,9 +83,9 @@ Destination include/exclude rules match both the entered domain and its subdomai
## Download
Public downloads should be attached to GitHub Releases after release validation is complete:
Public downloads are published through GitHub Releases:
[GitHub project](https://github.com/MaxiFan/TunnelX)
[Download the latest release](https://github.com/MaxiFan/TunnelX/releases/latest)
Release assets are built and uploaded by GitHub Actions. Each published standalone executable includes a `.sha256` checksum file, and the release notes link back to the workflow run that produced the artifact.