Skip to content

Commit

Permalink
Merge pull request #197 from HyNetwork/wip-geoip
Browse files Browse the repository at this point in the history
ACL GeoIP Country
  • Loading branch information
tobyxdd authored Jan 10, 2022
2 parents c3b76a5 + fb5b21a commit 1e63289
Show file tree
Hide file tree
Showing 15 changed files with 148 additions and 7,086 deletions.
8 changes: 4 additions & 4 deletions ACL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ Example:
direct domain evil.corp
proxy domain-suffix google.com
block ip 1.2.3.4
block country cn
hijack cidr 192.168.1.1/24 127.0.0.1
direct all
```

A real-life ACL example of directly connecting to all China IPs (and its generator Python
script) [can be found here](docs/acl).

Hysteria acts according to the first matching rule in the file for each request. When there is no match, the default
behavior is to proxy all connections. You can override this by adding a rule at the end of the file with the condition
`all`.
Expand All @@ -35,7 +33,7 @@ behavior is to proxy all connections. You can override this by adding a rule at

`hijack` - hijack the connection to another target address (must be specified in the argument)

5 condition types:
6 condition types:

`domain` - match a specific domain (does NOT match subdomains! e.g. `apple.com` will not match `cdn.apple.com`)

Expand All @@ -45,6 +43,8 @@ behavior is to proxy all connections. You can override this by adding a rule at

`ip` - IPv4 or IPv6 address

`country` - match IP by ISO 3166-1 alpha-2 country code

`all` - match anything (usually placed at the end of the file as a default rule)

For domain requests, Hysteria will try to resolve the domains and match both domain & IP rules. In other words, an IP
Expand Down
7 changes: 4 additions & 3 deletions ACL.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ ACL 文件描述如何处理传入请求。服务器和客户端都支持 ACL,
direct domain evil.corp
proxy domain-suffix google.com
block ip 1.2.3.4
block country cn
hijack cidr 192.168.1.1/24 127.0.0.1
direct all
```

一个直连所有中国 IP 的规则和 Python 生成脚本 [在这里](docs/acl)

Hysteria 根据文件中第一个匹配到规则对每个请求进行操作。当没有匹配时默认的行为是代理连接。可以通过在文件的末尾添加一个规则加上条件 "all" 来设置默认行为。

4 种处理方式:
Expand All @@ -31,7 +30,7 @@ Hysteria 根据文件中第一个匹配到规则对每个请求进行操作。

`hijack` - 把连接劫持到另一个目的地 (必须在参数中指定)

5 种条件类型:
6 种条件类型:

`domain` - 匹配特定的域名(不匹配子域名!例如:`apple.com` 不匹配 `cdn.apple.com`

Expand All @@ -41,6 +40,8 @@ Hysteria 根据文件中第一个匹配到规则对每个请求进行操作。

`ip` - IPv4 / IPv6 地址

`country` - 匹配国家 IP,ISO 两位字母国家代码

`all` - 匹配所有地址 (通常放在文件尾作为默认规则)

对于域名请求,Hysteria 将尝试解析域名并同时匹配域名规则和 IP 规则。换句话说,IP 规则能覆盖到所有连接,无论客户端是用 IP 还是域名请求。
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ encryption. If you need a proxy, just use our proxy modes.
"down_mbps": 100, // Max download Mbps per client
"disable_udp": false, // Disable UDP support
"acl": "my_list.acl", // See ACL below
"mmdb": "GeoLite2-Country.mmdb", // MaxMind database for ACL country lookups
"obfs": "AMOGUS", // Obfuscation password
"auth": { // Authentication
"mode": "password", // Mode, supports "password" "none" and "external" for now
Expand Down Expand Up @@ -318,6 +319,7 @@ hysteria_traffic_uplink_bytes_total{auth="aGFja2VyISE="} 37452
"timeout": 60 // UDP session timeout in seconds
},
"acl": "my_list.acl", // See ACL below
"mmdb": "GeoLite2-Country.mmdb", // MaxMind database for ACL country lookups
"obfs": "AMOGUS", // Obfuscation password
"auth": "[BASE64]", // Authentication payload in Base64
"auth_str": "yubiyubi", // Authentication payload in string, mutually exclusive with the option above
Expand Down
2 changes: 2 additions & 0 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ Hysteria 是一个功能丰富的,专为恶劣网络环境进行优化的网
"down_mbps": 100, // 单客户端最大下载速度
"disable_udp": false, // 禁用 UDP 支持
"acl": "my_list.acl", // 见下文 ACL
"mmdb": "GeoLite2-Country.mmdb", // MaxMind IP 库 (ACL)
"obfs": "AMOGUS", // 混淆密码
"auth": { // 验证
"mode": "password", // 验证模式,暂时只支持 "password" 与 "none"
Expand Down Expand Up @@ -303,6 +304,7 @@ hysteria_traffic_uplink_bytes_total{auth="aGFja2VyISE="} 37452
"timeout": 60 // UDP 超时秒数
},
"acl": "my_list.acl", // 见下文 ACL
"mmdb": "GeoLite2-Country.mmdb", // MaxMind IP 库 (ACL)
"obfs": "AMOGUS", // 混淆密码
"auth": "[BASE64]", // Base64 验证密钥
"auth_str": "yubiyubi", // 字符串验证密钥,和上面的选项二选一
Expand Down
9 changes: 8 additions & 1 deletion cmd/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"crypto/tls"
"crypto/x509"
"github.com/oschwald/geoip2-golang"
"io"
"io/ioutil"
"net"
Expand Down Expand Up @@ -93,7 +94,13 @@ func client(config *clientConfig) {
var aclEngine *acl.Engine
if len(config.ACL) > 0 {
var err error
aclEngine, err = acl.LoadFromFile(config.ACL, transport.DefaultTransport)
aclEngine, err = acl.LoadFromFile(config.ACL, transport.DefaultTransport, func() (*geoip2.Reader, error) {
if len(config.MMDB) > 0 {
return loadMMDBReader(config.MMDB)
} else {
return loadMMDBReader(DefaultMMDBFilename)
}
})
if err != nil {
logrus.WithFields(logrus.Fields{
"error": err,
Expand Down
4 changes: 4 additions & 0 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const (
DefaultMaxIncomingStreams = 1024

DefaultALPN = "hysteria"

DefaultMMDBFilename = "GeoLite2-Country.mmdb"
)

type serverConfig struct {
Expand All @@ -36,6 +38,7 @@ type serverConfig struct {
DownMbps int `json:"down_mbps"`
DisableUDP bool `json:"disable_udp"`
ACL string `json:"acl"`
MMDB string `json:"mmdb"`
Obfs string `json:"obfs"`
Auth struct {
Mode string `json:"mode"`
Expand Down Expand Up @@ -137,6 +140,7 @@ type clientConfig struct {
Timeout int `json:"timeout"`
} `json:"tproxy_udp"`
ACL string `json:"acl"`
MMDB string `json:"mmdb"`
Obfs string `json:"obfs"`
Auth []byte `json:"auth"`
AuthString string `json:"auth_str"`
Expand Down
51 changes: 51 additions & 0 deletions cmd/mmdb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package main

import (
"github.com/oschwald/geoip2-golang"
"github.com/sirupsen/logrus"
"io"
"net/http"
"os"
)

const (
mmdbURL = "https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-Country.mmdb"
)

func downloadMMDB(filename string) error {
resp, err := http.Get(mmdbURL)
if err != nil {
return err
}
defer resp.Body.Close()

file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()

_, err = io.Copy(file, resp.Body)
return err
}

func loadMMDBReader(filename string) (*geoip2.Reader, error) {
if _, err := os.Stat(filename); err != nil {
if os.IsNotExist(err) {
logrus.Info("GeoLite2 database not found, downloading...")
if err := downloadMMDB(filename); err != nil {
return nil, err
}
logrus.WithFields(logrus.Fields{
"file": filename,
}).Info("GeoLite2 database downloaded")
return geoip2.Open(filename)
} else {
// some other error
return nil, err
}
} else {
// file exists, just open it
return geoip2.Open(filename)
}
}
9 changes: 8 additions & 1 deletion cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/tls"
"github.com/lucas-clemente/quic-go"
"github.com/lucas-clemente/quic-go/congestion"
"github.com/oschwald/geoip2-golang"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -139,7 +140,13 @@ func server(config *serverConfig) {
// ACL
var aclEngine *acl.Engine
if len(config.ACL) > 0 {
aclEngine, err = acl.LoadFromFile(config.ACL, transport.DefaultTransport)
aclEngine, err = acl.LoadFromFile(config.ACL, transport.DefaultTransport, func() (*geoip2.Reader, error) {
if len(config.MMDB) > 0 {
return loadMMDBReader(config.MMDB)
} else {
return loadMMDBReader(DefaultMMDBFilename)
}
})
if err != nil {
logrus.WithFields(logrus.Fields{
"error": err,
Expand Down
Loading

0 comments on commit 1e63289

Please sign in to comment.