This repository has been archived on 2024-09-06. You can view files and clone it, but cannot push or open issues or pull requests.
2022-04-21 04:51:01 +08:00
2022-04-21 04:51:01 +08:00
2022-04-21 03:54:34 +08:00
2022-04-19 17:46:13 +08:00
2022-04-21 04:51:01 +08:00
2022-04-20 01:52:51 +08:00
2018-06-23 00:44:28 +08:00
2022-03-16 22:00:20 +08:00
2022-04-10 03:59:27 +08:00
2022-04-20 01:59:57 +08:00
2022-04-20 01:59:57 +08:00
2022-04-20 01:59:57 +08:00
2019-10-18 11:12:35 +08:00

Clash
Clash

A rule-based tunnel in Go.

Github Actions

Features

  • Local HTTP/HTTPS/SOCKS server with authentication support
  • VMess, Shadowsocks, Trojan, Snell protocol support for remote connections
  • Built-in DNS server that aims to minimize DNS pollution attack impact, supports DoH/DoT upstream and fake IP.
  • Rules based off domains, GEOIP, IPCIDR or Process to forward packets to different nodes
  • Remote groups allow users to implement powerful rules. Supports automatic fallback, load balancing or auto select node based off latency
  • Remote providers, allowing users to get node lists remotely instead of hardcoding in config
  • Netfilter TCP redirecting. Deploy Clash on your Internet gateway with iptables.
  • Comprehensive HTTP RESTful API controller

Getting Started

Documentations are now moved to GitHub Wiki.

Advanced usage for this branch

MITM configuration

A root CA certificate is required, the MITM proxy server will generate a CA certificate file and a CA private key file in your Clash home directory, you can use your own certificate replace it.

Need to install and trust the CA certificate on the client device, open this URL http://mitm.clash/cert.crt by the web browser to install the CA certificate, the host name 'mitm.clash' was always been hijacked.

NOTE: this feature cannot work on tls pinning

WARNING: DO NOT USE THIS FEATURE TO BREAK LOCAL LAWS

# Port of MITM proxy server on the local end
mitm-port: 7894

# Man-In-The-Middle attack
mitm:
  hosts: # use for others proxy type. E.g: TUN, socks
    - +.example.com
  rules: # rewrite rules
    - '^https?://www\.example\.com/1 url reject' # The "reject" returns HTTP status code 404 with no content.
    - '^https?://www\.example\.com/2 url reject-200' # The "reject-200" returns HTTP status code 200 with no content.
    - '^https?://www\.example\.com/3 url reject-img' # The "reject-img" returns HTTP status code 200 with content of 1px png.
    - '^https?://www\.example\.com/4 url reject-dict' # The "reject-dict" returns HTTP status code 200 with content of empty json object.
    - '^https?://www\.example\.com/5 url reject-array' # The "reject-array" returns HTTP status code 200 with content of empty json array.
    - '^https?://www\.example\.com/(6) url 302 https://www.example.com/new-$1'
    - '^https?://www\.(example)\.com/7 url 307 https://www.$1.com/new-7'
    - '^https?://www\.example\.com/8 url request-header (\r\n)User-Agent:.+(\r\n) request-header $1User-Agent: haha-wriohoh$2' # The "request-header" works for all the http headers not just one single header, so you can match two or more headers including CRLF in one regular expression.
    - '^https?://www\.example\.com/9 url request-body "pos_2":\[.*\],"pos_3" request-body "pos_2":[{"xx": "xx"}],"pos_3"'
    - '^https?://www\.example\.com/10 url response-header (\r\n)Tracecode:.+(\r\n) response-header $1Tracecode: 88888888888$2'
    - '^https?://www\.example\.com/11 url response-body "errmsg":"ok" response-body "errmsg":"not-ok"'

DNS configuration

Support resolve ip with a proxy tunnel.

Support geosite with fallback-filter.

Use curl -X POST controllerip:port/cache/fakeip/flush to flush persistence fakeip

dns:
  enable: true
  use-hosts: true
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  listen: 127.0.0.1:6868
  default-nameserver:
    - 119.29.29.29
    - 114.114.114.114
  nameserver:
    - https://doh.pub/dns-query
    - tls://223.5.5.5:853
  fallback:
    - 'https://1.0.0.1/dns-query#Proxy'  # append the proxy adapter name to the end of DNS URL with '#' prefix.
    - 'tls://8.8.4.4:853#Proxy'
  fallback-filter:
    geoip: false
    geosite:
      - gfw  # `geosite` filter only use fallback server to resolve ip, prevent DNS leaks to untrusted DNS providers.
    domain:
      - +.example.com
    ipcidr:
      - 0.0.0.0/32

TUN configuration

Supports macOS, Linux and Windows.

On Windows, you should download the Wintun driver and copy wintun.dll into the system32 directory.

# Enable the TUN listener
tun:
  enable: true
  stack: gvisor # System or gVisor
  # device: tun://utun8 # or fd://xxx, it's optional
  dns-hijack: 
    - 0.0.0.0:53 # hijack all public
  auto-route: true # auto set global route

Rules configuration

  • Support rule GEOSITE.
  • Support rule USER-AGENT.
  • Support multiport condition for rule SRC-PORT and DST-PORT.
  • Support network condition for all rules.
  • Support process condition for all rules.
  • Support source IPCIDR condition for all rules, just append to the end.

The GEOIP databases via https://github.com/Loyalsoldier/geoip.

The GEOSITE databases via https://github.com/Loyalsoldier/v2ray-rules-dat.

mode: rule

script:
  shortcuts:
    quic: 'network == "udp" and dst_port == 443'
    privacy: '"analytics" in host or "adservice" in host or "firebase" in host or "safebrowsing" in host or "doubleclick" in host'

rules:
  # rule SCRIPT
  - SCRIPT,quic,REJECT # Disable QUIC, same as rule "DST-PORT,443,REJECT,udp"
  - SCRIPT,privacy,REJECT
    
  # network condition for all rules
  - DOMAIN-SUFFIX,example.com,DIRECT,tcp
  - DOMAIN-SUFFIX,example.com,REJECT,udp

  # process condition for all rules (add 'P:' prefix)
  - DOMAIN-SUFFIX,example.com,REJECT,P:Google Chrome Helper

  # multiport condition for rules SRC-PORT and DST-PORT
  - DST-PORT,123/136/137-139,DIRECT,udp

  # USER-AGENT payload cannot include the comma character, '*' meaning any character.
  - USER-AGENT,*example*,PROXY

  # rule GEOSITE
  - GEOSITE,category-ads-all,REJECT
  - GEOSITE,icloud@cn,DIRECT
  - GEOSITE,apple@cn,DIRECT
  - GEOSITE,apple-cn,DIRECT
  - GEOSITE,microsoft@cn,DIRECT
  - GEOSITE,facebook,PROXY
  - GEOSITE,youtube,PROXY
  - GEOSITE,geolocation-cn,DIRECT
  - GEOSITE,geolocation-!cn,PROXY

  # source IPCIDR condition for all rules in gateway proxy
  #- GEOSITE,geolocation-!cn,REJECT,192.168.1.88/32,192.168.1.99/32
  
  - GEOIP,telegram,PROXY,no-resolve
  - GEOIP,lan,DIRECT,no-resolve
  - GEOIP,cn,DIRECT

  - MATCH,PROXY

Script configuration

Script enables users to programmatically select a policy for the packets with more flexibility.

mode: script

rules:
  # the rule GEOSITE just as a rule provider in mode script
  - GEOSITE,category-ads-all,Whatever
  - GEOSITE,youtube,Whatever
  - GEOSITE,geolocation-cn,Whatever
  
script:
  code: |
    def main(ctx, metadata):
      if metadata["process_name"] == 'apsd':
        return "DIRECT"

      if metadata["network"] == 'udp' and metadata["dst_port"] == 443:
        return "REJECT"
    
      host = metadata["host"]
      for kw in ['analytics', 'adservice', 'firebase', 'bugly', 'safebrowsing', 'doubleclick']:
        if kw in host:
          return "REJECT"
    
      now = time.now()
      if (now.hour < 8 or now.hour > 17) and metadata["src_ip"] == '192.168.1.99':
        return "REJECT"
      
      if ctx.rule_providers["geosite:category-ads-all"].match(metadata):
        return "REJECT"
    
      if ctx.rule_providers["geosite:youtube"].match(metadata):
        ctx.log('[Script] domain %s matched youtube' % host)
        return "Proxy"

      if ctx.rule_providers["geosite:geolocation-cn"].match(metadata):
        ctx.log('[Script] domain %s matched geolocation-cn' % host)
        return "DIRECT"
    
      ip = metadata["dst_ip"] 
      if host != "":
        ip = ctx.resolve_ip(host)
        if ip == "":
          return "Proxy"

      code = ctx.geoip(ip)
      if code == "LAN" or code == "CN":
        return "DIRECT"

      return "Proxy" # default policy for requests which are not matched by any other script

the context and metadata

interface Metadata {
  type: string // socks5、http
  network: string // tcp
  host: string
  process_name: string
  src_ip: string
  src_port: int
  dst_ip: string
  dst_port: int
}

interface Context {
  resolve_ip: (host: string) => string // ip string
  geoip: (ip: string) => string // country code
  log: (log: string) => void
  rule_providers: Record<string, { match: (metadata: Metadata) => boolean }>
}

Proxies configuration

Support outbound protocol VLESS.

Support Trojan with XTLS.

Currently XTLS only supports TCP transport.

proxies:
  # VLESS
  - name: "vless-tls"
    type: vless
    server: server
    port: 443
    uuid: uuid
    network: tcp
    servername: example.com
    udp: true
    # skip-cert-verify: true
  - name: "vless-xtls"
    type: vless
    server: server
    port: 443
    uuid: uuid
    network: tcp
    servername: example.com
    flow: xtls-rprx-direct # or xtls-rprx-origin
    # flow-show: true # print the XTLS direction log
    # udp: true
    # skip-cert-verify: true

  # Trojan
  - name: "trojan-xtls"
    type: trojan
    server: server
    port: 443
    password: yourpsk
    network: tcp
    flow: xtls-rprx-direct # or xtls-rprx-origin
    # flow-show: true # print the XTLS direction log
    # udp: true
    # sni: example.com # aka server name
    # skip-cert-verify: true

IPTABLES configuration

Work on Linux OS who's supported iptables

# Enable the TPROXY listener
tproxy-port: 9898

iptables:
  enable: true # default is false
  inbound-interface: eth0 # detect the inbound interface, default is 'lo'

Run Clash as a daemon.

Create the systemd configuration file at /etc/systemd/system/clash.service:

[Unit]
Description=Clash daemon, A rule-based proxy in Go.
After=network.target

[Service]
Type=simple
CapabilityBoundingSet=cap_net_admin
Restart=always
ExecStart=/usr/local/bin/clash -d /etc/clash

[Install]
WantedBy=multi-user.target

Launch clashd on system startup with:

$ systemctl enable clash

Launch clashd immediately with:

$ systemctl start clash

Display Process name

Add field Process to Metadata and prepare to get process name for Restful API GET /connections.

To display process name in GUI please use https://yaling888.github.io/yacd/.

Development

If you want to build an application that uses clash as a library, check out the the GitHub Wiki

Credits

License

This software is released under the GPL-3.0 license.

FOSSA Status

Description
A rule-based tunnel in Go.
Readme 9.1 MiB
Languages
Go 89.3%
C 10.2%
Makefile 0.3%