├── .github └── workflows │ └── go.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── cmd └── kone │ ├── main.go │ └── test.ini ├── config.go ├── config_test.go ├── dns.go ├── dns_ip_pool.go ├── dns_table.go ├── filters.go ├── geoip ├── geoip.go ├── geoip_test.go └── query.go ├── go.mod ├── go.sum ├── manager.go ├── misc ├── docker │ ├── Dockerfile │ └── docker-compose.yml ├── docs │ ├── fanqiang.list │ ├── gotunnel-kone-work-together.md │ ├── how-to-use-with-raspberry-pi.md │ ├── kone-in-ent-network.md │ └── squid.conf ├── images │ ├── kone.png │ └── kone_webui.png └── windows │ ├── README.md │ ├── check-firewall-rules.ps1 │ └── update-firewall-rules.ps1 ├── nat.go ├── nat_test.go ├── one.go ├── pattern.go ├── pattern_test.go ├── proxies.go ├── proxy ├── README.md ├── direct.go ├── http.go ├── https.go ├── proxy.go └── socks5.go ├── rule.go ├── syscalls_darwin.go ├── syscalls_linux.go ├── syscalls_other.go ├── syscalls_windows.go ├── tcp_relay.go ├── tcpip ├── checksum.go ├── checksum_test.go ├── common.go ├── icmp.go ├── ipv4.go ├── tcp.go └── udp.go ├── tun.go └── udp_relay.go /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a golang project 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go 3 | 4 | name: Go 5 | 6 | on: 7 | push: 8 | branches: [ "master" ] 9 | pull_request: 10 | branches: [ "master" ] 11 | 12 | jobs: 13 | 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | - name: Set up Go 20 | uses: actions/setup-go@v4 21 | with: 22 | go-version: '1.20' 23 | 24 | - name: Build 25 | run: go build -v ./cmd/kone 26 | 27 | - name: Test 28 | run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./... 29 | 30 | - name: Upload coverage reports to Codecov 31 | uses: codecov/codecov-action@v3 32 | env: 33 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .env 3 | .idea 4 | v2raya 5 | /kone 6 | /my.ini 7 | /kone.exe 8 | /coverage.txt 9 | cmd/kone/local.ini 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 2023/12/26 2 | - [x] feat: upgrade to surge like config 3 | - [x] feat: support windows 10 4 | - [x] tech: merge proxy code 5 | - [x] feat: reload rule by manager: curl http://127.0.0.1:9200/reload 6 | - [x] tech: use system dns config as default 7 | 8 | # plan 9 | - [ ] feat: default hijack dns query 10 | - [ ] feat: show process name of network 11 | - [ ] bug: traffic will be endless loop if proxy's ip use proxy by rule 12 | - [ ] feat: support ss protocol 13 | - [ ] feat: support IPv6 14 | - [ ] feat: update GEOIP database 15 | - [ ] feat: record all dns query 16 | - [ ] feat: support for internal domain name resolution 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 xjdrew 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![github workflow](https://github.com/xjdrew/kone/actions/workflows/go.yml/badge.svg) 3 | [![codecov](https://codecov.io/gh/xjdrew/kone/graph/badge.svg?token=cGQLHTtaVc)](https://codecov.io/gh/xjdrew/kone) 4 | # KONE 5 | The project aims to improve the experience of accessing internet in home/enterprise network. 6 | 7 | The name "KONE" comes from [k1](https://en.wikipedia.org/wiki/Larcum_Kendall#K1), a chronometer made by Larcum Kendall and played a important role in Captain Cook's voyage. 8 | 9 | By now, it supports: 10 | 11 | * linux 12 | * macosx 13 | * windows (10 and above) (refer to [use kone in windows](./misc/windows/README.md) for more information) 14 | 15 | ## Use 16 | 17 | ```bash 18 | go build ./cmd/kone 19 | sudo ./kone -debug -config cmd/kone/test.ini 20 | ``` 21 | For more information, please read [test.ini](./cmd/kone/test.ini). 22 | 23 | ## Web Status 24 | The default web status port is 9200 , just visit http://localhost:9200/ to check the kone status. 25 | 26 | 27 | 28 | ## Documents 29 | * [how to use with Raspberry Pi](./misc/docs/how-to-use-with-raspberry-pi.md) 30 | * [how to use kone in an ENT network](./misc/docs/kone-in-ent-network.md) 31 | * [how to make gotunnel & kone work together](./misc/docs/gotunnel-kone-work-together.md) 32 | 33 | ## License 34 | The MIT License (MIT) Copyright (c) 2016 xjdrew 35 | -------------------------------------------------------------------------------- /cmd/kone/main.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-02-18 3 | // author: xjdrew 4 | // 5 | 6 | package main 7 | 8 | import ( 9 | "flag" 10 | "fmt" 11 | "os" 12 | 13 | "github.com/op/go-logging" 14 | "github.com/xjdrew/kone" 15 | ) 16 | 17 | var VERSION = "0.3-dev" 18 | 19 | var logger = logging.MustGetLogger("kone") 20 | 21 | func init() { 22 | logging.SetFormatter(logging.MustStringFormatter( 23 | `%{color}%{time:06-01-02 15:04:05.000} %{level:.4s} @%{shortfile}%{color:reset} %{message}`, 24 | )) 25 | logging.SetBackend(logging.NewLogBackend(os.Stdout, "", 0)) 26 | } 27 | 28 | func main() { 29 | version := flag.Bool("version", false, "Get version info") 30 | debug := flag.Bool("debug", false, "Print debug info") 31 | config := flag.String("config", "config.ini", "config file") 32 | flag.Parse() 33 | 34 | if *version { 35 | fmt.Printf("Version: %s\n", VERSION) 36 | os.Exit(1) 37 | } 38 | 39 | if *debug { 40 | logging.SetLevel(logging.DEBUG, "kone") 41 | } else { 42 | logging.SetLevel(logging.INFO, "kone") 43 | } 44 | 45 | configFile := *config 46 | if configFile == "" { 47 | configFile = flag.Arg(0) 48 | } 49 | logger.Infof("using config file: %v", configFile) 50 | 51 | cfg, err := kone.ParseConfig(configFile) 52 | if err != nil { 53 | logger.Error(err.Error()) 54 | os.Exit(2) 55 | } 56 | 57 | one, err := kone.FromConfig(cfg) 58 | if err != nil { 59 | logger.Error(err.Error()) 60 | os.Exit(3) 61 | } 62 | one.Serve() 63 | } 64 | -------------------------------------------------------------------------------- /cmd/kone/test.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | # manager port 3 | manager-addr = "0.0.0.0:9200" 4 | 5 | # log level 6 | # log-level = 'verbose, info, notify, or warning' 7 | 8 | # nat config 9 | [Core] 10 | # outbound network interface 11 | # out = eth0 12 | 13 | # virtual network 14 | 15 | # tun name, auto allocate if not set 16 | # DEFAULT VALUE: "" 17 | # tun = tun0 18 | 19 | # inet addr/mask 20 | # DEFAULT VALUE: 10.192.0.1/16 21 | network = 10.192.0.1/16 22 | 23 | # tcp-listen-port = 82 24 | # tcp-nat-port-start = 10000 25 | # tcp-nat-port-end = 60000 26 | 27 | # udp-listen-port = 82 28 | # udp-nat-port-start = 10000 29 | # udp-nat-port-end = 60000 30 | 31 | # dns-listen-port = 53 32 | 33 | # dns-ttl = 600 34 | # dns-packet-size = 4096 35 | # dns-read-timeout = 5 36 | # dns-write-timeout = 5 37 | 38 | # set upstream dns 39 | # DEFAULT VALUE: system dns config 40 | # dns-server = 114.114.114.114,8.8.8.8 41 | 42 | [Proxy] 43 | # define a http proxy named "Proxy1" 44 | Proxy1 = http://example.com:23188 45 | 46 | # define a socks5 proxy named "Proxy2" 47 | Proxy2 = socks5://127.0.0.1:9080 48 | 49 | [Rule] 50 | # ALL domain's default rule is FINAL 51 | # ALL IP's default proxy is DIRECT 52 | 53 | # some applications use ip directly. To proxy these traffic, explicit routing rules need to be added. 54 | # eg: sudo ip route add 91.108.4.0/22 dev tun0 55 | IP-CIDR,91.108.4.0/22,Proxy1 56 | IP-CIDR,91.108.56.0/22,Proxy1 57 | IP-CIDR,109.239.140.0/24,Proxy1 58 | IP-CIDR,149.154.167.0/24,Proxy1 59 | IP-CIDR,172.16.0.0/16,DIRECT # ignore 60 | IP-CIDR,192.168.0.0/16,DIRECT # ignore 61 | IP-CIDR,208.31.254.33/32,Proxy1 62 | 63 | IP-CIDR,172.64.150.242/16,Proxy1 64 | IP-CIDR,104.18.37.14/16,Proxy1 65 | 66 | IP-CIDR6,2001:db8:abcd:8000::/50,DIRECT 67 | 68 | # match if the domain 69 | DOMAIN,www.twitter.com,Proxy1 70 | DOMAIN-SUFFIX,twitter.com,Proxy1 71 | DOMAIN-SUFFIX,telegram.org,Proxy1 72 | DOMAIN-KEYWORD,google,Proxy1 73 | DOMAIN-KEYWORD,taobao,DIRECT 74 | DOMAIN-KEYWORD,localhost,DIRECT 75 | DOMAIN-KEYWORD,baidu,REJECT 76 | 77 | # match if the GeoIP test result matches a specified country code 78 | # GEOIP,US,DIRECT 79 | 80 | # define default policy for requests which are not matched by any other rules 81 | FINAL,DIRECT 82 | -------------------------------------------------------------------------------- /config.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2023-12-12 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "os" 10 | "strings" 11 | "unicode" 12 | 13 | "github.com/xjdrew/dnsconfig" 14 | "gopkg.in/ini.v1" 15 | ) 16 | 17 | func init() { 18 | ini.PrettyFormat = true 19 | } 20 | 21 | const ( 22 | HTTP_PROXY = "http_proxy" 23 | HTTPS_PROXY = "https_proxy" 24 | SOCKS_PROXY = "socks_proxy" 25 | ) 26 | 27 | type GeneralConfig struct { 28 | ManagerAddr string `ini:"manager-addr"` 29 | LogLevel string `ini:"log-level"` 30 | } 31 | 32 | type CoreConfig struct { 33 | Tun string `ini:"tun"` // tun name 34 | Network string `ini:"network"` // tun network 35 | TcpListenPort uint16 `ini:"tcp-listen-port"` 36 | TcpNatPortStart uint16 `ini:"tcp-nat-port-start"` 37 | TcpNatPortEnd uint16 `ini:"tcp-nat-port-end"` 38 | UdpListenPort uint16 `ini:"udp-listen-port"` 39 | UdpNatPortStart uint16 `ini:"udp-nat-port-start"` 40 | UdpNatPortEnd uint16 `ini:"udp-nat-port-end"` 41 | DnsListenPort uint16 `ini:"dns-listen-port"` 42 | DnsTtl uint `ini:"dns-ttl"` 43 | DnsPacketSize uint16 `ini:"dns-packet-size"` 44 | DnsReadTimeout uint `ini:"dns-read-timeout"` 45 | DnsWriteTimeout uint `ini:"dns-write-timeout"` 46 | DnsServer []string `ini:"dns-server" delim:","` 47 | } 48 | 49 | type RuleConfig struct { 50 | Schema string 51 | Pattern string 52 | Proxy string 53 | } 54 | 55 | type KoneConfig struct { 56 | source interface{} // config source: file name or raw ini data 57 | inif *ini.File // parsed ini file 58 | 59 | General GeneralConfig 60 | Core CoreConfig 61 | Proxy map[string]string 62 | Rule []RuleConfig 63 | } 64 | 65 | func (cfg *KoneConfig) parseRule(sec *ini.Section) (err error) { 66 | keys := sec.KeyStrings() 67 | 68 | var ops []string 69 | for _, key := range keys { 70 | ops = strings.FieldsFunc(key, func(c rune) bool { 71 | if c == ',' || unicode.IsSpace(c) { 72 | return true 73 | } 74 | return false 75 | }) 76 | logger.Debugf("%s %v", key, ops) 77 | if len(ops) == 3 { // ignore invalid format 78 | cfg.Rule = append(cfg.Rule, RuleConfig{ 79 | Schema: ops[0], 80 | Pattern: ops[1], 81 | Proxy: ops[2], 82 | }) 83 | } 84 | } 85 | if len(ops) == 2 { //final rule 86 | cfg.Rule = append(cfg.Rule, RuleConfig{ 87 | Schema: ops[0], 88 | Proxy: ops[1], 89 | }) 90 | } 91 | return nil 92 | } 93 | 94 | func (cfg *KoneConfig) check() (err error) { 95 | return nil 96 | } 97 | 98 | func (cfg *KoneConfig) GetSystemDnsservers() (servers []string) { 99 | config := dnsconfig.ReadDnsConfig() 100 | if config.Err != nil { 101 | logger.Warningf("read dns config failed: %v", config.Err) 102 | return []string{"114.114.114.114", "8.8.8.8"} // default 103 | } 104 | return config.Servers 105 | } 106 | 107 | func ParseConfig(source interface{}) (*KoneConfig, error) { 108 | cfg := new(KoneConfig) 109 | cfg.source = source 110 | 111 | // set default value 112 | cfg.Core.Network = "10.192.0.1/16" 113 | cfg.Core.TcpListenPort = 82 114 | cfg.Core.TcpNatPortStart = 10000 115 | cfg.Core.TcpNatPortEnd = 60000 116 | 117 | cfg.Core.UdpListenPort = 82 118 | cfg.Core.UdpNatPortStart = 10000 119 | cfg.Core.UdpNatPortEnd = 60000 120 | 121 | cfg.Core.DnsListenPort = DnsDefaultPort 122 | cfg.Core.DnsTtl = DnsDefaultTtl 123 | cfg.Core.DnsPacketSize = DnsDefaultPacketSize 124 | cfg.Core.DnsReadTimeout = DnsDefaultReadTimeout 125 | cfg.Core.DnsWriteTimeout = DnsDefaultWriteTimeout 126 | 127 | // decode config value 128 | f, err := ini.LoadSources(ini.LoadOptions{AllowBooleanKeys: true, KeyValueDelimiters: "="}, source) 129 | if err != nil { 130 | logger.Errorf("%v", err) 131 | return nil, err 132 | } 133 | cfg.inif = f 134 | 135 | err = f.MapTo(cfg) 136 | if err != nil { 137 | return nil, err 138 | } 139 | 140 | // init proxy 141 | if proxySection, err := f.GetSection("Proxy"); err == nil { 142 | cfg.Proxy = proxySection.KeysHash() 143 | } 144 | 145 | // read proxy from env 146 | if os.Getenv(HTTP_PROXY) != "" { 147 | cfg.Proxy[HTTP_PROXY] = os.Getenv(HTTP_PROXY) 148 | logger.Debugf("[env]set proxy %s=%s", HTTP_PROXY, cfg.Proxy[HTTP_PROXY]) 149 | } 150 | 151 | if os.Getenv(HTTPS_PROXY) != "" { 152 | cfg.Proxy[HTTPS_PROXY] = os.Getenv(HTTPS_PROXY) 153 | logger.Debugf("[env]set proxy %s=%s", HTTPS_PROXY, cfg.Proxy[HTTPS_PROXY]) 154 | } 155 | 156 | if os.Getenv(SOCKS_PROXY) != "" { 157 | cfg.Proxy[SOCKS_PROXY] = os.Getenv(SOCKS_PROXY) 158 | logger.Debugf("[env]set proxy %s=%s", SOCKS_PROXY, cfg.Proxy[SOCKS_PROXY]) 159 | } 160 | 161 | // set backend dns default value 162 | if len(cfg.Core.DnsServer) == 0 { 163 | cfg.Core.DnsServer = cfg.GetSystemDnsservers() 164 | } 165 | 166 | // init rule 167 | if err := cfg.parseRule(f.Section("Rule")); err != nil { 168 | return nil, err 169 | } 170 | 171 | err = cfg.check() 172 | if err != nil { 173 | return nil, err 174 | } 175 | 176 | return cfg, nil 177 | } 178 | -------------------------------------------------------------------------------- /config_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2023-12-13 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "testing" 10 | 11 | "github.com/stretchr/testify/assert" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | const ( 16 | confData = ` 17 | [General] 18 | manager-addr = "0.0.0.0:9200" 19 | 20 | [Core] 21 | network = 10.192.0.1/16 22 | 23 | tcp-listen-port = 82 24 | tcp-nat-port-start = 10000 25 | tcp-nat-port-end = 60000 26 | 27 | udp-listen-port = 82 28 | udp-nat-port-start = 10000 29 | udp-nat-port-end = 60000 30 | 31 | dns-listen-port = 53 32 | dns-ttl = 600 33 | dns-packet-size = 4096 34 | dns-read-timeout = 5 35 | dns-write-timeout = 5 36 | dns-server = 1.1.1.1,8.8.8.8 37 | 38 | [Proxy] 39 | # define a http proxy named "Proxy1" 40 | Proxy1 = http://proxy.example.com:8080 41 | 42 | # define a socks5 proxy named "Proxy2" 43 | Proxy2 = socks5://127.0.0.1:9080 44 | 45 | [Rule] 46 | IP-CIDR, 91.108.4.0/22, Proxy1 # rule 0 47 | IP-CIDR,91.108.56.0/22,Proxy1 # rule 1 48 | IP-CIDR,109.239.140.0/24,Proxy1 49 | IP-CIDR,149.154.167.0/24,Proxy1 50 | IP-CIDR,172.16.0.0/16,DIRECT 51 | IP-CIDR,192.168.0.0/16,DIRECT 52 | 53 | IP-CIDR6,2001:db8:abcd:8000::/50,DIRECT 54 | 55 | # match if the domain 56 | DOMAIN, www.twitter.com, Proxy1 57 | DOMAIN-SUFFIX,twitter.com,Proxy1 58 | DOMAIN-SUFFIX,telegram.org,Proxy1 59 | DOMAIN-KEYWORD,google,Proxy1 60 | DOMAIN-KEYWORD,localhost,DIRECT 61 | DOMAIN-KEYWORD,baidu,REJECT 62 | 63 | # match if the GeoIP test result matches a specified country code 64 | GEOIP,US,DIRECT # rule 13 65 | 66 | # define default policy for requests which are not matched by any other rules 67 | FINAL,DIRECT # rule 14 68 | ` 69 | ) 70 | 71 | func TestParseConfig(t *testing.T) { 72 | cfg, err := ParseConfig([]byte(confData)) 73 | 74 | require.NoError(t, err) 75 | require.NotNil(t, cfg) 76 | 77 | assert.Equal(t, "0.0.0.0:9200", cfg.General.ManagerAddr) 78 | 79 | assert.Equal(t, "10.192.0.1/16", cfg.Core.Network) 80 | 81 | assert.Equal(t, uint16(82), cfg.Core.TcpListenPort) 82 | assert.Equal(t, uint16(10000), cfg.Core.TcpNatPortStart) 83 | assert.Equal(t, uint16(60000), cfg.Core.TcpNatPortEnd) 84 | 85 | assert.Equal(t, uint16(82), cfg.Core.UdpListenPort) 86 | assert.Equal(t, uint16(10000), cfg.Core.UdpNatPortStart) 87 | assert.Equal(t, uint16(60000), cfg.Core.UdpNatPortEnd) 88 | 89 | assert.Equal(t, uint16(53), cfg.Core.DnsListenPort) 90 | assert.Equal(t, uint(600), cfg.Core.DnsTtl) 91 | assert.Equal(t, uint16(4096), cfg.Core.DnsPacketSize) 92 | assert.Equal(t, uint(5), cfg.Core.DnsReadTimeout) 93 | assert.Equal(t, uint(5), cfg.Core.DnsWriteTimeout) 94 | assert.Equal(t, []string{"1.1.1.1", "8.8.8.8"}, cfg.Core.DnsServer) 95 | 96 | assert.Equal(t, "http://proxy.example.com:8080", cfg.Proxy["Proxy1"]) 97 | assert.Equal(t, "socks5://127.0.0.1:9080", cfg.Proxy["Proxy2"]) 98 | 99 | assert.Len(t, cfg.Rule, 15) 100 | assert.Equal(t, cfg.Rule[0].Schema, "IP-CIDR") 101 | assert.Equal(t, cfg.Rule[0].Pattern, "91.108.4.0/22") 102 | assert.Equal(t, cfg.Rule[0].Proxy, "Proxy1") 103 | 104 | assert.Equal(t, cfg.Rule[1].Schema, "IP-CIDR") 105 | assert.Equal(t, cfg.Rule[1].Pattern, "91.108.56.0/22") 106 | assert.Equal(t, cfg.Rule[1].Proxy, "Proxy1") 107 | 108 | assert.Equal(t, cfg.Rule[14].Schema, "FINAL") 109 | assert.Equal(t, cfg.Rule[14].Pattern, "") 110 | assert.Equal(t, cfg.Rule[14].Proxy, "DIRECT") 111 | } 112 | -------------------------------------------------------------------------------- /dns.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "errors" 10 | "fmt" 11 | "strings" 12 | "sync" 13 | "time" 14 | 15 | "github.com/miekg/dns" 16 | "github.com/miekg/dns/dnsutil" 17 | ) 18 | 19 | const ( 20 | DnsDefaultPort = 53 21 | DnsDefaultTtl = 600 22 | DnsDefaultPacketSize = 4096 23 | DnsDefaultReadTimeout = 5 24 | DnsDefaultWriteTimeout = 5 25 | ) 26 | 27 | var ErrResolve = errors.New("resolve timeout") 28 | 29 | type Dns struct { 30 | one *One 31 | server *dns.Server 32 | client *dns.Client 33 | nameservers []string 34 | } 35 | 36 | // query synchronously 37 | func (d *Dns) Resolve(domain string) (*dns.Msg, error) { 38 | r := new(dns.Msg) 39 | r.SetQuestion(dns.Fqdn(domain), dns.TypeA) 40 | 41 | return d.resolve(r) 42 | } 43 | 44 | func (d *Dns) resolve(r *dns.Msg) (*dns.Msg, error) { 45 | var wg sync.WaitGroup 46 | msgCh := make(chan *dns.Msg, 1) 47 | 48 | qname := r.Question[0].Name 49 | 50 | Q := func(ns string) { 51 | defer wg.Done() 52 | 53 | r, rtt, err := d.client.Exchange(r, ns) 54 | if err != nil { 55 | logger.Debugf("[dns] resolve %s on %s failed: %v", qname, ns, err) 56 | return 57 | } 58 | 59 | // remove this code 60 | if r.Rcode != dns.RcodeSuccess { 61 | logger.Debugf("[dns] resolve %s on %s failed: code %d", qname, ns, r.Rcode) 62 | return 63 | } 64 | 65 | logger.Debugf("[dns] resolve %s on %s, code: %d, rtt: %d", qname, ns, r.Rcode, rtt) 66 | 67 | select { 68 | case msgCh <- r: 69 | default: 70 | } 71 | } 72 | 73 | ticker := time.NewTicker(100 * time.Millisecond) 74 | defer ticker.Stop() 75 | 76 | for _, ns := range d.nameservers { 77 | wg.Add(1) 78 | go Q(ns) 79 | 80 | select { 81 | case r := <-msgCh: 82 | return r, nil 83 | case <-ticker.C: 84 | continue 85 | } 86 | } 87 | 88 | wg.Wait() 89 | 90 | select { 91 | case r := <-msgCh: 92 | return r, nil 93 | default: 94 | logger.Errorf("[dns] query %s timeout", qname) 95 | return nil, ErrResolve 96 | } 97 | } 98 | 99 | func (d *Dns) doIPv4Query(r *dns.Msg) (*dns.Msg, error) { 100 | one := d.one 101 | 102 | domain := dnsutil.TrimDomainName(r.Question[0].Name, ".") 103 | // short circuit: non proxy 104 | if one.dnsTable.IsNonProxyDomain(domain) { 105 | return d.resolve(r) 106 | } 107 | 108 | // short circuit: proxy 109 | record := one.dnsTable.Get(domain) 110 | if record != nil { 111 | return record.Answer(r), nil 112 | } 113 | 114 | // match by domain 115 | proxy := one.rule.Proxy(domain) 116 | if proxy != "DIRECT" { 117 | record := one.dnsTable.Set(domain, proxy) 118 | return record.Answer(r), nil 119 | } 120 | 121 | // match by IP & CNAME 122 | msg, err := d.resolve(r) 123 | if err != nil || len(msg.Answer) == 0 { 124 | return msg, err 125 | } 126 | 127 | for _, item := range msg.Answer { 128 | switch answer := item.(type) { 129 | case *dns.A: 130 | // test ip 131 | proxy = one.rule.Proxy(answer.A) 132 | if proxy != "DIRECT" { 133 | break 134 | } 135 | case *dns.CNAME: 136 | // test cname 137 | proxy = one.rule.Proxy(answer.Target) 138 | if proxy != "DIRECT" { 139 | break 140 | } 141 | default: 142 | logger.Noticef("[dns] unexpected response %s -> %v", domain, item) 143 | } 144 | } 145 | 146 | // if IP or CNAME use proxy 147 | if proxy != "DIRECT" { 148 | record := one.dnsTable.Set(domain, proxy) 149 | record.SetRealIP(msg) 150 | return record.Answer(r), nil 151 | } else { 152 | // set domain as a non-proxy-domain 153 | one.dnsTable.SetNonProxyDomain(domain, msg.Answer[0].Header().Ttl) 154 | // final 155 | return msg, err 156 | } 157 | } 158 | 159 | func isIPv4Query(q dns.Question) bool { 160 | if q.Qclass == dns.ClassINET && q.Qtype == dns.TypeA { 161 | return true 162 | } 163 | return false 164 | } 165 | 166 | func (d *Dns) ServeDNS(w dns.ResponseWriter, r *dns.Msg) { 167 | isIPv4 := isIPv4Query(r.Question[0]) 168 | 169 | var msg *dns.Msg 170 | var err error 171 | 172 | if isIPv4 { 173 | msg, err = d.doIPv4Query(r) 174 | } else { 175 | msg, err = d.resolve(r) 176 | } 177 | 178 | if err != nil { 179 | dns.HandleFailed(w, r) 180 | } else { 181 | w.WriteMsg(msg) 182 | } 183 | } 184 | 185 | func (d *Dns) Serve() error { 186 | logger.Infof("[dns] listen on %s", d.server.Addr) 187 | return d.server.ListenAndServe() 188 | } 189 | 190 | func NewDns(one *One, cfg CoreConfig) (*Dns, error) { 191 | d := new(Dns) 192 | d.one = one 193 | 194 | dnsListenAddr := fmt.Sprintf("%s:%d", fixTunIP(one.ip), cfg.DnsListenPort) 195 | server := &dns.Server{ 196 | Net: "udp", 197 | Addr: dnsListenAddr, 198 | Handler: dns.HandlerFunc(d.ServeDNS), 199 | UDPSize: int(cfg.DnsPacketSize), 200 | ReadTimeout: time.Duration(cfg.DnsReadTimeout) * time.Second, 201 | WriteTimeout: time.Duration(cfg.DnsWriteTimeout) * time.Second, 202 | } 203 | 204 | client := &dns.Client{ 205 | Net: "udp", 206 | UDPSize: cfg.DnsPacketSize, 207 | ReadTimeout: time.Duration(cfg.DnsReadTimeout) * time.Second, 208 | WriteTimeout: time.Duration(cfg.DnsWriteTimeout) * time.Second, 209 | } 210 | 211 | d.server = server 212 | d.client = client 213 | 214 | for _, addr := range cfg.DnsServer { 215 | if !strings.Contains(addr, ":") { 216 | addr = addr + ":53" 217 | } 218 | 219 | if addr != dnsListenAddr { // don't add self 220 | d.nameservers = append(d.nameservers, addr) 221 | } 222 | } 223 | logger.Infof("[dns] updstream dns server: %v", d.nameservers) 224 | return d, nil 225 | } 226 | -------------------------------------------------------------------------------- /dns_ip_pool.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-09-24 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "hash/adler32" 10 | "net" 11 | 12 | "github.com/xjdrew/kone/tcpip" 13 | ) 14 | 15 | const DnsIPPoolMaxSpace = 0x3ffff // 4*65535 16 | 17 | type DnsIPPool struct { 18 | base uint32 19 | space uint32 20 | flags []bool 21 | } 22 | 23 | func (pool *DnsIPPool) Capacity() int { 24 | return int(pool.space) 25 | } 26 | 27 | func (pool *DnsIPPool) Contains(ip net.IP) bool { 28 | index := tcpip.ConvertIPv4ToUint32(ip) - pool.base 29 | return index < pool.space 30 | } 31 | 32 | func (pool *DnsIPPool) Release(ip net.IP) { 33 | index := tcpip.ConvertIPv4ToUint32(ip) - pool.base 34 | if index < pool.space { 35 | pool.flags[index] = false 36 | } 37 | } 38 | 39 | // use tips as a hint to find a stable index 40 | func (pool *DnsIPPool) Alloc(tips string) net.IP { 41 | index := adler32.Checksum([]byte(tips)) % pool.space 42 | if pool.flags[index] { 43 | logger.Debugf("[dns] %s is not in main index: %d", tips, index) 44 | for i, used := range pool.flags { 45 | if !used { 46 | index = uint32(i) 47 | break 48 | } 49 | } 50 | } 51 | 52 | if pool.flags[index] { 53 | return nil 54 | } 55 | pool.flags[index] = true 56 | return tcpip.ConvertUint32ToIPv4(pool.base + index) 57 | } 58 | 59 | func NewDnsIPPool(ip net.IP, subnet *net.IPNet) *DnsIPPool { 60 | base := tcpip.ConvertIPv4ToUint32(subnet.IP) + 1 61 | max := base + ^tcpip.ConvertIPv4ToUint32(net.IP(subnet.Mask)) 62 | 63 | // space should not over 0x3ffff 64 | space := max - base 65 | if space > DnsIPPoolMaxSpace { 66 | space = DnsIPPoolMaxSpace 67 | } 68 | flags := make([]bool, space) 69 | 70 | // ip is used by tun 71 | index := tcpip.ConvertIPv4ToUint32(ip) - base 72 | if index < space { 73 | flags[index] = true 74 | } 75 | 76 | return &DnsIPPool{ 77 | base: base, 78 | space: space, 79 | flags: flags, 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /dns_table.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "fmt" 10 | "net" 11 | "sync" 12 | "time" 13 | 14 | "github.com/miekg/dns" 15 | ) 16 | 17 | // hijacked domain 18 | type DomainRecord struct { 19 | Hostname string // hostname 20 | Proxy string // proxy 21 | 22 | IP net.IP // nat ip 23 | RealIP net.IP // real ip 24 | Hits int 25 | Expires time.Time 26 | 27 | answer *dns.A // cache dns answer 28 | } 29 | 30 | func (record *DomainRecord) SetRealIP(msg *dns.Msg) { 31 | if record.RealIP != nil { 32 | return 33 | } 34 | 35 | for _, item := range msg.Answer { 36 | switch answer := item.(type) { 37 | case *dns.A: 38 | record.RealIP = answer.A 39 | logger.Debugf("[dns] %s real ip: %s", record.Hostname, answer.A) 40 | return 41 | } 42 | } 43 | } 44 | 45 | func (record *DomainRecord) Answer(request *dns.Msg) *dns.Msg { 46 | rsp := new(dns.Msg) 47 | rsp.SetReply(request) 48 | rsp.RecursionAvailable = true 49 | rsp.Answer = append(rsp.Answer, record.answer) 50 | return rsp 51 | } 52 | 53 | func (record *DomainRecord) Touch() { 54 | record.Hits++ 55 | record.Expires = time.Now().Add(DnsDefaultTtl * time.Second) 56 | } 57 | 58 | type DnsTable struct { 59 | ipNet *net.IPNet // local network 60 | ipPool *DnsIPPool // dns ip pool 61 | 62 | // hijacked domain records 63 | records map[string]*DomainRecord // domain -> record 64 | ip2Domain map[string]string // ip -> domain: map hijacked ip address to domain 65 | recordsLock sync.Mutex // protect records and ip2Domain 66 | 67 | nonProxyDomains map[string]time.Time // non proxy domain 68 | npdLock sync.Mutex // protect non proxy domain 69 | } 70 | 71 | func (c *DnsTable) IsLocalIP(ip net.IP) bool { 72 | return c.ipNet.Contains(ip) 73 | } 74 | 75 | func (c *DnsTable) get(domain string) *DomainRecord { 76 | record := c.records[domain] 77 | if record != nil { 78 | record.Touch() 79 | } 80 | return record 81 | } 82 | 83 | func (c *DnsTable) GetByIP(ip net.IP) *DomainRecord { 84 | c.recordsLock.Lock() 85 | defer c.recordsLock.Unlock() 86 | if domain, ok := c.ip2Domain[ip.String()]; ok { 87 | return c.get(domain) 88 | } 89 | return nil 90 | } 91 | 92 | func (c *DnsTable) Contains(ip net.IP) bool { 93 | return c.ipPool.Contains(ip) 94 | } 95 | 96 | func (c *DnsTable) Get(domain string) *DomainRecord { 97 | c.recordsLock.Lock() 98 | defer c.recordsLock.Unlock() 99 | return c.get(domain) 100 | } 101 | 102 | // forge a IPv4 dns reply 103 | func forgeIPv4Answer(domain string, ip net.IP) *dns.A { 104 | rr := new(dns.A) 105 | rr.Hdr = dns.RR_Header{Name: dns.Fqdn(domain), Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: DnsDefaultTtl} 106 | rr.A = ip.To4() 107 | return rr 108 | } 109 | 110 | func (c *DnsTable) Set(domain string, proxy string) *DomainRecord { 111 | c.recordsLock.Lock() 112 | defer c.recordsLock.Unlock() 113 | record := c.records[domain] 114 | if record != nil { 115 | record.Touch() 116 | return record 117 | } 118 | 119 | // alloc a ip 120 | ip := c.ipPool.Alloc(domain) 121 | if ip == nil { 122 | panic(fmt.Sprintf("[dns] ip space is used up, domain:%s", domain)) 123 | } 124 | 125 | record = new(DomainRecord) 126 | record.IP = ip 127 | record.Hostname = domain 128 | record.Proxy = proxy 129 | record.answer = forgeIPv4Answer(domain, ip) 130 | 131 | c.records[domain] = record 132 | c.ip2Domain[ip.String()] = domain 133 | logger.Debugf("[dns] hijack %s -> %s", domain, ip.String()) 134 | 135 | record.Touch() 136 | return record 137 | } 138 | 139 | func (c *DnsTable) IsNonProxyDomain(domain string) bool { 140 | c.npdLock.Lock() 141 | defer c.npdLock.Unlock() 142 | _, ok := c.nonProxyDomains[domain] 143 | return ok 144 | } 145 | 146 | func (c *DnsTable) SetNonProxyDomain(domain string, ttl uint32) { 147 | c.npdLock.Lock() 148 | defer c.npdLock.Unlock() 149 | c.nonProxyDomains[domain] = time.Now().Add(time.Duration(ttl) * time.Second) 150 | logger.Debugf("[dns] set non proxy domain: %s, ttl: %d", domain, ttl) 151 | } 152 | 153 | func (c *DnsTable) clearExpiredNonProxyDomain(now time.Time) { 154 | c.npdLock.Lock() 155 | defer c.npdLock.Unlock() 156 | for domain, expired := range c.nonProxyDomains { 157 | if expired.Before(now) { 158 | delete(c.nonProxyDomains, domain) 159 | logger.Debugf("[dns] release expired non proxy domain: %s", domain) 160 | } 161 | } 162 | } 163 | 164 | func (c *DnsTable) ClearNonProxyDomain() { 165 | c.npdLock.Lock() 166 | defer c.npdLock.Unlock() 167 | for domain := range c.nonProxyDomains { 168 | delete(c.nonProxyDomains, domain) 169 | logger.Debugf("[dns] release non proxy domain: %s", domain) 170 | 171 | } 172 | } 173 | 174 | func (c *DnsTable) clearExpiredDomain(now time.Time) { 175 | c.recordsLock.Lock() 176 | defer c.recordsLock.Unlock() 177 | 178 | threshold := 1000 179 | if threshold > c.ipPool.Capacity()/10 { 180 | threshold = c.ipPool.Capacity() / 10 181 | } 182 | 183 | if len(c.records) <= threshold { 184 | return 185 | } 186 | 187 | for domain, record := range c.records { 188 | if !record.Expires.Before(now) { 189 | continue 190 | } 191 | delete(c.records, domain) 192 | delete(c.ip2Domain, record.IP.String()) 193 | c.ipPool.Release(record.IP) 194 | logger.Debugf("[dns] release %s -> %s, hit: %d", domain, record.IP.String(), record.Hits) 195 | } 196 | } 197 | 198 | func (c *DnsTable) Serve() error { 199 | tick := time.NewTicker(60 * time.Second) 200 | for now := range tick.C { 201 | c.clearExpiredDomain(now) 202 | //TODO: is it necessary? 203 | c.clearExpiredNonProxyDomain(now) 204 | } 205 | return nil 206 | } 207 | 208 | func NewDnsTable(ip net.IP, subnet *net.IPNet) *DnsTable { 209 | c := new(DnsTable) 210 | c.ipNet = subnet 211 | c.ipPool = NewDnsIPPool(ip, subnet) 212 | c.records = make(map[string]*DomainRecord) 213 | c.ip2Domain = make(map[string]string) 214 | c.nonProxyDomains = make(map[string]time.Time) 215 | return c 216 | } 217 | -------------------------------------------------------------------------------- /filters.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "io" 10 | 11 | "github.com/xjdrew/kone/tcpip" 12 | ) 13 | 14 | type PacketFilter interface { 15 | Filter(wr io.Writer, p tcpip.IPv4Packet) 16 | } 17 | 18 | type PacketFilterFunc func(wr io.Writer, p tcpip.IPv4Packet) 19 | 20 | func (f PacketFilterFunc) Filter(wr io.Writer, p tcpip.IPv4Packet) { 21 | f(wr, p) 22 | } 23 | 24 | func icmpFilterFunc(wr io.Writer, ipPacket tcpip.IPv4Packet) { 25 | icmpPacket := tcpip.ICMPPacket(ipPacket.Payload()) 26 | if icmpPacket.Type() == tcpip.ICMPRequest && icmpPacket.Code() == 0 { 27 | logger.Debugf("[icmp filter] ping %s > %s", ipPacket.SourceIP(), ipPacket.DestinationIP()) 28 | // forge a reply 29 | icmpPacket.SetType(tcpip.ICMPEcho) 30 | srcIP := ipPacket.SourceIP() 31 | dstIP := ipPacket.DestinationIP() 32 | ipPacket.SetSourceIP(dstIP) 33 | ipPacket.SetDestinationIP(srcIP) 34 | 35 | icmpPacket.ResetChecksum() 36 | ipPacket.ResetChecksum() 37 | wr.Write(ipPacket) 38 | } else { 39 | logger.Debugf("icmp: %s -> %s", ipPacket.SourceIP(), ipPacket.DestinationIP()) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /geoip/geoip_test.go: -------------------------------------------------------------------------------- 1 | package geoip 2 | 3 | import ( 4 | "net" 5 | "testing" 6 | ) 7 | 8 | var cases = map[string]string{ 9 | "1.208.0.0": "KR", 10 | "114.114.114.114": "CN", 11 | "101.226.103.106": "CN", 12 | "14.17.32.211": "CN", 13 | "8.8.8.8": "US", 14 | "183.79.227.111": "JP", 15 | "255.255.255.255": "", 16 | "192.168.0.1": "", 17 | "224.0.0.1": "", 18 | } 19 | 20 | func TestQuery(t *testing.T) { 21 | for ip, country := range cases { 22 | result := QueryCountryByString(ip) 23 | if country != result { 24 | t.Errorf("failed on: %s:%s ! %s", ip, country, result) 25 | } 26 | } 27 | 28 | for v, country := range cases { 29 | ip := net.ParseIP(v) 30 | result := QueryCountryByIP(ip) 31 | if country != result { 32 | t.Errorf("failed on: %s:%s ! %s", ip, country, result) 33 | } 34 | } 35 | } 36 | 37 | func BenchmarkQuery(b *testing.B) { 38 | var i uint32 = 1 39 | for ; i < 1000000; i++ { 40 | QueryCountry(i) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /geoip/query.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package geoip 7 | 8 | import ( 9 | "net" 10 | "sort" 11 | ) 12 | 13 | var ( 14 | geoIPLen = len(geoIP) 15 | ) 16 | 17 | func QueryCountry(ip uint32) string { 18 | i := sort.Search(geoIPLen, func(i int) bool { 19 | n := geoIP[i] 20 | return n.End >= ip 21 | }) 22 | 23 | var country string 24 | if i < geoIPLen { 25 | n := geoIP[i] 26 | if n.Start <= ip { 27 | country = n.Name 28 | } 29 | } 30 | return country 31 | } 32 | 33 | func QueryCountryByIP(ip net.IP) string { 34 | ip = ip.To4() 35 | if ip == nil { 36 | return "" 37 | } 38 | 39 | v := uint32(ip[0]) << 24 40 | v += uint32(ip[1]) << 16 41 | v += uint32(ip[2]) << 8 42 | v += uint32(ip[3]) 43 | return QueryCountry(v) 44 | } 45 | 46 | func QueryCountryByString(v string) string { 47 | ip := net.ParseIP(v) 48 | if ip == nil { 49 | return "" 50 | } 51 | return QueryCountryByIP(ip) 52 | } 53 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/xjdrew/kone 2 | 3 | go 1.21.5 4 | 5 | require ( 6 | github.com/miekg/dns v1.1.57 7 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 8 | github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 9 | github.com/stretchr/testify v1.8.4 10 | github.com/thecodeteam/goodbye v0.0.0-20170927022442-a83968bda2d3 11 | gopkg.in/ini.v1 v1.67.0 12 | ) 13 | 14 | require ( 15 | github.com/davecgh/go-spew v1.1.1 // indirect 16 | github.com/pmezard/go-difflib v1.0.0 // indirect 17 | github.com/xjdrew/dnsconfig v0.0.0-20240104111907-3ab1a6f060b1 18 | golang.org/x/mod v0.14.0 // indirect 19 | golang.org/x/net v0.19.0 // indirect 20 | golang.org/x/sys v0.15.0 // indirect 21 | golang.org/x/tools v0.16.1 // indirect 22 | gopkg.in/yaml.v3 v3.0.1 // indirect 23 | ) 24 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= 4 | github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= 5 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= 6 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= 7 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 8 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 9 | github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8= 10 | github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E= 11 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= 12 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 13 | github.com/thecodeteam/goodbye v0.0.0-20170927022442-a83968bda2d3 h1:COy7ekr2jBEd34npP2LvMTqk9UtiLkuvkjiJFHihlTo= 14 | github.com/thecodeteam/goodbye v0.0.0-20170927022442-a83968bda2d3/go.mod h1:ehwM4AFY4byYSorQbigh79cKUOUNL3pAOz5eCAQNlGI= 15 | github.com/xjdrew/dnsconfig v0.0.0-20240104111907-3ab1a6f060b1 h1:8zrZIsWKgXLNQedGAPwaYK4OZ8EwWf/hWZhsvTD3MW4= 16 | github.com/xjdrew/dnsconfig v0.0.0-20240104111907-3ab1a6f060b1/go.mod h1:/6pBv59OGlUWZwToHJ7Aj5jBuWZJJArx0fRDpHoYJtI= 17 | golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= 18 | golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 19 | golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= 20 | golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= 21 | golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= 22 | golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 23 | golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= 24 | golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 25 | golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= 26 | golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= 27 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 28 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 29 | gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= 30 | gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 31 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 32 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 33 | -------------------------------------------------------------------------------- /manager.go: -------------------------------------------------------------------------------- 1 | package kone 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "html/template" 7 | "io" 8 | "net/http" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | const masterTmpl = ` 14 | {{define "header"}} 15 | 16 | 17 | 18 | {{.Title}} 19 | 20 | 56 | 57 | 58 | {{end}} 59 | 60 | {{define "footer"}} 61 | 62 | 63 | {{end}} 64 | 65 | {{define "index"}} 66 | {{template "header" .}} 67 |

List of URLs

68 | 73 |
74 |

Current State

75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 |
Total Hosts{{.TotalHosts}}
Total Websites{{.TotalWebistes}}
Total Proxies{{.TotalProxies}}
Total Traffic{{formatNumberComma .TotalTraffic}}
Upload Traffic{{formatNumberComma .UploadTraffic}}
Download Traffic{{formatNumberComma .DownloadTraffic}}
Uptime{{.Uptime}}
Now{{.Now.Format "2006-01-02 15:04:05.000"}}
85 | {{template "footer" .}} 86 | {{end}} 87 | 88 | {{define "traffic_record"}} 89 | {{template "header" .}} 90 |

{{.Title}}

91 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | {{range .Records}} 106 | 107 | 114 | 115 | 116 | 117 | 118 | 119 | {{end}} 120 |
NameTotalUploadDownloadLast
108 | {{if $.HasDetail}} 109 | {{.Name}} 110 | {{else}} 111 | {{.Name}} 112 | {{end}} 113 | {{sumInt64 .Upload .Download | formatNumberComma}}{{formatNumberComma .Upload}}{{formatNumberComma .Download}}{{.Touch.Format "2006-01-02 15:04:05.000"}}
121 | {{template "footer" .}} 122 | {{end}} 123 | 124 | {{define "traffic_record_detail"}} 125 | {{template "header" .}} 126 | {{with .Record}} 127 |

{{$.Title}}: {{.Name}}

128 | 135 | {{end}} 136 | {{with .Record.Details}} 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | {{range .}} 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | {{end}} 154 |
NameTotalUploadDownloadLast
{{.EndPoint}}{{sumInt64 .Upload .Download | formatNumberComma}}{{formatNumberComma .Upload}}{{formatNumberComma .Download}}{{.Touch.Format "2006-01-02 15:04:05.000"}}
155 | {{end}} 156 | {{template "footer" .}} 157 | {{end}} 158 | 159 | {{define "dns"}} 160 | {{template "header" .}} 161 |

Current State

162 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | {{range .Records}} 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | {{end}} 184 |
HostnameAddressProxyHitsExpires
{{.Hostname}}{{.IP}}{{.Proxy}}{{.Hits}}{{.Expires.Format "2006-01-02 15:04:05.000"}}{{if .Expires.Before $.Now}}[expired]{{end}}
185 | {{template "footer" .}} 186 | {{end}} 187 | 188 | 189 | {{define "config"}} 190 | {{template "header" .}} 191 |

Config

192 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 |
Source
{{.Source}}
203 | {{template "footer" .}} 204 | {{end}} 205 | ` 206 | 207 | // statistical data of every connection 208 | type ConnData struct { 209 | Src string 210 | Dst string 211 | Proxy string 212 | Upload int64 213 | Download int64 214 | } 215 | 216 | // statistical data of every host/website/proxy 217 | type TrafficRecordDetail struct { 218 | EndPoint string 219 | Upload int64 220 | Download int64 221 | Touch time.Time 222 | } 223 | 224 | type TrafficRecord struct { 225 | Name string 226 | Upload int64 227 | Download int64 228 | Touch time.Time 229 | Details map[string]*TrafficRecordDetail 230 | } 231 | 232 | type Manager struct { 233 | one *One 234 | cfg *KoneConfig 235 | startTime time.Time // process start time 236 | listen string 237 | tmpl *template.Template 238 | 239 | dataCh chan ConnData 240 | hosts map[string]*TrafficRecord 241 | websites map[string]*TrafficRecord 242 | proxies map[string]*TrafficRecord 243 | } 244 | 245 | func handleWrapper(f func(io.Writer, *http.Request) error) func(http.ResponseWriter, *http.Request) { 246 | return func(rw http.ResponseWriter, r *http.Request) { 247 | w := bytes.NewBuffer(nil) 248 | err := f(w, r) 249 | if err != nil { 250 | http.Error(rw, fmt.Sprintf("Internal server error: %s", err), http.StatusInternalServerError) 251 | } else { 252 | rw.Write(w.Bytes()) 253 | } 254 | } 255 | } 256 | 257 | func (m *Manager) indexHandle(w io.Writer, r *http.Request) error { 258 | var upload, download int64 259 | for _, v := range m.proxies { 260 | upload += v.Upload 261 | download += v.Download 262 | } 263 | return m.tmpl.ExecuteTemplate(w, "index", map[string]interface{}{ 264 | "Title": "kone", 265 | "Now": time.Now(), 266 | "Uptime": time.Since(m.startTime), 267 | "TotalHosts": len(m.hosts), 268 | "TotalWebistes": len(m.websites), 269 | "TotalProxies": len(m.proxies), 270 | "TotalTraffic": upload + download, 271 | "UploadTraffic": upload, 272 | "DownloadTraffic": download, 273 | "URLs": []string{ 274 | "/host/", 275 | "/website/", 276 | "/proxy/", 277 | "/dns/", 278 | "/reload/", 279 | "/config/", 280 | }, 281 | }) 282 | } 283 | 284 | func (m *Manager) hostHandle(w io.Writer, r *http.Request) error { 285 | name := strings.TrimPrefix(r.RequestURI, "/host/") 286 | record, ok := m.hosts[name] 287 | if ok { 288 | return m.tmpl.ExecuteTemplate(w, "traffic_record_detail", map[string]interface{}{ 289 | "Title": "Host Record Detail", 290 | "Record": record, 291 | }) 292 | } else { 293 | var upload, download int64 294 | for _, v := range m.hosts { 295 | upload += v.Upload 296 | download += v.Download 297 | } 298 | return m.tmpl.ExecuteTemplate(w, "traffic_record", map[string]interface{}{ 299 | "Title": "Host Record", 300 | "Upload": upload, 301 | "Download": download, 302 | "Records": m.hosts, 303 | "HasDetail": true, 304 | }) 305 | } 306 | } 307 | 308 | func (m *Manager) websiteHandle(w io.Writer, r *http.Request) error { 309 | name := strings.TrimPrefix(r.RequestURI, "/website/") 310 | record, ok := m.websites[name] 311 | if ok { 312 | return m.tmpl.ExecuteTemplate(w, "traffic_record_detail", map[string]interface{}{ 313 | "Title": "Website Record Detail", 314 | "Record": record, 315 | }) 316 | } else { 317 | var upload, download int64 318 | for _, v := range m.websites { 319 | upload += v.Upload 320 | download += v.Download 321 | } 322 | return m.tmpl.ExecuteTemplate(w, "traffic_record", map[string]interface{}{ 323 | "Title": "Website Record", 324 | "Upload": upload, 325 | "Download": download, 326 | "Records": m.websites, 327 | "HasDetail": true, 328 | }) 329 | } 330 | } 331 | 332 | func (m *Manager) proxyHandle(w io.Writer, r *http.Request) error { 333 | var upload, download int64 334 | for _, v := range m.proxies { 335 | upload += v.Upload 336 | download += v.Download 337 | } 338 | return m.tmpl.ExecuteTemplate(w, "traffic_record", map[string]interface{}{ 339 | "Title": "Proxy Data", 340 | "Upload": upload, 341 | "Download": download, 342 | "Records": m.proxies, 343 | }) 344 | } 345 | 346 | func (m *Manager) dnsHandle(w io.Writer, r *http.Request) error { 347 | records := m.one.dnsTable.records 348 | 349 | activeEntries, expiredEntires := 0, 0 350 | now := time.Now() 351 | for _, record := range records { 352 | if record.Expires.Before(now) { 353 | expiredEntires += 1 354 | } else { 355 | activeEntries += 1 356 | } 357 | } 358 | 359 | return m.tmpl.ExecuteTemplate(w, "dns", map[string]interface{}{ 360 | "Title": "dns cache", 361 | "DnsServer": strings.Join(m.one.dns.nameservers, ","), 362 | "ActiveEntries": activeEntries, 363 | "ExpiredEntries": expiredEntires, 364 | "Now": now, 365 | "Records": records, 366 | }) 367 | } 368 | 369 | func (m *Manager) reloadHandle(w io.Writer, r *http.Request) error { 370 | logger.Infof("[manager] reload config") 371 | newcfg, err := ParseConfig(m.cfg.source) 372 | if err != nil { 373 | return err 374 | } 375 | 376 | err = m.one.Reload(newcfg) 377 | if err != nil { 378 | return err 379 | } 380 | 381 | m.cfg = newcfg 382 | w.Write([]byte("reload succeed")) 383 | return nil 384 | } 385 | 386 | func (m *Manager) configHandle(w io.Writer, r *http.Request) error { 387 | b := bytes.NewBuffer([]byte{}) 388 | m.cfg.inif.WriteTo(b) 389 | 390 | return m.tmpl.ExecuteTemplate(w, "config", map[string]interface{}{ 391 | "Title": "Config", 392 | "RuleCount": len(m.cfg.Rule), 393 | "Source": string(b.Bytes()), 394 | }) 395 | } 396 | 397 | // statistical data api 398 | func (m *Manager) consumeData() { 399 | accumulate := func(s map[string]*TrafficRecord, name string, endpoint string, upload int64, download int64, now time.Time) { 400 | o, ok := s[name] 401 | if ok { 402 | o.Upload += upload 403 | o.Download += download 404 | o.Touch = now 405 | } else { 406 | o = &TrafficRecord{ 407 | Name: name, 408 | Upload: upload, 409 | Download: download, 410 | Touch: now, 411 | Details: make(map[string]*TrafficRecordDetail), 412 | } 413 | s[name] = o 414 | } 415 | 416 | if len(endpoint) == 0 { 417 | return 418 | } 419 | 420 | if d, ok := o.Details[endpoint]; ok { 421 | d.Upload += upload 422 | d.Download += download 423 | d.Touch = now 424 | } else { 425 | o.Details[endpoint] = &TrafficRecordDetail{ 426 | EndPoint: endpoint, 427 | Upload: upload, 428 | Download: download, 429 | Touch: now, 430 | } 431 | } 432 | } 433 | 434 | for data := range m.dataCh { 435 | now := time.Now() 436 | accumulate(m.hosts, data.Src, data.Dst, data.Upload, data.Download, now) 437 | accumulate(m.websites, data.Dst, data.Src, data.Upload, data.Download, now) 438 | accumulate(m.proxies, data.Proxy, "", data.Upload, data.Download, now) 439 | } 440 | } 441 | 442 | func (m *Manager) Serve() error { 443 | http.HandleFunc("/", handleWrapper(m.indexHandle)) 444 | http.HandleFunc("/host/", handleWrapper(m.hostHandle)) 445 | http.HandleFunc("/website/", handleWrapper(m.websiteHandle)) 446 | http.HandleFunc("/proxy/", handleWrapper(m.proxyHandle)) 447 | http.HandleFunc("/dns/", handleWrapper(m.dnsHandle)) 448 | http.HandleFunc("/reload/", handleWrapper(m.reloadHandle)) 449 | http.HandleFunc("/config/", handleWrapper(m.configHandle)) 450 | go m.consumeData() 451 | 452 | logger.Infof("[manager] listen on: %s", m.listen) 453 | return http.ListenAndServe(m.listen, nil) 454 | } 455 | 456 | func NewManager(one *One, cfg *KoneConfig) *Manager { 457 | if cfg.General.ManagerAddr == "" { 458 | return nil 459 | } 460 | 461 | tmpl := template.New("master").Funcs(map[string]interface{}{ 462 | "sumInt64": func(a int64, b int64) int64 { 463 | return a + b 464 | }, 465 | "formatNumberComma": func(a int64) string { 466 | var sign, ret string 467 | if a == 0 { 468 | return "0" 469 | } 470 | if a < 0 { 471 | sign, a = "-", -a 472 | } 473 | for a > 0 { 474 | b := a % 1000 475 | a = a / 1000 476 | 477 | var flag string 478 | if a > 0 { 479 | flag = "%03d" 480 | } else { 481 | flag = "%d" 482 | } 483 | if len(ret) > 0 { 484 | flag += ",%s" 485 | } else { 486 | flag += "%s" 487 | } 488 | ret = fmt.Sprintf(flag, b, ret) 489 | 490 | } 491 | return sign + ret 492 | }, 493 | }) 494 | 495 | return &Manager{ 496 | one: one, 497 | cfg: cfg, 498 | startTime: time.Now(), 499 | listen: cfg.General.ManagerAddr, 500 | dataCh: make(chan ConnData), 501 | hosts: make(map[string]*TrafficRecord), 502 | websites: make(map[string]*TrafficRecord), 503 | proxies: make(map[string]*TrafficRecord), 504 | tmpl: template.Must(tmpl.Parse(masterTmpl)), 505 | } 506 | } 507 | -------------------------------------------------------------------------------- /misc/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.20.2-bullseye as builder 2 | WORKDIR /app 3 | COPY go.mod go.sum ./ 4 | RUN go mod download 5 | COPY . . 6 | RUN go build -o main . 7 | 8 | 9 | FROM pihole/pihole:2023.03.1 10 | RUN apt-get update && apt-get install -y iproute2 11 | COPY --from=builder /app/main / 12 | COPY --from=builder /app/config.ini / 13 | CMD ["./main"] 14 | -------------------------------------------------------------------------------- /misc/docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # ports: HOST:CONTAINER 2 | 3 | version: '3.8' 4 | services: 5 | tun: 6 | build: . 7 | container_name: tun-go 8 | restart: unless-stopped 9 | privileged: true 10 | cap_add: 11 | - NET_ADMIN 12 | # network_mode: host 13 | ports: 14 | - "53:53/tcp" 15 | - "53:53/udp" 16 | - "80:80/tcp" 17 | - "9200:9200/tcp" 18 | environment: 19 | - SOCKS_PROXY=socks5://v2raya:1080 20 | - PIHOLE_DNS_=10.192.0.1#5385 21 | - WEBPASSWORD=123654789 22 | - FTLCONF_LOCAL_IPV4=127.0.0.1 23 | volumes: 24 | - ./config.ini:/config.ini # comment to use default config 25 | 26 | v2raya: 27 | image: mzz2017/v2raya 28 | container_name: v2raya 29 | restart: unless-stopped 30 | privileged: true 31 | expose: 32 | - "1080" 33 | - "9080" 34 | ports: 35 | - "2020:2017" 36 | environment: 37 | - V2RAYA_ADDRESS=0.0.0.0:2017 38 | volumes: 39 | - ./v2raya/v2raya:/etc/v2raya -------------------------------------------------------------------------------- /misc/docs/fanqiang.list: -------------------------------------------------------------------------------- 1 | 103.11.101.0/24 2 | 103.14.245.0/24 3 | 103.17.8.0/24 4 | 103.20.93.0/24 5 | 103.20.94.0/24 6 | 103.23.108.0/24 7 | 103.245.222.0/24 8 | 103.246.57.0/24 9 | 103.28.249.0/24 10 | 103.31.6.0/24 11 | 103.31.7.0/24 12 | 104.102.162.0/24 13 | 104.102.168.0/24 14 | 104.109.245.0/24 15 | 104.156.81.0/24 16 | 104.156.85.0/24 17 | 104.16.102.0/24 18 | 104.16.103.0/24 19 | 104.16.104.0/24 20 | 104.16.105.0/24 21 | 104.16.106.0/24 22 | 104.16.107.0/24 23 | 104.16.108.0/24 24 | 104.16.24.0/24 25 | 104.16.25.0/24 26 | 104.16.28.0/24 27 | 104.16.29.0/24 28 | 104.16.30.0/24 29 | 104.16.33.0/24 30 | 104.16.34.0/24 31 | 104.16.35.0/24 32 | 104.16.36.0/24 33 | 104.16.37.0/24 34 | 104.16.38.0/24 35 | 104.16.39.0/24 36 | 104.16.40.0/24 37 | 104.16.41.0/24 38 | 104.16.64.0/24 39 | 104.16.65.0/24 40 | 104.16.66.0/24 41 | 104.16.67.0/24 42 | 104.16.68.0/24 43 | 104.16.81.0/24 44 | 104.16.82.0/24 45 | 104.16.83.0/24 46 | 104.16.84.0/24 47 | 104.16.85.0/24 48 | 104.16.88.0/24 49 | 104.16.89.0/24 50 | 104.16.90.0/24 51 | 104.16.91.0/24 52 | 104.16.92.0/24 53 | 104.192.143.0/24 54 | 104.197.50.0/24 55 | 104.20.22.0/24 56 | 104.20.23.0/24 57 | 104.20.28.0/24 58 | 104.20.29.0/24 59 | 104.20.42.0/24 60 | 104.20.43.0/24 61 | 104.20.63.0/24 62 | 104.20.64.0/24 63 | 104.208.28.0/24 64 | 104.208.31.0/24 65 | 104.23.130.0/24 66 | 104.23.131.0/24 67 | 104.238.160.0/24 68 | 104.24.2.0/24 69 | 104.24.28.0/24 70 | 104.24.29.0/24 71 | 104.24.3.0/24 72 | 104.244.42.0/24 73 | 104.244.43.0/24 74 | 104.25.128.0/24 75 | 104.25.129.0/24 76 | 104.25.182.0/24 77 | 104.25.183.0/24 78 | 104.27.160.0/24 79 | 104.27.161.0/24 80 | 104.28.10.0/24 81 | 104.28.11.0/24 82 | 104.28.28.0/24 83 | 104.28.29.0/24 84 | 104.40.141.0/24 85 | 104.43.161.0/24 86 | 104.43.167.0/24 87 | 104.64.123.0/24 88 | 104.66.0.0/24 89 | 104.66.27.0/24 90 | 104.66.8.0/24 91 | 104.67.74.0/24 92 | 104.68.108.0/24 93 | 104.68.118.0/24 94 | 104.69.166.0/24 95 | 104.70.133.0/24 96 | 104.70.143.0/24 97 | 104.70.151.0/24 98 | 104.70.153.0/24 99 | 104.70.225.0/24 100 | 104.70.229.0/24 101 | 104.71.159.0/24 102 | 104.71.164.0/24 103 | 104.71.169.0/24 104 | 104.71.78.0/24 105 | 104.72.70.0/24 106 | 104.72.72.0/24 107 | 104.72.73.0/24 108 | 104.72.80.0/24 109 | 104.74.28.0/24 110 | 104.74.49.0/24 111 | 104.74.57.0/24 112 | 104.74.58.0/24 113 | 104.74.59.0/24 114 | 104.74.60.0/24 115 | 104.75.242.0/24 116 | 104.75.245.0/24 117 | 104.76.227.0/24 118 | 104.76.228.0/24 119 | 104.76.249.0/24 120 | 104.77.14.0/24 121 | 104.77.18.0/24 122 | 104.77.20.0/24 123 | 104.77.39.0/24 124 | 104.77.43.0/24 125 | 104.77.62.0/24 126 | 104.77.65.0/24 127 | 104.78.23.0/24 128 | 104.78.25.0/24 129 | 104.78.95.0/24 130 | 104.81.210.0/24 131 | 104.82.2.0/24 132 | 104.82.24.0/24 133 | 104.84.117.0/24 134 | 104.84.140.0/24 135 | 104.86.111.0/24 136 | 104.90.214.0/24 137 | 104.94.51.0/24 138 | 104.95.198.0/24 139 | 104.96.2.0/24 140 | 104.96.220.0/24 141 | 104.97.235.0/24 142 | 104.97.250.0/24 143 | 104.98.200.0/24 144 | 104.98.205.0/24 145 | 104.98.22.0/24 146 | 104.98.246.0/24 147 | 104.98.3.0/24 148 | 104.98.38.0/24 149 | 106.10.137.0/24 150 | 106.10.199.0/24 151 | 106.10.212.0/24 152 | 106.10.222.0/24 153 | 106.185.27.0/24 154 | 106.185.42.0/24 155 | 106.186.119.0/24 156 | 106.186.31.0/24 157 | 106.186.66.0/24 158 | 106.187.101.0/24 159 | 107.162.132.0/24 160 | 107.170.160.0/24 161 | 107.170.239.0/24 162 | 107.170.246.0/24 163 | 107.178.244.0/24 164 | 107.178.245.0/24 165 | 107.182.189.0/24 166 | 107.20.139.0/24 167 | 107.20.141.0/24 168 | 107.20.142.0/24 169 | 107.20.143.0/24 170 | 107.20.144.0/24 171 | 107.20.154.0/24 172 | 107.20.156.0/24 173 | 107.20.162.0/24 174 | 107.20.165.0/24 175 | 107.20.173.0/24 176 | 107.20.175.0/24 177 | 107.20.178.0/24 178 | 107.20.179.0/24 179 | 107.20.180.0/24 180 | 107.20.181.0/24 181 | 107.20.182.0/24 182 | 107.20.184.0/24 183 | 107.20.187.0/24 184 | 107.20.189.0/24 185 | 107.20.190.0/24 186 | 107.20.196.0/24 187 | 107.20.197.0/24 188 | 107.20.198.0/24 189 | 107.20.203.0/24 190 | 107.20.204.0/24 191 | 107.20.206.0/24 192 | 107.20.210.0/24 193 | 107.20.212.0/24 194 | 107.20.218.0/24 195 | 107.20.221.0/24 196 | 107.20.224.0/24 197 | 107.20.225.0/24 198 | 107.20.232.0/24 199 | 107.20.233.0/24 200 | 107.20.234.0/24 201 | 107.20.235.0/24 202 | 107.20.237.0/24 203 | 107.20.241.0/24 204 | 107.20.246.0/24 205 | 107.20.249.0/24 206 | 107.20.252.0/24 207 | 107.21.1.0/24 208 | 107.21.109.0/24 209 | 107.21.119.0/24 210 | 107.21.125.0/24 211 | 107.21.126.0/24 212 | 107.21.127.0/24 213 | 107.21.20.0/24 214 | 107.21.201.0/24 215 | 107.21.204.0/24 216 | 107.21.206.0/24 217 | 107.21.209.0/24 218 | 107.21.213.0/24 219 | 107.21.214.0/24 220 | 107.21.215.0/24 221 | 107.21.216.0/24 222 | 107.21.217.0/24 223 | 107.21.220.0/24 224 | 107.21.23.0/24 225 | 107.21.246.0/24 226 | 107.21.250.0/24 227 | 107.21.251.0/24 228 | 107.21.252.0/24 229 | 107.21.33.0/24 230 | 107.21.38.0/24 231 | 107.21.4.0/24 232 | 107.21.41.0/24 233 | 107.21.49.0/24 234 | 107.21.52.0/24 235 | 107.21.92.0/24 236 | 107.21.95.0/24 237 | 107.21.96.0/24 238 | 107.22.160.0/24 239 | 107.22.161.0/24 240 | 107.22.162.0/24 241 | 107.22.165.0/24 242 | 107.22.166.0/24 243 | 107.22.170.0/24 244 | 107.22.178.0/24 245 | 107.22.183.0/24 246 | 107.22.185.0/24 247 | 107.22.191.0/24 248 | 107.22.193.0/24 249 | 107.22.197.0/24 250 | 107.22.208.0/24 251 | 107.22.215.0/24 252 | 107.22.217.0/24 253 | 107.22.219.0/24 254 | 107.22.223.0/24 255 | 107.22.225.0/24 256 | 107.22.226.0/24 257 | 107.22.227.0/24 258 | 107.22.228.0/24 259 | 107.22.230.0/24 260 | 107.22.231.0/24 261 | 107.22.234.0/24 262 | 107.22.235.0/24 263 | 107.22.237.0/24 264 | 107.22.238.0/24 265 | 107.22.240.0/24 266 | 107.22.242.0/24 267 | 107.22.247.0/24 268 | 107.22.249.0/24 269 | 107.22.70.0/24 270 | 107.23.107.0/24 271 | 107.23.110.0/24 272 | 107.23.112.0/24 273 | 107.23.116.0/24 274 | 107.23.124.0/24 275 | 107.23.141.0/24 276 | 107.23.153.0/24 277 | 107.23.154.0/24 278 | 107.23.162.0/24 279 | 107.23.166.0/24 280 | 107.23.173.0/24 281 | 107.23.183.0/24 282 | 107.23.188.0/24 283 | 107.23.217.0/24 284 | 107.23.22.0/24 285 | 107.23.224.0/24 286 | 107.23.233.0/24 287 | 107.23.237.0/24 288 | 107.23.238.0/24 289 | 107.23.247.0/24 290 | 107.23.4.0/24 291 | 107.23.46.0/24 292 | 107.23.52.0/24 293 | 107.23.60.0/24 294 | 107.23.62.0/24 295 | 107.23.65.0/24 296 | 107.23.68.0/24 297 | 107.23.77.0/24 298 | 107.23.82.0/24 299 | 107.23.83.0/24 300 | 107.23.95.0/24 301 | 108.160.165.0/24 302 | 108.160.166.0/24 303 | 108.160.167.0/24 304 | 108.160.172.0/24 305 | 108.160.173.0/24 306 | 108.168.194.0/24 307 | 108.168.243.0/24 308 | 108.174.10.0/24 309 | 108.59.10.0/24 310 | 108.59.3.0/24 311 | 110.232.178.0/24 312 | 110.45.152.0/24 313 | 110.45.229.0/24 314 | 110.76.141.0/24 315 | 111.161.22.0/24 316 | 111.221.123.0/24 317 | 111.92.236.0/24 318 | 111.92.237.0/24 319 | 112.121.96.0/24 320 | 113.196.160.0/24 321 | 113.196.241.0/24 322 | 113.196.250.0/24 323 | 114.111.107.0/24 324 | 114.111.115.0/24 325 | 114.111.75.0/24 326 | 116.214.7.0/24 327 | 116.251.204.0/24 328 | 116.251.210.0/24 329 | 116.251.223.0/24 330 | 117.104.135.0/24 331 | 117.104.138.0/24 332 | 117.104.139.0/24 333 | 117.18.232.0/24 334 | 117.18.237.0/24 335 | 117.21.191.0/24 336 | 118.130.42.0/24 337 | 118.151.231.0/24 338 | 118.155.230.0/24 339 | 118.214.81.0/24 340 | 118.214.85.0/24 341 | 118.214.95.0/24 342 | 118.215.12.0/24 343 | 118.215.15.0/24 344 | 118.215.179.0/24 345 | 118.215.68.0/24 346 | 119.235.235.0/24 347 | 119.246.134.0/24 348 | 119.81.106.0/24 349 | 119.81.146.0/24 350 | 1.201.0.0/24 351 | 120.29.145.0/24 352 | 121.14.42.0/24 353 | 121.201.24.0/24 354 | 121.78.58.0/24 355 | 122.152.169.0/24 356 | 122.226.184.0/24 357 | 124.108.101.0/24 358 | 124.108.105.0/24 359 | 124.244.43.0/24 360 | 124.40.41.0/24 361 | 124.40.42.0/24 362 | 124.40.52.0/24 363 | 125.252.234.0/24 364 | 125.252.236.0/24 365 | 125.56.150.0/24 366 | 125.56.201.0/24 367 | 125.56.218.0/24 368 | 125.56.219.0/24 369 | 125.6.190.0/24 370 | 127.0.0.0/24 371 | 128.199.191.0/24 372 | 128.208.178.0/24 373 | 128.30.52.0/24 374 | 131.103.20.0/24 375 | 131.253.33.0/24 376 | 134.170.104.0/24 377 | 134.170.107.0/24 378 | 134.170.108.0/24 379 | 134.170.120.0/24 380 | 137.135.101.0/24 381 | 138.91.58.0/24 382 | 139.175.236.0/24 383 | 140.112.172.0/24 384 | 140.112.8.0/24 385 | 140.177.205.0/24 386 | 14.0.35.0/24 387 | 14.0.38.0/24 388 | 14.0.39.0/24 389 | 14.0.52.0/24 390 | 14.0.53.0/24 391 | 141.0.174.0/24 392 | 141.101.112.0/24 393 | 141.101.114.0/24 394 | 141.101.115.0/24 395 | 141.101.118.0/24 396 | 14.136.64.0/24 397 | 14.136.65.0/24 398 | 14.136.67.0/24 399 | 14.18.206.0/24 400 | 14.63.185.0/24 401 | 148.251.24.0/24 402 | 148.251.50.0/24 403 | 149.154.0.0/16 404 | 149.154.167.0/24 405 | 151.207.128.0/24 406 | 151.207.240.0/24 407 | 152.19.134.0/24 408 | 153.120.42.0/24 409 | 153.121.70.0/24 410 | 154.35.132.0/24 411 | 158.85.167.0/24 412 | 159.106.121.0/24 413 | 159.8.220.0/24 414 | 160.16.118.0/24 415 | 160.16.75.0/24 416 | 160.16.98.0/24 417 | 162.13.198.0/24 418 | 162.159.242.0/24 419 | 162.159.243.0/24 420 | 162.159.245.0/24 421 | 162.159.246.0/24 422 | 162.159.252.0/24 423 | 162.159.253.0/24 424 | 162.159.254.0/24 425 | 162.159.255.0/24 426 | 162.209.114.0/24 427 | 162.242.195.0/24 428 | 162.253.133.0/24 429 | 167.89.125.0/24 430 | 170.149.159.0/24 431 | 170.149.161.0/24 432 | 170.149.168.0/24 433 | 170.149.172.0/24 434 | 172.229.130.0/24 435 | 172.231.121.0/24 436 | 173.192.224.0/24 437 | 173.194.112.0/24 438 | 173.194.113.0/24 439 | 173.194.115.0/24 440 | 173.194.116.0/24 441 | 173.194.117.0/24 442 | 173.194.118.0/24 443 | 173.194.119.0/24 444 | 173.194.120.0/24 445 | 173.194.121.0/24 446 | 173.194.122.0/24 447 | 173.194.123.0/24 448 | 173.194.126.0/24 449 | 173.194.127.0/24 450 | 173.194.192.0/24 451 | 173.194.199.0/24 452 | 173.194.205.0/24 453 | 173.194.219.0/24 454 | 173.194.220.0/24 455 | 173.194.222.0/24 456 | 173.194.33.0/24 457 | 173.194.37.0/24 458 | 173.194.38.0/24 459 | 173.194.40.0/24 460 | 173.194.42.0/24 461 | 173.194.43.0/24 462 | 173.194.44.0/24 463 | 173.194.45.0/24 464 | 173.194.46.0/24 465 | 173.194.65.0/24 466 | 173.194.69.0/24 467 | 173.194.71.0/24 468 | 173.194.72.0/24 469 | 173.194.79.0/24 470 | 173.230.146.0/24 471 | 173.230.148.0/24 472 | 173.246.99.0/24 473 | 173.252.100.0/24 474 | 173.252.110.0/24 475 | 173.252.112.0/24 476 | 173.252.120.0/24 477 | 173.252.207.0/24 478 | 173.252.74.0/24 479 | 173.252.88.0/24 480 | 173.252.89.0/24 481 | 173.252.90.0/24 482 | 173.255.114.0/24 483 | 174.129.197.0/24 484 | 174.129.199.0/24 485 | 174.129.215.0/24 486 | 174.129.228.0/24 487 | 174.129.251.0/24 488 | 174.129.255.0/24 489 | 174.129.3.0/24 490 | 174.129.34.0/24 491 | 174.129.36.0/24 492 | 174.129.38.0/24 493 | 174.140.163.0/24 494 | 174.142.61.0/24 495 | 174.142.90.0/24 496 | 174.35.52.0/24 497 | 175.41.12.0/24 498 | 176.32.102.0/24 499 | 176.32.103.0/24 500 | 176.32.98.0/24 501 | 176.9.39.0/24 502 | 179.60.192.0/24 503 | 180.233.142.0/24 504 | 180.70.134.0/24 505 | 180.97.161.0/24 506 | 180.97.163.0/24 507 | 182.22.39.0/24 508 | 182.22.40.0/24 509 | 182.22.51.0/24 510 | 182.22.55.0/24 511 | 182.22.59.0/24 512 | 182.22.72.0/24 513 | 182.22.84.0/24 514 | 183.110.0.0/24 515 | 183.131.119.0/24 516 | 183.178.197.0/24 517 | 183.178.212.0/24 518 | 183.61.67.0/24 519 | 183.79.131.0/24 520 | 183.79.139.0/24 521 | 183.79.197.0/24 522 | 183.79.210.0/24 523 | 183.79.23.0/24 524 | 183.79.71.0/24 525 | 183.79.79.0/24 526 | 184.106.14.0/24 527 | 184.154.128.0/24 528 | 184.168.221.0/24 529 | 184.24.225.0/24 530 | 184.26.193.0/24 531 | 184.26.240.0/24 532 | 184.26.249.0/24 533 | 184.26.250.0/24 534 | 184.26.252.0/24 535 | 184.26.255.0/24 536 | 184.27.164.0/24 537 | 184.27.167.0/24 538 | 184.27.178.0/24 539 | 184.27.18.0/24 540 | 184.27.19.0/24 541 | 184.28.188.0/24 542 | 184.29.11.0/24 543 | 184.50.124.0/24 544 | 184.50.196.0/24 545 | 184.50.85.0/24 546 | 184.51.15.0/24 547 | 184.51.198.0/24 548 | 184.72.220.0/24 549 | 184.72.235.0/24 550 | 184.72.238.0/24 551 | 184.72.240.0/24 552 | 184.72.244.0/24 553 | 184.72.246.0/24 554 | 184.72.249.0/24 555 | 184.72.252.0/24 556 | 184.72.254.0/24 557 | 184.73.154.0/24 558 | 184.73.161.0/24 559 | 184.73.169.0/24 560 | 184.73.184.0/24 561 | 184.73.187.0/24 562 | 184.73.190.0/24 563 | 184.73.202.0/24 564 | 184.73.208.0/24 565 | 184.73.215.0/24 566 | 184.73.218.0/24 567 | 184.73.222.0/24 568 | 184.73.223.0/24 569 | 184.73.224.0/24 570 | 184.73.230.0/24 571 | 184.73.231.0/24 572 | 184.73.234.0/24 573 | 184.73.238.0/24 574 | 184.73.242.0/24 575 | 184.73.251.0/24 576 | 184.84.55.0/24 577 | 184.85.119.0/24 578 | 184.85.82.0/24 579 | 184.85.87.0/24 580 | 184.86.234.0/24 581 | 184.86.250.0/24 582 | 184.86.55.0/24 583 | 184.87.224.0/24 584 | 184.87.226.0/24 585 | 184.87.231.0/24 586 | 185.31.17.0/24 587 | 185.31.18.0/24 588 | 185.31.19.0/24 589 | 185.34.216.0/24 590 | 185.45.5.0/24 591 | 185.60.216.0/24 592 | 188.226.207.0/24 593 | 189.163.17.0/24 594 | 190.93.240.0/24 595 | 190.93.241.0/24 596 | 190.93.242.0/24 597 | 190.93.243.0/24 598 | 191.235.128.0/24 599 | 192.0.78.0/24 600 | 192.0.79.0/24 601 | 192.0.80.0/24 602 | 192.121.151.0/24 603 | 192.16.31.0/24 604 | 192.16.71.0/24 605 | 192.185.51.0/24 606 | 192.229.145.0/24 607 | 192.229.163.0/24 608 | 192.229.218.0/24 609 | 192.229.237.0/24 610 | 192.230.92.0/24 611 | 192.30.252.0/24 612 | 194.0.59.0/24 613 | 195.170.168.0/24 614 | 195.20.13.0/24 615 | 1.9.56.0/24 616 | 198.105.215.0/24 617 | 198.185.159.0/24 618 | 198.232.124.0/24 619 | 198.252.206.0/24 620 | 198.35.26.0/24 621 | 198.37.144.0/24 622 | 198.41.134.0/24 623 | 198.41.135.0/24 624 | 198.41.140.0/24 625 | 198.41.141.0/24 626 | 198.41.184.0/24 627 | 198.41.191.0/24 628 | 198.41.206.0/24 629 | 198.41.207.0/24 630 | 198.41.208.0/24 631 | 198.41.209.0/24 632 | 198.41.212.0/24 633 | 198.41.213.0/24 634 | 198.41.214.0/24 635 | 198.41.215.0/24 636 | 198.41.247.0/24 637 | 198.49.23.0/24 638 | 198.50.208.0/24 639 | 198.57.30.0/24 640 | 198.58.94.0/24 641 | 198.58.99.0/24 642 | 198.7.31.0/24 643 | 199.16.156.0/24 644 | 199.16.158.0/24 645 | 199.193.116.0/24 646 | 199.27.74.0/24 647 | 199.27.75.0/24 648 | 199.27.76.0/24 649 | 199.27.78.0/24 650 | 199.27.79.0/24 651 | 199.47.217.0/24 652 | 199.58.87.0/24 653 | 199.59.148.0/24 654 | 199.59.149.0/24 655 | 199.59.150.0/24 656 | 199.83.131.0/24 657 | 199.96.57.0/24 658 | 202.125.90.0/24 659 | 202.145.199.0/24 660 | 202.219.104.0/24 661 | 202.248.110.0/24 662 | 202.39.235.0/24 663 | 203.104.131.0/24 664 | 203.106.50.0/24 665 | 203.112.92.0/24 666 | 203.112.93.0/24 667 | 203.133.25.0/24 668 | 203.208.40.0/24 669 | 203.208.41.0/24 670 | 203.208.48.0/24 671 | 203.208.49.0/24 672 | 203.208.50.0/24 673 | 203.208.52.0/24 674 | 203.69.138.0/24 675 | 203.69.81.0/24 676 | 203.84.197.0/24 677 | 203.98.7.0/24 678 | 204.236.217.0/24 679 | 204.236.226.0/24 680 | 204.236.233.0/24 681 | 204.236.238.0/24 682 | 204.62.114.0/24 683 | 204.77.212.0/24 684 | 204.77.214.0/24 685 | 204.79.197.0/24 686 | 205.177.240.0/24 687 | 205.196.120.0/24 688 | 205.251.242.0/24 689 | 205.251.253.0/24 690 | 206.123.112.0/24 691 | 206.190.36.0/24 692 | 206.190.61.0/24 693 | 206.251.255.0/24 694 | 207.109.111.0/24 695 | 207.171.162.0/24 696 | 207.200.74.0/24 697 | 207.241.224.0/24 698 | 207.244.64.0/24 699 | 208.71.44.0/24 700 | 208.80.154.0/24 701 | 208.86.184.0/24 702 | 209.126.106.0/24 703 | 209.135.140.0/24 704 | 209.177.81.0/24 705 | 209.202.252.0/24 706 | 209.85.145.0/24 707 | 209.85.147.0/24 708 | 209.85.229.0/24 709 | 210.0.146.0/24 710 | 210.103.240.0/24 711 | 210.155.101.0/24 712 | 210.17.38.0/24 713 | 210.209.110.0/24 714 | 210.48.79.0/24 715 | 210.59.230.0/24 716 | 210.61.248.0/24 717 | 210.61.56.0/24 718 | 210.6.47.0/24 719 | 211.20.177.0/24 720 | 211.20.188.0/24 721 | 212.58.244.0/24 722 | 212.58.246.0/24 723 | 213.248.126.0/24 724 | 216.137.36.0/24 725 | 216.146.38.0/24 726 | 216.146.43.0/24 727 | 216.239.32.0/24 728 | 216.239.34.0/24 729 | 216.239.36.0/24 730 | 216.239.38.0/24 731 | 216.34.181.0/24 732 | 216.39.54.0/24 733 | 216.58.0.0/16 734 | 216.58.192.0/24 735 | 216.58.196.0/24 736 | 216.58.197.0/24 737 | 216.58.198.0/24 738 | 216.58.208.0/24 739 | 216.58.209.0/24 740 | 216.58.210.0/24 741 | 216.58.211.0/24 742 | 216.58.212.0/24 743 | 216.58.213.0/24 744 | 216.58.216.0/24 745 | 216.58.217.0/24 746 | 216.58.218.0/24 747 | 216.58.219.0/24 748 | 216.58.220.0/24 749 | 216.58.221.0/24 750 | 216.58.222.0/24 751 | 216.58.223.0/24 752 | 216.69.227.0/24 753 | 216.97.88.0/24 754 | 218.189.25.0/24 755 | 218.213.85.0/24 756 | 218.61.193.0/24 757 | 219.93.34.0/24 758 | 219.93.37.0/24 759 | 220.177.198.0/24 760 | 2.20.190.0/24 761 | 2.20.254.0/24 762 | 222.187.0.0/24 763 | 2.22.194.0/24 764 | 2.23.133.0/24 765 | 23.0.181.0/24 766 | 23.10.18.0/24 767 | 23.10.2.0/24 768 | 23.10.25.0/24 769 | 23.10.27.0/24 770 | 23.10.28.0/24 771 | 23.11.127.0/24 772 | 23.11.92.0/24 773 | 23.12.144.0/24 774 | 23.13.39.0/24 775 | 23.13.44.0/24 776 | 23.15.100.0/24 777 | 23.15.10.0/24 778 | 23.15.106.0/24 779 | 23.15.14.0/24 780 | 23.15.148.0/24 781 | 23.15.152.0/24 782 | 23.15.157.0/24 783 | 23.15.249.0/24 784 | 23.15.86.0/24 785 | 23.15.97.0/24 786 | 23.198.114.0/24 787 | 23.198.116.0/24 788 | 23.198.130.0/24 789 | 23.198.132.0/24 790 | 23.198.136.0/24 791 | 23.198.139.0/24 792 | 23.198.21.0/24 793 | 23.200.222.0/24 794 | 23.201.102.0/24 795 | 23.201.228.0/24 796 | 23.201.237.0/24 797 | 23.201.242.0/24 798 | 23.206.11.0/24 799 | 23.206.13.0/24 800 | 23.207.119.0/24 801 | 23.207.126.0/24 802 | 23.210.132.0/24 803 | 23.21.100.0/24 804 | 23.21.105.0/24 805 | 23.21.106.0/24 806 | 23.21.107.0/24 807 | 23.211.113.0/24 808 | 23.21.119.0/24 809 | 23.21.126.0/24 810 | 23.21.137.0/24 811 | 23.21.138.0/24 812 | 23.21.141.0/24 813 | 23.21.145.0/24 814 | 23.21.147.0/24 815 | 23.21.154.0/24 816 | 23.21.160.0/24 817 | 23.21.175.0/24 818 | 23.21.176.0/24 819 | 23.21.184.0/24 820 | 23.21.186.0/24 821 | 23.21.187.0/24 822 | 23.21.191.0/24 823 | 23.21.193.0/24 824 | 23.21.196.0/24 825 | 23.21.199.0/24 826 | 23.21.202.0/24 827 | 23.21.204.0/24 828 | 23.21.207.0/24 829 | 23.21.208.0/24 830 | 23.21.209.0/24 831 | 23.21.210.0/24 832 | 23.21.214.0/24 833 | 23.21.215.0/24 834 | 23.21.222.0/24 835 | 23.212.225.0/24 836 | 23.21.224.0/24 837 | 23.21.228.0/24 838 | 23.21.230.0/24 839 | 23.21.231.0/24 840 | 23.21.234.0/24 841 | 23.21.235.0/24 842 | 23.21.238.0/24 843 | 23.21.239.0/24 844 | 23.21.240.0/24 845 | 23.21.241.0/24 846 | 23.21.243.0/24 847 | 23.21.244.0/24 848 | 23.21.249.0/24 849 | 23.21.253.0/24 850 | 23.21.255.0/24 851 | 23.213.103.0/24 852 | 23.2.134.0/24 853 | 23.213.86.0/24 854 | 23.213.88.0/24 855 | 23.21.42.0/24 856 | 23.2.143.0/24 857 | 23.21.44.0/24 858 | 23.21.45.0/24 859 | 23.21.46.0/24 860 | 23.21.47.0/24 861 | 23.21.48.0/24 862 | 23.21.51.0/24 863 | 23.21.53.0/24 864 | 23.21.55.0/24 865 | 23.215.63.0/24 866 | 23.21.60.0/24 867 | 23.2.16.0/24 868 | 23.21.67.0/24 869 | 23.216.8.0/24 870 | 23.21.69.0/24 871 | 23.21.70.0/24 872 | 23.21.73.0/24 873 | 23.21.75.0/24 874 | 23.21.78.0/24 875 | 23.218.0.0/24 876 | 23.218.212.0/24 877 | 23.218.29.0/24 878 | 23.218.34.0/24 879 | 23.218.35.0/24 880 | 23.21.85.0/24 881 | 23.21.86.0/24 882 | 23.21.87.0/24 883 | 23.21.88.0/24 884 | 23.218.8.0/24 885 | 23.218.9.0/24 886 | 23.21.90.0/24 887 | 23.21.91.0/24 888 | 23.21.93.0/24 889 | 23.21.95.0/24 890 | 23.21.98.0/24 891 | 23.222.171.0/24 892 | 23.222.28.0/24 893 | 23.222.85.0/24 894 | 23.22.32.0/24 895 | 23.229.248.0/24 896 | 23.23.100.0/24 897 | 23.23.102.0/24 898 | 23.23.104.0/24 899 | 23.23.105.0/24 900 | 23.23.107.0/24 901 | 23.23.108.0/24 902 | 23.23.111.0/24 903 | 23.23.114.0/24 904 | 23.23.116.0/24 905 | 23.23.117.0/24 906 | 23.23.121.0/24 907 | 23.23.122.0/24 908 | 23.23.126.0/24 909 | 23.23.127.0/24 910 | 23.23.131.0/24 911 | 23.23.132.0/24 912 | 23.23.133.0/24 913 | 23.23.134.0/24 914 | 23.23.138.0/24 915 | 23.23.139.0/24 916 | 23.23.141.0/24 917 | 23.23.142.0/24 918 | 23.23.144.0/24 919 | 23.23.145.0/24 920 | 23.23.147.0/24 921 | 23.23.148.0/24 922 | 23.23.149.0/24 923 | 23.23.151.0/24 924 | 23.23.152.0/24 925 | 23.23.154.0/24 926 | 23.23.155.0/24 927 | 23.23.157.0/24 928 | 23.23.159.0/24 929 | 23.23.161.0/24 930 | 23.23.167.0/24 931 | 23.23.168.0/24 932 | 23.23.173.0/24 933 | 23.23.180.0/24 934 | 23.23.186.0/24 935 | 23.23.187.0/24 936 | 23.23.199.0/24 937 | 23.23.208.0/24 938 | 23.23.214.0/24 939 | 23.23.215.0/24 940 | 23.23.216.0/24 941 | 23.23.224.0/24 942 | 23.23.226.0/24 943 | 23.23.233.0/24 944 | 23.23.237.0/24 945 | 23.23.238.0/24 946 | 23.23.240.0/24 947 | 23.23.241.0/24 948 | 23.23.244.0/24 949 | 23.23.249.0/24 950 | 23.23.253.0/24 951 | 23.23.254.0/24 952 | 23.23.255.0/24 953 | 23.235.33.0/24 954 | 23.235.37.0/24 955 | 23.235.39.0/24 956 | 23.235.40.0/24 957 | 23.235.43.0/24 958 | 23.235.44.0/24 959 | 23.235.46.0/24 960 | 23.235.47.0/24 961 | 23.23.72.0/24 962 | 23.23.80.0/24 963 | 23.23.88.0/24 964 | 23.23.91.0/24 965 | 23.23.96.0/24 966 | 23.23.97.0/24 967 | 23.23.98.0/24 968 | 23.23.99.0/24 969 | 23.251.100.0/24 970 | 23.251.121.0/24 971 | 23.251.96.0/24 972 | 23.252.122.0/24 973 | 23.252.161.0/24 974 | 23.253.242.0/24 975 | 23.32.100.0/24 976 | 23.32.248.0/24 977 | 23.32.252.0/24 978 | 23.33.217.0/24 979 | 23.33.252.0/24 980 | 23.33.40.0/24 981 | 23.34.104.0/24 982 | 23.34.108.0/24 983 | 23.34.36.0/24 984 | 23.34.47.0/24 985 | 23.34.49.0/24 986 | 23.36.102.0/24 987 | 23.36.96.0/24 988 | 23.37.112.0/24 989 | 23.37.113.0/24 990 | 23.37.119.0/24 991 | 23.37.121.0/24 992 | 23.37.147.0/24 993 | 23.37.157.0/24 994 | 23.3.74.0/24 995 | 23.38.164.0/24 996 | 23.38.245.0/24 997 | 23.38.249.0/24 998 | 23.39.0.0/24 999 | 23.39.7.0/24 1000 | 23.41.176.0/24 1001 | 23.41.243.0/24 1002 | 23.41.48.0/24 1003 | 23.41.52.0/24 1004 | 23.41.69.0/24 1005 | 23.4.173.0/24 1006 | 23.41.92.0/24 1007 | 23.42.128.0/24 1008 | 23.42.130.0/24 1009 | 23.42.135.0/24 1010 | 23.42.209.0/24 1011 | 23.42.210.0/24 1012 | 23.42.44.0/24 1013 | 23.42.45.0/24 1014 | 23.42.70.0/24 1015 | 23.44.141.0/24 1016 | 23.44.154.0/24 1017 | 23.44.25.0/24 1018 | 23.45.130.0/24 1019 | 23.46.132.0/24 1020 | 23.46.26.0/24 1021 | 23.46.27.0/24 1022 | 23.46.6.0/24 1023 | 23.47.131.0/24 1024 | 23.47.135.0/24 1025 | 23.47.141.0/24 1026 | 23.47.143.0/24 1027 | 23.48.12.0/24 1028 | 23.48.140.0/24 1029 | 23.48.16.0/24 1030 | 23.48.17.0/24 1031 | 23.48.21.0/24 1032 | 23.48.5.0/24 1033 | 23.4.92.0/24 1034 | 23.50.17.0/24 1035 | 23.50.18.0/24 1036 | 23.50.27.0/24 1037 | 23.50.31.0/24 1038 | 23.51.37.0/24 1039 | 23.51.40.0/24 1040 | 23.51.61.0/24 1041 | 23.52.208.0/24 1042 | 23.52.26.0/24 1043 | 23.53.192.0/24 1044 | 23.53.197.0/24 1045 | 23.53.199.0/24 1046 | 23.54.245.0/24 1047 | 23.55.59.0/24 1048 | 23.58.224.0/24 1049 | 23.58.229.0/24 1050 | 23.58.247.0/24 1051 | 23.58.251.0/24 1052 | 23.58.40.0/24 1053 | 23.59.159.0/24 1054 | 23.59.8.0/24 1055 | 23.59.9.0/24 1056 | 23.59.93.0/24 1057 | 23.61.250.0/24 1058 | 23.6.186.0/24 1059 | 23.62.109.0/24 1060 | 23.62.248.0/24 1061 | 23.63.11.0/24 1062 | 23.6.33.0/24 1063 | 23.63.42.0/24 1064 | 23.63.8.0/24 1065 | 23.66.101.0/24 1066 | 23.66.146.0/24 1067 | 23.66.147.0/24 1068 | 23.66.148.0/24 1069 | 23.66.35.0/24 1070 | 23.66.37.0/24 1071 | 23.66.39.0/24 1072 | 23.66.81.0/24 1073 | 23.66.89.0/24 1074 | 23.66.90.0/24 1075 | 23.67.172.0/24 1076 | 23.67.175.0/24 1077 | 23.67.181.0/24 1078 | 23.74.53.0/24 1079 | 23.74.8.0/24 1080 | 23.76.204.0/24 1081 | 23.77.1.0/24 1082 | 23.77.12.0/24 1083 | 23.77.15.0/24 1084 | 23.77.17.0/24 1085 | 23.77.2.0/24 1086 | 23.77.24.0/24 1087 | 23.77.25.0/24 1088 | 23.77.27.0/24 1089 | 23.77.30.0/24 1090 | 23.8.81.0/24 1091 | 23.96.32.0/24 1092 | 23.97.186.0/24 1093 | 23.99.50.0/24 1094 | 243.185.187.0/24 1095 | 27.110.78.0/24 1096 | 27.121.46.0/24 1097 | 27.255.71.0/24 1098 | 31.13.64.0/24 1099 | 31.13.65.0/24 1100 | 31.13.66.0/24 1101 | 31.13.68.0/24 1102 | 31.13.69.0/24 1103 | 31.13.70.0/24 1104 | 31.13.71.0/24 1105 | 31.13.73.0/24 1106 | 31.13.74.0/24 1107 | 31.13.75.0/24 1108 | 31.13.76.0/24 1109 | 31.13.77.0/24 1110 | 31.13.78.0/24 1111 | 31.13.79.0/24 1112 | 31.13.81.0/24 1113 | 31.13.91.0/24 1114 | 31.13.92.0/24 1115 | 31.13.93.0/24 1116 | 31.13.95.0/24 1117 | 31.192.117.0/24 1118 | 31.192.122.0/24 1119 | 37.187.147.0/24 1120 | 37.235.55.0/24 1121 | 37.48.106.0/24 1122 | 37.61.54.0/24 1123 | 38.127.224.0/24 1124 | 38.229.72.0/24 1125 | 38.99.78.0/24 1126 | 40.112.188.0/24 1127 | 40.113.87.0/24 1128 | 40.114.149.0/24 1129 | 40.115.1.0/24 1130 | 40.117.100.0/24 1131 | 40.117.145.0/24 1132 | 40.118.214.0/24 1133 | 40.127.129.0/24 1134 | 40.78.98.0/24 1135 | 42.120.158.0/24 1136 | 42.99.254.0/24 1137 | 43.249.73.0/24 1138 | 43.249.75.0/24 1139 | 4.36.66.0/24 1140 | 45.55.202.0/24 1141 | 45.58.70.0/24 1142 | 45.58.74.0/24 1143 | 45.64.64.0/24 1144 | 45.79.109.0/24 1145 | 45.79.99.0/24 1146 | 46.105.55.0/24 1147 | 46.51.216.0/24 1148 | 46.82.174.0/24 1149 | 50.116.12.0/24 1150 | 50.116.20.0/24 1151 | 50.116.33.0/24 1152 | 50.116.51.0/24 1153 | 50.16.185.0/24 1154 | 50.16.192.0/24 1155 | 50.16.194.0/24 1156 | 50.16.197.0/24 1157 | 50.16.199.0/24 1158 | 50.16.204.0/24 1159 | 50.16.209.0/24 1160 | 50.16.213.0/24 1161 | 50.16.214.0/24 1162 | 50.16.224.0/24 1163 | 50.16.226.0/24 1164 | 50.16.230.0/24 1165 | 50.16.231.0/24 1166 | 50.16.233.0/24 1167 | 50.16.234.0/24 1168 | 50.16.237.0/24 1169 | 50.16.238.0/24 1170 | 50.16.239.0/24 1171 | 50.16.241.0/24 1172 | 50.16.243.0/24 1173 | 50.16.245.0/24 1174 | 50.16.246.0/24 1175 | 50.16.250.0/24 1176 | 50.17.130.0/24 1177 | 50.17.184.0/24 1178 | 50.17.189.0/24 1179 | 50.17.191.0/24 1180 | 50.17.194.0/24 1181 | 50.17.207.0/24 1182 | 50.17.208.0/24 1183 | 50.17.218.0/24 1184 | 50.17.219.0/24 1185 | 50.17.228.0/24 1186 | 50.17.236.0/24 1187 | 50.17.238.0/24 1188 | 50.17.239.0/24 1189 | 50.17.241.0/24 1190 | 50.17.254.0/24 1191 | 50.18.192.0/24 1192 | 50.19.102.0/24 1193 | 50.19.106.0/24 1194 | 50.19.116.0/24 1195 | 50.19.118.0/24 1196 | 50.19.120.0/24 1197 | 50.19.122.0/24 1198 | 50.19.212.0/24 1199 | 50.19.213.0/24 1200 | 50.19.217.0/24 1201 | 50.19.221.0/24 1202 | 50.19.234.0/24 1203 | 50.19.241.0/24 1204 | 50.19.247.0/24 1205 | 50.19.252.0/24 1206 | 50.19.82.0/24 1207 | 50.19.85.0/24 1208 | 50.19.86.0/24 1209 | 50.19.88.0/24 1210 | 50.19.95.0/24 1211 | 50.19.96.0/24 1212 | 50.202.217.0/24 1213 | 50.22.239.0/24 1214 | 50.23.146.0/24 1215 | 50.63.202.0/24 1216 | 5.135.190.0/24 1217 | 5.153.24.0/24 1218 | 52.0.115.0/24 1219 | 52.0.146.0/24 1220 | 52.0.149.0/24 1221 | 52.0.154.0/24 1222 | 52.0.218.0/24 1223 | 52.0.227.0/24 1224 | 52.0.233.0/24 1225 | 52.0.238.0/24 1226 | 52.0.42.0/24 1227 | 52.0.46.0/24 1228 | 52.0.57.0/24 1229 | 52.0.67.0/24 1230 | 52.0.68.0/24 1231 | 52.0.75.0/24 1232 | 52.10.204.0/24 1233 | 52.1.16.0/24 1234 | 52.1.176.0/24 1235 | 52.1.199.0/24 1236 | 52.1.207.0/24 1237 | 52.1.210.0/24 1238 | 52.1.217.0/24 1239 | 52.1.220.0/24 1240 | 52.1.22.0/24 1241 | 52.1.25.0/24 1242 | 52.1.27.0/24 1243 | 52.1.32.0/24 1244 | 52.1.47.0/24 1245 | 52.1.49.0/24 1246 | 52.1.64.0/24 1247 | 52.1.98.0/24 1248 | 52.20.112.0/24 1249 | 52.20.119.0/24 1250 | 52.20.125.0/24 1251 | 52.20.126.0/24 1252 | 52.20.128.0/24 1253 | 52.20.129.0/24 1254 | 52.20.140.0/24 1255 | 52.20.14.0/24 1256 | 52.20.163.0/24 1257 | 52.20.170.0/24 1258 | 52.20.178.0/24 1259 | 52.20.183.0/24 1260 | 52.20.194.0/24 1261 | 52.20.205.0/24 1262 | 52.20.216.0/24 1263 | 52.20.239.0/24 1264 | 52.20.41.0/24 1265 | 52.20.43.0/24 1266 | 52.20.46.0/24 1267 | 52.20.74.0/24 1268 | 52.20.78.0/24 1269 | 52.20.79.0/24 1270 | 52.20.82.0/24 1271 | 52.20.86.0/24 1272 | 52.20.91.0/24 1273 | 52.2.100.0/24 1274 | 52.21.176.0/24 1275 | 52.21.183.0/24 1276 | 52.21.184.0/24 1277 | 52.21.190.0/24 1278 | 52.21.219.0/24 1279 | 52.2.125.0/24 1280 | 52.21.33.0/24 1281 | 52.21.34.0/24 1282 | 52.21.37.0/24 1283 | 52.2.145.0/24 1284 | 52.21.47.0/24 1285 | 52.2.162.0/24 1286 | 52.2.166.0/24 1287 | 52.2.18.0/24 1288 | 52.21.81.0/24 1289 | 52.2.182.0/24 1290 | 52.21.89.0/24 1291 | 52.21.93.0/24 1292 | 52.2.194.0/24 1293 | 52.2.207.0/24 1294 | 52.22.114.0/24 1295 | 52.22.118.0/24 1296 | 52.22.140.0/24 1297 | 52.22.146.0/24 1298 | 52.2.215.0/24 1299 | 52.22.171.0/24 1300 | 52.22.186.0/24 1301 | 52.22.200.0/24 1302 | 52.22.201.0/24 1303 | 52.22.204.0/24 1304 | 52.22.228.0/24 1305 | 52.22.240.0/24 1306 | 52.22.247.0/24 1307 | 52.22.252.0/24 1308 | 52.22.31.0/24 1309 | 52.22.37.0/24 1310 | 52.2.245.0/24 1311 | 52.2.250.0/24 1312 | 52.2.253.0/24 1313 | 52.24.145.0/24 1314 | 52.24.240.0/24 1315 | 52.2.46.0/24 1316 | 52.2.47.0/24 1317 | 52.2.55.0/24 1318 | 52.2.65.0/24 1319 | 52.2.68.0/24 1320 | 52.2.9.0/24 1321 | 52.3.1.0/24 1322 | 52.3.107.0/24 1323 | 52.3.115.0/24 1324 | 52.3.143.0/24 1325 | 52.3.148.0/24 1326 | 52.3.162.0/24 1327 | 52.3.177.0/24 1328 | 52.3.178.0/24 1329 | 52.3.199.0/24 1330 | 52.3.203.0/24 1331 | 52.3.212.0/24 1332 | 52.33.98.0/24 1333 | 52.3.62.0/24 1334 | 52.3.85.0/24 1335 | 52.3.98.0/24 1336 | 52.4.102.0/24 1337 | 52.4.109.0/24 1338 | 52.4.114.0/24 1339 | 52.4.117.0/24 1340 | 52.4.118.0/24 1341 | 52.4.127.0/24 1342 | 52.4.128.0/24 1343 | 52.4.150.0/24 1344 | 52.4.156.0/24 1345 | 52.4.158.0/24 1346 | 52.4.160.0/24 1347 | 52.4.16.0/24 1348 | 52.4.161.0/24 1349 | 52.4.181.0/24 1350 | 52.4.183.0/24 1351 | 52.4.193.0/24 1352 | 52.4.200.0/24 1353 | 52.4.203.0/24 1354 | 52.4.204.0/24 1355 | 52.4.211.0/24 1356 | 52.4.220.0/24 1357 | 52.4.228.0/24 1358 | 52.4.247.0/24 1359 | 52.4.41.0/24 1360 | 52.4.50.0/24 1361 | 52.4.6.0/24 1362 | 52.4.62.0/24 1363 | 52.4.80.0/24 1364 | 52.5.109.0/24 1365 | 52.5.115.0/24 1366 | 52.5.116.0/24 1367 | 52.5.122.0/24 1368 | 52.5.123.0/24 1369 | 52.5.127.0/24 1370 | 52.5.130.0/24 1371 | 52.5.153.0/24 1372 | 52.5.181.0/24 1373 | 52.5.187.0/24 1374 | 52.5.198.0/24 1375 | 52.5.201.0/24 1376 | 52.5.202.0/24 1377 | 52.5.203.0/24 1378 | 52.5.212.0/24 1379 | 52.5.233.0/24 1380 | 52.5.236.0/24 1381 | 52.5.238.0/24 1382 | 52.5.249.0/24 1383 | 52.5.5.0/24 1384 | 52.5.51.0/24 1385 | 5.255.87.0/24 1386 | 52.5.63.0/24 1387 | 52.5.69.0/24 1388 | 52.5.96.0/24 1389 | 52.5.98.0/24 1390 | 52.6.115.0/24 1391 | 52.6.133.0/24 1392 | 52.6.156.0/24 1393 | 52.6.165.0/24 1394 | 52.6.171.0/24 1395 | 52.6.179.0/24 1396 | 52.6.188.0/24 1397 | 52.6.19.0/24 1398 | 52.6.214.0/24 1399 | 52.6.215.0/24 1400 | 52.6.22.0/24 1401 | 52.6.225.0/24 1402 | 52.6.23.0/24 1403 | 52.6.232.0/24 1404 | 52.6.246.0/24 1405 | 52.6.251.0/24 1406 | 52.6.255.0/24 1407 | 52.6.27.0/24 1408 | 52.6.56.0/24 1409 | 52.6.74.0/24 1410 | 52.6.76.0/24 1411 | 52.6.79.0/24 1412 | 52.6.8.0/24 1413 | 52.6.85.0/24 1414 | 52.69.101.0/24 1415 | 52.69.58.0/24 1416 | 52.7.106.0/24 1417 | 52.7.137.0/24 1418 | 52.7.144.0/24 1419 | 52.7.147.0/24 1420 | 52.7.149.0/24 1421 | 52.7.15.0/24 1422 | 52.7.153.0/24 1423 | 52.7.155.0/24 1424 | 52.7.174.0/24 1425 | 52.7.181.0/24 1426 | 52.7.183.0/24 1427 | 52.7.187.0/24 1428 | 52.7.206.0/24 1429 | 52.7.208.0/24 1430 | 52.7.211.0/24 1431 | 52.7.212.0/24 1432 | 52.7.215.0/24 1433 | 52.7.218.0/24 1434 | 52.7.225.0/24 1435 | 52.7.230.0/24 1436 | 52.7.245.0/24 1437 | 52.7.25.0/24 1438 | 52.7.31.0/24 1439 | 52.7.33.0/24 1440 | 52.7.50.0/24 1441 | 52.7.7.0/24 1442 | 52.7.74.0/24 1443 | 52.7.8.0/24 1444 | 52.84.21.0/24 1445 | 5.35.253.0/24 1446 | 54.148.2.0/24 1447 | 54.152.111.0/24 1448 | 54.152.118.0/24 1449 | 54.152.121.0/24 1450 | 54.152.122.0/24 1451 | 54.152.123.0/24 1452 | 54.152.147.0/24 1453 | 54.152.15.0/24 1454 | 54.152.159.0/24 1455 | 54.152.178.0/24 1456 | 54.152.192.0/24 1457 | 54.152.226.0/24 1458 | 54.152.23.0/24 1459 | 54.152.6.0/24 1460 | 54.152.62.0/24 1461 | 54.152.93.0/24 1462 | 54.163.247.0/24 1463 | 54.163.249.0/24 1464 | 54.164.12.0/24 1465 | 54.164.123.0/24 1466 | 54.164.129.0/24 1467 | 54.164.134.0/24 1468 | 54.164.135.0/24 1469 | 54.164.136.0/24 1470 | 54.164.139.0/24 1471 | 54.164.187.0/24 1472 | 54.164.204.0/24 1473 | 54.164.206.0/24 1474 | 54.164.207.0/24 1475 | 54.164.222.0/24 1476 | 54.164.229.0/24 1477 | 54.164.237.0/24 1478 | 54.164.245.0/24 1479 | 54.164.246.0/24 1480 | 54.164.250.0/24 1481 | 54.164.253.0/24 1482 | 54.164.32.0/24 1483 | 54.164.4.0/24 1484 | 54.164.44.0/24 1485 | 54.164.73.0/24 1486 | 54.164.82.0/24 1487 | 54.164.9.0/24 1488 | 54.164.96.0/24 1489 | 54.165.103.0/24 1490 | 54.165.112.0/24 1491 | 54.165.127.0/24 1492 | 54.165.136.0/24 1493 | 54.165.142.0/24 1494 | 54.165.166.0/24 1495 | 54.165.169.0/24 1496 | 54.165.172.0/24 1497 | 54.165.181.0/24 1498 | 54.165.189.0/24 1499 | 54.165.19.0/24 1500 | 54.165.191.0/24 1501 | 54.165.196.0/24 1502 | 54.165.203.0/24 1503 | 54.165.209.0/24 1504 | 54.165.223.0/24 1505 | 54.165.28.0/24 1506 | 54.165.30.0/24 1507 | 54.165.3.0/24 1508 | 54.165.34.0/24 1509 | 54.165.39.0/24 1510 | 54.165.64.0/24 1511 | 54.165.71.0/24 1512 | 54.165.72.0/24 1513 | 54.165.76.0/24 1514 | 54.165.77.0/24 1515 | 54.165.86.0/24 1516 | 54.165.88.0/24 1517 | 54.165.96.0/24 1518 | 54.165.99.0/24 1519 | 54.169.181.0/24 1520 | 54.172.111.0/24 1521 | 54.172.121.0/24 1522 | 54.172.14.0/24 1523 | 54.172.147.0/24 1524 | 54.172.171.0/24 1525 | 54.172.19.0/24 1526 | 54.172.193.0/24 1527 | 54.172.197.0/24 1528 | 54.172.201.0/24 1529 | 54.172.208.0/24 1530 | 54.172.24.0/24 1531 | 54.172.26.0/24 1532 | 54.172.40.0/24 1533 | 54.172.70.0/24 1534 | 54.172.91.0/24 1535 | 54.173.106.0/24 1536 | 54.173.118.0/24 1537 | 54.173.128.0/24 1538 | 54.173.13.0/24 1539 | 54.173.140.0/24 1540 | 54.173.166.0/24 1541 | 54.173.174.0/24 1542 | 54.173.191.0/24 1543 | 54.173.200.0/24 1544 | 54.173.230.0/24 1545 | 54.173.239.0/24 1546 | 54.173.39.0/24 1547 | 54.173.52.0/24 1548 | 54.173.70.0/24 1549 | 54.173.72.0/24 1550 | 54.173.74.0/24 1551 | 54.173.82.0/24 1552 | 54.173.92.0/24 1553 | 54.173.98.0/24 1554 | 54.174.107.0/24 1555 | 54.174.13.0/24 1556 | 54.174.137.0/24 1557 | 54.174.14.0/24 1558 | 54.174.166.0/24 1559 | 54.174.174.0/24 1560 | 54.174.189.0/24 1561 | 54.174.197.0/24 1562 | 54.174.201.0/24 1563 | 54.174.211.0/24 1564 | 54.174.217.0/24 1565 | 54.174.22.0/24 1566 | 54.174.26.0/24 1567 | 54.174.46.0/24 1568 | 54.174.64.0/24 1569 | 54.174.79.0/24 1570 | 54.175.1.0/24 1571 | 54.175.129.0/24 1572 | 54.175.147.0/24 1573 | 54.175.177.0/24 1574 | 54.175.182.0/24 1575 | 54.175.229.0/24 1576 | 54.175.239.0/24 1577 | 54.175.25.0/24 1578 | 54.175.31.0/24 1579 | 54.175.51.0/24 1580 | 54.175.59.0/24 1581 | 54.175.63.0/24 1582 | 54.175.73.0/24 1583 | 54.175.77.0/24 1584 | 54.182.0.0/24 1585 | 54.182.1.0/24 1586 | 54.182.2.0/24 1587 | 54.182.3.0/24 1588 | 54.182.4.0/24 1589 | 54.182.5.0/24 1590 | 54.183.130.0/24 1591 | 54.183.131.0/24 1592 | 54.183.132.0/24 1593 | 54.183.150.0/24 1594 | 54.183.81.0/24 1595 | 54.187.170.0/24 1596 | 54.192.101.0/24 1597 | 54.192.102.0/24 1598 | 54.192.116.0/24 1599 | 54.192.117.0/24 1600 | 54.192.119.0/24 1601 | 54.192.137.0/24 1602 | 54.192.138.0/24 1603 | 54.192.139.0/24 1604 | 54.192.140.0/24 1605 | 54.192.144.0/24 1606 | 54.192.145.0/24 1607 | 54.192.156.0/24 1608 | 54.192.157.0/24 1609 | 54.192.158.0/24 1610 | 54.192.19.0/24 1611 | 54.192.195.0/24 1612 | 54.192.232.0/24 1613 | 54.192.34.0/24 1614 | 54.192.35.0/24 1615 | 54.192.6.0/24 1616 | 54.192.68.0/24 1617 | 54.192.69.0/24 1618 | 54.192.70.0/24 1619 | 54.192.7.0/24 1620 | 54.192.71.0/24 1621 | 54.192.72.0/24 1622 | 54.192.73.0/24 1623 | 54.192.74.0/24 1624 | 54.192.75.0/24 1625 | 54.192.77.0/24 1626 | 54.192.79.0/24 1627 | 54.192.87.0/24 1628 | 54.192.91.0/24 1629 | 54.197.223.0/24 1630 | 54.197.234.0/24 1631 | 54.197.246.0/24 1632 | 54.197.247.0/24 1633 | 54.197.248.0/24 1634 | 54.197.252.0/24 1635 | 54.197.255.0/24 1636 | 54.198.109.0/24 1637 | 54.198.248.0/24 1638 | 54.201.118.0/24 1639 | 54.204.12.0/24 1640 | 54.204.18.0/24 1641 | 54.204.19.0/24 1642 | 54.204.22.0/24 1643 | 54.204.23.0/24 1644 | 54.204.24.0/24 1645 | 54.204.6.0/24 1646 | 54.204.8.0/24 1647 | 54.205.77.0/24 1648 | 54.208.0.0/24 1649 | 54.208.222.0/24 1650 | 54.208.246.0/24 1651 | 54.208.252.0/24 1652 | 54.208.28.0/24 1653 | 54.208.38.0/24 1654 | 54.208.58.0/24 1655 | 54.208.69.0/24 1656 | 54.208.88.0/24 1657 | 54.208.99.0/24 1658 | 54.209.111.0/24 1659 | 54.209.119.0/24 1660 | 54.209.12.0/24 1661 | 54.209.128.0/24 1662 | 54.209.139.0/24 1663 | 54.209.14.0/24 1664 | 54.209.148.0/24 1665 | 54.209.164.0/24 1666 | 54.209.168.0/24 1667 | 54.209.172.0/24 1668 | 54.209.187.0/24 1669 | 54.209.197.0/24 1670 | 54.209.199.0/24 1671 | 54.209.200.0/24 1672 | 54.209.218.0/24 1673 | 54.209.230.0/24 1674 | 54.209.247.0/24 1675 | 54.209.6.0/24 1676 | 54.209.9.0/24 1677 | 54.210.0.0/24 1678 | 54.210.102.0/24 1679 | 54.210.12.0/24 1680 | 54.210.141.0/24 1681 | 54.210.143.0/24 1682 | 54.210.163.0/24 1683 | 54.210.164.0/24 1684 | 54.210.167.0/24 1685 | 54.210.189.0/24 1686 | 54.210.191.0/24 1687 | 54.210.207.0/24 1688 | 54.210.210.0/24 1689 | 54.210.226.0/24 1690 | 54.210.23.0/24 1691 | 54.210.247.0/24 1692 | 54.210.42.0/24 1693 | 54.210.96.0/24 1694 | 54.215.176.0/24 1695 | 54.217.203.0/24 1696 | 54.217.236.0/24 1697 | 54.221.192.0/24 1698 | 54.221.198.0/24 1699 | 54.221.201.0/24 1700 | 54.221.207.0/24 1701 | 54.221.212.0/24 1702 | 54.221.213.0/24 1703 | 54.221.214.0/24 1704 | 54.221.218.0/24 1705 | 54.221.222.0/24 1706 | 54.221.224.0/24 1707 | 54.221.225.0/24 1708 | 54.221.248.0/24 1709 | 54.221.254.0/24 1710 | 54.223.204.0/24 1711 | 54.223.217.0/24 1712 | 54.223.235.0/24 1713 | 54.223.237.0/24 1714 | 54.225.100.0/24 1715 | 54.225.113.0/24 1716 | 54.225.121.0/24 1717 | 54.225.125.0/24 1718 | 54.225.130.0/24 1719 | 54.225.131.0/24 1720 | 54.225.134.0/24 1721 | 54.225.137.0/24 1722 | 54.225.138.0/24 1723 | 54.225.141.0/24 1724 | 54.225.142.0/24 1725 | 54.225.149.0/24 1726 | 54.225.159.0/24 1727 | 54.225.160.0/24 1728 | 54.225.161.0/24 1729 | 54.225.162.0/24 1730 | 54.225.163.0/24 1731 | 54.225.164.0/24 1732 | 54.225.166.0/24 1733 | 54.225.167.0/24 1734 | 54.225.171.0/24 1735 | 54.225.174.0/24 1736 | 54.225.176.0/24 1737 | 54.225.177.0/24 1738 | 54.225.181.0/24 1739 | 54.225.185.0/24 1740 | 54.225.187.0/24 1741 | 54.225.198.0/24 1742 | 54.225.199.0/24 1743 | 54.225.200.0/24 1744 | 54.225.201.0/24 1745 | 54.225.202.0/24 1746 | 54.225.203.0/24 1747 | 54.225.206.0/24 1748 | 54.225.210.0/24 1749 | 54.225.215.0/24 1750 | 54.225.217.0/24 1751 | 54.225.219.0/24 1752 | 54.225.222.0/24 1753 | 54.225.225.0/24 1754 | 54.225.228.0/24 1755 | 54.225.237.0/24 1756 | 54.225.247.0/24 1757 | 54.225.248.0/24 1758 | 54.225.64.0/24 1759 | 54.225.71.0/24 1760 | 54.225.86.0/24 1761 | 54.225.92.0/24 1762 | 54.227.33.0/24 1763 | 54.230.116.0/24 1764 | 54.230.117.0/24 1765 | 54.230.118.0/24 1766 | 54.230.124.0/24 1767 | 54.230.137.0/24 1768 | 54.230.138.0/24 1769 | 54.230.139.0/24 1770 | 54.230.140.0/24 1771 | 54.230.145.0/24 1772 | 54.230.146.0/24 1773 | 54.230.147.0/24 1774 | 54.230.148.0/24 1775 | 54.230.150.0/24 1776 | 54.230.151.0/24 1777 | 54.230.156.0/24 1778 | 54.230.158.0/24 1779 | 54.230.159.0/24 1780 | 54.230.16.0/24 1781 | 54.230.18.0/24 1782 | 54.230.19.0/24 1783 | 54.230.192.0/24 1784 | 54.230.194.0/24 1785 | 54.230.195.0/24 1786 | 54.230.32.0/24 1787 | 54.230.33.0/24 1788 | 54.230.4.0/24 1789 | 54.230.5.0/24 1790 | 54.230.68.0/24 1791 | 54.230.69.0/24 1792 | 54.230.70.0/24 1793 | 54.230.71.0/24 1794 | 54.230.72.0/24 1795 | 54.230.73.0/24 1796 | 54.230.74.0/24 1797 | 54.230.75.0/24 1798 | 54.230.76.0/24 1799 | 54.230.77.0/24 1800 | 54.230.78.0/24 1801 | 54.230.79.0/24 1802 | 54.230.87.0/24 1803 | 54.231.0.0/24 1804 | 54.231.10.0/24 1805 | 54.231.1.0/24 1806 | 54.231.11.0/24 1807 | 54.231.112.0/24 1808 | 54.231.113.0/24 1809 | 54.231.114.0/24 1810 | 54.231.12.0/24 1811 | 54.231.13.0/24 1812 | 54.231.14.0/24 1813 | 54.231.15.0/24 1814 | 54.231.16.0/24 1815 | 54.231.17.0/24 1816 | 54.231.18.0/24 1817 | 54.231.19.0/24 1818 | 54.231.2.0/24 1819 | 54.231.244.0/24 1820 | 54.231.32.0/24 1821 | 54.231.33.0/24 1822 | 54.231.34.0/24 1823 | 54.231.48.0/24 1824 | 54.231.49.0/24 1825 | 54.231.50.0/24 1826 | 54.231.64.0/24 1827 | 54.231.65.0/24 1828 | 54.231.66.0/24 1829 | 54.231.80.0/24 1830 | 54.231.8.0/24 1831 | 54.231.81.0/24 1832 | 54.231.82.0/24 1833 | 54.231.9.0/24 1834 | 54.231.96.0/24 1835 | 54.231.97.0/24 1836 | 54.231.98.0/24 1837 | 54.232.170.0/24 1838 | 54.234.180.0/24 1839 | 54.234.72.0/24 1840 | 54.235.106.0/24 1841 | 54.235.107.0/24 1842 | 54.235.11.0/24 1843 | 54.235.137.0/24 1844 | 54.235.147.0/24 1845 | 54.235.161.0/24 1846 | 54.235.163.0/24 1847 | 54.235.172.0/24 1848 | 54.235.173.0/24 1849 | 54.235.184.0/24 1850 | 54.235.185.0/24 1851 | 54.235.187.0/24 1852 | 54.235.189.0/24 1853 | 54.235.193.0/24 1854 | 54.235.194.0/24 1855 | 54.235.199.0/24 1856 | 54.235.202.0/24 1857 | 54.235.206.0/24 1858 | 54.235.208.0/24 1859 | 54.235.214.0/24 1860 | 54.235.222.0/24 1861 | 54.235.244.0/24 1862 | 54.235.77.0/24 1863 | 54.235.79.0/24 1864 | 54.235.98.0/24 1865 | 54.236.110.0/24 1866 | 54.236.111.0/24 1867 | 54.236.116.0/24 1868 | 54.236.117.0/24 1869 | 54.236.148.0/24 1870 | 54.236.151.0/24 1871 | 54.236.156.0/24 1872 | 54.236.162.0/24 1873 | 54.236.166.0/24 1874 | 54.236.170.0/24 1875 | 54.236.177.0/24 1876 | 54.236.178.0/24 1877 | 54.236.180.0/24 1878 | 54.236.185.0/24 1879 | 54.236.195.0/24 1880 | 54.236.199.0/24 1881 | 54.236.208.0/24 1882 | 54.236.213.0/24 1883 | 54.236.215.0/24 1884 | 54.236.219.0/24 1885 | 54.236.224.0/24 1886 | 54.236.226.0/24 1887 | 54.236.238.0/24 1888 | 54.236.247.0/24 1889 | 54.236.67.0/24 1890 | 54.236.69.0/24 1891 | 54.236.74.0/24 1892 | 54.236.84.0/24 1893 | 54.236.94.0/24 1894 | 54.236.99.0/24 1895 | 54.237.38.0/24 1896 | 54.239.130.0/24 1897 | 54.239.132.0/24 1898 | 54.239.152.0/24 1899 | 54.239.16.0/24 1900 | 54.239.17.0/24 1901 | 54.239.18.0/24 1902 | 54.239.194.0/24 1903 | 54.239.21.0/24 1904 | 54.239.216.0/24 1905 | 54.239.25.0/24 1906 | 54.239.26.0/24 1907 | 54.239.27.0/24 1908 | 54.239.28.0/24 1909 | 54.240.188.0/24 1910 | 54.240.235.0/24 1911 | 54.240.248.0/24 1912 | 54.240.250.0/24 1913 | 54.240.252.0/24 1914 | 54.242.22.0/24 1915 | 54.243.100.0/24 1916 | 54.243.102.0/24 1917 | 54.243.104.0/24 1918 | 54.243.111.0/24 1919 | 54.243.112.0/24 1920 | 54.243.113.0/24 1921 | 54.243.116.0/24 1922 | 54.243.117.0/24 1923 | 54.243.118.0/24 1924 | 54.243.119.0/24 1925 | 54.243.120.0/24 1926 | 54.243.127.0/24 1927 | 54.243.137.0/24 1928 | 54.243.139.0/24 1929 | 54.243.140.0/24 1930 | 54.243.141.0/24 1931 | 54.243.148.0/24 1932 | 54.243.159.0/24 1933 | 54.243.160.0/24 1934 | 54.243.165.0/24 1935 | 54.243.166.0/24 1936 | 54.243.168.0/24 1937 | 54.243.170.0/24 1938 | 54.243.174.0/24 1939 | 54.243.178.0/24 1940 | 54.243.179.0/24 1941 | 54.243.182.0/24 1942 | 54.243.195.0/24 1943 | 54.243.197.0/24 1944 | 54.243.203.0/24 1945 | 54.243.213.0/24 1946 | 54.243.215.0/24 1947 | 54.243.232.0/24 1948 | 54.243.233.0/24 1949 | 54.243.240.0/24 1950 | 54.243.241.0/24 1951 | 54.243.243.0/24 1952 | 54.243.248.0/24 1953 | 54.243.250.0/24 1954 | 54.243.251.0/24 1955 | 54.243.253.0/24 1956 | 54.243.254.0/24 1957 | 54.243.255.0/24 1958 | 54.243.34.0/24 1959 | 54.243.40.0/24 1960 | 54.243.46.0/24 1961 | 54.243.53.0/24 1962 | 54.243.55.0/24 1963 | 54.243.59.0/24 1964 | 54.243.63.0/24 1965 | 54.243.65.0/24 1966 | 54.243.69.0/24 1967 | 54.243.70.0/24 1968 | 54.243.71.0/24 1969 | 54.243.72.0/24 1970 | 54.243.74.0/24 1971 | 54.243.75.0/24 1972 | 54.243.76.0/24 1973 | 54.243.77.0/24 1974 | 54.243.80.0/24 1975 | 54.243.83.0/24 1976 | 54.243.85.0/24 1977 | 54.243.87.0/24 1978 | 54.243.88.0/24 1979 | 54.243.89.0/24 1980 | 54.243.92.0/24 1981 | 54.243.96.0/24 1982 | 54.243.97.0/24 1983 | 54.243.98.0/24 1984 | 54.65.52.0/24 1985 | 54.67.120.0/24 1986 | 54.67.57.0/24 1987 | 54.67.62.0/24 1988 | 54.69.250.0/24 1989 | 54.83.18.0/24 1990 | 54.83.197.0/24 1991 | 54.83.198.0/24 1992 | 54.83.204.0/24 1993 | 54.83.21.0/24 1994 | 54.83.22.0/24 1995 | 54.83.36.0/24 1996 | 54.83.38.0/24 1997 | 54.83.4.0/24 1998 | 54.83.45.0/24 1999 | 54.83.51.0/24 2000 | 54.83.57.0/24 2001 | 54.84.112.0/24 2002 | 54.84.119.0/24 2003 | 54.84.126.0/24 2004 | 54.84.160.0/24 2005 | 54.84.172.0/24 2006 | 54.84.182.0/24 2007 | 54.84.189.0/24 2008 | 54.84.202.0/24 2009 | 54.84.212.0/24 2010 | 54.84.236.0/24 2011 | 54.84.58.0/24 2012 | 54.85.110.0/24 2013 | 54.85.142.0/24 2014 | 54.85.186.0/24 2015 | 54.85.188.0/24 2016 | 54.85.200.0/24 2017 | 54.85.74.0/24 2018 | 54.86.101.0/24 2019 | 54.86.102.0/24 2020 | 54.86.139.0/24 2021 | 54.86.181.0/24 2022 | 54.86.203.0/24 2023 | 54.86.213.0/24 2024 | 54.86.239.0/24 2025 | 54.86.242.0/24 2026 | 54.86.43.0/24 2027 | 54.86.5.0/24 2028 | 54.86.58.0/24 2029 | 54.86.78.0/24 2030 | 54.86.97.0/24 2031 | 54.87.207.0/24 2032 | 54.88.101.0/24 2033 | 54.88.108.0/24 2034 | 54.88.128.0/24 2035 | 54.88.130.0/24 2036 | 54.88.151.0/24 2037 | 54.88.153.0/24 2038 | 54.88.158.0/24 2039 | 54.88.185.0/24 2040 | 54.88.187.0/24 2041 | 54.88.193.0/24 2042 | 54.88.21.0/24 2043 | 54.88.218.0/24 2044 | 54.88.226.0/24 2045 | 54.88.232.0/24 2046 | 54.88.233.0/24 2047 | 54.88.245.0/24 2048 | 54.88.3.0/24 2049 | 54.88.36.0/24 2050 | 54.88.54.0/24 2051 | 54.88.68.0/24 2052 | 54.88.78.0/24 2053 | 54.88.80.0/24 2054 | 54.88.91.0/24 2055 | 58.176.234.0/24 2056 | 58.176.48.0/24 2057 | 58.176.49.0/24 2058 | 58.26.1.0/24 2059 | 58.26.185.0/24 2060 | 58.27.22.0/24 2061 | 58.27.86.0/24 2062 | 58.64.155.0/24 2063 | 59.108.49.0/24 2064 | 59.188.18.0/24 2065 | 59.24.3.0/24 2066 | 59.56.26.0/24 2067 | 60.199.217.0/24 2068 | 60.210.18.0/24 2069 | 60.250.9.0/24 2070 | 60.254.131.0/24 2071 | 60.254.132.0/24 2072 | 60.254.134.0/24 2073 | 60.254.135.0/24 2074 | 60.254.169.0/24 2075 | 60.254.170.0/24 2076 | 61.167.54.0/24 2077 | 61.200.88.0/24 2078 | 61.213.151.0/24 2079 | 61.213.171.0/24 2080 | 61.213.181.0/24 2081 | 61.215.215.0/24 2082 | 61.219.39.0/24 2083 | 61.238.158.0/24 2084 | 61.238.191.0/24 2085 | 61.244.110.0/24 2086 | 61.57.48.0/24 2087 | 61.60.96.0/24 2088 | 61.64.127.0/24 2089 | 63.135.90.0/24 2090 | 63.141.194.0/24 2091 | 63.243.241.0/24 2092 | 64.150.189.0/24 2093 | 64.150.191.0/24 2094 | 64.233.160.0/24 2095 | 64.233.162.0/24 2096 | 64.233.163.0/24 2097 | 64.233.164.0/24 2098 | 64.233.165.0/24 2099 | 64.233.177.0/24 2100 | 64.233.180.0/24 2101 | 64.233.185.0/24 2102 | 64.233.186.0/24 2103 | 64.233.187.0/24 2104 | 64.233.188.0/24 2105 | 64.233.189.0/24 2106 | 64.233.190.0/24 2107 | 64.233.191.0/24 2108 | 64.38.230.0/24 2109 | 64.78.173.0/24 2110 | 65.118.123.0/24 2111 | 65.122.127.0/24 2112 | 65.254.250.0/24 2113 | 65.52.160.0/24 2114 | 65.55.157.0/24 2115 | 66.220.146.0/24 2116 | 66.220.156.0/24 2117 | 66.220.158.0/24 2118 | 66.228.45.0/24 2119 | 66.29.212.0/24 2120 | 67.131.104.0/24 2121 | 67.227.136.0/24 2122 | 68.232.44.0/24 2123 | 68.232.45.0/24 2124 | 68.234.31.0/24 2125 | 69.147.76.0/24 2126 | 69.163.131.0/24 2127 | 69.167.138.0/24 2128 | 69.171.230.0/24 2129 | 69.171.237.0/24 2130 | 69.192.3.0/24 2131 | 69.192.4.0/24 2132 | 69.31.136.0/24 2133 | 69.58.188.0/24 2134 | 69.73.132.0/24 2135 | 71.19.145.0/24 2136 | 72.11.150.0/24 2137 | 72.21.194.0/24 2138 | 72.21.203.0/24 2139 | 72.21.206.0/24 2140 | 72.21.211.0/24 2141 | 72.21.214.0/24 2142 | 72.21.215.0/24 2143 | 72.21.81.0/24 2144 | 72.21.91.0/24 2145 | 72.21.92.0/24 2146 | 72.246.103.0/24 2147 | 72.246.121.0/24 2148 | 72.246.161.0/24 2149 | 72.246.188.0/24 2150 | 72.246.189.0/24 2151 | 72.246.204.0/24 2152 | 72.246.205.0/24 2153 | 72.246.221.0/24 2154 | 72.246.35.0/24 2155 | 72.247.118.0/24 2156 | 72.247.169.0/24 2157 | 72.247.177.0/24 2158 | 72.247.235.0/24 2159 | 72.247.8.0/24 2160 | 72.247.9.0/24 2161 | 72.27.230.0/24 2162 | 72.8.141.0/24 2163 | 74.112.131.0/24 2164 | 74.113.233.0/24 2165 | 74.113.237.0/24 2166 | 74.120.180.0/24 2167 | 74.125.127.0/24 2168 | 74.125.130.0/24 2169 | 74.125.133.0/24 2170 | 74.125.135.0/24 2171 | 74.125.136.0/24 2172 | 74.125.141.0/24 2173 | 74.125.193.0/24 2174 | 74.125.196.0/24 2175 | 74.125.198.0/24 2176 | 74.125.200.0/24 2177 | 74.125.20.0/24 2178 | 74.125.201.0/24 2179 | 74.125.203.0/24 2180 | 74.125.204.0/24 2181 | 74.125.205.0/24 2182 | 74.125.206.0/24 2183 | 74.125.21.0/24 2184 | 74.125.22.0/24 2185 | 74.125.224.0/24 2186 | 74.125.225.0/24 2187 | 74.125.226.0/24 2188 | 74.125.227.0/24 2189 | 74.125.228.0/24 2190 | 74.125.23.0/24 2191 | 74.125.235.0/24 2192 | 74.125.237.0/24 2193 | 74.125.239.0/24 2194 | 74.125.24.0/24 2195 | 74.125.28.0/24 2196 | 74.125.31.0/24 2197 | 74.125.39.0/24 2198 | 74.125.68.0/24 2199 | 74.125.70.0/24 2200 | 74.82.5.0/24 2201 | 75.101.147.0/24 2202 | 75.101.150.0/24 2203 | 75.101.153.0/24 2204 | 75.101.156.0/24 2205 | 75.126.104.0/24 2206 | 75.126.118.0/24 2207 | 75.126.59.0/24 2208 | 77.244.254.0/24 2209 | 77.67.28.0/24 2210 | 77.93.214.0/24 2211 | 79.170.40.0/24 2212 | 80.231.228.0/24 2213 | 80.239.152.0/24 2214 | 80.67.28.0/24 2215 | 80.94.3.0/24 2216 | 82.145.215.0/24 2217 | 82.195.75.0/24 2218 | 86.59.30.0/24 2219 | 87.245.202.0/24 2220 | 88.208.34.0/24 2221 | 88.221.144.0/24 2222 | 88.85.84.0/24 2223 | 89.238.129.0/24 2224 | 89.248.162.0/24 2225 | 91.108.0.0/16 2226 | 91.189.88.0/24 2227 | 91.189.91.0/24 2228 | 91.189.92.0/24 2229 | 91.198.174.0/24 2230 | 91.198.22.0/24 2231 | 91.250.81.0/24 2232 | 92.122.212.0/24 2233 | 93.184.216.0/24 2234 | 93.185.104.0/24 2235 | 93.95.227.0/24 2236 | 94.199.254.0/24 2237 | 95.101.78.0/24 2238 | 95.215.44.0/24 2239 | 96.17.151.0/24 2240 | 96.17.199.0/24 2241 | 96.17.72.0/24 2242 | 96.44.184.0/24 2243 | 96.6.122.0/24 2244 | 96.6.64.0/24 2245 | 96.6.71.0/24 2246 | 96.7.104.0/24 2247 | 96.7.105.0/24 2248 | 96.7.110.0/24 2249 | 96.7.111.0/24 2250 | 96.7.161.0/24 2251 | 96.7.53.0/24 2252 | 96.7.54.0/24 2253 | 96.7.55.0/24 2254 | 96.7.64.0/24 2255 | 96.7.69.0/24 2256 | 96.7.97.0/24 2257 | 98.124.198.0/24 2258 | 98.124.199.0/24 2259 | 98.129.174.0/24 2260 | 98.129.229.0/24 2261 | 98.137.201.0/24 2262 | 98.137.236.0/24 2263 | -------------------------------------------------------------------------------- /misc/docs/gotunnel-kone-work-together.md: -------------------------------------------------------------------------------- 1 | # gotunnel和kone的珠联璧合 2 | 3 | 4 | ## 分工 5 | * [gotunnel]( https://github.com/xjdrew/gotunnel )负责打通内外,创建一个可用的proxy通道,当然,创建通道需要配合squid/ATS等传统proxy软件 6 | * kone负责做路由转发,实现透明xx 7 | 8 | ## 流程 9 | 一个典型的流程是这样的: 10 | * 首先在长城墙外申请一个XX云/linode之类的VPS,我们称为梯子的落点 11 | * 然后在国内的XX云也申请一个VPS,我们称为梯子的起点 12 | * 选择梯子的起点和落点,需要保证起点和落点之间的ping值质量要高,举个栗子,起点选择XX云的杭州节点,落点选择同一家公司的新加坡节点,因为是同一家公司的VPS,所以它们不同节点之间的网络质量还是有保证的 13 | * 有人会问,梯子起点能选择自己公司或者家里的网络出口吗?可以当然是可以,但到梯子落点的网络质量难以保证,而且容易被监控,选择服务商的VPS做起点,一来可以撇清关系,二来可以随时更换VPS,是不是更好? 14 | * 在梯子落点安装squid/ATS,在梯子起点与落点之间使用gotunnel搭建一条通道,通道最终指向squid/ATS,具体方法可参考[gotunnel](https://github.com/xjdrew/gotunnel)上的说明 15 | * 如果要更加安全,可以从公司或者家里的出口,也使用gotunnel做一条通道到梯子的起点 16 | ``` 17 | [home/office] ---gotunnel---> [梯子起点] ---gotunnel---> [梯子落点] ----> squid/ATS 18 | ``` 19 | * 最后按照 [在一个200人的企业中使用kone](./kone-in-ent-network.md)提供的方法,把需要xx的流量都转到这条proxy通道上即可 20 | * 除了使用kone的dns欺骗功能实现xx,更好的做法是在网关上启用策略路由,把需要xx的IP地址池全部指向kone创建的虚拟口tun0,这样流程会更加干净,而且对所有用户都是透明的,做法如下:kone启动,创建虚拟口tun0,虚拟地址为10.19.0.1,然后跑以下脚本 21 | ``` 22 | #!/bin/bash 23 | 24 | ####在策略路由中创建一个名为fanqiang的路由链,路由指向为tun0 25 | ip route delete default dev tun0 table fanqiang 26 | ip route add default dev tun0 table fanqiang 27 | 28 | #### 删除原来的fanqiang链中的策略 29 | ip rule show | egrep "lookup fanqiang" | awk '{print $5}' | sort | uniq > /etc/fanqiang_del.list 30 | for i in `cat /etc/fanqiang_del.list` 31 | do 32 | ip rule delete to ${i} table fanqiang 33 | done 34 | 35 | ####重新生成一次fanqiang路由链 36 | for p in `cat /etc/fanqiang.list` ##fanqiang.list为平时收集的需要xx的IP段 37 | do 38 | ip rule add to ${p} table fanqiang pref 77 ##fanqiang链的优先级设定为77,自行调配 39 | done 40 | 41 | ####刷新一次策略路由使其生效 42 | ip route flush cache 43 | ``` 44 | 45 | * 附上收集的需要xx的2000多个IP段[fanqiang.list]( ./fanqiang.list ) ,和久经考验的[squid.conf]( ./squid.conf ) 46 | 47 | -------------------------------------------------------------------------------- /misc/docs/how-to-use-with-raspberry-pi.md: -------------------------------------------------------------------------------- 1 | # 在树莓派上使用kone 2 | 3 | kone完全基于go语言开发,需要依赖linux 2.2.x以上内核版本。从go1.6开始,go官方提供ARMv6架构的预编译安装包,使得在树莓派上部署go程序非常方便。 4 | 5 | ## 硬件需求 6 | 7 | 1. 需要一个可以更改静态路由的路由器。 8 | 9 | 普通的非智能路由器,如[tp-link](http://service.tp-link.com.cn/detail_article_28.html)之类,都有这个功能。反而智能路由器,如小米、极路由之类没有开放这个功能。如果你的路由器恰好没有这个功能,那你可以把树莓派改造成路由器,不过这种方法不在这篇文档讨论:-) 10 | 11 | 2. 树莓派可以正常使用互联网。假设树莓派的局域网ip地址是: 192.168.10.101 12 | 13 | ## 软件安装 14 | 15 | * 在树莓派上安装go 16 | 17 | 目前最新版本的go是[go1.6.3](https://storage.googleapis.com/golang/go1.6.3.linux-armv6l.tar.gz)。 18 | 19 | 安装方法参考这个文档: https://golang.org/doc/install 20 | 21 | 安装成功后,运行如下命令检查: 22 | ```bash 23 | $ go version 24 | go version go1.6.3 linux/armv6l 25 | ``` 26 | 27 | * 编译kone 28 | 29 | kone是一个普通的go程序,简单说就是```go get -t github.com/xjdrew/kone``` 30 | 31 | ## 配置树莓派 32 | 33 | * 把树莓派设置成路由模式(需要切换到root用户) 34 | 35 | ``` 36 | echo 1 > /proc/sys/net/ipv4/ip_forward 37 | ``` 38 | 39 | ## 配置并启动kone 40 | 41 | * 修改kone的配置文件 42 | 43 | 在代码目录```[misc/example/example.ini](https://github.com/xjdrew/kone/blob/master/misc/example/example.ini)```,提供了一份默认配置文件。 44 | 为了简化问题,只需要把默认配置文件拷贝到合适的目录,命名为```my.ini```,然后把```[proxy "A"]```配置项下的url改成你拥有的代理,目前支持http, socks5代理。 45 | 46 | ``` 47 | [proxy "A"] 48 | url = http://example.com:3228 # 修改成你的代理,支持http, socks5 49 | default = yes 50 | ``` 51 | 52 | 其他配置选项的含义,参考配置文件里面的说明。 53 | 54 | * 启动kone 55 | 56 | ``` 57 | sudo ./kone my.ini & 58 | ``` 59 | 60 | ## 配置路由器 61 | * 配置静态路由 62 | 63 | 在路由器上添加一条静态路由: 64 | 65 | 目的IP地址 | 子网掩码 | 网关 | 状态 66 | ---------- | ----------- | -------------- | ---- 67 | 10.192.0.0 | 255.255.0.0 | 192.168.10.101 | 生效 68 | 69 | * 修改默认dns 70 | 71 | 把路由器的默认dns修改为:10.192.0.1 72 | 73 | tp-link 路由器的修改参考这里:http://service.tp-link.com.cn/detail_article_575.html 74 | 75 | ## 测试 76 | 77 | 取消手机的所有代理,使用wifi加入局域网,如果你提供的代理可以访问google,那么手机应该可以直接访问google.com 78 | 79 | ## 故障定位 80 | 81 | 1. 使用tcpdump在树莓派上抓包,看看dns请求是不是到了树莓派 82 | 2. 启动kone时加上```-debug```选项,查看打印日志 83 | ``` 84 | sudo ./kone -debug my.ini 85 | ``` 86 | 87 | ## 还有问题? 88 | 89 | join [telegram group](https://telegram.me/joinchat/B4cvLQl6H8RffE-6oATIVA) 90 | 91 | -------------------------------------------------------------------------------- /misc/docs/kone-in-ent-network.md: -------------------------------------------------------------------------------- 1 | # 在一个200人的企业网中使用kone 2 | 3 | 4 | ## 准备工作 5 | * 企业网关服务器(4G内存,i3以上的CPU),假设网关的IP是192.168.1.1,企业内部所有设备的default gateway都配置成192.168.1.1。当然,这台网关可能不是一台linux,而是一台商业网关服务器,只要它支持路由配置,都属于一台称职的网关服务器,本案例假设这台网关是一台标准的linux服务器。 6 | * [PC/手机] ----> [网关192.168.1.1] -----> [Internet] 7 | 8 | * 一个用于xx的httpproxy/sock5proxy服务器。是的,kone本身并不是一个proxy实现,kone的作用只是把路由请求转发到proxy server上 9 | 10 | ## 过程 11 | * 检查你的httpproxy/sock5proxy是否工作正常 12 | ``` 13 | curl -x http://myproxy:2080 https://www.google.com.hk 14 | ``` 15 | * 在网关上启动kone,配置文件参考example.ini 16 | ``` 17 | [general] 18 | network = 10.19.0.1/16 19 | ... 20 | [dns] 21 | # DEFAULT VALUE: 53 22 | # dns-port = 53 23 | nameserver = 192.168.1.1 24 | ... 25 | [proxy "A"] 26 | url = http://myproxy:2080 27 | default = yes 28 | ``` 29 | * 查看kone是否启动成功,缺省会创建虚拟网口tun0,IP地址为10.19.0.1,同时10.19.0.1也是一个新的DNS服务器 30 | ``` 31 | >ifconfig tun0 32 | tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 33 | inet addr:10.19.0.1 P-t-P:10.19.0.1 Mask:255.255.0.0 34 | UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1 35 | ``` 36 | 37 | * 在PC/手机上,把DNS服务器改成10.19.0.1,dig www.google.com.hk 测试是否返回一个10.19.x.x的地址池地址,如果返回的地址正常说明kone工作正常 38 | ``` 39 | >dig www.google.com.hk @10.19.0.1 40 | ;; ANSWER SECTION: 41 | www.google.com.hk. 600 IN A 10.19.0.55 42 | ``` 43 | * 改动企业网内部的DHCPD服务器,把缺省DNS服务器改为10.19.0.1,则企业内部的设备会自动使用kone实现透明xx 44 | * 一个200人的企业网络,httpproxy/sock5proxy至少需要3M带宽可以保证google/facebook/twitter等的访问,如果需要流畅的看youtube 720P,则带宽起码需要10M 45 | -------------------------------------------------------------------------------- /misc/docs/squid.conf: -------------------------------------------------------------------------------- 1 | acl SSL_ports port 443 2 | acl Safe_ports port 1-65535 # unregistered ports 3 | acl CONNECT method CONNECT 4 | acl HEAD method HEAD 5 | 6 | http_access deny !Safe_ports 7 | #http_access deny CONNECT !SSL_ports 8 | #http_access allow localhost manager 9 | http_access deny manager 10 | http_access allow localhost 11 | http_access deny all 12 | 13 | http_port 127.0.0.1:3128 14 | 15 | coredump_dir /var/spool/squid3 16 | 17 | # based on http://code.google.com/p/ghebhes/downloads/detail?name=tunning.conf&can=2&q= 18 | 19 | #All File 20 | refresh_pattern -i \.(3gp|7z|ace|asx|avi|bin|cab|dat|deb|rpm|divx|dvr-ms) 1440 100% 129600 reload-into-ims 21 | refresh_pattern -i \.(rar|jar|gz|tgz|tar|bz2|iso|m1v|m2(v|p)|mo(d|v)|(x-|)flv) 1440 100% 129600 reload-into-ims 22 | refresh_pattern -i \.(jp(e?g|e|2)|gif|pn[pg]|bm?|tiff?|ico|swf|css|js) 1440 100% 129600 reload-into-ims 23 | refresh_pattern -i \.(mp(e?g|a|e|1|2|3|4)|mk(a|v)|ms(i|u|p)) 1440 100% 129600 reload-into-ims 24 | refresh_pattern -i \.(og(x|v|a|g)|rar|rm|r(a|p)m|snd|vob|wav) 1440 100% 129600 reload-into-ims 25 | refresh_pattern -i \.(pp(s|t)|wax|wm(a|v)|wmx|wpl|zip|cb(r|z|t)) 1440 100% 129600 reload-into-ims 26 | 27 | refresh_pattern -i \.(doc|pdf)$ 1440 50% 43200 reload-into-ims 28 | refresh_pattern -i \.(html|htm)$ 1440 50% 40320 reload-into-ims 29 | 30 | refresh_pattern ^ftp: 1440 20% 10080 31 | refresh_pattern ^gopher: 1440 0% 1440 32 | refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 33 | refresh_pattern (Release|Packages(.gz)*)$ 0 20% 2880 34 | refresh_pattern . 0 20% 4320 35 | 36 | # http options 37 | via off 38 | 39 | # memory cache options 40 | cache_mem 512 MB 41 | maximum_object_size_in_memory 256 KB 42 | 43 | # disk cache 44 | #cache_dir diskd /var/spool/squid3 10240 16 256 45 | #maximum_object_size 20480 KB 46 | 47 | # timeouts 48 | # forward_timeout 10 seconds 49 | # connect_timeout 10 seconds 50 | # read_timeout 10 seconds 51 | # write_timeout 10 seconds 52 | # client_lifetime 59 minutes 53 | # request_timeout 30 seconds 54 | half_closed_clients off 55 | 56 | # 57 | forwarded_for delete 58 | dns_v4_first on 59 | ipcache_size 4096 60 | dns_nameservers 8.8.8.8 208.67.222.222 8.8.4.4 208.67.220.220 61 | 62 | # error page 63 | cache_mgr admin@example.com 64 | visible_hostname example.com 65 | email_err_data off 66 | err_page_stylesheet none 67 | -------------------------------------------------------------------------------- /misc/images/kone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjdrew/kone/9c896fdc18b1ae6b266223ea5a16307a6ddc55d6/misc/images/kone.png -------------------------------------------------------------------------------- /misc/images/kone_webui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjdrew/kone/9c896fdc18b1ae6b266223ea5a16307a6ddc55d6/misc/images/kone_webui.png -------------------------------------------------------------------------------- /misc/windows/README.md: -------------------------------------------------------------------------------- 1 | # use kone in Windows 2 | 3 | ## 预设条件 4 | 1. 安装 tap-windows (NDIS 6) 5 | 6 | * [tap-windows](https://community.openvpn.net/openvpn/wiki/GettingTapWindows) 7 | * [直接下载](https://build.openvpn.net/downloads/releases/tap-windows-9.21.0.exe) 8 | 9 | 2. 配置防火墙,允许kone重定向连接 10 | 使用管理员权限启动 PowerShell,执行`update-firewall-rules.ps1`。 11 | 12 | > 请注意修改 `update-firewall-rules.ps1` 脚本中 Program 参数为kone实际路径。 13 | > 关于Windows防火墙的更多信息,参考: 14 | > * [Manage Windows Firewall with the command line](https://learn.microsoft.com/en-us/windows/security/operating-system-security/network-security/windows-firewall/configure-with-command-line?tabs=powershell) 15 | > * [NetSecurity](https://learn.microsoft.com/en-us/powershell/module/netsecurity/?view=windowsserver2022-ps) 16 | 17 | 3. 编译&运行kone方式同linux -------------------------------------------------------------------------------- /misc/windows/check-firewall-rules.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 3 2 | #Requires -Modules NetSecurity 3 | 4 | $List = Get-NetFirewallRule -Enabled True -Action Allow -Description 'Work with Kone.' | Where-Object { 'Kone' -eq $_.DisplayName } 5 | $Report = foreach ($Rule in $List) 6 | { 7 | $Program = (Get-NetFirewallApplicationFilter -AssociatedNetFirewallRule $Rule).Program 8 | 9 | @{ 10 | Profile = $Rule.Profile 11 | Enabled = $Rule.Enabled 12 | Action = $Rule.Action 13 | Protocol = (Get-NetFirewallPortFilter -AssociatedNetFirewallRule $Rule).Protocol 14 | Program = $Program 15 | IsPathValid = Test-Path -PathType Leaf -LiteralPath $Program 16 | } 17 | } 18 | $Report 19 | Pause -------------------------------------------------------------------------------- /misc/windows/update-firewall-rules.ps1: -------------------------------------------------------------------------------- 1 | # $Program should direct to execute file 2 | Remove-NetFirewallRule -Description "Work with Kone." -ErrorAction SilentlyContinue 3 | 'TCP', 'UDP' | ForEach-Object { 4 | New-NetFirewallRule ` 5 | -DisplayName "Kone" ` 6 | -Profile "Any" ` 7 | -Description "Work with Kone." ` 8 | -Direction Inbound ` 9 | -Protocol $_ ` 10 | -Action Allow ` 11 | -Program "E:\go\github\kone\kone.exe" ` 12 | | Out-Null 13 | } -------------------------------------------------------------------------------- /nat.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "net" 10 | "time" 11 | ) 12 | 13 | const ( 14 | NatSessionLifeSeconds = 600 15 | NatSessionCheckInterval = 300 16 | ) 17 | 18 | type NatTable struct { 19 | from uint16 20 | to uint16 21 | 22 | next uint16 // next avaliable port 23 | h2Port map[uint64]uint16 24 | mapped []bool 25 | } 26 | 27 | func hashAddr(ip net.IP, port uint16) uint64 { 28 | v := uint64(ip[0]) << 40 29 | v += uint64(ip[1]) << 32 30 | v += uint64(ip[2]) << 24 31 | v += uint64(ip[3]) << 16 32 | v += uint64(port) 33 | return v 34 | } 35 | 36 | func (tbl *NatTable) Unmap(ip net.IP, port uint16) { 37 | h := hashAddr(ip, port) 38 | if port, ok := tbl.h2Port[h]; ok { 39 | delete(tbl.h2Port, h) 40 | tbl.mapped[port-tbl.from] = false 41 | } 42 | } 43 | 44 | // return: mapped port, is new mapped 45 | func (tbl *NatTable) Map(ip net.IP, port uint16) (uint16, bool) { 46 | h := hashAddr(ip, port) 47 | if port, ok := tbl.h2Port[h]; ok { 48 | return port, false 49 | } 50 | 51 | from := tbl.from 52 | to := tbl.to 53 | next := tbl.next 54 | var i uint16 55 | for ; i < to-from; i++ { 56 | next = next + i 57 | if next >= to { 58 | next = next%to + from 59 | } 60 | 61 | if tbl.mapped[next-from] { 62 | continue 63 | } 64 | tbl.mapped[next-from] = true 65 | tbl.h2Port[h] = next 66 | tbl.next = next + 1 67 | return next, true 68 | } 69 | return 0, false 70 | } 71 | 72 | func (tbl *NatTable) Count() int { 73 | return len(tbl.h2Port) 74 | } 75 | 76 | type NatSession struct { 77 | srcIP net.IP 78 | dstIP net.IP 79 | srcPort uint16 80 | dstPort uint16 81 | lastTouch int64 82 | } 83 | 84 | type Nat struct { 85 | tbl *NatTable 86 | sessions []*NatSession 87 | 88 | checkThreshold int 89 | lastCheck int64 90 | } 91 | 92 | func (nat *Nat) getSession(port uint16) *NatSession { 93 | if port < nat.tbl.from || port >= nat.tbl.to { 94 | return nil 95 | } 96 | 97 | session := nat.sessions[port-nat.tbl.from] 98 | if session != nil { 99 | session.lastTouch = time.Now().Unix() 100 | } 101 | 102 | return session 103 | } 104 | 105 | func (nat *Nat) allocSession(srcIP, dstIP net.IP, srcPort, dstPort uint16) (bool, uint16) { 106 | now := time.Now().Unix() 107 | nat.clearExpiredSessions(now) 108 | 109 | tbl := nat.tbl 110 | port, isNew := tbl.Map(srcIP, srcPort) 111 | if isNew { 112 | session := &NatSession{ 113 | srcIP: srcIP, 114 | dstIP: dstIP, 115 | srcPort: srcPort, 116 | dstPort: dstPort, 117 | lastTouch: now, 118 | } 119 | nat.sessions[port-tbl.from] = session 120 | } 121 | return isNew, port 122 | } 123 | 124 | func (nat *Nat) clearExpiredSessions(now int64) { 125 | if now-nat.lastCheck < NatSessionCheckInterval { 126 | return 127 | } 128 | 129 | if nat.count() < nat.checkThreshold { 130 | return 131 | } 132 | 133 | nat.lastCheck = now 134 | for index, session := range nat.sessions { 135 | if session != nil && now-session.lastTouch >= NatSessionLifeSeconds { 136 | nat.sessions[index] = nil 137 | nat.tbl.Unmap(session.srcIP, session.srcPort) 138 | } 139 | } 140 | } 141 | 142 | func (nat *Nat) count() int { 143 | return nat.tbl.Count() 144 | } 145 | 146 | // port range [from, to) 147 | func NewNat(from, to uint16) *Nat { 148 | count := to - from 149 | tbl := &NatTable{ 150 | from: from, 151 | to: to, 152 | next: from, 153 | h2Port: make(map[uint64]uint16, count), 154 | mapped: make([]bool, count), 155 | } 156 | 157 | logger.Infof("nat port range [%d, %d)", from, to) 158 | 159 | return &Nat{ 160 | tbl: tbl, 161 | sessions: make([]*NatSession, count), 162 | checkThreshold: int(count) / 10, 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /nat_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "math/rand" 10 | "net" 11 | "testing" 12 | "time" 13 | ) 14 | 15 | func TestNatAlloc(t *testing.T) { 16 | var from uint16 = 10 17 | var to uint16 = 20 18 | nat := NewNat(from, to) 19 | 20 | srcIP := net.ParseIP("127.0.0.1") 21 | dstIP := srcIP 22 | 23 | // map all ports 24 | for i := from; i < to; i++ { 25 | _, port := nat.allocSession(srcIP, dstIP, i, i) 26 | if i != port { 27 | t.Error("alloc session failed") 28 | return 29 | } 30 | } 31 | 32 | // release all sessions 33 | now := time.Now().Unix() + NatSessionLifeSeconds 34 | nat.clearExpiredSessions(now) 35 | if nat.count() != 0 { 36 | t.Error("release session failed") 37 | return 38 | } 39 | 40 | // test get session 41 | srcPort := uint16(rand.Int()) 42 | dstPort := uint16(rand.Int()) 43 | _, port := nat.allocSession(srcIP, dstIP, srcPort, dstPort) 44 | session := nat.getSession(port) 45 | if session == nil { 46 | t.Error("get session failed") 47 | return 48 | } 49 | 50 | if !net.IP.Equal(session.srcIP, srcIP) || !net.IP.Equal(session.dstIP, dstIP) || 51 | session.srcPort != srcPort || session.dstPort != dstPort { 52 | t.Error("check session failed") 53 | return 54 | } 55 | } 56 | 57 | func BenchmarkNat(b *testing.B) { 58 | var from uint16 = 10000 59 | var to uint16 = 60000 60 | nat := NewNat(from, to) 61 | 62 | srcIP := net.ParseIP("127.0.0.1") 63 | dstIP := srcIP 64 | 65 | // map all ports 66 | for i := from; i < to; i++ { 67 | _, port := nat.allocSession(srcIP, dstIP, i, i) 68 | if i != port { 69 | b.Error("alloc session failed") 70 | } 71 | } 72 | 73 | // release all sessions 74 | now := time.Now().Unix() + NatSessionLifeSeconds 75 | nat.clearExpiredSessions(now) 76 | if nat.count() != 0 { 77 | b.Error("release session failed") 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /one.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "net" 10 | "sync" 11 | 12 | "github.com/op/go-logging" 13 | "github.com/xjdrew/kone/tcpip" 14 | ) 15 | 16 | var logger = logging.MustGetLogger("kone") 17 | 18 | type One struct { 19 | // tun ip 20 | ip net.IP 21 | 22 | // tun virtual network 23 | subnet *net.IPNet 24 | 25 | rule *Rule 26 | dnsTable *DnsTable 27 | proxies *Proxies 28 | 29 | dns *Dns 30 | tcpRelay *TCPRelay 31 | udpRelay *UDPRelay 32 | tun *TunDriver 33 | manager *Manager 34 | } 35 | 36 | func (one *One) Serve() { 37 | var wg sync.WaitGroup 38 | 39 | runAndWait := func(f func() error) { 40 | defer wg.Done() 41 | err := f() 42 | logger.Errorf("%v", err) 43 | } 44 | 45 | wg.Add(5) 46 | go runAndWait(one.dnsTable.Serve) 47 | go runAndWait(one.dns.Serve) 48 | go runAndWait(one.tcpRelay.Serve) 49 | go runAndWait(one.udpRelay.Serve) 50 | go runAndWait(one.tun.Serve) 51 | if one.manager != nil { 52 | wg.Add(1) 53 | go runAndWait(one.manager.Serve) 54 | } 55 | wg.Wait() 56 | } 57 | 58 | func (one *One) Reload(cfg *KoneConfig) error { 59 | one.rule = NewRule(cfg.Rule) 60 | one.dnsTable.ClearNonProxyDomain() 61 | return nil 62 | } 63 | 64 | func FromConfig(cfg *KoneConfig) (*One, error) { 65 | ip, subnet, _ := net.ParseCIDR(cfg.Core.Network) 66 | 67 | logger.Infof("[tun] ip:%s, subnet: %s", ip, subnet) 68 | 69 | one := &One{ 70 | ip: ip.To4(), 71 | subnet: subnet, 72 | } 73 | 74 | // new rule 75 | one.rule = NewRule(cfg.Rule) 76 | 77 | // new dns cache 78 | one.dnsTable = NewDnsTable(ip, subnet) 79 | 80 | var err error 81 | 82 | // new dns 83 | if one.dns, err = NewDns(one, cfg.Core); err != nil { 84 | return nil, err 85 | } 86 | 87 | if one.proxies, err = NewProxies(one, cfg.Proxy); err != nil { 88 | return nil, err 89 | } 90 | 91 | one.tcpRelay = NewTCPRelay(one, cfg.Core) 92 | one.udpRelay = NewUDPRelay(one, cfg.Core) 93 | 94 | filters := map[tcpip.IPProtocol]PacketFilter{ 95 | tcpip.ICMP: PacketFilterFunc(icmpFilterFunc), 96 | tcpip.TCP: one.tcpRelay, 97 | tcpip.UDP: one.udpRelay, 98 | } 99 | 100 | if one.tun, err = NewTunDriver(ip, subnet, filters); err != nil { 101 | return nil, err 102 | } 103 | 104 | // set tun as all IP-CIDR rule output 105 | for _, pattern := range one.rule.patterns { 106 | switch p := pattern.(type) { 107 | case IPCIDRPattern: 108 | one.tun.AddRoute(p.ipNet) 109 | } 110 | } 111 | 112 | // new manager 113 | one.manager = NewManager(one, cfg) 114 | return one, nil 115 | } 116 | -------------------------------------------------------------------------------- /pattern.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "net" 10 | "strings" 11 | 12 | "github.com/xjdrew/kone/geoip" 13 | "github.com/xjdrew/kone/tcpip" 14 | ) 15 | 16 | type Pattern interface { 17 | Proxy() string 18 | Match(val interface{}) bool 19 | } 20 | 21 | // DOMAIN 22 | type DomainPattern struct { 23 | proxy string 24 | domain string 25 | } 26 | 27 | func (p DomainPattern) Proxy() string { 28 | return p.proxy 29 | } 30 | 31 | func (p DomainPattern) Match(val interface{}) bool { 32 | v, ok := val.(string) 33 | if !ok { 34 | return false 35 | } 36 | 37 | v = strings.ToLower(v) 38 | return v == p.domain 39 | } 40 | 41 | func NewDomainPattern(proxy, domain string) Pattern { 42 | return DomainPattern{ 43 | proxy: proxy, 44 | domain: strings.ToLower(domain), 45 | } 46 | } 47 | 48 | // DOMAIN-SUFFIX 49 | type DomainSuffixPattern struct { 50 | proxy string 51 | suffix string 52 | } 53 | 54 | func (p DomainSuffixPattern) Proxy() string { 55 | return p.proxy 56 | } 57 | 58 | func (p DomainSuffixPattern) Match(val interface{}) bool { 59 | v, ok := val.(string) 60 | if !ok { 61 | return false 62 | } 63 | 64 | v = strings.ToLower(v) 65 | return strings.HasSuffix(v, p.suffix) 66 | } 67 | 68 | func NewDomainSuffixPattern(proxy, suffix string) Pattern { 69 | return DomainSuffixPattern{ 70 | proxy: proxy, 71 | suffix: strings.ToLower(suffix), 72 | } 73 | } 74 | 75 | // DOMAIN-KEYWORD 76 | type DomainKeywordPattern struct { 77 | proxy string 78 | key string 79 | } 80 | 81 | func (p DomainKeywordPattern) Proxy() string { 82 | return p.proxy 83 | } 84 | 85 | func (p DomainKeywordPattern) Match(val interface{}) bool { 86 | v, ok := val.(string) 87 | if !ok { 88 | return false 89 | } 90 | v = strings.ToLower(v) 91 | return strings.Contains(v, p.key) 92 | } 93 | 94 | func NewDomainKeywordPattern(proxy string, key string) Pattern { 95 | return DomainKeywordPattern{ 96 | proxy: proxy, 97 | key: strings.ToLower(key), 98 | } 99 | } 100 | 101 | // GEOIP 102 | type GEOIPPattern struct { 103 | proxy string 104 | country string 105 | } 106 | 107 | func (p GEOIPPattern) Proxy() string { 108 | return p.proxy 109 | } 110 | 111 | func (p GEOIPPattern) Match(val interface{}) bool { 112 | var country string 113 | switch ip := val.(type) { 114 | case uint32: 115 | country = geoip.QueryCountry(ip) 116 | case net.IP: 117 | country = geoip.QueryCountryByIP(ip) 118 | } 119 | 120 | return p.country == country 121 | } 122 | 123 | func NewGEOIPPattern(proxy string, country string) Pattern { 124 | return GEOIPPattern{ 125 | proxy: proxy, 126 | country: country, 127 | } 128 | } 129 | 130 | // IP-CIDR 131 | type IPCIDRPattern struct { 132 | proxy string 133 | ipNet *net.IPNet 134 | } 135 | 136 | func (p IPCIDRPattern) Proxy() string { 137 | return p.proxy 138 | } 139 | 140 | func (p IPCIDRPattern) Match(val interface{}) bool { 141 | switch ip := val.(type) { 142 | case net.IP: 143 | return p.ipNet.Contains(ip) 144 | case uint32: 145 | return p.ipNet.Contains(tcpip.ConvertUint32ToIPv4(ip)) 146 | } 147 | 148 | return false 149 | } 150 | 151 | func NewIPCIDRPattern(proxy string, ipNet *net.IPNet) Pattern { 152 | return IPCIDRPattern{ 153 | proxy: proxy, 154 | ipNet: ipNet, 155 | } 156 | } 157 | 158 | // FINAL 159 | type FinalPattern struct { 160 | proxy string 161 | } 162 | 163 | func (p FinalPattern) Proxy() string { 164 | return p.proxy 165 | } 166 | 167 | func (p FinalPattern) Match(val interface{}) bool { 168 | return true 169 | } 170 | 171 | func NewFinalPattern(proxy string) FinalPattern { 172 | return FinalPattern{proxy: proxy} 173 | } 174 | 175 | func CreatePattern(rc RuleConfig) Pattern { 176 | proxy := rc.Proxy 177 | pattern := rc.Pattern 178 | schema := strings.ToUpper(rc.Schema) 179 | 180 | switch schema { 181 | case "DOMAIN": 182 | return NewDomainPattern(proxy, pattern) 183 | case "DOMAIN-SUFFIX": 184 | return NewDomainSuffixPattern(proxy, pattern) 185 | case "DOMAIN-KEYWORD": 186 | return NewDomainKeywordPattern(proxy, pattern) 187 | case "IP-CIDR": 188 | fallthrough 189 | case "IP-CIDR6": 190 | if proxy == "DIRECT" { // all IPNet default proxy is DIRECT 191 | logger.Debugf("skip DIRECT rule: %s,%s,%s", rc.Schema, rc.Pattern, rc.Proxy) 192 | return nil 193 | } 194 | _, ipNet, err := net.ParseCIDR(pattern) 195 | if err == nil { 196 | return NewIPCIDRPattern(proxy, ipNet) 197 | } 198 | case "GEOIP": 199 | return NewGEOIPPattern(proxy, pattern) 200 | case "FINAL": 201 | return NewFinalPattern(proxy) 202 | } 203 | logger.Errorf("invalid rule: %s,%s,%s", rc.Schema, rc.Pattern, rc.Proxy) 204 | return nil 205 | } 206 | -------------------------------------------------------------------------------- /pattern_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "net" 10 | "testing" 11 | 12 | "github.com/xjdrew/kone/tcpip" 13 | 14 | "github.com/stretchr/testify/assert" 15 | ) 16 | 17 | func TestDomainPattern(t *testing.T) { 18 | pattern := NewDomainPattern("A", "Example.com") 19 | assert.Equal(t, "A", pattern.Proxy()) 20 | assert.True(t, pattern.Match("example.com")) 21 | assert.True(t, pattern.Match("Example.Com")) // case insensitive 22 | assert.False(t, pattern.Match("api.example.com")) // suffix 23 | assert.False(t, pattern.Match("1example.com")) 24 | assert.False(t, pattern.Match("example.hk")) 25 | assert.False(t, pattern.Match("example.com.hk")) 26 | } 27 | 28 | func TestDomainSuffixPattern(t *testing.T) { 29 | pattern := NewDomainSuffixPattern("A", "Example.com") 30 | assert.Equal(t, "A", pattern.Proxy()) 31 | assert.True(t, pattern.Match("example.com")) 32 | assert.True(t, pattern.Match("Example.Com")) // case insensitive 33 | assert.True(t, pattern.Match("api.example.com")) // suffix 34 | assert.True(t, pattern.Match("1example.com")) 35 | assert.False(t, pattern.Match("example.hk")) 36 | assert.False(t, pattern.Match("example.com.hk")) 37 | } 38 | 39 | func TestDomainKeywordPattern(t *testing.T) { 40 | pattern := NewDomainKeywordPattern("A", "Example.com") 41 | assert.Equal(t, "A", pattern.Proxy()) 42 | assert.True(t, pattern.Match("example.com")) 43 | assert.True(t, pattern.Match("Example.Com")) // case insensitive 44 | assert.True(t, pattern.Match("api.example.com")) // suffix 45 | assert.True(t, pattern.Match("1example.com")) 46 | assert.False(t, pattern.Match("example.hk")) 47 | assert.True(t, pattern.Match("example.com.hk")) 48 | } 49 | 50 | func TestIPCountryPattern(t *testing.T) { 51 | pattern := NewGEOIPPattern("A", "US") 52 | assert.Equal(t, "A", pattern.Proxy()) 53 | assert.True(t, pattern.Match(net.ParseIP("216.58.197.99"))) // google.hk 54 | assert.False(t, pattern.Match(net.ParseIP("110.242.68.66"))) // baidu.com, china 55 | } 56 | 57 | func TestIPCIDRPattern(t *testing.T) { 58 | _, ipNet, _ := net.ParseCIDR("192.168.100.1/16") 59 | pattern := NewIPCIDRPattern("D", ipNet) 60 | assert.Equal(t, "D", pattern.Proxy()) 61 | assert.False(t, pattern.Match(net.ParseIP("192.167.255.255"))) 62 | assert.True(t, pattern.Match(net.ParseIP("192.168.0.0"))) 63 | assert.True(t, pattern.Match(net.ParseIP("192.168.255.255"))) 64 | assert.True(t, pattern.Match(net.ParseIP("192.168.108.255"))) 65 | assert.False(t, pattern.Match(tcpip.ConvertIPv4ToUint32(net.ParseIP("192.167.255.255")))) 66 | assert.True(t, pattern.Match(tcpip.ConvertIPv4ToUint32(net.ParseIP("192.168.0.0")))) 67 | assert.True(t, pattern.Match(tcpip.ConvertIPv4ToUint32(net.ParseIP("192.168.255.255")))) 68 | assert.True(t, pattern.Match(tcpip.ConvertIPv4ToUint32(net.ParseIP("192.168.108.255")))) 69 | } 70 | -------------------------------------------------------------------------------- /proxies.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "fmt" 10 | "net" 11 | "strings" 12 | 13 | "github.com/xjdrew/kone/proxy" 14 | ) 15 | 16 | type Proxies struct { 17 | proxies map[string]*proxy.Proxy 18 | } 19 | 20 | func (p *Proxies) Dial(pname string, addr string) (net.Conn, error) { 21 | logger.Debugf("[proxy] dail host %s by proxy %s", addr, pname) 22 | dialer := p.proxies[pname] 23 | if dialer != nil { 24 | return dialer.Dial("tcp", addr) 25 | } 26 | return nil, fmt.Errorf("no proxy: %s", pname) 27 | } 28 | 29 | func NewProxies(one *One, config map[string]string) (*Proxies, error) { 30 | p := &Proxies{} 31 | 32 | proxies := make(map[string]*proxy.Proxy) 33 | for pname, url := range config { 34 | proxy, err := proxy.FromUrl(url) 35 | if err != nil { 36 | return nil, err 37 | } 38 | 39 | logger.Debugf("[proxy] add proxy %s = %s", pname, url) 40 | proxies[pname] = proxy 41 | 42 | // don't hijack proxy domain 43 | host := proxy.Url.Host 44 | index := strings.IndexByte(proxy.Url.Host, ':') 45 | if index > 0 { 46 | host = proxy.Url.Host[:index] 47 | } 48 | one.rule.DirectDomain(host) 49 | } 50 | p.proxies = proxies 51 | return p, nil 52 | } 53 | -------------------------------------------------------------------------------- /proxy/README.md: -------------------------------------------------------------------------------- 1 | # proxy 2 | Origin from [proxy](github.com/xjdrew/proxy) 3 | 4 | supported proxy client: 5 | * socks5 6 | * http 7 | * https 8 | -------------------------------------------------------------------------------- /proxy/direct.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | import ( 4 | "net" 5 | ) 6 | 7 | type direct struct{} 8 | 9 | // Direct is a direct proxy: one that makes network connections directly. 10 | var Direct = direct{} 11 | 12 | func (direct) Dial(network, addr string) (net.Conn, error) { 13 | return net.Dial(network, addr) 14 | } 15 | -------------------------------------------------------------------------------- /proxy/http.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-02-18 3 | // author: xjdrew 4 | // 5 | package proxy 6 | 7 | import ( 8 | "bufio" 9 | "encoding/base64" 10 | "errors" 11 | "net" 12 | "net/http" 13 | "net/url" 14 | ) 15 | 16 | type http11 struct { 17 | addr string 18 | user *url.Userinfo 19 | forward Dialer 20 | } 21 | 22 | func basicAuth(username, password string) string { 23 | auth := username + ":" + password 24 | return base64.StdEncoding.EncodeToString([]byte(auth)) 25 | } 26 | 27 | func (h *http11) Dial(network, addr string) (net.Conn, error) { 28 | conn, err := h.forward.Dial(network, h.addr) 29 | if err != nil { 30 | return nil, err 31 | } 32 | 33 | req := &http.Request{ 34 | Method: "CONNECT", 35 | URL: &url.URL{ 36 | Host: addr, 37 | }, 38 | Proto: "HTTP/1.1", 39 | ProtoMajor: 1, 40 | ProtoMinor: 1, 41 | Header: make(http.Header), 42 | } 43 | 44 | req.Header.Set("Proxy-Connection", "keep-alive") 45 | 46 | // req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") 47 | 48 | if h.user != nil { 49 | if password, ok := h.user.Password(); ok { 50 | req.Header.Set("Proxy-Authorization", "Basic "+basicAuth(h.user.Username(), password)) 51 | } 52 | } 53 | 54 | if err = req.Write(conn); err != nil { 55 | conn.Close() 56 | return nil, err 57 | } 58 | 59 | var resp *http.Response 60 | resp, err = http.ReadResponse(bufio.NewReader(conn), nil) 61 | if err != nil { 62 | conn.Close() 63 | return nil, err 64 | } 65 | 66 | //defer resp.Body.Close() 67 | if resp.StatusCode != http.StatusOK { 68 | conn.Close() 69 | return nil, errors.New(resp.Status) 70 | } 71 | 72 | return conn, nil 73 | } 74 | 75 | func init() { 76 | registerDialerType("http", func(url *url.URL, forward Dialer) (Dialer, error) { 77 | return &http11{ 78 | addr: url.Host, 79 | user: url.User, 80 | forward: forward, 81 | }, nil 82 | }) 83 | } 84 | -------------------------------------------------------------------------------- /proxy/https.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | import ( 4 | "crypto/tls" 5 | "net" 6 | "net/url" 7 | "strings" 8 | ) 9 | 10 | type tlsDialer struct { 11 | forward Dialer 12 | } 13 | 14 | func hostname(addr string) string { 15 | colonPos := strings.LastIndex(addr, ":") 16 | if colonPos == -1 { 17 | return addr 18 | } 19 | return addr[:colonPos] 20 | } 21 | 22 | func (h *tlsDialer) Dial(network, addr string) (net.Conn, error) { 23 | conn, err := h.forward.Dial(network, addr) 24 | if err != nil { 25 | return nil, err 26 | } 27 | tlsConn := tls.Client(conn, &tls.Config{ 28 | ServerName: hostname(addr), 29 | }) 30 | return tlsConn, nil 31 | } 32 | 33 | func init() { 34 | registerDialerType("https", func(url *url.URL, forward Dialer) (Dialer, error) { 35 | dialer := &tlsDialer{ 36 | forward: forward, 37 | } 38 | return &http11{ 39 | addr: url.Host, 40 | user: url.User, 41 | forward: dialer, 42 | }, nil 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /proxy/proxy.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package proxy 7 | 8 | import ( 9 | "errors" 10 | "net" 11 | "net/url" 12 | ) 13 | 14 | // A Dialer is a means to establish a connection. 15 | type Dialer interface { 16 | // Dial connects to the given address via the proxy. 17 | Dial(network, addr string) (c net.Conn, err error) 18 | } 19 | 20 | // proxySchemes is a map from URL schemes to a function that creates a Dialer 21 | // from a URL with such a scheme. 22 | var proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error)) 23 | 24 | // RegisterDialerType takes a URL scheme and a function to generate Dialers from 25 | // a URL with that scheme and a forwarding Dialer. Registered schemes are used 26 | // by FromURL. 27 | func registerDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) { 28 | proxySchemes[scheme] = f 29 | } 30 | 31 | func getDialerByURL(u *url.URL, forward Dialer) (Dialer, error) { 32 | if f, ok := proxySchemes[u.Scheme]; ok { 33 | return f(u, forward) 34 | } 35 | return nil, errors.New("proxy: unknown scheme: " + u.Scheme) 36 | } 37 | 38 | type Proxy struct { 39 | Url *url.URL 40 | dialer Dialer 41 | } 42 | 43 | func (p *Proxy) Dial(network, addr string) (net.Conn, error) { 44 | return p.dialer.Dial(network, addr) 45 | } 46 | 47 | func FromUrl(rawurl string) (*Proxy, error) { 48 | u, err := url.Parse(rawurl) 49 | if err != nil { 50 | return nil, err 51 | } 52 | 53 | dailer, err := getDialerByURL(u, Direct) 54 | if err != nil { 55 | return nil, err 56 | } 57 | 58 | proxy := &Proxy{ 59 | Url: u, 60 | dialer: dailer, 61 | } 62 | 63 | return proxy, nil 64 | } 65 | -------------------------------------------------------------------------------- /proxy/socks5.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | import ( 4 | "errors" 5 | "io" 6 | "net" 7 | "net/url" 8 | "strconv" 9 | ) 10 | 11 | type socks5 struct { 12 | user, password string 13 | network, addr string 14 | forward Dialer 15 | } 16 | 17 | const socks5Version = 5 18 | 19 | const ( 20 | socks5AuthNone = 0 21 | socks5AuthPassword = 2 22 | ) 23 | 24 | const socks5Connect = 1 25 | 26 | const ( 27 | socks5IP4 = 1 28 | socks5Domain = 3 29 | socks5IP6 = 4 30 | ) 31 | 32 | var socks5Errors = []string{ 33 | "", 34 | "general failure", 35 | "connection forbidden", 36 | "network unreachable", 37 | "host unreachable", 38 | "connection refused", 39 | "TTL expired", 40 | "command not supported", 41 | "address type not supported", 42 | } 43 | 44 | // Dial connects to the address addr on the network net via the SOCKS5 proxy. 45 | func (s *socks5) Dial(network, addr string) (net.Conn, error) { 46 | switch network { 47 | case "tcp", "tcp6", "tcp4": 48 | default: 49 | return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network) 50 | } 51 | 52 | conn, err := s.forward.Dial(s.network, s.addr) 53 | if err != nil { 54 | return nil, err 55 | } 56 | if err := s.connect(conn, addr); err != nil { 57 | conn.Close() 58 | return nil, err 59 | } 60 | return conn, nil 61 | } 62 | 63 | // connect takes an existing connection to a socks5 proxy server, 64 | // and commands the server to extend that connection to target, 65 | // which must be a canonical address with a host and port. 66 | func (s *socks5) connect(conn net.Conn, target string) error { 67 | host, portStr, err := net.SplitHostPort(target) 68 | if err != nil { 69 | return err 70 | } 71 | 72 | port, err := strconv.Atoi(portStr) 73 | if err != nil { 74 | return errors.New("proxy: failed to parse port number: " + portStr) 75 | } 76 | if port < 1 || port > 0xffff { 77 | return errors.New("proxy: port number out of range: " + portStr) 78 | } 79 | 80 | // the size here is just an estimate 81 | buf := make([]byte, 0, 6+len(host)) 82 | 83 | buf = append(buf, socks5Version) 84 | if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 { 85 | buf = append(buf, 2 /* num auth methods */, socks5AuthNone, socks5AuthPassword) 86 | } else { 87 | buf = append(buf, 1 /* num auth methods */, socks5AuthNone) 88 | } 89 | 90 | if _, err := conn.Write(buf); err != nil { 91 | return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) 92 | } 93 | 94 | if _, err := io.ReadFull(conn, buf[:2]); err != nil { 95 | return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) 96 | } 97 | if buf[0] != 5 { 98 | return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) 99 | } 100 | if buf[1] == 0xff { 101 | return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") 102 | } 103 | 104 | if buf[1] == socks5AuthPassword { 105 | buf = buf[:0] 106 | buf = append(buf, 1 /* password protocol version */) 107 | buf = append(buf, uint8(len(s.user))) 108 | buf = append(buf, s.user...) 109 | buf = append(buf, uint8(len(s.password))) 110 | buf = append(buf, s.password...) 111 | 112 | if _, err := conn.Write(buf); err != nil { 113 | return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) 114 | } 115 | 116 | if _, err := io.ReadFull(conn, buf[:2]); err != nil { 117 | return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) 118 | } 119 | 120 | if buf[1] != 0 { 121 | return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") 122 | } 123 | } 124 | 125 | buf = buf[:0] 126 | buf = append(buf, socks5Version, socks5Connect, 0 /* reserved */) 127 | 128 | if ip := net.ParseIP(host); ip != nil { 129 | if ip4 := ip.To4(); ip4 != nil { 130 | buf = append(buf, socks5IP4) 131 | ip = ip4 132 | } else { 133 | buf = append(buf, socks5IP6) 134 | } 135 | buf = append(buf, ip...) 136 | } else { 137 | if len(host) > 255 { 138 | return errors.New("proxy: destination hostname too long: " + host) 139 | } 140 | buf = append(buf, socks5Domain) 141 | buf = append(buf, byte(len(host))) 142 | buf = append(buf, host...) 143 | } 144 | buf = append(buf, byte(port>>8), byte(port)) 145 | 146 | if _, err := conn.Write(buf); err != nil { 147 | return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) 148 | } 149 | 150 | if _, err := io.ReadFull(conn, buf[:4]); err != nil { 151 | return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) 152 | } 153 | 154 | failure := "unknown error" 155 | if int(buf[1]) < len(socks5Errors) { 156 | failure = socks5Errors[buf[1]] 157 | } 158 | 159 | if len(failure) > 0 { 160 | return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) 161 | } 162 | 163 | bytesToDiscard := 0 164 | switch buf[3] { 165 | case socks5IP4: 166 | bytesToDiscard = net.IPv4len 167 | case socks5IP6: 168 | bytesToDiscard = net.IPv6len 169 | case socks5Domain: 170 | _, err := io.ReadFull(conn, buf[:1]) 171 | if err != nil { 172 | return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) 173 | } 174 | bytesToDiscard = int(buf[0]) 175 | default: 176 | return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) 177 | } 178 | 179 | if cap(buf) < bytesToDiscard { 180 | buf = make([]byte, bytesToDiscard) 181 | } else { 182 | buf = buf[:bytesToDiscard] 183 | } 184 | if _, err := io.ReadFull(conn, buf); err != nil { 185 | return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) 186 | } 187 | 188 | // Also need to discard the port number 189 | if _, err := io.ReadFull(conn, buf[:2]); err != nil { 190 | return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) 191 | } 192 | 193 | return nil 194 | } 195 | 196 | func init() { 197 | registerDialerType("socks5", func(url *url.URL, forward Dialer) (Dialer, error) { 198 | s := &socks5{ 199 | network: "tcp", 200 | addr: url.Host, 201 | forward: forward, 202 | } 203 | 204 | if url.User != nil { 205 | s.user = url.User.Username() 206 | if p, ok := url.User.Password(); ok { 207 | s.password = p 208 | } 209 | } 210 | return s, nil 211 | }) 212 | } 213 | -------------------------------------------------------------------------------- /rule.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | type Rule struct { 9 | directDomains map[string]bool // always direct connect for proxy domain 10 | patterns []Pattern 11 | } 12 | 13 | func (rule *Rule) DirectDomain(domain string) { 14 | logger.Debugf("[rule] add direct domain: %s", domain) 15 | rule.directDomains[domain] = true 16 | } 17 | 18 | // match a proxy for target `val` 19 | func (rule *Rule) Proxy(val interface{}) string { 20 | if domain, ok := val.(string); ok { 21 | if rule.directDomains[domain] { 22 | logger.Debugf("[rule match] %v, proxy %q", val, "DIRECT") 23 | return "DIRECT" // direct 24 | } 25 | } 26 | 27 | for _, pattern := range rule.patterns { 28 | if pattern.Match(val) { 29 | proxy := pattern.Proxy() 30 | logger.Debugf("[rule match] %v, proxy %s", val, proxy) 31 | return proxy 32 | } 33 | } 34 | logger.Debugf("[rule final] %v, proxy %q", val, "") 35 | return "DIRECT" // direct connect 36 | } 37 | 38 | func NewRule(rcs []RuleConfig) *Rule { 39 | rule := &Rule{ 40 | directDomains: map[string]bool{}, 41 | } 42 | 43 | for _, rc := range rcs { 44 | if pattern := CreatePattern(rc); pattern != nil { 45 | rule.patterns = append(rule.patterns, pattern) 46 | } 47 | } 48 | return rule 49 | } 50 | -------------------------------------------------------------------------------- /syscalls_darwin.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2017-07-14 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "fmt" 10 | "net" 11 | "os/exec" 12 | "strings" 13 | 14 | "github.com/songgao/water" 15 | ) 16 | 17 | func execCommand(name, sargs string) error { 18 | args := strings.Split(sargs, " ") 19 | cmd := exec.Command(name, args...) 20 | logger.Infof("exec command: %s %s", name, sargs) 21 | return cmd.Run() 22 | } 23 | 24 | func initTun(tun string, ipNet *net.IPNet, mtu int) error { 25 | ip := ipNet.IP 26 | maskIP := net.IP(ipNet.Mask) 27 | sargs := fmt.Sprintf("%s %s %s mtu %d netmask %s up", tun, ip.String(), ip.String(), mtu, maskIP.String()) 28 | if err := execCommand("ifconfig", sargs); err != nil { 29 | return err 30 | } 31 | return addRoute(tun, ipNet) 32 | } 33 | 34 | func addRoute(tun string, subnet *net.IPNet) error { 35 | ip := subnet.IP 36 | maskIP := net.IP(subnet.Mask) 37 | sargs := fmt.Sprintf("-n add -net %s -netmask %s -interface %s", ip.String(), maskIP.String(), tun) 38 | return execCommand("route", sargs) 39 | } 40 | 41 | func createTun(ip net.IP, mask net.IPMask) (*water.Interface, error) { 42 | ifce, err := water.New(water.Config{ 43 | DeviceType: water.TUN, 44 | }) 45 | 46 | if err != nil { 47 | return nil, err 48 | } 49 | 50 | logger.Infof("create %s", ifce.Name()) 51 | 52 | ipNet := &net.IPNet{ 53 | IP: ip, 54 | Mask: mask, 55 | } 56 | 57 | if err := initTun(ifce.Name(), ipNet, MTU); err != nil { 58 | return nil, err 59 | } 60 | return ifce, nil 61 | } 62 | 63 | // can't listen on tun's ip in macosx 64 | func fixTunIP(ip net.IP) net.IP { 65 | return net.IPv4zero 66 | } 67 | -------------------------------------------------------------------------------- /syscalls_linux.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2017-07-14 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "fmt" 10 | "net" 11 | "os/exec" 12 | "strings" 13 | 14 | "github.com/songgao/water" 15 | ) 16 | 17 | func execCommand(name, sargs string) error { 18 | args := strings.Split(sargs, " ") 19 | cmd := exec.Command(name, args...) 20 | logger.Infof("exec command: %s %s", name, sargs) 21 | return cmd.Run() 22 | } 23 | 24 | func initTun(tun string, ipNet *net.IPNet, mtu int) error { 25 | sargs := fmt.Sprintf("addr add %s dev %s", ipNet, tun) 26 | if err := execCommand("ip", sargs); err != nil { 27 | return err 28 | } 29 | 30 | // brings the link up 31 | sargs = fmt.Sprintf("link set dev %s up mtu %d qlen 1000", tun, mtu) 32 | return execCommand("ip", sargs) 33 | } 34 | 35 | func addRoute(tun string, subnet *net.IPNet) error { 36 | sargs := fmt.Sprintf("route add %s dev %s", subnet, tun) 37 | return execCommand("ip", sargs) 38 | } 39 | 40 | func createTun(ip net.IP, mask net.IPMask) (*water.Interface, error) { 41 | ifce, err := water.New(water.Config{ 42 | DeviceType: water.TUN, 43 | }) 44 | 45 | if err != nil { 46 | return nil, err 47 | } 48 | 49 | logger.Infof("create %s", ifce.Name()) 50 | 51 | ipNet := &net.IPNet{ 52 | IP: ip, 53 | Mask: mask, 54 | } 55 | 56 | if err := initTun(ifce.Name(), ipNet, MTU); err != nil { 57 | return nil, err 58 | } 59 | return ifce, nil 60 | } 61 | 62 | func fixTunIP(ip net.IP) net.IP { 63 | return ip 64 | } 65 | -------------------------------------------------------------------------------- /syscalls_other.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2017-07-14 3 | // author: xjdrew 4 | // 5 | 6 | //go:build !linux && !darwin && !windows 7 | // +build !linux,!darwin,!windows 8 | 9 | package kone 10 | 11 | import ( 12 | "errors" 13 | "net" 14 | ) 15 | 16 | var errOS = errors.New("unsupported os") 17 | 18 | func initTun(tun string, ipNet *net.IPNet, mtu int) error { 19 | return errOS 20 | } 21 | 22 | func addRoute(tun string, subnet *net.IPNet) error { 23 | return errOS 24 | } 25 | 26 | func fixTunIP(ip net.IP) net.IP { 27 | return ip 28 | } 29 | -------------------------------------------------------------------------------- /syscalls_windows.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2019-08-29 3 | // author: SUCHMOKUO 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "context" 10 | "fmt" 11 | "net" 12 | "os" 13 | "os/exec" 14 | "strconv" 15 | "strings" 16 | 17 | "github.com/songgao/water" 18 | "github.com/thecodeteam/goodbye" 19 | ) 20 | 21 | var tunNet string 22 | 23 | func powershell(args ...string) error { 24 | cmd := exec.Command("powershell", args...) 25 | return cmd.Run() 26 | } 27 | 28 | func clearRoute(tun string) { 29 | powershell( 30 | "Remove-NetRoute", 31 | "-InterfaceAlias", tun, 32 | "-Confirm:$false") 33 | } 34 | 35 | func addRoute(tun string, subnet *net.IPNet) error { 36 | tun = fmt.Sprintf(`"%s"`, tun) 37 | subnetArg := fmt.Sprintf(`"%s"`, subnet.String()) 38 | return powershell( 39 | "New-NetRoute", 40 | "-DestinationPrefix", subnetArg, 41 | "-InterfaceAlias", tun, 42 | "-PolicyStore", "ActiveStore", 43 | "-AddressFamily", "IPv4", 44 | "-NextHop", tunNet) 45 | } 46 | 47 | func createTun(ip net.IP, mask net.IPMask) (*water.Interface, error) { 48 | ipNet := &net.IPNet{ 49 | IP: ip, 50 | Mask: mask, 51 | } 52 | 53 | s := make([]byte, 4) 54 | ip4 := ip.To4() 55 | for i := range s { 56 | s[i] = ip4[i] & mask[i] 57 | } 58 | tunNet = net.IPv4(s[0], s[1], s[2], s[3]).String() 59 | 60 | ifce, err := water.New(water.Config{ 61 | DeviceType: water.TUN, 62 | PlatformSpecificParams: water.PlatformSpecificParams{ 63 | ComponentID: "tap0901", 64 | Network: ipNet.String(), 65 | }, 66 | }) 67 | 68 | if err != nil { 69 | return nil, err 70 | } 71 | 72 | logger.Infof("initializing %s, please wait...", ifce.Name()) 73 | 74 | err = initTun(ifce.Name(), ipNet, MTU) 75 | if err != nil { 76 | return nil, err 77 | } 78 | 79 | logger.Infof("created %s", ifce.Name()) 80 | return ifce, nil 81 | } 82 | 83 | func initTun(tun string, ipNet *net.IPNet, mtu int) (err error) { 84 | tun = fmt.Sprintf(`"%s"`, tun) 85 | ip := fmt.Sprintf(`"%s"`, ipNet.IP) 86 | prefix := strings.Split(ipNet.String(), "/")[1] 87 | 88 | // clear previous route. 89 | clearRoute(tun) 90 | 91 | // clear route on quit. 92 | goodbye.Notify(context.Background()) 93 | goodbye.Register(func(ctx context.Context, s os.Signal) { 94 | logger.Infof("clearing route of %s, please wait...", tun) 95 | clearRoute(tun) 96 | }) 97 | 98 | // set interface mtu and metric. 99 | err = powershell( 100 | "Set-NetIPInterface", 101 | "-InterfaceAlias", tun, 102 | "-NlMtuBytes", strconv.Itoa(mtu), 103 | "-InterfaceMetric", "1") 104 | 105 | if err != nil { 106 | return err 107 | } 108 | 109 | // remove all previous ips of tun. 110 | err = powershell( 111 | "Remove-NetIPAddress", 112 | "-InterfaceAlias", tun, 113 | "-AddressFamily", "IPv4", 114 | "-Confirm:$false") 115 | 116 | if err != nil { 117 | return err 118 | } 119 | 120 | // add dns for tun. 121 | err = powershell( 122 | "Set-DnsClientServerAddress", 123 | "-InterfaceAlias", tun, 124 | "-ServerAddresses", ip) 125 | 126 | if err != nil { 127 | return err 128 | } 129 | 130 | // add ip for tun. 131 | return powershell( 132 | "New-NetIPAddress", 133 | "-InterfaceAlias", tun, 134 | "-IPAddress", ip, 135 | "-PrefixLength", prefix, 136 | "-PolicyStore", "ActiveStore", 137 | "-AddressFamily", "IPv4") 138 | } 139 | 140 | func fixTunIP(ip net.IP) net.IP { 141 | return ip 142 | } 143 | -------------------------------------------------------------------------------- /tcp_relay.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "fmt" 10 | "io" 11 | "net" 12 | "time" 13 | 14 | "github.com/xjdrew/kone/tcpip" 15 | ) 16 | 17 | type TCPRelay struct { 18 | one *One 19 | nat *Nat 20 | relayIP net.IP 21 | relayPort uint16 22 | } 23 | 24 | func copy(src net.Conn, dst net.Conn, ch chan<- int64) { 25 | defer dst.Close() 26 | 27 | written, _ := io.Copy(dst, src) 28 | ch <- written 29 | } 30 | 31 | func (r *TCPRelay) realRemoteHost(conn net.Conn, connData *ConnData) (addr string, proxy string) { 32 | remoteAddr := conn.RemoteAddr().(*net.TCPAddr) 33 | remotePort := uint16(remoteAddr.Port) 34 | 35 | session := r.nat.getSession(remotePort) 36 | if session == nil { 37 | logger.Errorf("[tcp relay] %s > %s no session", conn.LocalAddr(), remoteAddr) 38 | return 39 | } 40 | 41 | one := r.one 42 | dstIP := session.dstIP 43 | 44 | var host string 45 | if one.dnsTable.IsLocalIP(dstIP) { // for dns hijacked traffic 46 | record := one.dnsTable.GetByIP(dstIP) 47 | if record == nil { 48 | logger.Debugf("[tcp relay] %s:%d > %s:%d dns expired", session.srcIP, session.srcPort, dstIP, session.dstPort) 49 | return 50 | } 51 | 52 | host = record.Hostname 53 | proxy = record.Proxy 54 | } else { // for IP-CIDR rule traffic 55 | host = dstIP.String() 56 | proxy = one.rule.Proxy(dstIP) 57 | } 58 | 59 | connData.Src = session.srcIP.String() 60 | connData.Dst = host 61 | connData.Proxy = proxy 62 | 63 | addr = fmt.Sprintf("%s:%d", host, session.dstPort) 64 | logger.Debugf("[tcp relay] tunnel %s:%d > %s proxy %q", session.srcIP, session.srcPort, addr, proxy) 65 | return 66 | } 67 | 68 | func (r *TCPRelay) handleConn(conn net.Conn) { 69 | var connData ConnData 70 | remoteAddr, proxy := r.realRemoteHost(conn, &connData) 71 | if remoteAddr == "" { 72 | conn.Close() 73 | return 74 | } 75 | 76 | if proxy == "DIRECT" { // impossible 77 | conn.Close() 78 | logger.Errorf("[tcp relay] %s > %s traffic dead loop", conn.LocalAddr(), remoteAddr) 79 | return 80 | } 81 | 82 | proxies := r.one.proxies 83 | tunnel, err := proxies.Dial(proxy, remoteAddr) 84 | if err != nil { 85 | conn.Close() 86 | logger.Errorf("[tcp relay] dial %s by proxy %q failed: %s", remoteAddr, proxy, err) 87 | return 88 | } 89 | 90 | logger.Debugf("[tcp relay] new tunnel, to %s through %s", remoteAddr, proxy) 91 | 92 | uploadChan := make(chan int64) 93 | downloadChan := make(chan int64) 94 | 95 | go copy(conn, tunnel, uploadChan) 96 | go copy(tunnel, conn, downloadChan) 97 | 98 | connData.Upload = <-uploadChan 99 | connData.Download = <-downloadChan 100 | 101 | logger.Debugf("[tcp relay] domain %s, upload %v bytes, download %v bytes", remoteAddr, connData.Upload, connData.Download) 102 | if r.one.manager != nil { 103 | r.one.manager.dataCh <- connData 104 | } 105 | } 106 | 107 | func (r *TCPRelay) Serve() error { 108 | addr := &net.TCPAddr{IP: r.relayIP, Port: int(r.relayPort)} 109 | ln, err := net.ListenTCP("tcp", addr) 110 | if err != nil { 111 | logger.Errorf("[tcp relay] listen failed: %v", err) 112 | return err 113 | } 114 | 115 | logger.Infof("[tcp relay] listen on %v", addr) 116 | 117 | for { 118 | conn, err := ln.AcceptTCP() 119 | if err != nil { 120 | logger.Errorf("[tcp relay] acceept failed temporary: %v", err) 121 | time.Sleep(time.Second) //prevent log storms 122 | continue 123 | } 124 | logger.Debugf("[tcp relay] new connection [%s > %s]", conn.RemoteAddr(), conn.LocalAddr()) 125 | go r.handleConn(conn) 126 | } 127 | } 128 | 129 | // redirect tcp packet to relay 130 | func (r *TCPRelay) Filter(wr io.Writer, ipPacket tcpip.IPv4Packet) { 131 | tcpPacket := tcpip.TCPPacket(ipPacket.Payload()) 132 | 133 | srcIP := ipPacket.SourceIP() 134 | dstIP := ipPacket.DestinationIP() 135 | srcPort := tcpPacket.SourcePort() 136 | dstPort := tcpPacket.DestinationPort() 137 | 138 | if r.relayIP.Equal(srcIP) && srcPort == r.relayPort { 139 | // from relay 140 | session := r.nat.getSession(dstPort) 141 | if session == nil { 142 | logger.Debugf("[tcp filter] %s:%d > %s:%d: no session", srcIP, srcPort, dstIP, dstPort) 143 | return 144 | } 145 | 146 | ipPacket.SetSourceIP(session.dstIP) 147 | ipPacket.SetDestinationIP(session.srcIP) 148 | tcpPacket.SetSourcePort(session.dstPort) 149 | tcpPacket.SetDestinationPort(session.srcPort) 150 | } else { 151 | // redirect to relay 152 | isNew, port := r.nat.allocSession(srcIP, dstIP, srcPort, dstPort) 153 | 154 | ipPacket.SetSourceIP(dstIP) 155 | tcpPacket.SetSourcePort(port) 156 | ipPacket.SetDestinationIP(r.relayIP) 157 | tcpPacket.SetDestinationPort(r.relayPort) 158 | 159 | if isNew { 160 | logger.Debugf("[tcp filter] reshape connection from [%s:%d > %s:%d] to [%s:%d > %s:%d]", 161 | srcIP, srcPort, dstIP, dstPort, dstIP, port, r.relayIP, r.relayPort) 162 | } 163 | } 164 | 165 | // write back packet 166 | tcpPacket.ResetChecksum(ipPacket.PseudoSum()) 167 | ipPacket.ResetChecksum() 168 | wr.Write(ipPacket) 169 | } 170 | 171 | func NewTCPRelay(one *One, cfg CoreConfig) *TCPRelay { 172 | relay := new(TCPRelay) 173 | relay.one = one 174 | relay.nat = NewNat(cfg.TcpNatPortStart, cfg.TcpNatPortEnd) 175 | relay.relayIP = one.ip 176 | relay.relayPort = cfg.TcpListenPort 177 | return relay 178 | } 179 | -------------------------------------------------------------------------------- /tcpip/checksum.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package tcpip 7 | 8 | var ( 9 | zeroChecksum = [2]byte{0x00, 0x00} 10 | ) 11 | 12 | func Sum(b []byte) uint32 { 13 | var sum uint32 14 | 15 | n := len(b) 16 | for i := 0; i < n; i = i + 2 { 17 | sum += (uint32(b[i]) << 8) 18 | if i+1 < n { 19 | sum += uint32(b[i+1]) 20 | } 21 | } 22 | return sum 23 | } 24 | 25 | // checksum for Internet Protocol family headers 26 | func Checksum(sum uint32, b []byte) (answer [2]byte) { 27 | sum += Sum(b) 28 | sum = (sum >> 16) + (sum & 0xffff) 29 | sum += (sum >> 16) 30 | sum = ^sum 31 | answer[0] = byte(sum >> 8) 32 | answer[1] = byte(sum) 33 | return 34 | } 35 | -------------------------------------------------------------------------------- /tcpip/checksum_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package tcpip 7 | 8 | import ( 9 | "testing" 10 | 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | func TestChecksum(t *testing.T) { 15 | b := []byte{ 16 | 0x45, 0x00, 0x00, 0x73, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 17 | 0xb8, 0x61, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8, 0x00, 0xc7, 18 | } 19 | 20 | expected := [2]byte{0x00, 0x00} 21 | v := Checksum(0, b) 22 | assert.Equal(t, v, expected) 23 | } 24 | -------------------------------------------------------------------------------- /tcpip/common.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package tcpip 7 | 8 | import ( 9 | "net" 10 | ) 11 | 12 | func IsIPv4(packet []byte) bool { 13 | return (packet[0] >> 4) == 4 14 | } 15 | 16 | func IsIPv6(packet []byte) bool { 17 | return (packet[0] >> 4) == 6 18 | } 19 | 20 | func ConvertIPv4ToUint32(ip net.IP) uint32 { 21 | ip = ip.To4() 22 | if ip == nil { 23 | return 0 24 | } 25 | 26 | v := uint32(ip[0]) << 24 27 | v += uint32(ip[1]) << 16 28 | v += uint32(ip[2]) << 8 29 | v += uint32(ip[3]) 30 | return v 31 | } 32 | 33 | func ConvertUint32ToIPv4(v uint32) net.IP { 34 | return net.IPv4(byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) 35 | } 36 | -------------------------------------------------------------------------------- /tcpip/icmp.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package tcpip 7 | 8 | import ( 9 | "encoding/binary" 10 | ) 11 | 12 | type ICMPType byte 13 | 14 | const ( 15 | ICMPEcho ICMPType = 0x0 16 | ICMPRequest ICMPType = 0x8 17 | ) 18 | 19 | type ICMPPacket []byte 20 | 21 | func (p ICMPPacket) Type() ICMPType { 22 | return ICMPType(p[0]) 23 | } 24 | 25 | func (p ICMPPacket) SetType(v ICMPType) { 26 | p[0] = byte(v) 27 | } 28 | 29 | func (p ICMPPacket) Code() byte { 30 | return p[1] 31 | } 32 | 33 | func (p ICMPPacket) Checksum() uint16 { 34 | return binary.BigEndian.Uint16(p[2:]) 35 | } 36 | 37 | func (p ICMPPacket) SetChecksum(sum [2]byte) { 38 | p[2] = sum[0] 39 | p[3] = sum[1] 40 | } 41 | 42 | func (p ICMPPacket) ResetChecksum() { 43 | p.SetChecksum(zeroChecksum) 44 | p.SetChecksum(Checksum(0, p)) 45 | } 46 | -------------------------------------------------------------------------------- /tcpip/ipv4.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package tcpip 7 | 8 | import ( 9 | "encoding/binary" 10 | "net" 11 | ) 12 | 13 | type IPProtocol byte 14 | 15 | const ( 16 | ICMP IPProtocol = 0x01 17 | TCP IPProtocol = 0x06 18 | UDP IPProtocol = 0x11 19 | ) 20 | 21 | type IPv4Packet []byte 22 | 23 | func (p IPv4Packet) TotalLen() uint16 { 24 | return binary.BigEndian.Uint16(p[2:]) 25 | } 26 | 27 | func (p IPv4Packet) HeaderLen() uint16 { 28 | return uint16(p[0]&0xf) * 4 29 | } 30 | 31 | func (p IPv4Packet) DataLen() uint16 { 32 | return p.TotalLen() - p.HeaderLen() 33 | } 34 | 35 | func (p IPv4Packet) Payload() []byte { 36 | return p[p.HeaderLen():p.TotalLen()] 37 | } 38 | 39 | func (p IPv4Packet) Protocol() IPProtocol { 40 | return IPProtocol(p[9]) 41 | } 42 | 43 | func (p IPv4Packet) SourceIP() net.IP { 44 | var ip = [4]byte{p[12], p[13], p[14], p[15]} 45 | return net.IP(ip[:]) 46 | } 47 | 48 | func (p IPv4Packet) SetSourceIP(ip net.IP) { 49 | ip = ip.To4() 50 | if ip != nil { 51 | copy(p[12:16], ip) 52 | } 53 | } 54 | 55 | func (p IPv4Packet) DestinationIP() net.IP { 56 | var ip = [4]byte{p[16], p[17], p[18], p[19]} 57 | return net.IP(ip[:]) 58 | } 59 | 60 | func (p IPv4Packet) SetDestinationIP(ip net.IP) { 61 | ip = ip.To4() 62 | if ip != nil { 63 | copy(p[16:20], ip) 64 | } 65 | } 66 | 67 | func (p IPv4Packet) Checksum() uint16 { 68 | return binary.BigEndian.Uint16(p[10:]) 69 | } 70 | 71 | func (p IPv4Packet) SetChecksum(sum [2]byte) { 72 | p[10] = sum[0] 73 | p[11] = sum[1] 74 | } 75 | 76 | func (p IPv4Packet) ResetChecksum() { 77 | p.SetChecksum(zeroChecksum) 78 | p.SetChecksum(Checksum(0, p[:p.HeaderLen()])) 79 | } 80 | 81 | // for tcp checksum 82 | func (p IPv4Packet) PseudoSum() uint32 { 83 | sum := Sum(p[12:20]) 84 | sum += uint32(p.Protocol()) 85 | sum += uint32(p.DataLen()) 86 | return sum 87 | } 88 | -------------------------------------------------------------------------------- /tcpip/tcp.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package tcpip 7 | 8 | import ( 9 | "encoding/binary" 10 | ) 11 | 12 | type TCPPacket []byte 13 | 14 | func (p TCPPacket) SourcePort() uint16 { 15 | return binary.BigEndian.Uint16(p) 16 | } 17 | 18 | func (p TCPPacket) SetSourcePort(port uint16) { 19 | binary.BigEndian.PutUint16(p, port) 20 | } 21 | 22 | func (p TCPPacket) DestinationPort() uint16 { 23 | return binary.BigEndian.Uint16(p[2:]) 24 | } 25 | 26 | func (p TCPPacket) SetDestinationPort(port uint16) { 27 | binary.BigEndian.PutUint16(p[2:], port) 28 | } 29 | 30 | func (p TCPPacket) SetChecksum(sum [2]byte) { 31 | p[16] = sum[0] 32 | p[17] = sum[1] 33 | } 34 | 35 | func (p TCPPacket) Checksum() uint16 { 36 | return binary.BigEndian.Uint16(p[16:]) 37 | } 38 | 39 | func (p TCPPacket) ResetChecksum(psum uint32) { 40 | p.SetChecksum(zeroChecksum) 41 | p.SetChecksum(Checksum(psum, p)) 42 | } 43 | -------------------------------------------------------------------------------- /tcpip/udp.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-17 3 | // author: xjdrew 4 | // 5 | 6 | package tcpip 7 | 8 | import ( 9 | "encoding/binary" 10 | ) 11 | 12 | type UDPPacket []byte 13 | 14 | func (p UDPPacket) SourcePort() uint16 { 15 | return binary.BigEndian.Uint16(p) 16 | } 17 | 18 | func (p UDPPacket) SetSourcePort(port uint16) { 19 | binary.BigEndian.PutUint16(p, port) 20 | } 21 | 22 | func (p UDPPacket) DestinationPort() uint16 { 23 | return binary.BigEndian.Uint16(p[2:]) 24 | } 25 | 26 | func (p UDPPacket) SetDestinationPort(port uint16) { 27 | binary.BigEndian.PutUint16(p[2:], port) 28 | } 29 | 30 | func (p UDPPacket) SetChecksum(sum [2]byte) { 31 | p[6] = sum[0] 32 | p[7] = sum[1] 33 | } 34 | 35 | func (p UDPPacket) Checksum() uint16 { 36 | return binary.BigEndian.Uint16(p[6:]) 37 | } 38 | 39 | func (p UDPPacket) ResetChecksum(psum uint32) { 40 | p.SetChecksum(zeroChecksum) 41 | p.SetChecksum(Checksum(psum, p)) 42 | } 43 | -------------------------------------------------------------------------------- /tun.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-13 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "net" 10 | 11 | "github.com/songgao/water" 12 | 13 | "github.com/xjdrew/kone/tcpip" 14 | ) 15 | 16 | var MTU = 1500 17 | 18 | type TunDriver struct { 19 | ifce *water.Interface 20 | filters map[tcpip.IPProtocol]PacketFilter 21 | } 22 | 23 | func (tun *TunDriver) Serve() error { 24 | ifce := tun.ifce 25 | filters := tun.filters 26 | 27 | buffer := make([]byte, MTU) 28 | for { 29 | n, err := ifce.Read(buffer) 30 | if err != nil { 31 | logger.Errorf("[tun] read failed: %v", err) 32 | return err 33 | } 34 | 35 | packet := buffer[:n] 36 | if tcpip.IsIPv4(packet) { 37 | ipPacket := tcpip.IPv4Packet(packet) 38 | protocol := ipPacket.Protocol() 39 | filter := filters[protocol] 40 | if filter == nil { 41 | logger.Noticef("%v > %v protocol %d unsupport", ipPacket.SourceIP(), ipPacket.DestinationIP(), protocol) 42 | continue 43 | } 44 | 45 | filter.Filter(ifce, ipPacket) 46 | } 47 | } 48 | } 49 | 50 | func (tun *TunDriver) AddRoute(ipNet *net.IPNet) bool { 51 | addRoute(tun.ifce.Name(), ipNet) 52 | logger.Infof("add route %s by %s", ipNet.String(), tun.ifce.Name()) 53 | return true 54 | } 55 | 56 | func (tun *TunDriver) AddRouteString(val string) bool { 57 | _, subnet, err := net.ParseCIDR(val) 58 | if err != nil { 59 | return false 60 | } 61 | return tun.AddRoute(subnet) 62 | } 63 | 64 | func NewTunDriver(ip net.IP, subnet *net.IPNet, filters map[tcpip.IPProtocol]PacketFilter) (*TunDriver, error) { 65 | ifce, err := createTun(ip, subnet.Mask) 66 | if err != nil { 67 | return nil, err 68 | } 69 | return &TunDriver{ifce: ifce, filters: filters}, nil 70 | } 71 | -------------------------------------------------------------------------------- /udp_relay.go: -------------------------------------------------------------------------------- 1 | // 2 | // date : 2016-05-16 3 | // author: xjdrew 4 | // 5 | 6 | package kone 7 | 8 | import ( 9 | "io" 10 | "net" 11 | "sync" 12 | "time" 13 | 14 | "github.com/xjdrew/kone/tcpip" 15 | ) 16 | 17 | type UDPTunnel struct { 18 | session *NatSession 19 | record *DomainRecord 20 | 21 | cliaddr *net.UDPAddr 22 | 23 | localConn *net.UDPConn 24 | remoteConn *net.UDPConn 25 | } 26 | 27 | func (tunnel *UDPTunnel) SetDeadline(duration time.Duration) error { 28 | return tunnel.remoteConn.SetDeadline(time.Now().Add(duration)) 29 | } 30 | 31 | func (tunnel *UDPTunnel) Pump() error { 32 | b := make([]byte, MTU) 33 | for { 34 | n, err := tunnel.remoteConn.Read(b) 35 | if err != nil { 36 | if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() { 37 | return nil 38 | } 39 | return err 40 | } 41 | _, err = tunnel.localConn.WriteToUDP(b[:n], tunnel.cliaddr) 42 | if err != nil { 43 | return err 44 | } 45 | } 46 | } 47 | 48 | func (tunnel *UDPTunnel) Write(b []byte) (int, error) { 49 | return tunnel.remoteConn.Write(b) 50 | } 51 | 52 | type UDPRelay struct { 53 | one *One 54 | nat *Nat 55 | relayIP net.IP 56 | relayPort uint16 57 | 58 | lock sync.Mutex 59 | tunnels map[string]*UDPTunnel 60 | } 61 | 62 | // bypass udp packet 63 | func (r *UDPRelay) grabTunnel(localConn *net.UDPConn, cliaddr *net.UDPAddr) *UDPTunnel { 64 | r.lock.Lock() 65 | defer r.lock.Unlock() 66 | addr := cliaddr.String() 67 | tunnel := r.tunnels[addr] 68 | if tunnel == nil { 69 | port := uint16(cliaddr.Port) 70 | session := r.nat.getSession(port) 71 | if session == nil { 72 | return nil 73 | } 74 | record := r.one.dnsTable.GetByIP(session.dstIP) 75 | if record == nil { // by IP-CIDR rule 76 | return nil 77 | } 78 | 79 | if record.RealIP == nil { 80 | // try resolve real ip 81 | msg, err := r.one.dns.Resolve(record.Hostname) 82 | if err == nil { 83 | record.SetRealIP(msg) 84 | } 85 | 86 | if record.RealIP == nil { 87 | // resolve real ip failed 88 | return nil 89 | } 90 | } 91 | 92 | srvaddr := &net.UDPAddr{IP: record.RealIP, Port: int(session.dstPort)} 93 | remoteConn, err := net.DialUDP("udp", nil, srvaddr) 94 | if err != nil { 95 | logger.Errorf("[udp relay] connect to %s failed: %v", srvaddr, err) 96 | return nil 97 | } 98 | tunnel = &UDPTunnel{ 99 | session: session, 100 | record: record, 101 | cliaddr: cliaddr, 102 | localConn: localConn, 103 | remoteConn: remoteConn, 104 | } 105 | 106 | logger.Debugf("[udp relay] %s:%d > %v: new tunnel", session.srcIP, session.srcPort, srvaddr) 107 | 108 | r.tunnels[addr] = tunnel 109 | go func() { 110 | err := tunnel.Pump() 111 | if err != nil { 112 | logger.Debugf("[udp relay] pump to %v failed: %v", tunnel.remoteConn.RemoteAddr(), err) 113 | } 114 | tunnel.remoteConn.Close() 115 | logger.Debugf("[udp relay] %s:%d > %v: destroy tunnel", tunnel.session.srcIP, tunnel.session.srcPort, srvaddr) 116 | 117 | r.lock.Lock() 118 | delete(r.tunnels, addr) 119 | r.lock.Unlock() 120 | }() 121 | } 122 | tunnel.SetDeadline(NatSessionLifeSeconds * time.Second) 123 | return tunnel 124 | } 125 | 126 | func (r *UDPRelay) handlePacket(localConn *net.UDPConn, cliaddr *net.UDPAddr, packet []byte) { 127 | tunnel := r.grabTunnel(localConn, cliaddr) 128 | if tunnel == nil { 129 | logger.Errorf("[udp relay %v > %v: grap tunnel failed", cliaddr, localConn.LocalAddr()) 130 | return 131 | } 132 | _, err := tunnel.Write(packet) 133 | if err != nil { 134 | logger.Debugf("[udp relay] tunnel write failed: %v", err) 135 | } 136 | } 137 | 138 | func (r *UDPRelay) Serve() error { 139 | addr := &net.UDPAddr{IP: r.relayIP, Port: int(r.relayPort)} 140 | conn, err := net.ListenUDP("udp", addr) 141 | if err != nil { 142 | logger.Errorf("[udp relay] listen failed: %v", err) 143 | return err 144 | } 145 | 146 | for { 147 | b := make([]byte, MTU) 148 | n, cliaddr, err := conn.ReadFromUDP(b) 149 | if err != nil { 150 | logger.Errorf("[udp relay] acceept failed temporary: %v", err) 151 | time.Sleep(time.Second) //prevent log storms 152 | continue 153 | } 154 | go r.handlePacket(conn, cliaddr, b[:n]) 155 | } 156 | } 157 | 158 | // redirect udp packet to relay 159 | func (r *UDPRelay) Filter(wr io.Writer, ipPacket tcpip.IPv4Packet) { 160 | udpPacket := tcpip.UDPPacket(ipPacket.Payload()) 161 | 162 | srcIP := ipPacket.SourceIP() 163 | dstIP := ipPacket.DestinationIP() 164 | srcPort := udpPacket.SourcePort() 165 | dstPort := udpPacket.DestinationPort() 166 | 167 | one := r.one 168 | 169 | if net.IP.Equal(srcIP, r.relayIP) && srcPort == r.relayPort { 170 | // from remote 171 | session := r.nat.getSession(dstPort) 172 | if session == nil { 173 | logger.Debugf("[udp filter] %s:%d > %s:%d: no session", srcIP, srcPort, dstIP, dstPort) 174 | return 175 | } 176 | ipPacket.SetSourceIP(session.dstIP) 177 | ipPacket.SetDestinationIP(session.srcIP) 178 | udpPacket.SetSourcePort(session.dstPort) 179 | udpPacket.SetDestinationPort(session.srcPort) 180 | } else if one.dnsTable.Contains(dstIP) { 181 | // redirect to relay 182 | isNew, port := r.nat.allocSession(srcIP, dstIP, srcPort, dstPort) 183 | 184 | ipPacket.SetSourceIP(dstIP) 185 | udpPacket.SetSourcePort(port) 186 | ipPacket.SetDestinationIP(r.relayIP) 187 | udpPacket.SetDestinationPort(r.relayPort) 188 | 189 | if isNew { 190 | logger.Debugf("[udp filter] reshape packet from [%s:%d > %s:%d] to [%s:%d > %s:%d]", 191 | srcIP, srcPort, dstIP, dstPort, dstIP, port, r.relayIP, r.relayPort) 192 | } 193 | } else { 194 | logger.Errorf("[udp filter] %s:%d > %s:%d: invalid packet", srcIP, srcPort, dstIP, dstPort) 195 | return 196 | } 197 | 198 | // write back packet 199 | udpPacket.ResetChecksum(ipPacket.PseudoSum()) 200 | ipPacket.ResetChecksum() 201 | wr.Write(ipPacket) 202 | } 203 | 204 | func NewUDPRelay(one *One, cfg CoreConfig) *UDPRelay { 205 | r := new(UDPRelay) 206 | r.one = one 207 | r.nat = NewNat(cfg.UdpNatPortStart, cfg.UdpNatPortEnd) 208 | r.relayIP = one.ip 209 | r.relayPort = cfg.UdpListenPort 210 | r.tunnels = make(map[string]*UDPTunnel) 211 | return r 212 | } 213 | --------------------------------------------------------------------------------