Feature: SOURCE-IP-CIDR rule type (#96)
This commit is contained in:
parent
bfe51e46b0
commit
42d33fe629
10 changed files with 39 additions and 15 deletions
|
@ -170,6 +170,7 @@ Rule:
|
||||||
- DOMAIN,google.com,Proxy
|
- DOMAIN,google.com,Proxy
|
||||||
- DOMAIN-SUFFIX,ad.com,REJECT
|
- DOMAIN-SUFFIX,ad.com,REJECT
|
||||||
- IP-CIDR,127.0.0.0/8,DIRECT
|
- IP-CIDR,127.0.0.0/8,DIRECT
|
||||||
|
- SOURCE-IP-CIDR,192.168.1.201/32,DIRECT
|
||||||
- GEOIP,CN,DIRECT
|
- GEOIP,CN,DIRECT
|
||||||
# FINAL would remove after prerelease
|
# FINAL would remove after prerelease
|
||||||
# you also can use `FINAL,Proxy` or `FINAL,,Proxy` now
|
# you also can use `FINAL,Proxy` or `FINAL,,Proxy` now
|
||||||
|
|
|
@ -32,8 +32,10 @@ func (h *HTTPAdapter) Conn() net.Conn {
|
||||||
|
|
||||||
// NewHTTP is HTTPAdapter generator
|
// NewHTTP is HTTPAdapter generator
|
||||||
func NewHTTP(request *http.Request, conn net.Conn) *HTTPAdapter {
|
func NewHTTP(request *http.Request, conn net.Conn) *HTTPAdapter {
|
||||||
|
metadata := parseHTTPAddr(request)
|
||||||
|
metadata.SourceIP = parseSourceIP(conn)
|
||||||
return &HTTPAdapter{
|
return &HTTPAdapter{
|
||||||
metadata: parseHTTPAddr(request),
|
metadata: metadata,
|
||||||
R: request,
|
R: request,
|
||||||
conn: conn,
|
conn: conn,
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,10 @@ import (
|
||||||
|
|
||||||
// NewHTTPS is HTTPAdapter generator
|
// NewHTTPS is HTTPAdapter generator
|
||||||
func NewHTTPS(request *http.Request, conn net.Conn) *SocketAdapter {
|
func NewHTTPS(request *http.Request, conn net.Conn) *SocketAdapter {
|
||||||
|
metadata := parseHTTPAddr(request)
|
||||||
|
metadata.SourceIP = parseSourceIP(conn)
|
||||||
return &SocketAdapter{
|
return &SocketAdapter{
|
||||||
metadata: parseHTTPAddr(request),
|
metadata: metadata,
|
||||||
conn: conn,
|
conn: conn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ func (s *SocketAdapter) Conn() net.Conn {
|
||||||
func NewSocket(target socks.Addr, conn net.Conn, source C.SourceType) *SocketAdapter {
|
func NewSocket(target socks.Addr, conn net.Conn, source C.SourceType) *SocketAdapter {
|
||||||
metadata := parseSocksAddr(target)
|
metadata := parseSocksAddr(target)
|
||||||
metadata.Source = source
|
metadata.Source = source
|
||||||
|
metadata.SourceIP = parseSourceIP(conn)
|
||||||
|
|
||||||
return &SocketAdapter{
|
return &SocketAdapter{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
|
|
|
@ -61,3 +61,10 @@ func parseHTTPAddr(request *http.Request) *C.Metadata {
|
||||||
|
|
||||||
return metadata
|
return metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseSourceIP(conn net.Conn) *net.IP {
|
||||||
|
if addr, ok := conn.RemoteAddr().(*net.TCPAddr); ok {
|
||||||
|
return &addr.IP
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -338,7 +338,9 @@ func parseRules(cfg *rawConfig) ([]C.Rule, error) {
|
||||||
case "GEOIP":
|
case "GEOIP":
|
||||||
rules = append(rules, R.NewGEOIP(payload, target))
|
rules = append(rules, R.NewGEOIP(payload, target))
|
||||||
case "IP-CIDR", "IP-CIDR6":
|
case "IP-CIDR", "IP-CIDR6":
|
||||||
rules = append(rules, R.NewIPCIDR(payload, target))
|
rules = append(rules, R.NewIPCIDR(payload, target, false))
|
||||||
|
case "SOURCE-IP-CIDR":
|
||||||
|
rules = append(rules, R.NewIPCIDR(payload, target, true))
|
||||||
case "MATCH":
|
case "MATCH":
|
||||||
fallthrough
|
fallthrough
|
||||||
case "FINAL":
|
case "FINAL":
|
||||||
|
|
|
@ -33,6 +33,7 @@ type SourceType int
|
||||||
type Metadata struct {
|
type Metadata struct {
|
||||||
NetWork NetWork
|
NetWork NetWork
|
||||||
Source SourceType
|
Source SourceType
|
||||||
|
SourceIP *net.IP
|
||||||
AddrType int
|
AddrType int
|
||||||
Host string
|
Host string
|
||||||
IP *net.IP
|
IP *net.IP
|
||||||
|
|
|
@ -7,6 +7,7 @@ const (
|
||||||
DomainKeyword
|
DomainKeyword
|
||||||
GEOIP
|
GEOIP
|
||||||
IPCIDR
|
IPCIDR
|
||||||
|
SourceIPCIDR
|
||||||
FINAL
|
FINAL
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,6 +25,8 @@ func (rt RuleType) String() string {
|
||||||
return "GEOIP"
|
return "GEOIP"
|
||||||
case IPCIDR:
|
case IPCIDR:
|
||||||
return "IPCIDR"
|
return "IPCIDR"
|
||||||
|
case SourceIPCIDR:
|
||||||
|
return "SourceIPCIDR"
|
||||||
case FINAL:
|
case FINAL:
|
||||||
return "FINAL"
|
return "FINAL"
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -9,18 +9,22 @@ import (
|
||||||
type IPCIDR struct {
|
type IPCIDR struct {
|
||||||
ipnet *net.IPNet
|
ipnet *net.IPNet
|
||||||
adapter string
|
adapter string
|
||||||
|
isSourceIP bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IPCIDR) RuleType() C.RuleType {
|
func (i *IPCIDR) RuleType() C.RuleType {
|
||||||
|
if i.isSourceIP {
|
||||||
|
return C.SourceIPCIDR
|
||||||
|
}
|
||||||
return C.IPCIDR
|
return C.IPCIDR
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IPCIDR) IsMatch(metadata *C.Metadata) bool {
|
func (i *IPCIDR) IsMatch(metadata *C.Metadata) bool {
|
||||||
if metadata.IP == nil {
|
ip := metadata.IP
|
||||||
return false
|
if i.isSourceIP {
|
||||||
|
ip = metadata.SourceIP
|
||||||
}
|
}
|
||||||
|
return i.ipnet.Contains(*ip)
|
||||||
return i.ipnet.Contains(*metadata.IP)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IPCIDR) Adapter() string {
|
func (i *IPCIDR) Adapter() string {
|
||||||
|
@ -31,12 +35,13 @@ func (i *IPCIDR) Payload() string {
|
||||||
return i.ipnet.String()
|
return i.ipnet.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIPCIDR(s string, adapter string) *IPCIDR {
|
func NewIPCIDR(s string, adapter string, isSourceIP bool) *IPCIDR {
|
||||||
_, ipnet, err := net.ParseCIDR(s)
|
_, ipnet, err := net.ParseCIDR(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
}
|
}
|
||||||
return &IPCIDR{
|
return &IPCIDR{
|
||||||
ipnet: ipnet,
|
ipnet: ipnet,
|
||||||
adapter: adapter,
|
adapter: adapter,
|
||||||
|
isSourceIP: isSourceIP,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ func (t *Tunnel) handleConn(localConn C.ServerAdapter) {
|
||||||
|
|
||||||
remoConn, err := proxy.Generator(metadata)
|
remoConn, err := proxy.Generator(metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnln("Proxy[%s] connect [%s] error: %s", proxy.Name(), metadata.String(), err.Error())
|
log.Warnln("Proxy[%s] connect [%s --> %s] error: %s", proxy.Name(), metadata.SourceIP.String(), metadata.String(), err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer remoConn.Close()
|
defer remoConn.Close()
|
||||||
|
@ -174,12 +174,12 @@ func (t *Tunnel) match(metadata *C.Metadata) (C.Proxy, error) {
|
||||||
|
|
||||||
if rule.IsMatch(metadata) {
|
if rule.IsMatch(metadata) {
|
||||||
if a, ok := t.proxies[rule.Adapter()]; ok {
|
if a, ok := t.proxies[rule.Adapter()]; ok {
|
||||||
log.Infoln("%v match %s using %s", metadata.String(), rule.RuleType().String(), rule.Adapter())
|
log.Infoln("%s --> %v match %s using %s", metadata.SourceIP.String(), metadata.String(), rule.RuleType().String(), rule.Adapter())
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Infoln("%v doesn't match any rule using DIRECT", metadata.String())
|
log.Infoln("%s --> %v doesn't match any rule using DIRECT", metadata.SourceIP.String(), metadata.String())
|
||||||
return t.proxies["DIRECT"], nil
|
return t.proxies["DIRECT"], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue