# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2025-2026 honeok <i@honeok.com>
# Copyright (c) 2025 zzwsec <zzwsec@163.com>

# References:
# https://github.com/MetaCubeX/mihomo/blob/Meta/docs/config.yaml
# https://github.com/Kook-9527/Plugin-backup/blob/main/ClashMeta.yaml
# https://github.com/qichiyuhub/rule/blob/main/config/mihomo/config.yaml
# https://github.com/yyhhyyyyyy/selfproxy/blob/main/Mihomo/mihomo_single.yaml
# https://www.nodeseek.com/post-290031-1
# https://gist.github.com/zhengxiongzhao/097ce20efee1ba0efe3796a1e10e5150
# https://github.com/HenryChiao/mihomo_yamls

## 全局配置
# port: 7890 # HTTP(S)代理服务器端口
# socks-port: 7891 # SOCKS5代理端口
mixed-port: 7890 # HTTP(S)和SOCKS代理混合端口
# redir-port: 7892 # 透明代理端口, 用于Linux和MacOS

# Transparent proxy server port for Linux (TProxy TCP and TProxy UDP)
# tproxy-port: 7893 # Linux透明代理服务器端口

allow-lan: true # 允许局域网连接
bind-address: "*" # 绑定IP地址, 仅作用于allow-lan为true, '*'表示所有地址
skip-auth-prefixes: # 设置跳过验证的IP段
  - 127.0.0.1/8
  - ::1/128

#  find-process-mode has 3 values: always strict off
#  - always: 开启, 强制匹配所有进程
#  - strict: 默认, 由mihomo判断是否开启
#  - off: 不匹配进程, 推荐在路由器上使用此模式
find-process-mode: strict

mode: rule

# 自定义 geodata url
geox-url:
  geoip: "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@mihomo-geodata/geoip-all.dat"
  geosite: "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@mihomo-geodata/geosite-all.dat"
  mmdb: "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@mihomo-geodata/Country-all.mmdb"
  asn: "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@mihomo-geodata/Country-ASN-all.mmdb"

# https://keunlas.net/posts/a2809040
# geodata-mode: true # 默认: false 使用 mmdb 数据库
geo-auto-update: true # 是否自动更新geodata
geo-update-interval: 24 # 更新间隔 单位: 小时

log-level: warning # 日志等级silent/error/warning/info/debug

ipv6: false # IPv6总开关, 关闭阻断所有IPv6链接和屏蔽DNS请求AAAA记录

unified-delay: true # 统一延迟时会计算RTT以消除连接握手等带来的不同类型节点的延迟差异

tcp-concurrent: true # TCP并发连接所有IP, 将使用最快握手的TCP

# interface-name: en0 # 设置出口网卡

# 全局TLS指纹, 优先低于proxy内的client-fingerprint
# 可选： "chrome" "firefox" "safari" "ios" "random" "none" options.
# Utls is currently support TLS transport in TCP/grpc/WS/HTTP for VLESS/Vmess and trojan.
global-client-fingerprint: firefox

# TCP保持活动间隔
disable-keep-alive: false # 目前在android端强制为true
keep-alive-idle: 600 # 设置TCP连接的空闲超时时间为600秒

# 缓解移动设备耗电问题
# https://github.com/vernesong/OpenClash/issues/2614
keep-alive-interval: 1800 # 设置TCP保活探测的间隔时间

profile:
  store-selected: true # 存储select选择记录
  store-fake-ip: true # 持久化fake-ip

ntp:
  enable: false
  write-to-system: true
  server: time.apple.com
  port: 123
  interval: 30

## Tun配置
tun:
  enable: false
  stack: mixed # system/gvisor/mixed
  dns-hijack: # 需要劫持的DNS
    - "any:53"
    - "tcp://any:53"
  auto-route: true # 配置路由表
  auto-detect-interface: true # 自动识别出口网卡

## DNS模块
dns:
  cache-algorithm: arc
  enable: true # 关闭将使用系统DNS
  listen: :53 # 开启DNS服务器监听
  # ipv6: false # false将返回AAAA的空结果
  # ipv6-timeout: 300 # 单位：ms 内部双栈并发时, 向上游查询AAAA时, 等待AAAA的时间, 默认100ms
  default-nameserver: # 指定初始DNS解析服务器, 用于解析mihomo自身需要的域名 (如订阅地址、规则集地址) 只能使用纯IP地址
    - tls://1.12.12.12:853
    - tls://223.5.5.5:853
  enhanced-mode: fake-ip # 启用Fake-IP模式 or redir-host

  fake-ip-range: 198.18.0.1/16 # fake-ip池设置
  # fake-ip-range6: fdfe:dcba:9876::1/64 # fake-ip6池设置

  # 配置不使用fake-ip的域名
  fake-ip-filter:
    - rule-set:fakeipfilter_domain
  fake-ip-filter-mode: blacklist # 配置fake-ip-filter的匹配模式, 默认为blacklist, 即如果匹配成功不返回fake-ip

  # use-hosts: true # 查询hosts

  # 配置后面的nameserver fallback和nameserver-policy向dns服务器的连接过程是否遵守遵守rules规则
  # 如果为false(默认值) 则这三部分的dns服务器在未特别指定的情况下会直连
  # 如果为true, 将会按照rules的规则匹配链接方式 (走代理或直连), 如果有特别指定则任然以指定值为准
  # 仅当proxy-server-nameserver非空时可以开启此选项, 强烈不建议和prefer-h3一起使用
  # 此外, 这三者配置中的dns服务器如果出现域名会采用default-nameserver配置项解析, 也请确保正确配置default-nameserver
  respect-rules: true

  # DNS主要域名配置
  # 支持UDP TCP DoT DoH DoQ
  # 这部分为主要DNS配置, 影响所有直连, 确保使用对大陆解析精准的DNS
  nameserver:
    - https://one.one.one.one/dns-query
    - https://dns.google/dns-query

  # 专用于节点域名解析的DNS服务器, 非必要配置项, 如果不填则遵循nameserver-policy nameserver和fallback的配置
  proxy-server-nameserver:
    - https://doh.pub/dns-query
    - https://dns.alidns.com/dns-query

  # 配置查询域名使用的DNS服务器
  nameserver-policy:
    "rule-set:cn_domain,private_domain":
      - https://doh.pub/dns-query
      - https://dns.alidns.com/dns-query

## 节点信息
proxies:
  # 链式代理流量走向机制 丨 Mihomo本机 <-> 前置节点 <-> 落地节点 <-> Internet互联网
  - name: "🇸🇬 狮城链式"
    dialer-proxy: "🇸🇬 狮城自动"
    type: socks5
    server: "1.1.1.1"
    port: 1080
    username: "socks"
    password: "socks"

  # Shadowsocks
  # cipher支持:
  # aes-128-gcm aes-192-gcm aes-256-gcm
  # aes-128-cfb aes-192-cfb aes-256-cfb
  # aes-128-ctr aes-192-ctr aes-256-ctr
  # rc4-md5 chacha20-ietf xchacha20
  # chacha20-ietf-poly1305 xchacha20-ietf-poly1305
  # 2022-blake3-aes-128-gcm 2022-blake3-aes-256-gcm 2022-blake3-chacha20-poly1305
  - name: "🇭🇰 香港链式"
    dialer-proxy: "🇭🇰 香港自动"
    type: ss
    server: "1.0.0.1"
    port: 8388
    cipher: "aes-128-gcm"
    password: "shadowsocks"

## 机场通用配置模板
airport_conf: &airport_conf
  type: http
  interval: 3600 # 自动更新时间(秒)
  proxy: DIRECT # 通过直连拉取机场订阅, 该名字是指策略组或某个代理节点的名字
  lazy: true # 懒加载
  health-check: # 节点自动检测延时
    enable: true
    interval: 300
    url: "http://www.gstatic.com/generate_204"
    expected-status: 204 # 当健康检查返回状态码与期望值不符时认为节点不可用

# 策略组引用列表
Airports: &airports
  use:
    - Airport1
    - Airport2

# 机场订阅合集
proxy-providers:
  Airport1:
    <<: *airport_conf
    url: "url1"
  Airport2:
    <<: *airport_conf
    url: "url2"

## 代理分组锚点
main: &main { type: select, include-all: true, proxies: [🚀 默认代理, ♻️ 自动选择, 🇭🇰 香港自动, 🇹🇼 台湾自动, 🇸🇬 狮城自动, 🇯🇵 日本自动, 🇺🇸 美国自动, 🇳🇱 荷兰自动, 🇩🇪 德国自动, DIRECT] }
proxy: &proxy { type: select, include-all: true, proxies: [🚀 默认代理, ♻️ 自动选择, 🇭🇰 香港自动, 🇹🇼 台湾自动, 🇸🇬 狮城自动, 🇯🇵 日本自动, 🇺🇸 美国自动, 🇳🇱 荷兰自动, 🇩🇪 德国自动] }
specific: &specific { type: select, include-all: true, proxies: [🚀 默认代理, ♻️ 自动选择, 🇹🇼 台湾自动, 🇸🇬 狮城自动, 🇯🇵 日本自动, 🇺🇸 美国自动, 🇳🇱 荷兰自动, 🇩🇪 德国自动], <<: *airports, filter: "^((?!(?i)(🇭🇰|香港|hk|hong\\s?kong|🇲🇴|澳门|澳門|macau|macao|🇷🇺|俄罗斯|ru|russia|🇨🇳|中国|回国|china|cn)).)*$" }
island: &island { type: select, proxies: [DIRECT], <<: *airports, filter: "(?i)(🇭🇰|香港|hk|hong\\s?kong|🇲🇴|澳门|澳門|macau|macao|🇹🇼|台湾|tw|taiwan)" }

## 代理分组
proxy-groups:
  #------------------------基础分组------------------------#
  - { name: 🚀 默认代理, type: select, include-all: true, proxies: [♻️ 自动选择, 🇭🇰 香港自动, 🇹🇼 台湾自动, 🇸🇬 狮城自动, 🇯🇵 日本自动, 🇺🇸 美国自动, 🇳🇱 荷兰自动, 🇩🇪 德国自动] }
  - { name: ♻️ 自动选择, type: url-test, include-all: true, tolerance: 100, interval: 300 }

  #------------------------场景分组------------------------#
  - { name: 🤖 AI, <<: *specific }
  - { name: 🍀 Google, <<: *proxy }
  - { name: 👨‍💻 GitHub, <<: *proxy }
  - { name: 🦊 GitLab, <<: *proxy }
  - { name: 🐳 Docker, <<: *proxy }
  - { name: 🪟 Microsoft, <<: *main }
  - { name: 🐬 OneDrive, <<: *main }
  - { name: 📲 Telegram, <<: *proxy }
  - { name: 🐦 Twitter, <<: *proxy }
  - { name: 📺 BiliBili, <<: *island }
  - { name: 🎥 NETFLIX, <<: *specific }
  - { name: 🎧 Spotify, <<: *island }
  - { name: 🎵 TikTok, <<: *specific }
  - { name: 💶 PayPal, <<: *main }
  - { name: ✈️ Speedtest, <<: *main }
  - { name: 🍎 Apple, <<: *main }

  #------------------------地区分组------------------------#
  - { name: 🇭🇰 香港自动, type: url-test, <<: *airports, include-all: true, tolerance: 100, interval: 300, filter: "(?i)(🇭🇰|香港|hk|hong\\s?kong)" }
  - { name: 🇹🇼 台湾自动, type: url-test, <<: *airports, include-all: true, tolerance: 100, interval: 300, filter: "(?i)(🇹🇼|台湾|tw|taiwan)" }
  - { name: 🇸🇬 狮城自动, type: url-test, <<: *airports, include-all: true, tolerance: 100, interval: 300, filter: "(?i)(🇸🇬|新加坡|sg|singapore|lion\\s?city)" }
  - { name: 🇯🇵 日本自动, type: url-test, <<: *airports, include-all: true, tolerance: 100, interval: 300, filter: "(?i)(🇯🇵|日本|jp|japan|tokyo|osaka)" }
  - { name: 🇺🇸 美国自动, type: url-test, <<: *airports, include-all: true, tolerance: 100, interval: 300, filter: "(?i)(🇺🇸|美国|us|united\\s?states|america)" }
  - { name: 🇳🇱 荷兰自动, type: url-test, <<: *airports, include-all: true, tolerance: 100, interval: 300, filter: "(?i)(🇳🇱|荷兰|nl|netherlands|amsterdam)" }
  - { name: 🇩🇪 德国自动, type: url-test, <<: *airports, include-all: true, tolerance: 100, interval: 300, filter: "(?i)(🇩🇪|德国|de|germany|frankfurt)" }

  #------------------------特殊分组------------------------#
  - { name: 🎯 全球直连, type: select, proxies: [DIRECT, 🚀 默认代理] }
  - { name: 🎣 漏网之鱼, <<: *main }

## 规则匹配
rules:
  # 本地局域网
  - RULE-SET,private_ip,DIRECT,no-resolve
  - RULE-SET,private_domain,DIRECT

  # 广告拦截
  # - RULE-SET,antiAd_domain,REJECT
  - RULE-SET,awaAd_domain,REJECT

  - RULE-SET,meituan_list,DIRECT

  # 应用分流
  - RULE-SET,apple_domain,🍎 Apple
  - RULE-SET,applecn_domain,🍎 Apple
  - RULE-SET,google_domain,🍀 Google
  - RULE-SET,googlecn_domain,🍀 Google
  - RULE-SET,ai_domain,🤖 AI
  - RULE-SET,github_domain,👨‍💻 GitHub
  - RULE-SET,gitlab_domain,🦊 GitLab
  - RULE-SET,docker_domain, 🐳 Docker
  - RULE-SET,microsoft_domain,🪟 Microsoft
  - RULE-SET,onedrive_domain,🐬 OneDrive
  - RULE-SET,telegram_domain,📲 Telegram
  - RULE-SET,twitter_domain,🐦 Twitter
  - RULE-SET,bilibili_domain,📺 BiliBili
  - RULE-SET,netflix_domain,🎥 NETFLIX
  - RULE-SET,spotify_domain,🎧 Spotify
  - RULE-SET,tiktok_domain,🎵 TikTok
  - RULE-SET,paypal_domain,💶 PayPal
  - RULE-SET,speedtest_domain,✈️ Speedtest

  - RULE-SET,geolocation-!cn,🚀 默认代理
  - RULE-SET,cn_domain,🎯 全球直连

  - RULE-SET,apple_ip,🍎 Apple,no-resolve
  - RULE-SET,google_ip,🍀 Google,no-resolve
  - RULE-SET,netflix_ip,🎥 NETFLIX,no-resolve
  - RULE-SET,telegram_ip,📲 Telegram,no-resolve
  - RULE-SET,twitter_ip,🐦 Twitter,no-resolve
  - RULE-SET,cn_ip,🎯 全球直连

  # 兜底规则
  - MATCH,🎣 漏网之鱼

## 规则集
# https://github.com/MetaCubeX/meta-rules-dat
rule-anchor:
  class: &class { type: http, interval: 86400, behavior: classical, format: text }
  domain: &domain { type: http, interval: 86400, behavior: domain, format: mrs }
  ip: &ip { type: http, interval: 86400, behavior: ipcidr, format: mrs }

## 规则
rule-providers:
  meituan_list: { <<: *class, url: "https://fastly.jsdelivr.net/gh/blackmatrix7/ios_rule_script@master/rule/Shadowrocket/MeiTuan/MeiTuan.list" }

  ai_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/category-ai-!cn.mrs" }
  # antiAd_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/privacy-protection-tools/anti-ad.github.io@master/docs/mihomo.mrs" }
  awaAd_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/TG-Twilight/AWAvenue-Ads-Rule@main/Filters/AWAvenue-Ads-Rule-Clash.mrs" }
  apple_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/apple.mrs" }
  applecn_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/apple-cn.mrs" }
  bilibili_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/bilibili.mrs" }
  cn_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/DustinWin/ruleset_geodata@mihomo-ruleset/cn.mrs" }
  docker_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/docker.mrs" }
  fakeipfilter_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/wwqgtxx/clash-rules@release/fakeip-filter.mrs" }
  geolocation-!cn: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/geolocation-!cn.mrs" }
  github_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/github.mrs" }
  gitlab_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/gitlab.mrs" }
  google_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/google.mrs" }
  googlecn_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/google-cn.mrs" }
  microsoft_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/microsoft.mrs" }
  netflix_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/netflix.mrs" }
  onedrive_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/onedrive.mrs" }
  paypal_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/paypal.mrs" }
  private_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/private.mrs" }
  speedtest_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/speedtest.mrs" }
  spotify_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/spotify.mrs" }
  telegram_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/telegram.mrs" }
  tiktok_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/tiktok.mrs" }
  twitter_domain: { <<: *domain, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geosite/twitter.mrs" }

  apple_ip: { <<: *ip, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo-lite/geoip/apple.mrs" }
  cn_ip: { <<: *ip, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geoip/cn.mrs" }
  google_ip: { <<: *ip, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geoip/google.mrs" }
  netflix_ip: { <<: *ip, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geoip/netflix.mrs" }
  private_ip: { <<: *ip, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geoip/private.mrs" }
  telegram_ip: { <<: *ip, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geoip/telegram.mrs" }
  twitter_ip: { <<: *ip, url: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@meta/geo/geoip/twitter.mrs" }
