apernet / OpenGFW

OpenGFW is a flexible, easy-to-use, open source implementation of GFW (Great Firewall of China) on Linux
https://gfw.dev/
Mozilla Public License 2.0
9.32k stars 703 forks source link

feat: add openVPN analyzer #114

Closed KujouRinka closed 3 months ago

KujouRinka commented 4 months ago

添加了一个 OpenVPN 的 analyzer,我参考了下面一些东西:

据官方,OpenVPN 有 pre-shared secret 和 tls 两种模式,前者可以认为所有数据均为密文,难以分析指纹,但应该能够用 FETAnalyzer 识别出来,现在实现的 OpenVPN analyzer 用于识别 tls 模式

PropMap:

{
  "openvpn_tcp": {
    "rx_pkt_cnt": 0,
    "tx_pkt_cnt": 0
  },
  "openvpn_udp": {
    "rx_pkt_cnt": 0,
    "tx_pkt_cnt": 0
  }
}

rx_pkt_cnttx_pkt_cnt 分别为这条连接上被判断为可能是 OpenVPN 包收到/发送的数量,所以 block 规则可以这样写:

- name: block openvpn tcp
  action: block
  expr: openvpn_tcp.rx_pkt_cnt + openvpn_tcp.tx_pkt_cnt > 50

- name: block openvpn udp
  action: block
  expr: openvpn_udp.rx_pkt_cnt + openvpn_udp.tx_pkt_cnt > 50

包的数量越多,假阳性越低。假阳性的概率大致可以这样计算:3/32 * 2/32 * (6/32)^(rx_pkt_cnt + tx_pkt_cnt)

目前限制了最多判别 256 个包,依据是这样假阳性概率大致能达到要求,并且在正常网络活动的情况下,达到这个数量的包所需要的时间不会超过 10s

关于假阴性,TCP 有可靠的流,理论上不会有假阴性。但 UDP 可能在较差的网络环境下具有较高的假阴性,当 OpenVPN 的 P_CONTROL_HARD_RESET_CLIENT_*P_CONTROL_HARD_RESET_SERVER_* 这两个控制包,即 OpenVPN 握手阶段才会发送的包被丢包时就会出现假阴性的情况,目前代码里面没有引入 invalidCount 来解决,原因是考虑到可能会提高 UDP 的假阳性,需要的话也许后续可以加上(?)

tobyxdd commented 4 months ago

感谢!我这周末 review 下。能把 TCP 和 UDP 的逻辑合并到同一个 analyzer 吗?同一个 analyzer 是可以同时实现 TCP/UDP 的接口的,可以参考已有的 DNS analyzer

tobyxdd commented 4 months ago

对于用 psk 的情况,我在考虑让 FET analyzer 支持 UDP... 应该可以对付开了 tls-crypt 的 OpenVPN

KujouRinka commented 4 months ago

现在把逻辑都合并到 analyzer/udp/openvpn.go 里面了,PropMap 是下面这样:

{
  "openvpn": {
    "rx_pkt_cnt": 0,
    "tx_pkt_cnt": 0
  }
}
do02fw commented 3 months ago

openvpn udp tls1.3 aes-256-gcm 1 也能分析出来吗?