From 0735fa831df116d990fdfc3cd30bffbef3c6e2a7 Mon Sep 17 00:00:00 2001 From: Toby Date: Fri, 29 Mar 2024 13:06:29 -0700 Subject: [PATCH] docs: move to website --- .gitignore | 3 + README.ja.md | 126 +------------- README.md | 129 +------------- README.zh.md | 126 +------------- docs/Analyzers.md | 415 ---------------------------------------------- 5 files changed, 12 insertions(+), 787 deletions(-) delete mode 100644 docs/Analyzers.md diff --git a/.gitignore b/.gitignore index a26175e..2518397 100644 --- a/.gitignore +++ b/.gitignore @@ -205,3 +205,6 @@ $RECYCLE.BIN/ *.lnk # End of https://www.toptal.com/developers/gitignore/api/windows,macos,linux,go,goland+all,visualstudiocode + +# Internal tools not ready for public use yet +tools/flowseq/ diff --git a/README.ja.md b/README.ja.md index af55020..91e8afd 100644 --- a/README.ja.md +++ b/README.ja.md @@ -8,13 +8,12 @@ OpenGFW は、あなた専用の DIY 中国のグレートファイアウォール (https://en.wikipedia.org/wiki/Great_Firewall) です。Linux 上で利用可能な柔軟で使いやすいオープンソースプログラムとして提供されています。なぜ権力者だけが楽しむのでしょうか?権力を人々に与え、検閲を民主化する時が来ました。自宅のルーターにサイバー主権のスリルをもたらし、プロのようにフィルタリングを始めましょう - あなたもビッグブラザーになることができます。 +**ドキュメントウェブサイト: https://gfw.dev/** + Telegram グループ: https://t.me/OpGFW > [!CAUTION] -> このプロジェクトはまだ開発の初期段階です。使用は自己責任でお願いします。 - -> [!NOTE] -> 私たちはこのプロジェクト、特により多くのプロトコル用のアナライザーの実装を手伝ってくれるコントリビューターを探しています!!! +> 本プロジェクトはまだ初期開発段階にあります。テスト時のリスクは自己責任でお願いします。私たちは、このプロジェクトを一緒に改善するために貢献者を探しています。 ## 特徴 @@ -40,122 +39,3 @@ Telegram グループ: https://t.me/OpGFW - VPN/プロキシサービスの不正利用防止 - トラフィック分析(ログのみモード) - 独裁的な野心を実現するのを助ける - -## 使用方法 - -### ビルド - -```shell -go build -``` - -### 実行 - -```shell -export OPENGFW_LOG_LEVEL=debug -./OpenGFW -c config.yaml rules.yaml -``` - -#### OpenWrt - -OpenGFW は OpenWrt 23.05 で動作することがテストされています(他のバージョンも動作するはずですが、検証されていません)。 - -依存関係をインストールしてください: - -```shell -opkg install nftables kmod-nft-queue kmod-nf-conntrack-netlink -``` - -### 設定例 - -```yaml -io: - queueSize: 1024 - rcvBuf: 4194304 - sndBuf: 4194304 - local: true # FORWARD チェーンで OpenGFW を実行したい場合は false に設定する - rst: false # ブロックされたTCP接続に対してRSTを送信する場合はtrueに設定してください。local=falseのみです - -workers: - count: 4 - queueSize: 16 - tcpMaxBufferedPagesTotal: 4096 - tcpMaxBufferedPagesPerConn: 64 - udpMaxStreams: 4096 - -# 特定のローカルGeoIP / GeoSiteデータベースファイルを読み込むためのパス。 -# 設定されていない場合は、https://github.com/LoyalSoldier/v2ray-rules-dat から自動的にダウンロードされます。 -# geo: -# geoip: geoip.dat -# geosite: geosite.dat -``` - -### ルール例 - -[アナライザーのプロパティ](docs/Analyzers.md) - -式言語の構文については、[Expr 言語定義](https://expr-lang.org/docs/language-definition)を参照してください。 - -```yaml -# ルールは、"action" または "log" の少なくとも一方が設定されていなければなりません。 -- name: log horny people - log: true - expr: let sni = string(tls?.req?.sni); sni contains "porn" || sni contains "hentai" - -- name: block v2ex http - action: block - expr: string(http?.req?.headers?.host) endsWith "v2ex.com" - -- name: block v2ex https - action: block - expr: string(tls?.req?.sni) endsWith "v2ex.com" - -- name: block v2ex quic - action: block - expr: string(quic?.req?.sni) endsWith "v2ex.com" - -- name: block and log shadowsocks - action: block - log: true - expr: fet != nil && fet.yes - -- name: block trojan - action: block - expr: trojan != nil && trojan.yes - -- name: v2ex dns poisoning - action: modify - modifier: - name: dns - args: - a: "0.0.0.0" - aaaa: "::" - expr: dns != nil && dns.qr && any(dns.questions, {.name endsWith "v2ex.com"}) - -- name: block google socks - action: block - expr: string(socks?.req?.addr) endsWith "google.com" && socks?.req?.port == 80 - -- name: block wireguard by handshake response - action: drop - expr: wireguard?.handshake_response?.receiver_index_matched == true - -- name: block bilibili geosite - action: block - expr: geosite(string(tls?.req?.sni), "bilibili") - -- name: block CN geoip - action: block - expr: geoip(string(ip.dst), "cn") - -- name: block cidr - action: block - expr: cidr(string(ip.dst), "192.168.0.0/16") -``` - -#### サポートされるアクション - -- `allow`: 接続を許可し、それ以上の処理は行わない。 -- `block`: 接続をブロックし、それ以上の処理は行わない。 -- `drop`: UDP の場合、ルールのトリガーとなったパケットをドロップし、同じフローに含まれる以降のパケットの処理を継続する。TCP の場合は、`block` と同じ。 -- `modify`: UDP の場合、与えられた修飾子を使って、ルールをトリガしたパケットを修正し、同じフロー内の今後のパケットを処理し続ける。TCP の場合は、`allow` と同じ。 diff --git a/README.md b/README.md index 485348f..7cc3956 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,12 @@ OpenGFW is your very own DIY Great Firewall of China (https://en.wikipedia.org/wiki/Great_Firewall), available as a flexible, easy-to-use open source program on Linux. Why let the powers that be have all the fun? It's time to give power to the people and democratize censorship. Bring the thrill of cyber-sovereignty right into your home router and start filtering like a pro - you too can play Big Brother. +**Documentation site: https://gfw.dev/** + Telegram group: https://t.me/OpGFW > [!CAUTION] -> This project is still in very early stages of development. Use at your own risk. - -> [!NOTE] -> We are looking for contributors to help us with this project, especially implementing analyzers for more protocols!!! +> This project is still in very early stages of development. Use at your own risk. We are looking for contributors to help us improve and expand the project. ## Features @@ -44,125 +43,3 @@ Telegram group: https://t.me/OpGFW - Abuse prevention for VPN/proxy services - Traffic analysis (log only mode) - Help you fulfill your dictatorial ambitions - -## Usage - -### Build - -```shell -go build -``` - -### Run - -```shell -export OPENGFW_LOG_LEVEL=debug -./OpenGFW -c config.yaml rules.yaml -``` - -#### OpenWrt - -OpenGFW has been tested to work on OpenWrt 23.05 (other versions should also work, just not verified). - -Install the dependencies: - -```shell -opkg install nftables kmod-nft-queue kmod-nf-conntrack-netlink -``` - -### Example config - -```yaml -io: - queueSize: 1024 - rcvBuf: 4194304 - sndBuf: 4194304 - local: true # set to false if you want to run OpenGFW on FORWARD chain - rst: false # set to true if you want to send RST for blocked TCP connections, local=false only - -workers: - count: 4 - queueSize: 16 - tcpMaxBufferedPagesTotal: 4096 - tcpMaxBufferedPagesPerConn: 64 - udpMaxStreams: 4096 - -# The path to load specific local geoip/geosite db files. -# If not set, they will be automatically downloaded from https://github.com/Loyalsoldier/v2ray-rules-dat -# geo: -# geoip: geoip.dat -# geosite: geosite.dat -``` - -### Example rules - -[Analyzer properties](docs/Analyzers.md) - -For syntax of the expression language, please refer -to [Expr Language Definition](https://expr-lang.org/docs/language-definition). - -```yaml -# A rule must have at least one of "action" or "log" field set. -- name: log horny people - log: true - expr: let sni = string(tls?.req?.sni); sni contains "porn" || sni contains "hentai" - -- name: block v2ex http - action: block - expr: string(http?.req?.headers?.host) endsWith "v2ex.com" - -- name: block v2ex https - action: block - expr: string(tls?.req?.sni) endsWith "v2ex.com" - -- name: block v2ex quic - action: block - expr: string(quic?.req?.sni) endsWith "v2ex.com" - -- name: block and log shadowsocks - action: block - log: true - expr: fet != nil && fet.yes - -- name: block trojan - action: block - expr: trojan != nil && trojan.yes - -- name: v2ex dns poisoning - action: modify - modifier: - name: dns - args: - a: "0.0.0.0" - aaaa: "::" - expr: dns != nil && dns.qr && any(dns.questions, {.name endsWith "v2ex.com"}) - -- name: block google socks - action: block - expr: string(socks?.req?.addr) endsWith "google.com" && socks?.req?.port == 80 - -- name: block wireguard by handshake response - action: drop - expr: wireguard?.handshake_response?.receiver_index_matched == true - -- name: block bilibili geosite - action: block - expr: geosite(string(tls?.req?.sni), "bilibili") - -- name: block CN geoip - action: block - expr: geoip(string(ip.dst), "cn") - -- name: block cidr - action: block - expr: cidr(string(ip.dst), "192.168.0.0/16") -``` - -#### Supported actions - -- `allow`: Allow the connection, no further processing. -- `block`: Block the connection, no further processing. -- `drop`: For UDP, drop the packet that triggered the rule, continue processing future packets in the same flow. For - TCP, same as `block`. -- `modify`: For UDP, modify the packet that triggered the rule using the given modifier, continue processing future - packets in the same flow. For TCP, same as `allow`. diff --git a/README.zh.md b/README.zh.md index babdea3..ba9a791 100644 --- a/README.zh.md +++ b/README.zh.md @@ -8,13 +8,12 @@ OpenGFW 是一个 Linux 上灵活、易用、开源的 DIY [GFW](https://zh.wikipedia.org/wiki/%E9%98%B2%E7%81%AB%E9%95%BF%E5%9F%8E) 实现,并且在许多方面比真正的 GFW 更强大。为何让那些掌权者独享乐趣?是时候把权力归还给人民,人人有墙建了。立即安装可以部署在家用路由器上的网络主权 - 你也能是老大哥。 +**文档网站: https://gfw.dev/** + Telegram 群组: https://t.me/OpGFW > [!CAUTION] -> 本项目仍处于早期开发阶段。测试时自行承担风险。 - -> [!NOTE] -> 我们正在寻求贡献者一起完善本项目,尤其是实现更多协议的解析器! +> 本项目仍处于早期开发阶段。测试时自行承担风险。我们正在寻求贡献者一起完善本项目。 ## 功能 @@ -40,122 +39,3 @@ Telegram 群组: https://t.me/OpGFW - VPN/代理服务滥用防护 - 流量分析 (纯日志模式) - 助你实现你的独裁野心 - -## 使用 - -### 构建 - -```shell -go build -``` - -### 运行 - -```shell -export OPENGFW_LOG_LEVEL=debug -./OpenGFW -c config.yaml rules.yaml -``` - -#### OpenWrt - -OpenGFW 在 OpenWrt 23.05 上测试可用(其他版本应该也可以,暂时未经验证)。 - -安装依赖: - -```shell -opkg install nftables kmod-nft-queue kmod-nf-conntrack-netlink -``` - -### 样例配置 - -```yaml -io: - queueSize: 1024 - rcvBuf: 4194304 - sndBuf: 4194304 - local: true # 如果需要在 FORWARD 链上运行 OpenGFW,请设置为 false - rst: false # 是否对要阻断的 TCP 连接发送 RST。仅在 local=false 时有效 - -workers: - count: 4 - queueSize: 16 - tcpMaxBufferedPagesTotal: 4096 - tcpMaxBufferedPagesPerConn: 64 - udpMaxStreams: 4096 - -# 指定的 geoip/geosite 档案路径 -# 如果未设置,将自动从 https://github.com/Loyalsoldier/v2ray-rules-dat 下载 -# geo: -# geoip: geoip.dat -# geosite: geosite.dat -``` - -### 样例规则 - -[解析器属性](docs/Analyzers.md) - -规则的语法请参考 [Expr Language Definition](https://expr-lang.org/docs/language-definition)。 - -```yaml -# 每条规则必须至少包含 action 或 log 中的一个。 -- name: log horny people - log: true - expr: let sni = string(tls?.req?.sni); sni contains "porn" || sni contains "hentai" - -- name: block v2ex http - action: block - expr: string(http?.req?.headers?.host) endsWith "v2ex.com" - -- name: block v2ex https - action: block - expr: string(tls?.req?.sni) endsWith "v2ex.com" - -- name: block v2ex quic - action: block - expr: string(quic?.req?.sni) endsWith "v2ex.com" - -- name: block and log shadowsocks - action: block - log: true - expr: fet != nil && fet.yes - -- name: block trojan - action: block - expr: trojan != nil && trojan.yes - -- name: v2ex dns poisoning - action: modify - modifier: - name: dns - args: - a: "0.0.0.0" - aaaa: "::" - expr: dns != nil && dns.qr && any(dns.questions, {.name endsWith "v2ex.com"}) - -- name: block google socks - action: block - expr: string(socks?.req?.addr) endsWith "google.com" && socks?.req?.port == 80 - -- name: block wireguard by handshake response - action: drop - expr: wireguard?.handshake_response?.receiver_index_matched == true - -- name: block bilibili geosite - action: block - expr: geosite(string(tls?.req?.sni), "bilibili") - -- name: block CN geoip - action: block - expr: geoip(string(ip.dst), "cn") - -- name: block cidr - action: block - expr: cidr(string(ip.dst), "192.168.0.0/16") -``` - -#### 支持的 action - -- `allow`: 放行连接,不再处理后续的包。 -- `block`: 阻断连接,不再处理后续的包。 -- `drop`: 对于 UDP,丢弃触发规则的包,但继续处理同一流中的后续包。对于 TCP,效果同 `block`。 -- `modify`: 对于 UDP,用指定的修改器修改触发规则的包,然后继续处理同一流中的后续包。对于 TCP,效果同 `allow`。 diff --git a/docs/Analyzers.md b/docs/Analyzers.md deleted file mode 100644 index 7c57cdf..0000000 --- a/docs/Analyzers.md +++ /dev/null @@ -1,415 +0,0 @@ -# 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: - -```json -{ - "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: - -```json -{ - "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`: - -```yaml -- 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. - -```json -{ - "fet": { - "ex1": 3.7560976, - "ex2": true, - "ex3": 0.9512195, - "ex4": 39, - "ex5": false, - "yes": false - } -} -``` - -Example for blocking fully encrypted traffic: - -```yaml -- name: Block suspicious proxy traffic - action: block - expr: fet != nil && fet.yes -``` - -## HTTP - -```json -{ - "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`: - -```yaml -- name: Block ipinfo.io HTTP - action: block - expr: http != nil && http.req != nil && http.req.headers != nil && http.req.headers.host == "ipinfo.io" -``` - -## SSH - -```json -{ - "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: - -```yaml -- name: Block SSH - action: block - expr: ssh != nil -``` - -## TLS - -```json -{ - "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`: - -```yaml -- name: Block ipinfo.io TLS - action: block - expr: tls != nil && tls.req != nil && tls.req.sni == "ipinfo.io" -``` - -## QUIC - -QUIC analyzer produces the same result format as TLS analyzer, but currently only supports "req" direction (client -hello), not "resp" (server hello). - -```json -{ - "quic": { - "req": { - "alpn": ["h3"], - "ciphers": [4865, 4866, 4867], - "compression": "AA==", - "ech": true, - "random": "FUYLceFReLJl9dRQ0HAus7fi2ZGuKIAApF4keeUqg00=", - "session": "", - "sni": "quic.rocks", - "supported_versions": [772], - "version": 771 - } - } -} -``` - -Example for blocking QUIC connections to `quic.rocks`: - -```yaml -- name: Block quic.rocks QUIC - action: block - expr: quic != nil && quic.req != nil && quic.req.sni == "quic.rocks" -``` - -## Trojan (proxy protocol) - -```json -{ - "trojan": { - "seq": [680, 4514, 293], - "yes": true - } -} -``` - -Example for blocking Trojan connections: - -```yaml -- name: Block Trojan - action: block - expr: trojan != nil && trojan.yes -``` - -## SOCKS - -SOCKS4: - -```json -{ - "socks": { - "version": 4, - "req": { - "cmd": 1, - "addr_type": 1, // same as socks5 - "addr": "1.1.1.1", - // for socks4a - // "addr_type": 3, - // "addr": "google.com", - "port": 443, - "auth": { - "user_id": "user" - } - }, - "resp": { - "rep": 90, // 0x5A(90) granted - "addr_type": 1, - "addr": "1.1.1.1", - "port": 443 - } - } -} -``` - -SOCKS5 without auth: - -```json -{ - "socks": { - "version": 5, - "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 with auth: - -```json -{ - "socks": { - "version": 5, - "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 connections to `google.com:80` and user `foobar`: - -```yaml -- name: Block SOCKS google.com:80 - action: block - expr: string(socks?.req?.addr) endsWith "google.com" && socks?.req?.port == 80 - -- name: Block SOCKS user foobar - action: block - expr: socks?.req?.auth?.method == 2 && socks?.req?.auth?.username == "foobar" -``` - -## WireGuard - -```json -{ - "wireguard": { - "message_type": 1, // 0x1: handshake_initiation, 0x2: handshake_response, 0x3: packet_cookie_reply, 0x4: packet_data - "handshake_initiation": { - "sender_index": 0x12345678 - }, - "handshake_response": { - "sender_index": 0x12345678, - "receiver_index": 0x87654321, - "receiver_index_matched": true - }, - "packet_data": { - "receiver_index": 0x12345678, - "receiver_index_matched": true - }, - "packet_cookie_reply": { - "receiver_index": 0x12345678, - "receiver_index_matched": true - } - } -} -``` - -Example for blocking WireGuard traffic: - -```yaml -# false positive: high -- name: Block all WireGuard-like traffic - action: block - expr: wireguard != nil - -# false positive: medium -- name: Block WireGuard by handshake_initiation - action: drop - expr: wireguard?.handshake_initiation != nil - -# false positive: low -- name: Block WireGuard by handshake_response - action: drop - expr: wireguard?.handshake_response?.receiver_index_matched == true - -# false positive: pretty low -- name: Block WireGuard by packet_data - action: block - expr: wireguard?.packet_data?.receiver_index_matched == true -```