Skip to content

Commit

Permalink
Initial Commit!
Browse files Browse the repository at this point in the history
  • Loading branch information
HelloLingC committed Nov 10, 2023
0 parents commit 530f276
Show file tree
Hide file tree
Showing 8 changed files with 443 additions and 0 deletions.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Reality SNI Fetch Script

查找多个同一AS下的可用于 Reality SNI 的域名

中文 | [Engligh](/README_EN.md)

使用本脚本筛选出的域名:
与目标IP处于同一AS下(IP相似)
支持TLS v1.3
支持HTTP2

# 使用

安装 Golang

```bash
git clone
```

安装依赖

```bash
go get ./,,,
```

运行脚本

```bash
go run . -t 目标IP
```
可选参数:
-n 请求的SNI数量

# 其他

[目前使用的查询源](https://bgp.he.net)
Empty file added README_EN.md
Empty file.
64 changes: 64 additions & 0 deletions challenge/challenge.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package challenge

import (
"crypto/tls"
"github.com/gookit/color"
"net"
"net/http"
"fmt"
"time"
)

func Check(host string) bool {
fmt.Printf("Start checking %v ...\n", host)
result := checkTLSv3(host) && checkHTTP2(host)
if(result) {
color.Green.Printf("%v is available\n", host)
}
return result
}

func checkTLSv3(host string) bool {
timeout := 5 * time.Second
addr := net.JoinHostPort(host, "443")
// Todo: handle www redirect
conn, err := tls.DialWithDialer(&net.Dialer{Timeout: timeout}, "tcp", addr, &tls.Config{
InsecureSkipVerify: true,
MinVersion: tls.VersionTLS11,
MaxVersion: tls.VersionTLS13,
})
if err != nil {
return fail("Failed")
}
defer conn.Close()

// Check the negotiated TLS version
tlsVer := conn.ConnectionState().Version
if (tlsVer != tls.VersionTLS13) {
return fail("TLSv1.3 Failed")
}
return true
}

func checkHTTP2(host string) bool {
url := "https://" + host
client := &http.Client{
Transport: &http.Transport{},
}

resp, err := client.Get(url)
if err != nil {
return fail("Failed")
}
defer resp.Body.Close()

if !(resp.ProtoMajor == 2) {
return fail("HTTP/2 Failed")
}
return true
}

func fail(info string) bool {
color.Red.Printf(info + "\n")
return false
}
71 changes: 71 additions & 0 deletions fetch/fetch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package fetch

import(
"github.com/gocolly/colly/v2"
"log"
"strings"
)

type Record struct {
IP string
Domains []string
}

var requiredSNINum int

func errorHandle(r *colly.Response, err error) {
log.Fatal("Error:", err)
}

func Start(addr string, num int) {
requiredSNINum = num
apiHost := "https://bgp.he.net"
api := "https://bgp.he.net/ip/"
col := colly.NewCollector()
col.OnHTML("td.nowrap > a", func(e *colly.HTMLElement) {
link := e.Attr("href")
getDNSList(apiHost + link)
})

col.OnError(errorHandle)

err := col.Visit(api + addr)
if err != nil {
log.Fatal("Cannot get ASN info", err)
}

}

var domainList []string
func getDNSList(url string) {
var waitList []Record
url += "#_dnsrecords"
c := colly.NewCollector()
c.OnHTML("tr", func(row *colly.HTMLElement) {
var IP string
var domains []string
i := 0
row.ForEach("td", func(_ int, e *colly.HTMLElement) {
// Skip PTR records
if i == 0 {
IP = e.Text
} else if i == 2 {
domains = strings.Split(e.Text, ", ")
domainList = append(domainList, domains...)
}
i++
})
record := Record{IP, domains}
waitList = append(waitList, record)
})
c.OnScraped(func(r *colly.Response) {
HandleRecords(waitList)
})
c.OnError(errorHandle)

err := c.Visit(url)
if err != nil {
log.Fatal("Cannot get DNS list", err)
}

}
45 changes: 45 additions & 0 deletions fetch/manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package fetch
import(
"sni-fetch/challenge"
"fmt"
_ "log"
"strings"
"sync"
)

var vaildSNIs []string
var sniNum = 0

func HandleRecords(rs []Record) {
// completedCh := make(chan struct{}, requiredSNINum)
var wg sync.WaitGroup

con := 5
index := 0
for i:= 0; i < len(domainList) / con; i++ {
for j := 0; j < con; j++ {
wg.Add(1)
go processChallenge(domainList[index], &wg)
index++
}
wg.Wait()
if(sniNum >= requiredSNINum) {
output()
return
}
}

output()
}

func processChallenge(domain string, wg *sync.WaitGroup) {
defer wg.Done()
if(challenge.Check(domain)) {
vaildSNIs = append(vaildSNIs, domain)
sniNum++
}
}

func output() {
fmt.Printf("[Finished] Found %v SNIs available: \n %v", len(vaildSNIs), strings.Join(vaildSNIs, "\n"))
}
25 changes: 25 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module sni-fetch

go 1.21.3

require (
github.com/PuerkitoBio/goquery v1.8.1 // indirect
github.com/andybalholm/cascadia v1.3.2 // indirect
github.com/antchfx/htmlquery v1.3.0 // indirect
github.com/antchfx/xmlquery v1.3.18 // indirect
github.com/antchfx/xpath v1.2.5 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gocolly/colly/v2 v2.1.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/gookit/color v1.5.4 // indirect
github.com/kennygrant/sanitize v1.2.4 // indirect
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
github.com/temoto/robotstxt v1.1.2 // indirect
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
golang.org/x/net v0.18.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/protobuf v1.31.0 // indirect
)
Loading

0 comments on commit 530f276

Please sign in to comment.