mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-20 10:00:58 +00:00
Add remote routing URL support (#6168)
* Add remote routing URL support * Harden remote routing refresh * fix(sub): harden remote routing fetch and accept Mihomo src rule flag Remote routing bytes reach the YAML/JSON parsers from goroutines that run outside Gin's recovery, so a parser panic on crafted input would take down the whole panel. Contain it in fetch() (a panic now degrades to a failed refresh that keeps the last-good value and releases the in-flight slot) and start the refresh, cache-load and startup-warm goroutines through common.GoRecover like the other background workers. The route-graph validator only skipped a trailing no-resolve flag, so a valid Mihomo rule like IP-CIDR,x,DIRECT,no-resolve,src was rejected as an unknown target; skip both option flags. Also deduplicate the HTTPS-source classification into common.ParseRemoteRoutingURL so the save-time validator and the resolver can never drift (internal/sub imports internal/web/service, so the copy existed only to avoid the import cycle), move the test-only mergeRemoteClashRulesYAML helper into the test file, and trim oversized comment blocks. --------- Co-authored-by: Duxxie <yelloduxx@users.noreply.github.com> Co-authored-by: Sanaei <ho3ein.sanaei@gmail.com>
This commit is contained in:
@@ -23,6 +23,7 @@ func TestJobCadencesAreValidCronSpecs(t *testing.T) {
|
||||
"cadenceNodeHeartbeat": cadenceNodeHeartbeat,
|
||||
"cadenceNodeTraffic": cadenceNodeTraffic,
|
||||
"cadenceOutboundSub": cadenceOutboundSub,
|
||||
"cadenceRemoteRouting": cadenceRemoteRouting,
|
||||
"cadenceCheckHash": cadenceCheckHash,
|
||||
"cadenceCPUAlarm": cadenceCPUAlarm,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package job
|
||||
|
||||
import (
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/logger"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/sub"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/web/service"
|
||||
)
|
||||
|
||||
// RemoteRoutingJob keeps remote Happ and Clash/Mihomo routing URLs warm: all
|
||||
// network work runs here (cron + startup warm), never in a request handler.
|
||||
type RemoteRoutingJob struct {
|
||||
settingService service.SettingService
|
||||
}
|
||||
|
||||
func NewRemoteRoutingJob() *RemoteRoutingJob {
|
||||
return &RemoteRoutingJob{}
|
||||
}
|
||||
|
||||
func (j *RemoteRoutingJob) Run() {
|
||||
happ, err := j.settingService.GetSubRoutingRules()
|
||||
if err != nil {
|
||||
logger.Warning("Could not read Happ routing source:", err)
|
||||
return
|
||||
}
|
||||
clash, err := j.settingService.GetSubClashRules()
|
||||
if err != nil {
|
||||
logger.Warning("Could not read Clash routing source:", err)
|
||||
return
|
||||
}
|
||||
sub.RefreshRemoteRoutingSources(happ, clash)
|
||||
}
|
||||
@@ -1327,6 +1327,26 @@ func validateSettingsURLs(allSetting *entity.AllSetting) error {
|
||||
// the scheme instead of forcing SanitizeHTTPURL's http(s)-only rule.
|
||||
allSetting.SubSupportUrl = common.EnsureURLScheme(allSetting.SubSupportUrl)
|
||||
allSetting.SubProfileUrl = common.EnsureURLScheme(allSetting.SubProfileUrl)
|
||||
for name, value := range map[string]*string{
|
||||
"Happ routing source": &allSetting.SubRoutingRules,
|
||||
"Clash/Mihomo routing source": &allSetting.SubClashRules,
|
||||
"Incy routing source": &allSetting.SubIncyRoutingRules,
|
||||
} {
|
||||
if err := validateRemoteRoutingURLSetting(name, value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateRemoteRoutingURLSetting(name string, value *string) error {
|
||||
canonical, remote, err := common.ParseRemoteRoutingURL(*value)
|
||||
if err != nil {
|
||||
return common.NewError(name, err.Error())
|
||||
}
|
||||
if remote {
|
||||
*value = canonical
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/web/entity"
|
||||
)
|
||||
|
||||
func TestValidateRemoteRoutingURLSettings(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
value string
|
||||
want string
|
||||
wantError string
|
||||
}{
|
||||
{name: "valid HTTPS", value: " https://example.com/rules#fragment ", want: "https://example.com/rules"},
|
||||
{name: "credentials", value: "https://user:pass@example.com/rules", wantError: "must not contain URL credentials"},
|
||||
{name: "missing host", value: "https:///rules", wantError: "absolute HTTPS URL"},
|
||||
{name: "legacy HTTP stays inline", value: "http://example.com/rules", want: "http://example.com/rules"},
|
||||
{name: "multiline Clash stays inline", value: "https://example.com/rules\nMATCH,PROXY", want: "https://example.com/rules\nMATCH,PROXY"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
settings := &entity.AllSetting{SubRoutingRules: tt.value}
|
||||
err := validateSettingsURLs(settings)
|
||||
if tt.wantError != "" {
|
||||
if err == nil || !strings.Contains(err.Error(), tt.wantError) {
|
||||
t.Fatalf("err=%v, want %q", err, tt.wantError)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil || settings.SubRoutingRules != tt.want {
|
||||
t.Fatalf("value=%q err=%v", settings.SubRoutingRules, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1158,17 +1158,17 @@
|
||||
"subEnableRouting": "تفعيل التوجيه",
|
||||
"subEnableRoutingDesc": "إعداد عام لتمكين التوجيه (Routing) في عميل VPN. (فقط لـ Happ)",
|
||||
"subRoutingRules": "قواعد التوجيه",
|
||||
"subRoutingRulesDesc": "قواعد التوجيه العامة لعميل VPN. (فقط لـ Happ)",
|
||||
"subRoutingRulesDesc": "ألصق رابط happ:// جاهزًا أو عنوان HTTPS دائمًا. تحدّث اللوحة القواعد البعيدة في الخلفية وتحتفظ بآخر قيمة صالحة، لذلك لا تنتظر طلبات الاشتراك المصدر. (فقط لـ Happ)",
|
||||
"subHideSettings": "إخفاء إعدادات الخادم",
|
||||
"subHideSettingsDesc": "إخفاء إمكانية عرض وتعديل إعدادات الخادم في عميل VPN. (فقط لـ Happ)",
|
||||
"subIncyEnableRouting": "تفعيل التوجيه",
|
||||
"subIncyEnableRoutingDesc": "حقن ملف تعريف التوجيه في محتوى الاشتراك لعميل Incy. (فقط لـ Incy)",
|
||||
"subIncyRoutingRules": "قواعد التوجيه",
|
||||
"subIncyRoutingRulesDesc": "رابط توجيه Incy المُضاف إلى محتوى الاشتراك، مثل incy://routing/onadd/<base64>. (فقط لـ Incy)",
|
||||
"subIncyRoutingRulesDesc": "ألصق رابط incy:// جاهزًا أو عنوان HTTPS دائمًا لملف JSON. ينشئ Incy ملف autorouting ويحدّثه تلقائيًا. (فقط لـ Incy)",
|
||||
"subClashEnableRouting": "تفعيل التوجيه",
|
||||
"subClashEnableRoutingDesc": "تضمين قواعد توجيه Clash/Mihomo العامة في اشتراكات YAML المُنشأة.",
|
||||
"subClashRoutingRules": "قواعد التوجيه العامة",
|
||||
"subClashRoutingRulesDesc": "قواعد Clash/Mihomo التي تُضاف في بداية كل اشتراك YAML قبل MATCH,PROXY.",
|
||||
"subClashRoutingRulesDesc": "ألصق قواعد/YAML أو عنوان HTTPS دائمًا. تحدّثه اللوحة في الخلفية، وتستورد المجموعات وموفري القواعد والقواعد فقط، وتحافظ على عقد VPN المُنشأة وآخر قيمة صالحة.",
|
||||
"subListen": "IP الاستماع",
|
||||
"subListenDesc": "عنوان IP لخدمة الاشتراك. (سيبه فاضي عشان يستمع على كل الـ IPs)",
|
||||
"subPort": "بورت الاستماع",
|
||||
|
||||
@@ -1280,17 +1280,17 @@
|
||||
"subEnableRouting": "Enable routing",
|
||||
"subEnableRoutingDesc": "Global setting to enable routing in the VPN client. (Only for Happ)",
|
||||
"subRoutingRules": "Routing rules",
|
||||
"subRoutingRulesDesc": "Global routing rules for the VPN client. (Only for Happ)",
|
||||
"subRoutingRulesDesc": "Paste a ready happ:// deeplink or one permanent HTTPS URL returning a deeplink or JSON. The panel refreshes remote rules in the background and keeps the last valid value, so subscription requests never wait for the source. (Happ only)",
|
||||
"subHideSettings": "Hide server settings",
|
||||
"subHideSettingsDesc": "Hide the ability to view and edit server configurations in the VPN client. (Only for Happ)",
|
||||
"subIncyEnableRouting": "Enable routing",
|
||||
"subIncyEnableRoutingDesc": "Inject a routing profile into the subscription body for the Incy client. (Only for Incy)",
|
||||
"subIncyRoutingRules": "Routing rules",
|
||||
"subIncyRoutingRulesDesc": "Incy routing deep-link added to the subscription body, e.g. incy://routing/onadd/<base64>. (Only for Incy)",
|
||||
"subIncyRoutingRulesDesc": "Paste a ready incy:// deeplink or one permanent HTTPS URL returning JSON. An HTTPS URL becomes an autorouting profile refreshed by Incy itself. (Incy only)",
|
||||
"subClashEnableRouting": "Enable routing",
|
||||
"subClashEnableRoutingDesc": "Include global Clash/Mihomo routing rules in generated YAML subscriptions.",
|
||||
"subClashRoutingRules": "Global routing rules",
|
||||
"subClashRoutingRulesDesc": "Default Clash/Mihomo rules prepended to every generated YAML subscription before MATCH,PROXY.",
|
||||
"subClashRoutingRulesDesc": "Paste inline rules/YAML or one permanent HTTPS URL. The panel refreshes it in the background, imports only groups/providers/rules, preserves generated VPN nodes and keeps the last valid value.",
|
||||
"subListen": "Listen IP",
|
||||
"subListenDesc": "The IP address for the subscription service. (leave blank to listen on all IPs)",
|
||||
"subPort": "Listen Port",
|
||||
|
||||
@@ -1158,17 +1158,17 @@
|
||||
"subEnableRouting": "Habilitar enrutamiento",
|
||||
"subEnableRoutingDesc": "Configuración global para habilitar el enrutamiento en el cliente VPN. (Solo para Happ)",
|
||||
"subRoutingRules": "Reglas de enrutamiento",
|
||||
"subRoutingRulesDesc": "Reglas de enrutamiento globales para el cliente VPN. (Solo para Happ)",
|
||||
"subRoutingRulesDesc": "Pegue un enlace happ:// listo o una URL HTTPS permanente. El panel actualiza las reglas remotas en segundo plano y conserva el último valor válido, sin retrasar las solicitudes de suscripción. (Solo para Happ)",
|
||||
"subHideSettings": "Ocultar configuración del servidor",
|
||||
"subHideSettingsDesc": "Ocultar la posibilidad de ver y editar las configuraciones del servidor en el cliente VPN. (Solo para Happ)",
|
||||
"subIncyEnableRouting": "Habilitar enrutamiento",
|
||||
"subIncyEnableRoutingDesc": "Inyectar un perfil de enrutamiento en el cuerpo de la suscripción para el cliente Incy. (Solo para Incy)",
|
||||
"subIncyRoutingRules": "Reglas de enrutamiento",
|
||||
"subIncyRoutingRulesDesc": "Enlace de enrutamiento de Incy añadido al cuerpo de la suscripción, p. ej. incy://routing/onadd/<base64>. (Solo para Incy)",
|
||||
"subIncyRoutingRulesDesc": "Pegue un enlace incy:// listo o una URL HTTPS permanente a JSON. Incy crea un perfil de autorouting y lo actualiza automáticamente. (Solo para Incy)",
|
||||
"subClashEnableRouting": "Habilitar enrutamiento",
|
||||
"subClashEnableRoutingDesc": "Incluir reglas globales de enrutamiento Clash/Mihomo en las suscripciones YAML generadas.",
|
||||
"subClashRoutingRules": "Reglas globales de enrutamiento",
|
||||
"subClashRoutingRulesDesc": "Reglas Clash/Mihomo agregadas al inicio de cada suscripción YAML antes de MATCH,PROXY.",
|
||||
"subClashRoutingRulesDesc": "Pegue reglas/YAML o una URL HTTPS permanente. El panel la actualiza en segundo plano, importa solo grupos, proveedores de reglas y reglas, y conserva los nodos VPN generados y el último valor válido.",
|
||||
"subListen": "Listening IP",
|
||||
"subListenDesc": "Dejar en blanco por defecto para monitorear todas las IPs.",
|
||||
"subPort": "Puerto de Suscripción",
|
||||
|
||||
@@ -1162,17 +1162,17 @@
|
||||
"subEnableRouting": "فعالسازی مسیریابی",
|
||||
"subEnableRoutingDesc": "تنظیمات سراسری برای فعالسازی مسیریابی در کلاینت VPN. (فقط برای Happ)",
|
||||
"subRoutingRules": "قوانین مسیریابی",
|
||||
"subRoutingRulesDesc": "قوانین مسیریابی سراسری برای کلاینت VPN. (فقط برای Happ)",
|
||||
"subRoutingRulesDesc": "یک پیوند آماده happ:// یا یک نشانی دائمی HTTPS وارد کنید. پنل قوانین راهدور را در پسزمینه بهروزرسانی و آخرین مقدار معتبر را نگه میدارد، بنابراین درخواست اشتراک منتظر منبع نمیماند. (فقط برای Happ)",
|
||||
"subHideSettings": "پنهان کردن تنظیمات سرور",
|
||||
"subHideSettingsDesc": "پنهان کردن توانایی مشاهده و ویرایش پیکربندی سرور در کلاینت VPN. (فقط برای Happ)",
|
||||
"subIncyEnableRouting": "فعالسازی مسیریابی",
|
||||
"subIncyEnableRoutingDesc": "تزریق پروفایل مسیریابی به بدنه اشتراک برای کلاینت Incy. (فقط برای Incy)",
|
||||
"subIncyRoutingRules": "قوانین مسیریابی",
|
||||
"subIncyRoutingRulesDesc": "لینک مسیریابی Incy که به بدنه اشتراک افزوده میشود، مثلاً incy://routing/onadd/<base64>. (فقط برای Incy)",
|
||||
"subIncyRoutingRulesDesc": "یک پیوند آماده incy:// یا یک نشانی دائمی HTTPS برای JSON وارد کنید. Incy یک نمایه autorouting میسازد و آن را خودکار بهروزرسانی میکند. (فقط برای Incy)",
|
||||
"subClashEnableRouting": "فعالسازی مسیریابی",
|
||||
"subClashEnableRoutingDesc": "قوانین مسیریابی سراسری Clash/Mihomo را در اشتراکهای YAML تولیدشده وارد کن.",
|
||||
"subClashRoutingRules": "قوانین مسیریابی سراسری",
|
||||
"subClashRoutingRulesDesc": "قوانین Clash/Mihomo که پیش از MATCH,PROXY به ابتدای هر اشتراک YAML افزوده میشوند.",
|
||||
"subClashRoutingRulesDesc": "قوانین/YAML یا یک نشانی دائمی HTTPS وارد کنید. پنل آن را در پسزمینه بهروزرسانی میکند، فقط گروهها، ارائهدهندگان قانون و قوانین را وارد میکند و گرههای VPN ساختهشده و آخرین مقدار معتبر را حفظ میکند.",
|
||||
"subListen": "آدرس آیپی",
|
||||
"subListenDesc": "آدرس آیپی برای سرویس سابسکریپشن. برای گوش دادن بهتمام آیپیها خالیبگذارید",
|
||||
"subPort": "پورت",
|
||||
|
||||
@@ -1158,17 +1158,17 @@
|
||||
"subEnableRouting": "Aktifkan perutean",
|
||||
"subEnableRoutingDesc": "Pengaturan global untuk mengaktifkan perutean (routing) di klien VPN. (Hanya untuk Happ)",
|
||||
"subRoutingRules": "Aturan routing",
|
||||
"subRoutingRulesDesc": "Aturan routing global untuk klien VPN. (Hanya untuk Happ)",
|
||||
"subRoutingRulesDesc": "Tempel deeplink happ:// siap pakai atau satu URL HTTPS permanen. Panel memperbarui aturan jarak jauh di latar belakang dan menyimpan nilai valid terakhir, sehingga permintaan langganan tidak menunggu sumber. (Hanya untuk Happ)",
|
||||
"subHideSettings": "Sembunyikan pengaturan server",
|
||||
"subHideSettingsDesc": "Menyembunyikan kemampuan untuk melihat dan mengedit konfigurasi server di klien VPN. (Hanya untuk Happ)",
|
||||
"subIncyEnableRouting": "Aktifkan perutean",
|
||||
"subIncyEnableRoutingDesc": "Menyuntikkan profil perutean ke dalam body langganan untuk klien Incy. (Hanya untuk Incy)",
|
||||
"subIncyRoutingRules": "Aturan routing",
|
||||
"subIncyRoutingRulesDesc": "Tautan perutean Incy yang ditambahkan ke body langganan, mis. incy://routing/onadd/<base64>. (Hanya untuk Incy)",
|
||||
"subIncyRoutingRulesDesc": "Tempel deeplink incy:// siap pakai atau URL HTTPS permanen ke JSON. Incy membuat profil autorouting dan memperbaruinya secara otomatis. (Hanya untuk Incy)",
|
||||
"subClashEnableRouting": "Aktifkan routing",
|
||||
"subClashEnableRoutingDesc": "Sertakan aturan routing global Clash/Mihomo dalam langganan YAML yang dibuat.",
|
||||
"subClashRoutingRules": "Aturan routing global",
|
||||
"subClashRoutingRulesDesc": "Aturan Clash/Mihomo yang ditambahkan di awal setiap langganan YAML sebelum MATCH,PROXY.",
|
||||
"subClashRoutingRulesDesc": "Tempel aturan/YAML atau satu URL HTTPS permanen. Panel memperbaruinya di latar belakang, hanya mengimpor grup, penyedia aturan, dan aturan, serta mempertahankan node VPN buatan panel dan nilai valid terakhir.",
|
||||
"subListen": "IP Pendengar",
|
||||
"subListenDesc": "Alamat IP untuk layanan langganan. (biarkan kosong untuk mendengarkan semua IP)",
|
||||
"subPort": "Port Pendengar",
|
||||
|
||||
@@ -1158,17 +1158,17 @@
|
||||
"subEnableRouting": "ルーティングを有効化",
|
||||
"subEnableRoutingDesc": "VPNクライアントでルーティングを有効にするためのグローバル設定。(Happのみ)",
|
||||
"subRoutingRules": "ルーティングルール",
|
||||
"subRoutingRulesDesc": "VPNクライアントのグローバルルーティングルール。(Happのみ)",
|
||||
"subRoutingRulesDesc": "完成した happ:// ディープリンク、または永続的な HTTPS URL を入力します。パネルはリモートルールをバックグラウンドで更新し、最後の有効値を保持するため、サブスクリプション要求は取得を待ちません。(Happのみ)",
|
||||
"subHideSettings": "サーバー設定を非表示",
|
||||
"subHideSettingsDesc": "VPNクライアントでサーバー設定の表示・編集機能を非表示にします。(Happのみ)",
|
||||
"subIncyEnableRouting": "ルーティングを有効化",
|
||||
"subIncyEnableRoutingDesc": "Incyクライアント用に、サブスクリプション本文へルーティングプロファイルを挿入します。(Incyのみ)",
|
||||
"subIncyRoutingRules": "ルーティングルール",
|
||||
"subIncyRoutingRulesDesc": "サブスクリプション本文に追加するIncyルーティングのディープリンク。例: incy://routing/onadd/<base64>。(Incyのみ)",
|
||||
"subIncyRoutingRulesDesc": "完成した incy:// ディープリンク、または JSON への永続的な HTTPS URL を入力します。Incy は autorouting プロファイルを作成し、自動更新します。(Incyのみ)",
|
||||
"subClashEnableRouting": "ルーティングを有効化",
|
||||
"subClashEnableRoutingDesc": "生成されたYAMLサブスクリプションにClash/Mihomoのグローバルルーティングルールを含めます。",
|
||||
"subClashRoutingRules": "グローバルルーティングルール",
|
||||
"subClashRoutingRulesDesc": "各YAMLサブスクリプションのMATCH,PROXYより前に追加されるClash/Mihomoルール。",
|
||||
"subClashRoutingRulesDesc": "ルール/YAML、または永続的な HTTPS URL を入力します。パネルはバックグラウンドで更新し、グループ・ルールプロバイダー・ルールのみを取り込み、生成済み VPN ノードと最後の有効値を保持します。",
|
||||
"subListen": "監視IP",
|
||||
"subListenDesc": "サブスクリプションサービスが監視するIPアドレス(空白にするとすべてのIPを監視)",
|
||||
"subPort": "監視ポート",
|
||||
|
||||
@@ -1158,17 +1158,17 @@
|
||||
"subEnableRouting": "Ativar roteamento",
|
||||
"subEnableRoutingDesc": "Configuração global para habilitar o roteamento no cliente VPN. (Apenas para Happ)",
|
||||
"subRoutingRules": "Regras de roteamento",
|
||||
"subRoutingRulesDesc": "Regras de roteamento globais para o cliente VPN. (Apenas para Happ)",
|
||||
"subRoutingRulesDesc": "Cole um deeplink happ:// pronto ou uma URL HTTPS permanente. O painel atualiza as regras remotas em segundo plano e mantém o último valor válido, sem atrasar as solicitações de assinatura. (Apenas para Happ)",
|
||||
"subHideSettings": "Ocultar configurações do servidor",
|
||||
"subHideSettingsDesc": "Ocultar a capacidade de visualizar e editar as configurações do servidor no cliente VPN. (Apenas para Happ)",
|
||||
"subIncyEnableRouting": "Ativar roteamento",
|
||||
"subIncyEnableRoutingDesc": "Injetar um perfil de roteamento no corpo da assinatura para o cliente Incy. (Apenas para Incy)",
|
||||
"subIncyRoutingRules": "Regras de roteamento",
|
||||
"subIncyRoutingRulesDesc": "Link de roteamento do Incy adicionado ao corpo da assinatura, ex. incy://routing/onadd/<base64>. (Apenas para Incy)",
|
||||
"subIncyRoutingRulesDesc": "Cole um deeplink incy:// pronto ou uma URL HTTPS permanente para JSON. O Incy cria um perfil de autorouting e o atualiza automaticamente. (Apenas para Incy)",
|
||||
"subClashEnableRouting": "Ativar roteamento",
|
||||
"subClashEnableRoutingDesc": "Incluir regras globais de roteamento Clash/Mihomo nas assinaturas YAML geradas.",
|
||||
"subClashRoutingRules": "Regras globais de roteamento",
|
||||
"subClashRoutingRulesDesc": "Regras Clash/Mihomo adicionadas ao início de cada assinatura YAML antes de MATCH,PROXY.",
|
||||
"subClashRoutingRulesDesc": "Cole regras/YAML ou uma URL HTTPS permanente. O painel a atualiza em segundo plano, importa apenas grupos, provedores de regras e regras, e preserva os nós VPN gerados e o último valor válido.",
|
||||
"subListen": "IP de Escuta",
|
||||
"subListenDesc": "O endereço IP para o serviço de assinatura. (deixe em branco para escutar em todos os IPs)",
|
||||
"subPort": "Porta de Escuta",
|
||||
|
||||
@@ -1158,17 +1158,17 @@
|
||||
"subEnableRouting": "Включить маршрутизацию",
|
||||
"subEnableRoutingDesc": "Глобальная настройка для включения маршрутизации в VPN-клиенте. (Только для Happ)",
|
||||
"subRoutingRules": "Правила маршрутизации",
|
||||
"subRoutingRulesDesc": "Глобальные правила маршрутизации для VPN-клиента. (Только для Happ)",
|
||||
"subRoutingRulesDesc": "Вставьте готовый happ:// deeplink либо одну постоянную HTTPS-ссылку на deeplink или JSON. Панель обновляет удалённые правила в фоне и хранит последнее рабочее значение, поэтому запрос подписки не ждёт источник. (Только для Happ)",
|
||||
"subHideSettings": "Скрыть настройки сервера",
|
||||
"subHideSettingsDesc": "Скрыть возможность просмотра и редактирования конфигурации сервера в VPN-клиенте. (Только для Happ)",
|
||||
"subIncyEnableRouting": "Включить маршрутизацию",
|
||||
"subIncyEnableRoutingDesc": "Внедрять профиль маршрутизации в тело подписки для клиента Incy. (Только для Incy)",
|
||||
"subIncyRoutingRules": "Правила маршрутизации",
|
||||
"subIncyRoutingRulesDesc": "Ссылка маршрутизации Incy, добавляемая в тело подписки, напр. incy://routing/onadd/<base64>. (Только для Incy)",
|
||||
"subIncyRoutingRulesDesc": "Вставьте готовый incy:// deeplink либо одну постоянную HTTPS-ссылку на JSON. Для HTTPS-ссылки создаётся autorouting-профиль, который Incy обновляет самостоятельно. (Только для Incy)",
|
||||
"subClashEnableRouting": "Включить маршрутизацию",
|
||||
"subClashEnableRoutingDesc": "Добавлять глобальные правила маршрутизации Clash/Mihomo в сгенерированные YAML-подписки.",
|
||||
"subClashRoutingRules": "Глобальные правила маршрутизации",
|
||||
"subClashRoutingRulesDesc": "Правила Clash/Mihomo, добавляемые в начало каждой YAML-подписки перед MATCH,PROXY.",
|
||||
"subClashRoutingRulesDesc": "Вставьте правила/YAML либо одну постоянную HTTPS-ссылку. Панель обновляет её в фоне, импортирует только группы, провайдеры правил и правила, сохраняет созданные VPN-узлы и последнее рабочее значение.",
|
||||
"subListen": "Прослушивание IP",
|
||||
"subListenDesc": "Оставьте пустым по умолчанию, чтобы отслеживать все IP-адреса",
|
||||
"subPort": "Порт подписки",
|
||||
|
||||
@@ -1158,17 +1158,17 @@
|
||||
"subEnableRouting": "Yönlendirmeyi etkinleştir",
|
||||
"subEnableRoutingDesc": "VPN istemcisinde yönlendirmeyi etkinleştirmek için genel ayar. (Yalnızca Happ için)",
|
||||
"subRoutingRules": "Yönlendirme kuralları",
|
||||
"subRoutingRulesDesc": "VPN istemcisi için genel yönlendirme kuralları. (Yalnızca Happ için)",
|
||||
"subRoutingRulesDesc": "Hazır bir happ:// derin bağlantısı veya kalıcı bir HTTPS URL'si yapıştırın. Panel uzak kuralları arka planda yeniler ve son geçerli değeri saklar; abonelik istekleri kaynağı beklemez. (Yalnızca Happ için)",
|
||||
"subHideSettings": "Sunucu ayarlarını gizle",
|
||||
"subHideSettingsDesc": "VPN istemcisinde sunucu yapılandırmalarını görüntüleme ve düzenleme özelliğini gizleyin. (Yalnızca Happ için)",
|
||||
"subIncyEnableRouting": "Yönlendirmeyi etkinleştir",
|
||||
"subIncyEnableRoutingDesc": "Incy istemcisi için abonelik gövdesine bir yönlendirme profili ekleyin. (Yalnızca Incy için)",
|
||||
"subIncyRoutingRules": "Yönlendirme kuralları",
|
||||
"subIncyRoutingRulesDesc": "Abonelik gövdesine eklenen Incy yönlendirme bağlantısı, örn. incy://routing/onadd/<base64>. (Yalnızca Incy için)",
|
||||
"subIncyRoutingRulesDesc": "Hazır bir incy:// derin bağlantısı veya JSON için kalıcı bir HTTPS URL'si yapıştırın. Incy bir autorouting profili oluşturur ve otomatik olarak günceller. (Yalnızca Incy için)",
|
||||
"subClashEnableRouting": "Yönlendirmeyi Etkinleştir",
|
||||
"subClashEnableRoutingDesc": "Oluşturulan YAML aboneliklerine genel Clash/Mihomo yönlendirme kurallarını ekler.",
|
||||
"subClashRoutingRules": "Genel Yönlendirme Kuralları",
|
||||
"subClashRoutingRulesDesc": "Her YAML aboneliğinin başına MATCH,PROXY öncesinde eklenen varsayılan Clash/Mihomo kuralları.",
|
||||
"subClashRoutingRulesDesc": "Kurallar/YAML veya kalıcı bir HTTPS URL'si yapıştırın. Panel bunu arka planda yeniler, yalnızca grupları, kural sağlayıcılarını ve kuralları içe aktarır; oluşturulan VPN düğümlerini ve son geçerli değeri korur.",
|
||||
"subListen": "Dinleme IP",
|
||||
"subListenDesc": "Abonelik hizmeti için IP adresi. (tüm IP'leri dinlemek için boş bırakın)",
|
||||
"subPort": "Dinleme Portu",
|
||||
|
||||
@@ -1158,17 +1158,17 @@
|
||||
"subEnableRouting": "Увімкнути маршрутизацію",
|
||||
"subEnableRoutingDesc": "Глобальне налаштування для увімкнення маршрутизації у VPN-клієнті. (Тільки для Happ)",
|
||||
"subRoutingRules": "Правила маршрутизації",
|
||||
"subRoutingRulesDesc": "Глобальні правила маршрутизації для VPN-клієнта. (Тільки для Happ)",
|
||||
"subRoutingRulesDesc": "Вставте готове посилання happ:// або одну постійну HTTPS-адресу. Панель оновлює віддалені правила у фоні та зберігає останнє коректне значення, тому запит підписки не чекає на джерело. (Тільки для Happ)",
|
||||
"subHideSettings": "Приховати налаштування сервера",
|
||||
"subHideSettingsDesc": "Приховати можливість перегляду та редагування конфігурації сервера у VPN-клієнті. (Тільки для Happ)",
|
||||
"subIncyEnableRouting": "Увімкнути маршрутизацію",
|
||||
"subIncyEnableRoutingDesc": "Вставляти профіль маршрутизації в тіло підписки для клієнта Incy. (Тільки для Incy)",
|
||||
"subIncyRoutingRules": "Правила маршрутизації",
|
||||
"subIncyRoutingRulesDesc": "Посилання маршрутизації Incy, що додається в тіло підписки, напр. incy://routing/onadd/<base64>. (Тільки для Incy)",
|
||||
"subIncyRoutingRulesDesc": "Вставте готове посилання incy:// або постійну HTTPS-адресу JSON. Incy створює профіль autorouting і автоматично його оновлює. (Тільки для Incy)",
|
||||
"subClashEnableRouting": "Увімкнути маршрутизацію",
|
||||
"subClashEnableRoutingDesc": "Додавати глобальні правила маршрутизації Clash/Mihomo до згенерованих YAML-підписок.",
|
||||
"subClashRoutingRules": "Глобальні правила маршрутизації",
|
||||
"subClashRoutingRulesDesc": "Правила Clash/Mihomo, що додаються на початок кожної YAML-підписки перед MATCH,PROXY.",
|
||||
"subClashRoutingRulesDesc": "Вставте правила/YAML або одну постійну HTTPS-адресу. Панель оновлює її у фоні, імпортує лише групи, постачальників правил і правила, зберігаючи створені VPN-вузли та останнє коректне значення.",
|
||||
"subListen": "Слухати IP",
|
||||
"subListenDesc": "IP-адреса для служби підписки. (залиште порожнім, щоб слухати всі IP-адреси)",
|
||||
"subPort": "Слухати порт",
|
||||
|
||||
@@ -1158,17 +1158,17 @@
|
||||
"subEnableRouting": "Bật định tuyến",
|
||||
"subEnableRoutingDesc": "Cài đặt toàn cục để bật định tuyến trong ứng dụng khách VPN. (Chỉ dành cho Happ)",
|
||||
"subRoutingRules": "Quy tắc định tuyến",
|
||||
"subRoutingRulesDesc": "Quy tắc định tuyến toàn cầu cho client VPN. (Chỉ dành cho Happ)",
|
||||
"subRoutingRulesDesc": "Dán deeplink happ:// có sẵn hoặc một URL HTTPS cố định. Bảng điều khiển cập nhật quy tắc từ xa trong nền và giữ giá trị hợp lệ gần nhất, nên yêu cầu đăng ký không phải chờ nguồn. (Chỉ dành cho Happ)",
|
||||
"subHideSettings": "Ẩn cài đặt máy chủ",
|
||||
"subHideSettingsDesc": "Ẩn khả năng xem và chỉnh sửa cấu hình máy chủ trong ứng dụng khách VPN. (Chỉ dành cho Happ)",
|
||||
"subIncyEnableRouting": "Bật định tuyến",
|
||||
"subIncyEnableRoutingDesc": "Chèn hồ sơ định tuyến vào nội dung đăng ký cho ứng dụng Incy. (Chỉ dành cho Incy)",
|
||||
"subIncyRoutingRules": "Quy tắc định tuyến",
|
||||
"subIncyRoutingRulesDesc": "Liên kết định tuyến Incy được thêm vào nội dung đăng ký, ví dụ incy://routing/onadd/<base64>. (Chỉ dành cho Incy)",
|
||||
"subIncyRoutingRulesDesc": "Dán deeplink incy:// có sẵn hoặc URL HTTPS cố định tới JSON. Incy tạo hồ sơ autorouting và tự động cập nhật. (Chỉ dành cho Incy)",
|
||||
"subClashEnableRouting": "Bật định tuyến",
|
||||
"subClashEnableRoutingDesc": "Bao gồm quy tắc định tuyến Clash/Mihomo toàn cầu trong các đăng ký YAML được tạo.",
|
||||
"subClashRoutingRules": "Quy tắc định tuyến toàn cầu",
|
||||
"subClashRoutingRulesDesc": "Quy tắc Clash/Mihomo được thêm vào đầu mỗi đăng ký YAML trước MATCH,PROXY.",
|
||||
"subClashRoutingRulesDesc": "Dán quy tắc/YAML hoặc một URL HTTPS cố định. Bảng điều khiển cập nhật trong nền, chỉ nhập nhóm, nhà cung cấp quy tắc và quy tắc, đồng thời giữ các nút VPN đã tạo và giá trị hợp lệ gần nhất.",
|
||||
"subListen": "Listening IP",
|
||||
"subListenDesc": "Mặc định để trống để nghe tất cả các IP",
|
||||
"subPort": "Cổng gói đăng ký",
|
||||
|
||||
@@ -1158,17 +1158,17 @@
|
||||
"subEnableRouting": "启用路由",
|
||||
"subEnableRoutingDesc": "在 VPN 客户端中启用路由的全局设置。(仅限 Happ)",
|
||||
"subRoutingRules": "路由规则",
|
||||
"subRoutingRulesDesc": "VPN 用户端的全域路由规则。(仅限 Happ)",
|
||||
"subRoutingRulesDesc": "粘贴现成的 happ:// 深层链接或一个固定 HTTPS URL。面板会在后台更新远程规则并保留最后一个有效值,因此订阅请求无需等待远程源。(仅限 Happ)",
|
||||
"subHideSettings": "隐藏服务器设置",
|
||||
"subHideSettingsDesc": "在 VPN 客户端中隐藏查看和编辑服务器配置的功能。(仅限 Happ)",
|
||||
"subIncyEnableRouting": "启用路由",
|
||||
"subIncyEnableRoutingDesc": "为 Incy 客户端将路由配置注入订阅内容中。(仅限 Incy)",
|
||||
"subIncyRoutingRules": "路由规则",
|
||||
"subIncyRoutingRulesDesc": "添加到订阅内容的 Incy 路由深层链接,例如 incy://routing/onadd/<base64>。(仅限 Incy)",
|
||||
"subIncyRoutingRulesDesc": "粘贴现成的 incy:// 深层链接或指向 JSON 的固定 HTTPS URL。Incy 会创建 autorouting 配置并自动更新。(仅限 Incy)",
|
||||
"subClashEnableRouting": "启用路由",
|
||||
"subClashEnableRoutingDesc": "在生成的 YAML 订阅中包含 Clash/Mihomo 全局路由规则。",
|
||||
"subClashRoutingRules": "全局路由规则",
|
||||
"subClashRoutingRulesDesc": "添加到每个 YAML 订阅开头、MATCH,PROXY 之前的 Clash/Mihomo 规则。",
|
||||
"subClashRoutingRulesDesc": "粘贴规则/YAML 或一个固定 HTTPS URL。面板会在后台更新,仅导入代理组、规则提供者和规则,并保留面板生成的 VPN 节点及最后一个有效值。",
|
||||
"subListen": "监听 IP",
|
||||
"subListenDesc": "订阅服务监听的 IP 地址(留空表示监听所有 IP)",
|
||||
"subPort": "监听端口",
|
||||
|
||||
@@ -1158,17 +1158,17 @@
|
||||
"subEnableRouting": "啟用路由",
|
||||
"subEnableRoutingDesc": "在 VPN 用戶端中啟用路由的全域設定。(僅限 Happ)",
|
||||
"subRoutingRules": "路由規則",
|
||||
"subRoutingRulesDesc": "VPN 用戶端的全域路由規則。(僅限 Happ)",
|
||||
"subRoutingRulesDesc": "貼上現成的 happ:// 深層連結或一個固定 HTTPS URL。面板會在背景更新遠端規則並保留最後一個有效值,因此訂閱請求不需等待遠端來源。(僅限 Happ)",
|
||||
"subHideSettings": "隱藏伺服器設定",
|
||||
"subHideSettingsDesc": "在 VPN 用戶端中隱藏查看和編輯伺服器配置的功能。(僅限 Happ)",
|
||||
"subIncyEnableRouting": "啟用路由",
|
||||
"subIncyEnableRoutingDesc": "為 Incy 用戶端將路由設定檔注入訂閱內容中。(僅限 Incy)",
|
||||
"subIncyRoutingRules": "路由規則",
|
||||
"subIncyRoutingRulesDesc": "加入訂閱內容的 Incy 路由深層連結,例如 incy://routing/onadd/<base64>。(僅限 Incy)",
|
||||
"subIncyRoutingRulesDesc": "貼上現成的 incy:// 深層連結或指向 JSON 的固定 HTTPS URL。Incy 會建立 autorouting 設定並自動更新。(僅限 Incy)",
|
||||
"subClashEnableRouting": "啟用路由",
|
||||
"subClashEnableRoutingDesc": "在產生的 YAML 訂閱中包含 Clash/Mihomo 全域路由規則。",
|
||||
"subClashRoutingRules": "全域路由規則",
|
||||
"subClashRoutingRulesDesc": "加入到每個 YAML 訂閱開頭、MATCH,PROXY 之前的 Clash/Mihomo 規則。",
|
||||
"subClashRoutingRulesDesc": "貼上規則/YAML 或一個固定 HTTPS URL。面板會在背景更新,只匯入代理群組、規則提供者與規則,並保留面板產生的 VPN 節點及最後一個有效值。",
|
||||
"subListen": "監聽 IP",
|
||||
"subListenDesc": "訂閱服務監聽的 IP 地址(留空表示監聽所有 IP)",
|
||||
"subPort": "監聽埠",
|
||||
|
||||
@@ -296,6 +296,7 @@ const (
|
||||
cadenceNodeTraffic = "@every 5s"
|
||||
cadenceOutboundSub = "@every 5m"
|
||||
cadenceReapOrphans = "@every 5m"
|
||||
cadenceRemoteRouting = "@every 5m"
|
||||
cadenceXrayLogPrune = "@every 10m"
|
||||
cadenceCheckHash = "@every 2m"
|
||||
// cpu.Percent samples over a full minute (blocking), so a finer cadence just
|
||||
@@ -343,6 +344,12 @@ func (s *Server) startTask(restartXray bool, loc *time.Location) {
|
||||
|
||||
_, _ = s.cron.AddJob(cadenceReapOrphans, job.NewReapSyncOrphansJob())
|
||||
|
||||
// Warm permanent routing URLs immediately and refresh them outside the
|
||||
// latency-sensitive subscription request path.
|
||||
remoteRoutingJob := job.NewRemoteRoutingJob()
|
||||
_, _ = s.cron.AddJob(cadenceRemoteRouting, remoteRoutingJob)
|
||||
common.GoRecover("remote-routing-warm", remoteRoutingJob.Run)
|
||||
|
||||
// check client ips from log file every day
|
||||
_, _ = s.cron.AddJob("@daily", job.NewClearLogsJob())
|
||||
_, _ = s.cron.AddJob(cadenceXrayLogPrune, job.NewPruneXrayLogsJob())
|
||||
|
||||
Reference in New Issue
Block a user