mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 17:35:40 +08:00
ipset: only allow to set ipset in rule files #69
This commit is contained in:
parent
86478d2c25
commit
5a43cf873e
@ -26,6 +26,8 @@ Listen (local proxy server):
|
|||||||
- TCP tunnel
|
- TCP tunnel
|
||||||
- UDP tunnel
|
- UDP tunnel
|
||||||
- UDP over TCP tunnel
|
- UDP over TCP tunnel
|
||||||
|
- TLS, use it together with above proxy protocols(tcp)
|
||||||
|
- Unix domain socket, use it together with above proxy protocols(tcp)
|
||||||
|
|
||||||
Forward (local proxy client/upstream proxy server):
|
Forward (local proxy client/upstream proxy server):
|
||||||
|
|
||||||
@ -36,6 +38,7 @@ Forward (local proxy client/upstream proxy server):
|
|||||||
- VMess proxy(tcp)
|
- VMess proxy(tcp)
|
||||||
- TLS, use it together with above proxy protocols(tcp)
|
- TLS, use it together with above proxy protocols(tcp)
|
||||||
- Websocket, use it together with above proxy protocols(tcp)
|
- Websocket, use it together with above proxy protocols(tcp)
|
||||||
|
- Unix domain socket, use it together with above proxy protocols(tcp)
|
||||||
|
|
||||||
DNS Forwarding Server (udp2tcp):
|
DNS Forwarding Server (udp2tcp):
|
||||||
|
|
||||||
@ -135,8 +138,6 @@ glider v0.6.9 usage:
|
|||||||
forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS]
|
forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS]
|
||||||
-interface string
|
-interface string
|
||||||
source ip or source interface
|
source ip or source interface
|
||||||
-ipset string
|
|
||||||
ipset name
|
|
||||||
-listen value
|
-listen value
|
||||||
listen url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS
|
listen url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS
|
||||||
-maxfailures int
|
-maxfailures int
|
||||||
@ -262,7 +263,7 @@ Examples:
|
|||||||
glider -listen socks5://:1080 -verbose
|
glider -listen socks5://:1080 -verbose
|
||||||
-listen on :1080 as a socks5 proxy server, in verbose mode.
|
-listen on :1080 as a socks5 proxy server, in verbose mode.
|
||||||
|
|
||||||
glider -listen =tls://:443?cert=crtFilePath&key=keyFilePath,http:// -verbose
|
glider -listen tls://:443?cert=crtFilePath&key=keyFilePath,http:// -verbose
|
||||||
-listen on :443 as a https proxy server.
|
-listen on :443 as a https proxy server.
|
||||||
|
|
||||||
glider -listen http://:8080 -forward socks5://127.0.0.1:1080
|
glider -listen http://:8080 -forward socks5://127.0.0.1:1080
|
||||||
|
6
conf.go
6
conf.go
@ -29,8 +29,6 @@ var conf struct {
|
|||||||
DNS string
|
DNS string
|
||||||
DNSConfig dns.Config
|
DNSConfig dns.Config
|
||||||
|
|
||||||
IPSet string
|
|
||||||
|
|
||||||
rules []*rule.Config
|
rules []*rule.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,8 +55,6 @@ func confInit() {
|
|||||||
flag.IntVar(&conf.DNSConfig.MinTTL, "dnsminttl", 0, "minimum TTL value for entries in the CACHE(seconds)")
|
flag.IntVar(&conf.DNSConfig.MinTTL, "dnsminttl", 0, "minimum TTL value for entries in the CACHE(seconds)")
|
||||||
flag.StringSliceUniqVar(&conf.DNSConfig.Records, "dnsrecord", nil, "custom dns record, format: domain/ip")
|
flag.StringSliceUniqVar(&conf.DNSConfig.Records, "dnsrecord", nil, "custom dns record, format: domain/ip")
|
||||||
|
|
||||||
flag.StringVar(&conf.IPSet, "ipset", "", "ipset name")
|
|
||||||
|
|
||||||
flag.Usage = usage
|
flag.Usage = usage
|
||||||
err := flag.Parse()
|
err := flag.Parse()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -240,7 +236,7 @@ func usage() {
|
|||||||
fmt.Fprintf(os.Stderr, " "+app+" -listen socks5://:1080 -verbose\n")
|
fmt.Fprintf(os.Stderr, " "+app+" -listen socks5://:1080 -verbose\n")
|
||||||
fmt.Fprintf(os.Stderr, " -listen on :1080 as a socks5 proxy server, in verbose mode.\n")
|
fmt.Fprintf(os.Stderr, " -listen on :1080 as a socks5 proxy server, in verbose mode.\n")
|
||||||
fmt.Fprintf(os.Stderr, "\n")
|
fmt.Fprintf(os.Stderr, "\n")
|
||||||
fmt.Fprintf(os.Stderr, " "+app+" -listen =tls://:443?cert=crtFilePath&key=keyFilePath,http:// -verbose\n")
|
fmt.Fprintf(os.Stderr, " "+app+" -listen tls://:443?cert=crtFilePath&key=keyFilePath,http:// -verbose\n")
|
||||||
fmt.Fprintf(os.Stderr, " -listen on :443 as a https proxy server.\n")
|
fmt.Fprintf(os.Stderr, " -listen on :443 as a https proxy server.\n")
|
||||||
fmt.Fprintf(os.Stderr, "\n")
|
fmt.Fprintf(os.Stderr, "\n")
|
||||||
fmt.Fprintf(os.Stderr, " "+app+" -listen http://:8080 -forward socks5://127.0.0.1:1080\n")
|
fmt.Fprintf(os.Stderr, " "+app+" -listen http://:8080 -forward socks5://127.0.0.1:1080\n")
|
||||||
|
@ -9,8 +9,5 @@ listen=redir://:1081
|
|||||||
dns=:53
|
dns=:53
|
||||||
dnsserver=8.8.8.8:53
|
dnsserver=8.8.8.8:53
|
||||||
|
|
||||||
# as a ipset manager
|
|
||||||
ipset=glider
|
|
||||||
|
|
||||||
# parse all *.rule files in rules.d folder
|
# parse all *.rule files in rules.d folder
|
||||||
rules-dir=rules.d
|
rules-dir=rules.d
|
||||||
|
@ -13,6 +13,8 @@ strategy=rr
|
|||||||
checkwebsite=www.apple.com
|
checkwebsite=www.apple.com
|
||||||
checkduration=30
|
checkduration=30
|
||||||
|
|
||||||
|
# as a ipset manager
|
||||||
|
ipset=glider
|
||||||
|
|
||||||
# matches 192.168.0.0/16
|
# matches 192.168.0.0/16
|
||||||
cidr=192.168.0.0/16
|
cidr=192.168.0.0/16
|
||||||
|
@ -15,6 +15,9 @@ checkduration=30
|
|||||||
# specify a different dns server(if need)
|
# specify a different dns server(if need)
|
||||||
dnsserver=208.67.222.222:53
|
dnsserver=208.67.222.222:53
|
||||||
|
|
||||||
|
# as a ipset manager
|
||||||
|
ipset=glider
|
||||||
|
|
||||||
# specify destinations
|
# specify destinations
|
||||||
include=office.list
|
include=office.list
|
||||||
|
|
||||||
|
@ -107,6 +107,9 @@ listen=socks5://:1080
|
|||||||
# forward=tls://1.1.1.1:443,ws://,vmess://5a146038-0b56-4e95-b1dc-5c6f5a32cd98@?alterID=2
|
# forward=tls://1.1.1.1:443,ws://,vmess://5a146038-0b56-4e95-b1dc-5c6f5a32cd98@?alterID=2
|
||||||
# forward=tls://1.1.1.1:443,ws://@/path,vmess://5a146038-0b56-4e95-b1dc-5c6f5a32cd98@?alterID=2
|
# forward=tls://1.1.1.1:443,ws://@/path,vmess://5a146038-0b56-4e95-b1dc-5c6f5a32cd98@?alterID=2
|
||||||
|
|
||||||
|
# socks5 over unix domain socket
|
||||||
|
# forward=unix:///tmp/glider.socket,socks5://
|
||||||
|
|
||||||
# FORWARDER CHAIN
|
# FORWARDER CHAIN
|
||||||
# ---------------
|
# ---------------
|
||||||
# We can setup a forward chain using 1 forward option,
|
# We can setup a forward chain using 1 forward option,
|
||||||
@ -167,15 +170,6 @@ dnsminttl=0
|
|||||||
dnsrecord=www.example.com/1.2.3.4
|
dnsrecord=www.example.com/1.2.3.4
|
||||||
dnsrecord=www.example.com/2606:2800:220:1:248:1893:25c8:1946
|
dnsrecord=www.example.com/2606:2800:220:1:248:1893:25c8:1946
|
||||||
|
|
||||||
|
|
||||||
# IPSET MANAGEMENT
|
|
||||||
# ----------------
|
|
||||||
# Create and mange ipset on linux based on destinations in rule files
|
|
||||||
# - add ip/cidrs in rule files on startup
|
|
||||||
# - add resolved ips for domains in rule files by dns forwarding server
|
|
||||||
# Usually used in transparent proxy mode on linux
|
|
||||||
ipset=glider
|
|
||||||
|
|
||||||
# INTERFACE SPECIFIC
|
# INTERFACE SPECIFIC
|
||||||
# ------------------
|
# ------------------
|
||||||
# Specify the outbound ip/interface.
|
# Specify the outbound ip/interface.
|
||||||
|
@ -20,9 +20,13 @@ checkduration=30
|
|||||||
# DNS SERVER for domains in this rule file
|
# DNS SERVER for domains in this rule file
|
||||||
dnsserver=208.67.222.222:53
|
dnsserver=208.67.222.222:53
|
||||||
|
|
||||||
# IPSET
|
# IPSET MANAGEMENT
|
||||||
# specify a ipset for destinations in this rule file
|
# ----------------
|
||||||
#ipset=office
|
# Create and mange ipset on linux based on destinations in rule files
|
||||||
|
# - add ip/cidrs in rule files on startup
|
||||||
|
# - add resolved ips for domains in rule files by dns forwarding server
|
||||||
|
# Usually used in transparent proxy mode on linux
|
||||||
|
ipset=glider
|
||||||
|
|
||||||
# DESTINATIONS
|
# DESTINATIONS
|
||||||
# ------------
|
# ------------
|
||||||
|
@ -91,17 +91,17 @@ func (s *Server) ListenAndServeTCP(wg *sync.WaitGroup) {
|
|||||||
l, err := net.Listen("tcp", s.addr)
|
l, err := net.Listen("tcp", s.addr)
|
||||||
wg.Done()
|
wg.Done()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.F("[dns]-tcp error: %v", err)
|
log.F("[dns-tcp] error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer l.Close()
|
defer l.Close()
|
||||||
|
|
||||||
log.F("[dns]-tcp listening TCP on %s", s.addr)
|
log.F("[dns-tcp] listening TCP on %s", s.addr)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
c, err := l.Accept()
|
c, err := l.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.F("[dns]-tcp error: failed to accept: %v", err)
|
log.F("[dns-tcp] error: failed to accept: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
go s.ServeTCP(c)
|
go s.ServeTCP(c)
|
||||||
@ -116,14 +116,14 @@ func (s *Server) ServeTCP(c net.Conn) {
|
|||||||
|
|
||||||
var reqLen uint16
|
var reqLen uint16
|
||||||
if err := binary.Read(c, binary.BigEndian, &reqLen); err != nil {
|
if err := binary.Read(c, binary.BigEndian, &reqLen); err != nil {
|
||||||
log.F("[dns]-tcp failed to get request length: %v", err)
|
log.F("[dns-tcp] failed to get request length: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
reqBytes := make([]byte, reqLen+2)
|
reqBytes := make([]byte, reqLen+2)
|
||||||
_, err := io.ReadFull(c, reqBytes[2:])
|
_, err := io.ReadFull(c, reqBytes[2:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.F("[dns]-tcp error in read reqBytes %s", err)
|
log.F("[dns-tcp] error in read reqBytes %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,12 +131,12 @@ func (s *Server) ServeTCP(c net.Conn) {
|
|||||||
|
|
||||||
respBytes, err := s.Exchange(reqBytes, c.RemoteAddr().String(), true)
|
respBytes, err := s.Exchange(reqBytes, c.RemoteAddr().String(), true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.F("[dns]-tcp error in exchange: %s", err)
|
log.F("[dns-tcp] error in exchange: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := binary.Write(c, binary.BigEndian, respBytes); err != nil {
|
if err := binary.Write(c, binary.BigEndian, respBytes); err != nil {
|
||||||
log.F("[dns]-tcp error in local write respBytes: %s", err)
|
log.F("[dns-tcp] error in local write respBytes: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,12 +73,11 @@ type Manager struct {
|
|||||||
fd int
|
fd int
|
||||||
lsa syscall.SockaddrNetlink
|
lsa syscall.SockaddrNetlink
|
||||||
|
|
||||||
mainSet string
|
|
||||||
domainSet sync.Map
|
domainSet sync.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewManager returns a Manager
|
// NewManager returns a Manager
|
||||||
func NewManager(mainSet string, rules []*rule.Config) (*Manager, error) {
|
func NewManager(rules []*rule.Config) (*Manager, error) {
|
||||||
fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_NETFILTER)
|
fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_NETFILTER)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.F("%s", err)
|
log.F("%s", err)
|
||||||
@ -95,37 +94,28 @@ func NewManager(mainSet string, rules []*rule.Config) (*Manager, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
m := &Manager{fd: fd, lsa: lsa, mainSet: mainSet}
|
m := &Manager{fd: fd, lsa: lsa}
|
||||||
CreateSet(fd, lsa, mainSet)
|
|
||||||
|
|
||||||
|
// create ipset
|
||||||
for _, r := range rules {
|
for _, r := range rules {
|
||||||
set := r.IPSet
|
if r.IPSet != "" {
|
||||||
|
CreateSet(fd, lsa, r.IPSet)
|
||||||
if set != "" && set != m.mainSet {
|
}
|
||||||
CreateSet(fd, lsa, set)
|
|
||||||
} else {
|
|
||||||
set = m.mainSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// if dialer is Direct, do not insert to ipset, in order to avoid iptables redirect loop
|
|
||||||
if len(r.Forward) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init ipset
|
||||||
|
for _, r := range rules {
|
||||||
|
if r.IPSet != "" {
|
||||||
for _, domain := range r.Domain {
|
for _, domain := range r.Domain {
|
||||||
m.domainSet.Store(domain, set)
|
m.domainSet.Store(domain, r.IPSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ip := range r.IP {
|
for _, ip := range r.IP {
|
||||||
AddToSet(fd, lsa, mainSet, ip)
|
|
||||||
AddToSet(fd, lsa, r.IPSet, ip)
|
AddToSet(fd, lsa, r.IPSet, ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cidr := range r.CIDR {
|
for _, cidr := range r.CIDR {
|
||||||
AddToSet(fd, lsa, mainSet, cidr)
|
|
||||||
AddToSet(fd, lsa, r.IPSet, cidr)
|
AddToSet(fd, lsa, r.IPSet, cidr)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return m, nil
|
return m, nil
|
||||||
@ -141,14 +131,11 @@ func (m *Manager) AddDomainIP(domain, ip string) error {
|
|||||||
|
|
||||||
// find in domainMap
|
// find in domainMap
|
||||||
if ipset, ok := m.domainSet.Load(domain); ok {
|
if ipset, ok := m.domainSet.Load(domain); ok {
|
||||||
AddToSet(m.fd, m.lsa, m.mainSet, ip)
|
|
||||||
if ipset.(string) != m.mainSet {
|
|
||||||
AddToSet(m.fd, m.lsa, ipset.(string), ip)
|
AddToSet(m.fd, m.lsa, ipset.(string), ip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
type Manager struct{}
|
type Manager struct{}
|
||||||
|
|
||||||
// NewManager returns a Manager
|
// NewManager returns a Manager
|
||||||
func NewManager(mainSet string, rules []*rule.Config) (*Manager, error) {
|
func NewManager(rules []*rule.Config) (*Manager, error) {
|
||||||
return nil, errors.New("ipset not supported on this os")
|
return nil, errors.New("ipset not supported on this os")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
main.go
2
main.go
@ -44,7 +44,7 @@ func main() {
|
|||||||
dialer := rule.NewDialer(conf.rules, strategy.NewDialer(conf.Forward, &conf.StrategyConfig))
|
dialer := rule.NewDialer(conf.rules, strategy.NewDialer(conf.Forward, &conf.StrategyConfig))
|
||||||
|
|
||||||
// ipset manager
|
// ipset manager
|
||||||
ipsetM, _ := ipset.NewManager(conf.IPSet, conf.rules)
|
ipsetM, _ := ipset.NewManager(conf.rules)
|
||||||
|
|
||||||
// check and setup dns server
|
// check and setup dns server
|
||||||
if conf.DNS != "" {
|
if conf.DNS != "" {
|
||||||
|
@ -232,7 +232,7 @@ func (s *SOCKS5) Dial(network, addr string) (net.Conn, error) {
|
|||||||
|
|
||||||
c, err := s.dialer.Dial(network, s.addr)
|
c, err := s.dialer.Dial(network, s.addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.F("dial to %s error: %s", s.addr, err)
|
log.F("[socks5]: dial to %s error: %s", s.addr, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ func init() {
|
|||||||
proxy.RegisterServer("tls", NewTLSServer)
|
proxy.RegisterServer("tls", NewTLSServer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTLS returns a tls proxy
|
// NewTLS returns a tls proxy struct
|
||||||
func NewTLS(s string, dialer proxy.Dialer) (*TLS, error) {
|
func NewTLS(s string, dialer proxy.Dialer) (*TLS, error) {
|
||||||
u, err := url.Parse(s)
|
u, err := url.Parse(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -69,7 +69,7 @@ func NewTLS(s string, dialer proxy.Dialer) (*TLS, error) {
|
|||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTLSDialer returns a tls proxy dialer.
|
// NewTLSDialer returns a tls proxy dialer
|
||||||
func NewTLSDialer(s string, dialer proxy.Dialer) (proxy.Dialer, error) {
|
func NewTLSDialer(s string, dialer proxy.Dialer) (proxy.Dialer, error) {
|
||||||
p, err := NewTLS(s, dialer)
|
p, err := NewTLS(s, dialer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -104,7 +104,7 @@ func NewTLSServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
|||||||
|
|
||||||
cert, err := stdtls.LoadX509KeyPair(p.certFile, p.keyFile)
|
cert, err := stdtls.LoadX509KeyPair(p.certFile, p.keyFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.F("[tls] unabled load cert: %s, key %s", p.certFile, p.keyFile)
|
log.F("[tls] unable to load cert: %s, key %s", p.certFile, p.keyFile)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,8 +144,11 @@ func (s *TLS) ListenAndServe() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serve .
|
// Serve serves requests
|
||||||
func (s *TLS) Serve(c net.Conn) {
|
func (s *TLS) Serve(c net.Conn) {
|
||||||
|
// we know the internal server will close the connection after serve
|
||||||
|
// defer c.Close()
|
||||||
|
|
||||||
if s.server != nil {
|
if s.server != nil {
|
||||||
cc := stdtls.Server(c, s.tlsConfig)
|
cc := stdtls.Server(c, s.tlsConfig)
|
||||||
s.server.Serve(cc)
|
s.server.Serve(cc)
|
||||||
|
@ -93,7 +93,8 @@ func (s *Unix) ListenAndServe() {
|
|||||||
|
|
||||||
// Serve serves requests
|
// Serve serves requests
|
||||||
func (s *Unix) Serve(c net.Conn) {
|
func (s *Unix) Serve(c net.Conn) {
|
||||||
defer c.Close()
|
// we know the internal server will close the connection after serve
|
||||||
|
// defer c.Close()
|
||||||
|
|
||||||
if s.server != nil {
|
if s.server != nil {
|
||||||
s.server.Serve(c)
|
s.server.Serve(c)
|
||||||
|
Loading…
Reference in New Issue
Block a user