基于 Clash 的 EAF 规则代理解决方案
Emacs
EAF
2021-12-17 4033字

EAF 浏览器是基于 QWebEngine 来实现的, QWebEngine 因为受限于底层 Chromium 代码的实现, QWebEngine 无法像 QWebKit 那样, 通过 Qt 代码来实现基于自定义规则的代理路由。

如果修改 Qt5 的源码则非常麻烦, 一个比较合理解决方案是 “通过引入第二个本地代理来变相实现规则代理”, 简单逻辑如下图:

EAF Browser ---> Transfer Proxy ---> Need Proxy ------> Local Proxy ---> Proxy Server ---> Target Website
                       |
                       ------------> No Need Proxy ---> Target Website

用 Clash 作为规则代理(Transfer Proxy), 充当 EAF 浏览器和本地代理客户端的中间代理, 如果一个域名匹配代理规则, Clash 就把流量定向到本地代理客户端, 再由本地代理客户端发送请求给代理服务器。 如果一个域名匹配直连规则, Clash 直接略过本地代理客户端直接访问目标网站。

安装 Clash

首先从 Clash 安装 Clash, Arch 直接用 pacman 安装即可。

配置 Clash

首先你需要在本地配置一个本地 socks5 代理, 可以参考我的另外一篇文章最佳代理实践

比如本地 socks5 代理是 127.0.0.1 的 1080 端口(如果不是, 请修改下面配置中 proxies 字段内容), 然后新建一个 config.yml 配置文件:

# config.yml
# 本地 http(s)代理端口
port: 18080
# 本地 socks5 代理端口
socks-port: 10808
# 是否允许局域网中其他机器访问
allow-lan: false
# 仅当 allow-lan 设置为 true 时生效
# '*': 绑定所有 IP
# 192.168.122.11:绑定单个 IPV4
# "[aaaa::a8aa:ff:fe09:57d8]":绑定单个 IPV6
bind-address: '*'
# 运行模式
# rule: 基于规则
# global: 全局代理
# direct: 不代理
mode: rule
# 日志输出级别
# info / warning / error / debug / silent
log-level: info
# 当设置为 false 时, 不解析 IPV6 地址
ipv6: false
# 流量出口
interface-name: wlp4s0

# DNS 设置
dns:
  enable: false
  listen: 0.0.0.0:53
  # ipv6: false # when the false, response to AAAA questions will be empty

  # These nameservers are used to resolve the DNS nameserver hostnames below.
  # Specify IP addresses only
  default-nameserver:
    - 114.114.114.114
    - 8.8.8.8
  enhanced-mode: redir-host # or fake-ip
  fake-ip-range: 198.18.0.1/16 # Fake IP addresses pool CIDR
  # use-hosts: true # lookup hosts and return IP record

  # Hostnames in this list will not be resolved with fake IPs
  # i.e. questions to these domain names will always be answered with their
  # real IP addresses
  # fake-ip-filter:
  #   - '*.lan'
  #   - localhost.ptlogin2.qq.com

  # Supports UDP, TCP, DoT, DoH. You can specify the port to connect to.
  # All DNS questions are sent directly to the nameserver, without proxies
  # involved. Clash answers the DNS question with the first result gathered.
  nameserver:
    - 114.114.114.114 # default value
    - 8.8.8.8 # default value
    - tls://dns.rubyfish.cn:853 # DNS over TLS
    - https://1.1.1.1/dns-query # DNS over HTTPS
    - dhcp://en0 # dns from dhcp

  # When `fallback` is present, the DNS server will send concurrent requests
  # to the servers in this section along with servers in `nameservers`.
  # The answers from fallback servers are used when the GEOIP country
  # is not `CN`.
  # fallback:
  #   - tcp://1.1.1.1

  # If IP addresses resolved with servers in `nameservers` are in the specified
  # subnets below, they are considered invalid and results from `fallback`
  # servers are used instead.
  #
  # IP address resolved with servers in `nameserver` is used when
  # `fallback-filter.geoip` is true and when GEOIP of the IP address is `CN`.
  #
  # If `fallback-filter.geoip` is false, results from `nameserver` nameservers
  # are always used if not match `fallback-filter.ipcidr`.
  #
  # This is a countermeasure against DNS pollution attacks.
  # fallback-filter:
  #   geoip: true
  #   geoip-code: CN
  #   ipcidr:
  #     - 240.0.0.0/4
  #   domain:
  #     - '+.google.com'
  #     - '+.facebook.com'
  #     - '+.youtube.com'

  # Lookup domains via specific nameservers
  # nameserver-policy:
  #   'www.baidu.com': '114.114.114.114'
  #   '+.internal.crop.com': '10.0.0.1'
proxies:
# 代理服务器配置, 更多的代理设置请查看: https://lancellc.gitbook.io/clash/clash-config-file/an-example-configuration-file
  - name: "local-socks5"
    type: socks5
    server: localhost
    port: 1080

proxy-groups:
  # 组策略
  # url-test 自动选择最快的节点进行访问.
  - name: "auto"   #策略名
    type: url-test
    proxies:
      - local-socks5
    # tolerance: 150
    url: 'http://www.gstatic.com/generate_204'
    interval: 300

rules:
# 规则策略
# 当一级域名是 google.com 时使用 auto 策略
  - DOMAIN-SUFFIX,google.com,auto
  - DOMAIN-SUFFIX,github.com,auto
  - DOMAIN-SUFFIX,github.io,auto
  - DOMAIN-SUFFIX,gitee.com,DIRECT
  - DOMAIN-SUFFIX,emacs-china.org,DIRECT
  - DOMAIN-SUFFIX,ruby-china.org,DIRECT
  - DOMAIN-SUFFIX,baidu.com,DIRECT
# 当域名含有关键词 google 时使用 auto
  - DOMAIN-KEYWORD,google,auto
  - DOMAIN,google.com,auto
# 当一级域名是 ad.com 时拒绝访问, 可以用于屏蔽广告
  - DOMAIN-SUFFIX,ad.com,REJECT
# 内网服务 ip 不走代理
  - SRC-IP-CIDR,192.168.1.0/32,DIRECT
  - SRC-IP-CIDR,10.0.0.0/8,DIRECT
# 可选参数 "no-resolve" , 基于 IP 的规则 (GEOIP, IP-CIDR, IP-CIDR6)
  - IP-CIDR,127.0.0.0/8,DIRECT
  - GEOIP,CN,DIRECT
# 目标端口是 8888 时, 直接访问不走代理
  - SRC-PORT,8888,DIRECT
# 默认规则
  - MATCH,auto

接着运行命令 clash -f config.yml 来启动 Clash, Clash 会对外暴露一个 http 类型的 18080 端口代理。

配置 EAF

最后在 Emacs 中通过如下配置来设置 EAF 使用 Clash 代理:

(setq eaf-proxy-type "http")
(setq eaf-proxy-host "127.0.0.1")
(setq eaf-proxy-port "18080")

最后

通过上面的配置, 可以让 EAF 浏览器实现基于规则的自动代理, 当然这种方法也适用于任何其他软件, 比如 Chrome 浏览器。

Clash 中转代理的方法, 可以让系统中多个软件共用同一套代理规则, 更新规则也很方便, 只需修改上面配置文件中的 rules 字段内容。

感谢 EmacsChina 社区的 EdmondFrank 的贡献, 使得 EAF 具备自动代理的能力, 感谢!