├── .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 | 
3 | [](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 |
69 | {{range .URLs}}
70 | - {{.}}
71 | {{end}}
72 |
73 |
74 | Current State
75 |
76 | Total Hosts | {{.TotalHosts}} |
77 | Total Websites | {{.TotalWebistes}} |
78 | Total Proxies | {{.TotalProxies}} |
79 | Total Traffic | {{formatNumberComma .TotalTraffic}} |
80 | Upload Traffic | {{formatNumberComma .UploadTraffic}} |
81 | Download Traffic | {{formatNumberComma .DownloadTraffic}} |
82 | Uptime | {{.Uptime}} |
83 | Now | {{.Now.Format "2006-01-02 15:04:05.000"}} |
84 |
85 | {{template "footer" .}}
86 | {{end}}
87 |
88 | {{define "traffic_record"}}
89 | {{template "header" .}}
90 | {{.Title}}
91 |
92 | - Entries: {{len .Records}}
93 | - Total: {{sumInt64 .Upload .Download | formatNumberComma}}
94 | - Upload: {{formatNumberComma .Upload}}
95 | - Download: {{formatNumberComma .Download}}
96 |
97 |
98 |
99 | Name |
100 | Total |
101 | Upload |
102 | Download |
103 | Last |
104 |
105 | {{range .Records}}
106 |
107 |
108 | {{if $.HasDetail}}
109 | {{.Name}}
110 | {{else}}
111 | {{.Name}}
112 | {{end}}
113 | |
114 | {{sumInt64 .Upload .Download | formatNumberComma}} |
115 | {{formatNumberComma .Upload}} |
116 | {{formatNumberComma .Download}} |
117 | {{.Touch.Format "2006-01-02 15:04:05.000"}} |
118 |
119 | {{end}}
120 |
121 | {{template "footer" .}}
122 | {{end}}
123 |
124 | {{define "traffic_record_detail"}}
125 | {{template "header" .}}
126 | {{with .Record}}
127 | {{$.Title}}: {{.Name}}
128 |
129 | - Entries: {{len .Details}}
130 | - Total: {{sumInt64 .Upload .Download | formatNumberComma}}
131 | - Upload: {{formatNumberComma .Upload}}
132 | - Download: {{formatNumberComma .Download}}
133 | - Last: {{.Touch.Format "2006-01-02 15:04:05.000"}}
134 |
135 | {{end}}
136 | {{with .Record.Details}}
137 |
138 |
139 | Name |
140 | Total |
141 | Upload |
142 | Download |
143 | Last |
144 |
145 | {{range .}}
146 |
147 | {{.EndPoint}} |
148 | {{sumInt64 .Upload .Download | formatNumberComma}} |
149 | {{formatNumberComma .Upload}} |
150 | {{formatNumberComma .Download}} |
151 | {{.Touch.Format "2006-01-02 15:04:05.000"}} |
152 |
153 | {{end}}
154 |
155 | {{end}}
156 | {{template "footer" .}}
157 | {{end}}
158 |
159 | {{define "dns"}}
160 | {{template "header" .}}
161 | Current State
162 |
163 | - Dns server: {{.DnsServer}}
164 | - Active entries: {{.ActiveEntries}}
165 | - Expired entries:{{.ExpiredEntries}}
166 |
167 |
168 |
169 | Hostname |
170 | Address |
171 | Proxy |
172 | Hits |
173 | Expires |
174 |
175 | {{range .Records}}
176 |
177 | {{.Hostname}} |
178 | {{.IP}} |
179 | {{.Proxy}} |
180 | {{.Hits}} |
181 | {{.Expires.Format "2006-01-02 15:04:05.000"}}{{if .Expires.Before $.Now}}[expired]{{end}} |
182 |
183 | {{end}}
184 |
185 | {{template "footer" .}}
186 | {{end}}
187 |
188 |
189 | {{define "config"}}
190 | {{template "header" .}}
191 | Config
192 |
193 | - rules: {{.RuleCount}}
194 |
195 |
196 |
197 | Source |
198 |
199 |
200 | {{.Source}} |
201 |
202 |
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 |
--------------------------------------------------------------------------------