OpenGFW/docs/Analyzers.md

6.5 KiB

Analyzers

Analyzers are one of the main components of OpenGFW. Their job is to analyze a connection, see if it's a protocol they support, and if so, extract information from that connection and provide properties for the rule engine to match against user-provided rules. OpenGFW will automatically analyze which analyzers are referenced in the given rules and enable only those that are needed.

This document lists the properties provided by each analyzer that can be used by rules.

DNS (TCP & UDP)

For queries:

{
  "dns": {
    "aa": false,
    "id": 41953,
    "opcode": 0,
    "qr": false,
    "questions": [
      {
        "class": 1,
        "name": "www.google.com",
        "type": 1
      }
    ],
    "ra": false,
    "rcode": 0,
    "rd": true,
    "tc": false,
    "z": 0
  }
}

For responses:

{
  "dns": {
    "aa": false,
    "answers": [
      {
        "a": "142.251.32.36",
        "class": 1,
        "name": "www.google.com",
        "ttl": 255,
        "type": 1
      }
    ],
    "id": 41953,
    "opcode": 0,
    "qr": true,
    "questions": [
      {
        "class": 1,
        "name": "www.google.com",
        "type": 1
      }
    ],
    "ra": true,
    "rcode": 0,
    "rd": true,
    "tc": false,
    "z": 0
  }
}

Example for blocking DNS queries for www.google.com:

- name: Block Google DNS
  action: drop
  expr: dns != nil && !dns.qr && any(dns.questions, {.name == "www.google.com"})

FET (Fully Encrypted Traffic)

Check https://www.usenix.org/system/files/usenixsecurity23-wu-mingshi.pdf for more information.

{
  "fet": {
    "ex1": 3.7560976,
    "ex2": true,
    "ex3": 0.9512195,
    "ex4": 39,
    "ex5": false,
    "yes": false
  }
}

Example for blocking fully encrypted traffic:

- name: Block suspicious proxy traffic
  action: block
  expr: fet != nil && fet.yes

HTTP

{
  "http": {
    "req": {
      "headers": {
        "accept": "*/*",
        "host": "ipinfo.io",
        "user-agent": "curl/7.81.0"
      },
      "method": "GET",
      "path": "/",
      "version": "HTTP/1.1"
    },
    "resp": {
      "headers": {
        "access-control-allow-origin": "*",
        "content-length": "333",
        "content-type": "application/json; charset=utf-8",
        "date": "Wed, 24 Jan 2024 05:41:44 GMT",
        "referrer-policy": "strict-origin-when-cross-origin",
        "server": "nginx/1.24.0",
        "strict-transport-security": "max-age=2592000; includeSubDomains",
        "via": "1.1 google",
        "x-content-type-options": "nosniff",
        "x-envoy-upstream-service-time": "2",
        "x-frame-options": "SAMEORIGIN",
        "x-xss-protection": "1; mode=block"
      },
      "status": 200,
      "version": "HTTP/1.1"
    }
  }
}

Example for blocking HTTP requests to ipinfo.io:

- name: Block ipinfo.io HTTP
  action: block
  expr: http != nil && http.req != nil && http.req.headers != nil && http.req.headers.host == "ipinfo.io"

SSH

{
  "ssh": {
    "server": {
      "comments": "Ubuntu-3ubuntu0.6",
      "protocol": "2.0",
      "software": "OpenSSH_8.9p1"
    },
    "client": {
      "comments": "IMHACKER",
      "protocol": "2.0",
      "software": "OpenSSH_8.9p1"
    }
  }
}

Example for blocking all SSH connections:

- name: Block SSH
  action: block
  expr: ssh != nil

TLS

{
  "tls": {
    "req": {
      "alpn": [
        "h2",
        "http/1.1"
      ],
      "ciphers": [
        4866,
        4867,
        4865,
        49196,
        49200,
        159,
        52393,
        52392,
        52394,
        49195,
        49199,
        158,
        49188,
        49192,
        107,
        49187,
        49191,
        103,
        49162,
        49172,
        57,
        49161,
        49171,
        51,
        157,
        156,
        61,
        60,
        53,
        47,
        255
      ],
      "compression": "AA==",
      "random": "UqfPi+EmtMgusILrKcELvVWwpOdPSM/My09nPXl84dg=",
      "session": "jCTrpAzHpwrfuYdYx4FEjZwbcQxCuZ52HGIoOcbw1vA=",
      "sni": "ipinfo.io",
      "supported_versions": [
        772,
        771
      ],
      "version": 771,
      "ech": true
    },
    "resp": {
      "cipher": 4866,
      "compression": 0,
      "random": "R/Cy1m9pktuBMZQIHahD8Y83UWPRf8j8luwNQep9yJI=",
      "session": "jCTrpAzHpwrfuYdYx4FEjZwbcQxCuZ52HGIoOcbw1vA=",
      "supported_versions": 772,
      "version": 771
    }
  }
}

Example for blocking TLS connections to ipinfo.io:

- name: Block ipinfo.io TLS
  action: block
  expr: tls != nil && tls.req != nil && tls.req.sni == "ipinfo.io"

Trojan (proxy protocol)

Check https://github.com/XTLS/Trojan-killer for more information.

{
  "trojan": {
    "down": 4712,
    "up": 671,
    "yes": true
  }
}

Example for blocking Trojan connections:

- name: Block Trojan
  action: block
  expr: trojan != nil && trojan.yes

Socks5

Socks5 that don't need auth:

{
  "socks5": {
    "req": {
      "cmd": 1,         // 0x01: connect, 0x02: bind, 0x03: udp
      "addr_type": 3,   // 0x01: ipv4, 0x03: domain, 0x04: ipv6
      "addr": "google.com",
      "port": 80,
      "auth": {
        "method": 0     // 0x00: no auth, 0x02: username/password
      }
    },
    "resp": {
      "rep": 0,         // 0x00: success
      "addr_type": 1,   // 0x01: ipv4, 0x03: domain, 0x04: ipv6
      "addr": "198.18.1.31",
      "port": 80,
      "auth": {
        "method": 0     // 0x00: no auth, 0x02: username/password
      }
    }
  }
}

Socks5 that need auth:

{
  "socks5": {
    "req": {
      "cmd": 1,         // 0x01: connect, 0x02: bind, 0x03: udp
      "addr_type": 3,   // 0x01: ipv4, 0x03: domain, 0x04: ipv6
      "addr": "google.com",
      "port": 80,
      "auth": {
        "method": 2,    // 0x00: no auth, 0x02: username/password
        "username": "user",
        "password": "pass"
      }
    },
    "resp": {
      "rep": 0,         // 0x00: success
      "addr_type": 1,   // 0x01: ipv4, 0x03: domain, 0x04: ipv6
      "addr": "198.18.1.31",
      "port": 80,
      "auth": {
        "method": 2,    // 0x00: no auth, 0x02: username/password
        "status": 0     // 0x00: success, 0x01: failure
      }
    }
  }
}

Example for blocking Socks5 connections:

# Block connection to google.com:80
- name: Block Google
  action: block
  expr: string(socks5?.req?.addr) endsWith "google.com" && socks5?.req?.port == 80

# Block specified user
- name: Block user foobar
  action: block
  expr: socks5?.req?.auth?.method == 2 && socks5?.req?.auth?.username == "foobar"