Fix proxy-providers: bypass clash.yaml for Mihomo provider refresh requests

When Mihomo fetches proxy-providers it sends a Clash UA, causing nginx to
return clash.yaml instead of the actual proxy list — resulting in empty groups.

Fix: proxy-providers in clash.yaml now send X-Proxy-Provider: true header.
nginx map checks combined key "$is_clash_ua:$http_x_proxy_provider":
- Clash UA with no header ("1:") → serve clash.yaml (initial import)
- Clash UA with header present  → pass through to x-ui sub port (provider refresh)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ivan Razin
2026-06-24 14:43:32 +03:00
co-authored by Claude Sonnet 4.6
parent 33fef3b27b
commit aa6c744070
2 changed files with 12 additions and 3 deletions
+9 -3
View File
@@ -328,7 +328,7 @@ EOF
# and routes Clash/Mihomo clients to dynamic clash.yaml generator
location ~ ^/${sub_path}/(?<clash_sub_id>[^/]+)$ {
if (\$hack = 1) { return 404; }
if (\$is_clash_client = 1) { rewrite ^ /__clash_api?sub_id=\$clash_sub_id last; }
if (\$serve_clash_yaml = 1) { rewrite ^ /__clash_api?sub_id=\$clash_sub_id last; }
proxy_redirect off;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
@@ -412,11 +412,17 @@ limit_req_zone \$binary_remote_addr zone=diag_api:10m rate=6r/m;
limit_req_zone \$binary_remote_addr zone=diag_page:10m rate=30r/m;
limit_conn_zone \$binary_remote_addr zone=per_ip:10m;
# Detect Clash/Mihomo subscription clients by User-Agent
map \$http_user_agent \$is_clash_client {
# Detect Clash/Mihomo clients by User-Agent
map \$http_user_agent \$is_clash_ua {
~*(clash|clashx|clashn|mihomo|stash|surfboard) 1;
default 0;
}
# Serve clash.yaml only when: Clash UA AND no X-Proxy-Provider header
# (proxy-provider refresh requests carry X-Proxy-Provider: true and must get the real sub)
map "\$is_clash_ua:\$http_x_proxy_provider" \$serve_clash_yaml {
"1:" 1;
default 0;
}
server {
server_tokens off;