make tun config compatible with premium
This commit is contained in:
parent
63254f0306
commit
f507672d4b
11 changed files with 180 additions and 121 deletions
23
Makefile
23
Makefile
|
@ -15,15 +15,27 @@ GOBUILDOP=CGO_ENABLED=0 go build -trimpath -ldflags '-X "github.com/Dreamacro/cl
|
||||||
PLATFORM_LIST = \
|
PLATFORM_LIST = \
|
||||||
darwin-amd64 \
|
darwin-amd64 \
|
||||||
darwin-arm64 \
|
darwin-arm64 \
|
||||||
linux-arm64 \
|
|
||||||
linux-amd64 \
|
linux-amd64 \
|
||||||
linux-arm64-AutoIptables\
|
linux-armv5 \
|
||||||
linux-amd64-AutoIptables
|
linux-armv6 \
|
||||||
|
linux-armv7 \
|
||||||
|
linux-armv8 \
|
||||||
|
linux-mips64 \
|
||||||
|
linux-mips64le \
|
||||||
|
linux-mips-softfloat \
|
||||||
|
linux-mips-hardfloat \
|
||||||
|
linux-mipsle-softfloat \
|
||||||
|
linux-mipsle-hardfloat \
|
||||||
|
freebsd-386 \
|
||||||
|
freebsd-amd64 \
|
||||||
|
freebsd-arm64
|
||||||
|
|
||||||
|
|
||||||
WINDOWS_ARCH_LIST = \
|
WINDOWS_ARCH_LIST = \
|
||||||
windows-386 \
|
windows-386 \
|
||||||
windows-amd64
|
windows-amd64 \
|
||||||
|
windows-arm64 \
|
||||||
|
windows-arm32v7
|
||||||
|
|
||||||
|
|
||||||
all: linux-arm64-AutoIptables linux-amd64-AutoIptables linux-arm64 linux-amd64 darwin-amd64 darwin-arm64 windows-amd64 windows-386 # Most used
|
all: linux-arm64-AutoIptables linux-amd64-AutoIptables linux-arm64 linux-amd64 darwin-amd64 darwin-arm64 windows-amd64 windows-386 # Most used
|
||||||
|
@ -109,6 +121,9 @@ windows-386:
|
||||||
windows-amd64:
|
windows-amd64:
|
||||||
GOARCH=amd64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe
|
GOARCH=amd64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe
|
||||||
|
|
||||||
|
windows-arm64:
|
||||||
|
GOARCH=arm64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe
|
||||||
|
|
||||||
windows-arm32v7:
|
windows-arm32v7:
|
||||||
GOARCH=arm GOOS=windows GOARM=7 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe
|
GOARCH=arm GOOS=windows GOARM=7 $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,6 @@ type Inbound struct {
|
||||||
RedirPort int `json:"redir-port"`
|
RedirPort int `json:"redir-port"`
|
||||||
TProxyPort int `json:"tproxy-port"`
|
TProxyPort int `json:"tproxy-port"`
|
||||||
MixedPort int `json:"mixed-port"`
|
MixedPort int `json:"mixed-port"`
|
||||||
Tun Tun `json:"tun"`
|
|
||||||
Authentication []string `json:"authentication"`
|
Authentication []string `json:"authentication"`
|
||||||
AllowLan bool `json:"allow-lan"`
|
AllowLan bool `json:"allow-lan"`
|
||||||
BindAddress string `json:"bind-address"`
|
BindAddress string `json:"bind-address"`
|
||||||
|
@ -99,10 +98,11 @@ type Profile struct {
|
||||||
|
|
||||||
// Tun config
|
// Tun config
|
||||||
type Tun struct {
|
type Tun struct {
|
||||||
Enable bool `yaml:"enable" json:"enable"`
|
Enable bool `yaml:"enable" json:"enable"`
|
||||||
Stack string `yaml:"stack" json:"stack"`
|
Stack string `yaml:"stack" json:"stack"`
|
||||||
DNSListen string `yaml:"dns-listen" json:"dns-listen"`
|
DnsHijack []string `yaml:"dns-hijack" json:"dns-hijack"`
|
||||||
AutoRoute bool `yaml:"auto-route" json:"auto-route"`
|
AutoRoute bool `yaml:"auto-route" json:"auto-route"`
|
||||||
|
AutoDetectInterface bool `yaml:"auto-detect-interface" json:"auto-detect-interface"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Script config
|
// Script config
|
||||||
|
@ -207,10 +207,11 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
|
||||||
Proxy: []map[string]interface{}{},
|
Proxy: []map[string]interface{}{},
|
||||||
ProxyGroup: []map[string]interface{}{},
|
ProxyGroup: []map[string]interface{}{},
|
||||||
Tun: Tun{
|
Tun: Tun{
|
||||||
Enable: false,
|
Enable: false,
|
||||||
Stack: "gvisor",
|
Stack: "gvisor",
|
||||||
DNSListen: "0.0.0.0:53",
|
DnsHijack: []string{"192.18.0.2:53"},
|
||||||
AutoRoute: true,
|
AutoRoute: true,
|
||||||
|
AutoDetectInterface: true,
|
||||||
},
|
},
|
||||||
DNS: RawDNS{
|
DNS: RawDNS{
|
||||||
Enable: false,
|
Enable: false,
|
||||||
|
@ -225,6 +226,17 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
|
||||||
DefaultNameserver: []string{
|
DefaultNameserver: []string{
|
||||||
"114.114.114.114",
|
"114.114.114.114",
|
||||||
"223.5.5.5",
|
"223.5.5.5",
|
||||||
|
"8.8.8.8",
|
||||||
|
"1.0.0.1",
|
||||||
|
},
|
||||||
|
NameServer: []string{
|
||||||
|
"https://8.8.8.8/dns-query",
|
||||||
|
"https://1.0.0.1/dns-query",
|
||||||
|
},
|
||||||
|
FakeIPFilter: []string{
|
||||||
|
"dns.msftnsci.com",
|
||||||
|
"www.msftnsci.com",
|
||||||
|
"www.msftconnecttest.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Profile: Profile{
|
Profile: Profile{
|
||||||
|
@ -254,7 +266,7 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
config.General = general
|
config.General = general
|
||||||
//TODO 暂未使用
|
|
||||||
config.Tun = &rawCfg.Tun
|
config.Tun = &rawCfg.Tun
|
||||||
|
|
||||||
proxies, providers, err := parseProxies(rawCfg)
|
proxies, providers, err := parseProxies(rawCfg)
|
||||||
|
@ -312,7 +324,6 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
|
||||||
RedirPort: cfg.RedirPort,
|
RedirPort: cfg.RedirPort,
|
||||||
TProxyPort: cfg.TProxyPort,
|
TProxyPort: cfg.TProxyPort,
|
||||||
MixedPort: cfg.MixedPort,
|
MixedPort: cfg.MixedPort,
|
||||||
Tun: cfg.Tun,
|
|
||||||
AllowLan: cfg.AllowLan,
|
AllowLan: cfg.AllowLan,
|
||||||
BindAddress: cfg.BindAddress,
|
BindAddress: cfg.BindAddress,
|
||||||
},
|
},
|
||||||
|
@ -332,7 +343,7 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
|
||||||
func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[string]providerTypes.ProxyProvider, err error) {
|
func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[string]providerTypes.ProxyProvider, err error) {
|
||||||
proxies = make(map[string]C.Proxy)
|
proxies = make(map[string]C.Proxy)
|
||||||
providersMap = make(map[string]providerTypes.ProxyProvider)
|
providersMap = make(map[string]providerTypes.ProxyProvider)
|
||||||
proxyList := []string{}
|
var proxyList []string
|
||||||
_proxiesList := list.New()
|
_proxiesList := list.New()
|
||||||
_groupsList := list.New()
|
_groupsList := list.New()
|
||||||
proxiesConfig := cfg.Proxy
|
proxiesConfig := cfg.Proxy
|
||||||
|
@ -421,7 +432,7 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ps := []C.Proxy{}
|
var ps []C.Proxy
|
||||||
for _, v := range proxyList {
|
for _, v := range proxyList {
|
||||||
ps = append(ps, proxies[v])
|
ps = append(ps, proxies[v])
|
||||||
}
|
}
|
||||||
|
@ -502,14 +513,14 @@ func parseRules(cfg *RawConfig, proxies map[string]C.Proxy) ([]C.Rule, map[strin
|
||||||
R.SetRuleProvider(rp)
|
R.SetRuleProvider(rp)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, provider := range ruleProviders {
|
for _, ruleProvider := range ruleProviders {
|
||||||
log.Infoln("Start initial provider %s", (*provider).Name())
|
log.Infoln("Start initial provider %s", (*ruleProvider).Name())
|
||||||
if err := (*provider).Initial(); err != nil {
|
if err := (*ruleProvider).Initial(); err != nil {
|
||||||
return nil, nil, fmt.Errorf("initial rule provider %s error: %w", (*provider).Name(), err)
|
return nil, nil, fmt.Errorf("initial rule provider %s error: %w", (*ruleProvider).Name(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rules := []C.Rule{}
|
var rules []C.Rule
|
||||||
rulesConfig := cfg.Rule
|
rulesConfig := cfg.Rule
|
||||||
mode := cfg.Mode
|
mode := cfg.Mode
|
||||||
|
|
||||||
|
@ -519,7 +530,7 @@ func parseRules(cfg *RawConfig, proxies map[string]C.Proxy) ([]C.Rule, map[strin
|
||||||
var (
|
var (
|
||||||
payload string
|
payload string
|
||||||
target string
|
target string
|
||||||
params = []string{}
|
params []string
|
||||||
ruleName = strings.ToUpper(rule[0])
|
ruleName = strings.ToUpper(rule[0])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -607,7 +618,7 @@ func hostWithDefaultPort(host string, defPort string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseNameServer(servers []string) ([]dns.NameServer, error) {
|
func parseNameServer(servers []string) ([]dns.NameServer, error) {
|
||||||
nameservers := []dns.NameServer{}
|
var nameservers []dns.NameServer
|
||||||
|
|
||||||
for idx, server := range servers {
|
for idx, server := range servers {
|
||||||
// parse without scheme .e.g 8.8.8.8:53
|
// parse without scheme .e.g 8.8.8.8:53
|
||||||
|
@ -675,7 +686,7 @@ func parseNameServerPolicy(nsPolicy map[string]string) (map[string]dns.NameServe
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseFallbackIPCIDR(ips []string) ([]*net.IPNet, error) {
|
func parseFallbackIPCIDR(ips []string) ([]*net.IPNet, error) {
|
||||||
ipNets := []*net.IPNet{}
|
var ipNets []*net.IPNet
|
||||||
|
|
||||||
for idx, ip := range ips {
|
for idx, ip := range ips {
|
||||||
_, ipnet, err := net.ParseCIDR(ip)
|
_, ipnet, err := net.ParseCIDR(ip)
|
||||||
|
@ -689,7 +700,7 @@ func parseFallbackIPCIDR(ips []string) ([]*net.IPNet, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseFallbackGeoSite(countries []string, rules []C.Rule) ([]*router.DomainMatcher, error) {
|
func parseFallbackGeoSite(countries []string, rules []C.Rule) ([]*router.DomainMatcher, error) {
|
||||||
sites := []*router.DomainMatcher{}
|
var sites []*router.DomainMatcher
|
||||||
|
|
||||||
for _, country := range countries {
|
for _, country := range countries {
|
||||||
found := false
|
found := false
|
||||||
|
@ -784,7 +795,7 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie, rules []C.Rule) (*DNS,
|
||||||
if net.ParseIP(fb.Addr) != nil {
|
if net.ParseIP(fb.Addr) != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
host.Insert(fb.Addr, true)
|
_ = host.Insert(fb.Addr, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package constant
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
@ -89,6 +90,14 @@ func (m *Metadata) SourceAddress() string {
|
||||||
return net.JoinHostPort(m.SrcIP.String(), m.SrcPort)
|
return net.JoinHostPort(m.SrcIP.String(), m.SrcPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Metadata) SourceDetail() string {
|
||||||
|
if m.Process != "" {
|
||||||
|
return fmt.Sprintf("%s(%s)", m.SourceAddress(), m.Process)
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("%s", m.SourceAddress())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Metadata) Resolved() bool {
|
func (m *Metadata) Resolved() bool {
|
||||||
return m.DstIP != nil
|
return m.DstIP != nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,9 +78,10 @@ func ApplyConfig(cfg *config.Config, force bool) {
|
||||||
updateRules(cfg.Rules, cfg.RuleProviders)
|
updateRules(cfg.Rules, cfg.RuleProviders)
|
||||||
updateHosts(cfg.Hosts)
|
updateHosts(cfg.Hosts)
|
||||||
updateProfile(cfg)
|
updateProfile(cfg)
|
||||||
updateIPTables(cfg.DNS, cfg.General)
|
updateIPTables(cfg.DNS, cfg.General, cfg.Tun)
|
||||||
updateDNS(cfg.DNS, cfg.General)
|
updateDNS(cfg.DNS, cfg.Tun)
|
||||||
updateGeneral(cfg.General, force)
|
updateGeneral(cfg.General, force)
|
||||||
|
updateTun(cfg.General, cfg.Tun)
|
||||||
updateExperimental(cfg)
|
updateExperimental(cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +99,6 @@ func GetGeneral() *config.General {
|
||||||
RedirPort: ports.RedirPort,
|
RedirPort: ports.RedirPort,
|
||||||
TProxyPort: ports.TProxyPort,
|
TProxyPort: ports.TProxyPort,
|
||||||
MixedPort: ports.MixedPort,
|
MixedPort: ports.MixedPort,
|
||||||
Tun: P.Tun(),
|
|
||||||
Authentication: authenticator,
|
Authentication: authenticator,
|
||||||
AllowLan: P.AllowLan(),
|
AllowLan: P.AllowLan(),
|
||||||
BindAddress: P.BindAddress(),
|
BindAddress: P.BindAddress(),
|
||||||
|
@ -113,8 +113,8 @@ func GetGeneral() *config.General {
|
||||||
|
|
||||||
func updateExperimental(c *config.Config) {}
|
func updateExperimental(c *config.Config) {}
|
||||||
|
|
||||||
func updateDNS(c *config.DNS, general *config.General) {
|
func updateDNS(c *config.DNS, Tun *config.Tun) {
|
||||||
if !c.Enable && !general.Tun.Enable {
|
if !c.Enable && !Tun.Enable {
|
||||||
resolver.DefaultResolver = nil
|
resolver.DefaultResolver = nil
|
||||||
resolver.MainResolver = nil
|
resolver.MainResolver = nil
|
||||||
resolver.DefaultHostMapper = nil
|
resolver.DefaultHostMapper = nil
|
||||||
|
@ -152,7 +152,7 @@ func updateDNS(c *config.DNS, general *config.General) {
|
||||||
resolver.DefaultResolver = r
|
resolver.DefaultResolver = r
|
||||||
resolver.MainResolver = mr
|
resolver.MainResolver = mr
|
||||||
resolver.DefaultHostMapper = m
|
resolver.DefaultHostMapper = m
|
||||||
if general.Tun.Enable && !strings.EqualFold(general.Tun.Stack, "gvisor") {
|
if Tun.Enable && !strings.EqualFold(Tun.Stack, "gVisor") {
|
||||||
resolver.DefaultLocalServer = dns.NewLocalServer(r, m)
|
resolver.DefaultLocalServer = dns.NewLocalServer(r, m)
|
||||||
} else {
|
} else {
|
||||||
resolver.DefaultLocalServer = nil
|
resolver.DefaultLocalServer = nil
|
||||||
|
@ -179,20 +179,6 @@ func updateGeneral(general *config.General, force bool) {
|
||||||
tunnel.SetMode(general.Mode)
|
tunnel.SetMode(general.Mode)
|
||||||
resolver.DisableIPv6 = !general.IPv6
|
resolver.DisableIPv6 = !general.IPv6
|
||||||
adapter.UnifiedDelay.Store(general.UnifiedDelay)
|
adapter.UnifiedDelay.Store(general.UnifiedDelay)
|
||||||
|
|
||||||
if (general.Tun.Enable || general.TProxyPort != 0) && general.Interface == "" {
|
|
||||||
autoDetectInterfaceName, err := dev.GetAutoDetectInterface()
|
|
||||||
if err == nil {
|
|
||||||
if autoDetectInterfaceName != "" && autoDetectInterfaceName != "<nil>" {
|
|
||||||
general.Interface = autoDetectInterfaceName
|
|
||||||
} else {
|
|
||||||
log.Debugln("Auto detect interface name is empty.")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Debugln("Can not find auto detect interface. %s", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dialer.DefaultInterface.Store(general.Interface)
|
dialer.DefaultInterface.Store(general.Interface)
|
||||||
|
|
||||||
log.Infoln("Use interface name: %s", general.Interface)
|
log.Infoln("Use interface name: %s", general.Interface)
|
||||||
|
@ -219,12 +205,33 @@ func updateGeneral(general *config.General, force bool) {
|
||||||
P.ReCreateTProxy(general.TProxyPort, tcpIn, udpIn)
|
P.ReCreateTProxy(general.TProxyPort, tcpIn, udpIn)
|
||||||
P.ReCreateMixed(general.MixedPort, tcpIn, udpIn)
|
P.ReCreateMixed(general.MixedPort, tcpIn, udpIn)
|
||||||
|
|
||||||
if err := P.ReCreateTun(general.Tun, tcpIn, udpIn); err != nil {
|
log.SetLevel(general.LogLevel)
|
||||||
log.Errorln("Start Tun interface error: %s", err.Error())
|
}
|
||||||
os.Exit(2)
|
|
||||||
|
func updateTun(General *config.General, Tun *config.Tun) {
|
||||||
|
if Tun == nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.SetLevel(general.LogLevel)
|
if (Tun.Enable || General.TProxyPort != 0) && General.Interface == "" {
|
||||||
|
autoDetectInterfaceName, err := dev.GetAutoDetectInterface()
|
||||||
|
if err == nil {
|
||||||
|
if autoDetectInterfaceName != "" && autoDetectInterfaceName != "<nil>" {
|
||||||
|
General.Interface = autoDetectInterfaceName
|
||||||
|
} else {
|
||||||
|
log.Debugln("Auto detect interface name is empty.")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Debugln("Can not find auto detect interface. %s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tcpIn := tunnel.TCPIn()
|
||||||
|
udpIn := tunnel.UDPIn()
|
||||||
|
|
||||||
|
if err := P.ReCreateTun(*Tun, tcpIn, udpIn); err != nil {
|
||||||
|
log.Errorln("Start Tun interface error: %s", err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateUsers(users []auth.AuthUser) {
|
func updateUsers(users []auth.AuthUser) {
|
||||||
|
@ -270,9 +277,9 @@ func patchSelectGroup(proxies map[string]C.Proxy) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateIPTables(dns *config.DNS, general *config.General) {
|
func updateIPTables(dns *config.DNS, general *config.General, tun *config.Tun) {
|
||||||
AutoIptables := C.AutoIptables
|
AutoIptables := C.AutoIptables
|
||||||
if runtime.GOOS != "linux" || dns.Listen == "" || general.TProxyPort == 0 || general.Tun.Enable || AutoIptables != "Enable" {
|
if runtime.GOOS != "linux" || dns.Listen == "" || general.TProxyPort == 0 || tun.Enable || AutoIptables != "Enable" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ type Rule struct {
|
||||||
|
|
||||||
func getRules(w http.ResponseWriter, r *http.Request) {
|
func getRules(w http.ResponseWriter, r *http.Request) {
|
||||||
rawRules := tunnel.Rules()
|
rawRules := tunnel.Rules()
|
||||||
|
|
||||||
rules := []Rule{}
|
rules := []Rule{}
|
||||||
for _, rule := range rawRules {
|
for _, rule := range rawRules {
|
||||||
rules = append(rules, Rule{
|
rules = append(rules, Rule{
|
||||||
|
@ -31,6 +30,7 @@ func getRules(w http.ResponseWriter, r *http.Request) {
|
||||||
Payload: rule.Payload(),
|
Payload: rule.Payload(),
|
||||||
Proxy: rule.Adapter(),
|
Proxy: rule.Adapter(),
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render.JSON(w, r, render.M{
|
render.JSON(w, r, render.M{
|
||||||
|
|
|
@ -71,7 +71,7 @@ func Tun() config.Tun {
|
||||||
return config.Tun{
|
return config.Tun{
|
||||||
Enable: true,
|
Enable: true,
|
||||||
Stack: tunAdapter.Stack(),
|
Stack: tunAdapter.Stack(),
|
||||||
DNSListen: tunAdapter.DNSListen(),
|
DnsHijack: tunAdapter.DnsHijack(),
|
||||||
AutoRoute: tunAdapter.AutoRoute(),
|
AutoRoute: tunAdapter.AutoRoute(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,10 +34,10 @@ import (
|
||||||
const nicID tcpip.NICID = 1
|
const nicID tcpip.NICID = 1
|
||||||
|
|
||||||
type gvisorAdapter struct {
|
type gvisorAdapter struct {
|
||||||
device dev.TunDevice
|
device dev.TunDevice
|
||||||
ipstack *stack.Stack
|
ipstack *stack.Stack
|
||||||
dnsserver *DNSServer
|
dnsServers []*DNSServer
|
||||||
udpIn chan<- *inbound.PacketAdapter
|
udpIn chan<- *inbound.PacketAdapter
|
||||||
|
|
||||||
stackName string
|
stackName string
|
||||||
autoRoute bool
|
autoRoute bool
|
||||||
|
@ -113,7 +113,7 @@ func NewAdapter(device dev.TunDevice, conf config.Tun, tcpIn chan<- C.ConnContex
|
||||||
ipstack.SetTransportProtocolHandler(udp.ProtocolNumber, adapter.udpHandlePacket)
|
ipstack.SetTransportProtocolHandler(udp.ProtocolNumber, adapter.udpHandlePacket)
|
||||||
|
|
||||||
if resolver.DefaultResolver != nil {
|
if resolver.DefaultResolver != nil {
|
||||||
err = adapter.ReCreateDNSServer(resolver.DefaultResolver.(*dns.Resolver), resolver.DefaultHostMapper.(*dns.ResolverEnhancer), conf.DNSListen)
|
err = adapter.ReCreateDNSServer(resolver.DefaultResolver.(*dns.Resolver), resolver.DefaultHostMapper.(*dns.ResolverEnhancer), conf.DnsHijack)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -132,9 +132,7 @@ func (t *gvisorAdapter) AutoRoute() bool {
|
||||||
|
|
||||||
// Close close the TunAdapter
|
// Close close the TunAdapter
|
||||||
func (t *gvisorAdapter) Close() {
|
func (t *gvisorAdapter) Close() {
|
||||||
if t.dnsserver != nil {
|
t.StopAllDNSServer()
|
||||||
t.dnsserver.Stop()
|
|
||||||
}
|
|
||||||
if t.ipstack != nil {
|
if t.ipstack != nil {
|
||||||
t.ipstack.Close()
|
t.ipstack.Close()
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,51 +241,55 @@ func (s *DNSServer) Stop() {
|
||||||
s.NICID)
|
s.NICID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DNSListen return the listening address of DNS Server
|
// DnsHijack return the listening address of DNS Server
|
||||||
func (t *gvisorAdapter) DNSListen() string {
|
func (t *gvisorAdapter) DnsHijack() []string {
|
||||||
if t.dnsserver != nil {
|
results := make([]string, len(t.dnsServers))
|
||||||
id := t.dnsserver.udpEndpointID
|
for i, dnsServer := range t.dnsServers {
|
||||||
return fmt.Sprintf("%s:%d", id.LocalAddress.String(), id.LocalPort)
|
id := dnsServer.udpEndpointID
|
||||||
|
results[i] = fmt.Sprintf("%s:%d", id.LocalAddress.String(), id.LocalPort)
|
||||||
}
|
}
|
||||||
return ""
|
|
||||||
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop stop the DNS Server on tun
|
func (t *gvisorAdapter) StopAllDNSServer() {
|
||||||
func (t *gvisorAdapter) ReCreateDNSServer(resolver *dns.Resolver, mapper *dns.ResolverEnhancer, addr string) error {
|
for _, dnsServer := range t.dnsServers {
|
||||||
if addr == "" && t.dnsserver == nil {
|
dnsServer.Stop()
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
log.Debugln("tun DNS server stoped")
|
||||||
|
t.dnsServers = nil
|
||||||
|
}
|
||||||
|
|
||||||
if addr == t.DNSListen() && t.dnsserver != nil && t.dnsserver.resolver == resolver {
|
// ReCreateDNSServer recreate the DNS Server on tun
|
||||||
return nil
|
func (t *gvisorAdapter) ReCreateDNSServer(resolver *dns.Resolver, mapper *dns.ResolverEnhancer, addrs []string) error {
|
||||||
}
|
t.StopAllDNSServer()
|
||||||
|
|
||||||
if t.dnsserver != nil {
|
|
||||||
t.dnsserver.Stop()
|
|
||||||
t.dnsserver = nil
|
|
||||||
log.Debugln("tun DNS server stoped")
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
_, port, err := net.SplitHostPort(addr)
|
|
||||||
if port == "0" || port == "" || err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if resolver == nil {
|
if resolver == nil {
|
||||||
return fmt.Errorf("failed to create DNS server on tun: resolver not provided")
|
return fmt.Errorf("failed to create DNS server on tun: resolver not provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
udpAddr, err := net.ResolveUDPAddr("udp", addr)
|
if len(addrs) == 0 {
|
||||||
if err != nil {
|
return fmt.Errorf("failed to create DNS server on tun: len(addrs) == 0")
|
||||||
return err
|
}
|
||||||
|
for _, addr := range addrs {
|
||||||
|
var err error
|
||||||
|
_, port, err := net.SplitHostPort(addr)
|
||||||
|
if port == "0" || port == "" || err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
udpAddr, err := net.ResolveUDPAddr("udp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
server, err := CreateDNSServer(t.ipstack, resolver, mapper, udpAddr.IP, udpAddr.Port, nicID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
t.dnsServers = append(t.dnsServers, server)
|
||||||
|
log.Infoln("Tun DNS server listening at: %s, fake ip enabled: %v", addr, mapper.FakeIPEnabled())
|
||||||
}
|
}
|
||||||
|
|
||||||
server, err := CreateDNSServer(t.ipstack, resolver, mapper, udpAddr.IP, udpAddr.Port, nicID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
t.dnsserver = server
|
|
||||||
log.Infoln("Tun DNS server listening at: %s, fake ip enabled: %v", addr, mapper.FakeIPEnabled())
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,6 @@ package ipstack
|
||||||
type TunAdapter interface {
|
type TunAdapter interface {
|
||||||
Close()
|
Close()
|
||||||
Stack() string
|
Stack() string
|
||||||
DNSListen() string
|
DnsHijack() []string
|
||||||
AutoRoute() bool
|
AutoRoute() bool
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,26 +17,26 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type systemAdapter struct {
|
type systemAdapter struct {
|
||||||
device dev.TunDevice
|
device dev.TunDevice
|
||||||
tun *tun2socket.Tun2Socket
|
tun *tun2socket.Tun2Socket
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
stackName string
|
stackName string
|
||||||
dnsListen string
|
dnsHackjack []string
|
||||||
autoRoute bool
|
autoRoute bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAdapter(device dev.TunDevice, conf config.Tun, mtu int, gateway, mirror string, onStop func(), tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) (ipstack.TunAdapter, error) {
|
func NewAdapter(device dev.TunDevice, conf config.Tun, mtu int, gateway, mirror string, onStop func(), tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) (ipstack.TunAdapter, error) {
|
||||||
adapter := &systemAdapter{
|
adapter := &systemAdapter{
|
||||||
device: device,
|
device: device,
|
||||||
stackName: conf.Stack,
|
stackName: conf.Stack,
|
||||||
dnsListen: conf.DNSListen,
|
dnsHackjack: conf.DnsHijack,
|
||||||
autoRoute: conf.AutoRoute,
|
autoRoute: conf.AutoRoute,
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter.lock.Lock()
|
adapter.lock.Lock()
|
||||||
defer adapter.lock.Unlock()
|
defer adapter.lock.Unlock()
|
||||||
|
|
||||||
dnsHost, dnsPort, err := net.SplitHostPort(conf.DNSListen)
|
dnsHost, dnsPort, err := net.SplitHostPort(conf.DnsHijack[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -91,8 +91,8 @@ func (t *systemAdapter) AutoRoute() bool {
|
||||||
return t.autoRoute
|
return t.autoRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *systemAdapter) DNSListen() string {
|
func (t *systemAdapter) DnsHijack() []string {
|
||||||
return t.dnsListen
|
return t.dnsHackjack
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *systemAdapter) Close() {
|
func (t *systemAdapter) Close() {
|
||||||
|
|
|
@ -242,17 +242,24 @@ func handleUDPConn(packet *inbound.PacketAdapter) {
|
||||||
pCtx.InjectPacketConn(rawPc)
|
pCtx.InjectPacketConn(rawPc)
|
||||||
pc := statistic.NewUDPTracker(rawPc, statistic.DefaultManager, metadata, rule)
|
pc := statistic.NewUDPTracker(rawPc, statistic.DefaultManager, metadata, rule)
|
||||||
|
|
||||||
|
var ruleDetail string
|
||||||
|
if rule.Payload() != "" {
|
||||||
|
ruleDetail = fmt.Sprintf("%s(%s)", rule.RuleType().String(), rule.Payload())
|
||||||
|
} else {
|
||||||
|
ruleDetail = rule.RuleType().String()
|
||||||
|
}
|
||||||
|
|
||||||
switch true {
|
switch true {
|
||||||
case rule != nil:
|
case rule != nil:
|
||||||
log.Infoln("[UDP] %s(%s) --> %s match %s(%s) using %s", metadata.SourceAddress(), metadata.Process, metadata.RemoteAddress(), rule.RuleType().String(), rule.Payload(), rawPc.Chains().String())
|
log.Infoln("[UDP] %s --> %s match %s using %s", metadata.SourceDetail(), metadata.RemoteAddress(), ruleDetail, rawPc.Chains().String())
|
||||||
case mode == Script:
|
case mode == Script:
|
||||||
log.Infoln("[UDP] %s --> %s using SCRIPT %s", metadata.SourceAddress(), metadata.RemoteAddress(), rawPc.Chains().String())
|
log.Infoln("[UDP] %s --> %s using SCRIPT %s", metadata.SourceDetail(), metadata.RemoteAddress(), rawPc.Chains().String())
|
||||||
case mode == Global:
|
case mode == Global:
|
||||||
log.Infoln("[UDP] %s(%s) --> %s using GLOBAL", metadata.SourceAddress(), metadata.Process, metadata.RemoteAddress())
|
log.Infoln("[UDP] %s --> %s using GLOBAL", metadata.SourceDetail(), metadata.RemoteAddress())
|
||||||
case mode == Direct:
|
case mode == Direct:
|
||||||
log.Infoln("[UDP] %s(%s) --> %s using DIRECT", metadata.SourceAddress(), metadata.Process, metadata.RemoteAddress())
|
log.Infoln("[UDP] %s --> %s using DIRECT", metadata.SourceDetail(), metadata.RemoteAddress())
|
||||||
default:
|
default:
|
||||||
log.Infoln("[UDP] %s(%s) --> %s doesn't match any rule using DIRECT", metadata.SourceAddress(), metadata.Process, metadata.RemoteAddress())
|
log.Infoln("[UDP] %s --> %s doesn't match any rule using DIRECT", metadata.SourceDetail(), metadata.RemoteAddress())
|
||||||
}
|
}
|
||||||
|
|
||||||
go handleUDPToLocal(packet.UDPPacket, pc, key, fAddr)
|
go handleUDPToLocal(packet.UDPPacket, pc, key, fAddr)
|
||||||
|
@ -296,17 +303,25 @@ func handleTCPConn(connCtx C.ConnContext) {
|
||||||
remoteConn = statistic.NewTCPTracker(remoteConn, statistic.DefaultManager, metadata, rule)
|
remoteConn = statistic.NewTCPTracker(remoteConn, statistic.DefaultManager, metadata, rule)
|
||||||
defer remoteConn.Close()
|
defer remoteConn.Close()
|
||||||
|
|
||||||
|
var ruleDetail string
|
||||||
|
|
||||||
|
if rule.Payload() != "" {
|
||||||
|
ruleDetail = fmt.Sprintf("%s(%s)", rule.RuleType().String(), rule.Payload())
|
||||||
|
} else {
|
||||||
|
ruleDetail = rule.RuleType().String()
|
||||||
|
}
|
||||||
|
|
||||||
switch true {
|
switch true {
|
||||||
case rule != nil:
|
case rule != nil:
|
||||||
log.Infoln("[TCP] %s(%s) --> %s match %s(%s) using %s", metadata.SourceAddress(), metadata.Process, metadata.RemoteAddress(), rule.RuleType().String(), rule.Payload(), remoteConn.Chains().String())
|
log.Infoln("[TCP] %s --> %s match %s using %s", metadata.SourceDetail(), metadata.RemoteAddress(), ruleDetail, remoteConn.Chains().String())
|
||||||
case mode == Script:
|
case mode == Script:
|
||||||
log.Infoln("[TCP] %s(%s) --> %s using SCRIPT %s", metadata.SourceAddress(), metadata.Process, metadata.RemoteAddress(), remoteConn.Chains().String())
|
log.Infoln("[TCP] %s --> %s using SCRIPT %s", metadata.SourceDetail(), metadata.RemoteAddress(), remoteConn.Chains().String())
|
||||||
case mode == Global:
|
case mode == Global:
|
||||||
log.Infoln("[TCP] %s(%s) --> %s using GLOBAL", metadata.SourceAddress(), metadata.Process, metadata.RemoteAddress())
|
log.Infoln("[TCP] %s --> %s using GLOBAL", metadata.SourceDetail(), metadata.RemoteAddress())
|
||||||
case mode == Direct:
|
case mode == Direct:
|
||||||
log.Infoln("[TCP] %s(%s) --> %s using DIRECT", metadata.SourceAddress(), metadata.Process, metadata.RemoteAddress())
|
log.Infoln("[TCP] %s --> %s using DIRECT", metadata.SourceDetail(), metadata.RemoteAddress())
|
||||||
default:
|
default:
|
||||||
log.Infoln("[TCP] %s(%s) --> %s doesn't match any rule using DIRECT", metadata.SourceAddress(), metadata.Process, metadata.RemoteAddress())
|
log.Infoln("[TCP] %s --> %s doesn't match any rule using DIRECT", metadata.SourceAddress(), metadata.RemoteAddress())
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSocket(connCtx, remoteConn)
|
handleSocket(connCtx, remoteConn)
|
||||||
|
|
Loading…
Reference in a new issue