You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
star/whois/cmd.go

336 lines
8.4 KiB
Go

10 months ago
package whois
import (
3 months ago
"b612.me/sdk/whois"
"b612.me/stario"
8 months ago
"b612.me/starlog"
10 months ago
"b612.me/staros"
3 months ago
"bufio"
"fmt"
10 months ago
"github.com/spf13/cobra"
8 months ago
"golang.org/x/net/proxy"
3 months ago
"io"
10 months ago
"os"
8 months ago
"strings"
3 months ago
"sync"
10 months ago
"time"
)
var timeout int
var output string
8 months ago
var whoisServer []string
var socks5 string
var socks5Auth string
3 months ago
var showFull bool
var hideFormat bool
var useDict bool
var hideExists bool
var hideNoExists bool
var thread int
var suffix string
var retries int
10 months ago
func init() {
Cmd.Flags().IntVarP(&timeout, "timeout", "t", 20, "超时时间")
Cmd.Flags().StringVarP(&output, "output", "o", "", "输出文件夹")
8 months ago
Cmd.Flags().StringSliceVarP(&whoisServer, "server", "s", nil, "whois服务器")
Cmd.Flags().StringVarP(&socks5, "socks5", "p", "", "socks5代理示例127.0.0.1:1080")
3 months ago
Cmd.Flags().StringVarP(&socks5Auth, "socks5-auth", "a", "", "socks5代理认证示例username:password")
Cmd.Flags().BoolVarP(&showFull, "full", "f", false, "显示完整信息")
Cmd.Flags().BoolVarP(&hideFormat, "hide-format", "g", false, "隐藏格式化信息")
CmdExists.Flags().IntVarP(&timeout, "timeout", "t", 20, "超时时间")
CmdExists.Flags().StringVarP(&output, "output", "o", "", "输出文件")
CmdExists.Flags().BoolVarP(&useDict, "use-dict", "d", false, "使用字典查询")
CmdExists.Flags().StringSliceVarP(&whoisServer, "server", "s", nil, "whois服务器")
CmdExists.Flags().StringVarP(&socks5, "socks5", "p", "", "socks5代理示例127.0.0.1:1080")
CmdExists.Flags().StringVarP(&socks5Auth, "socks5-auth", "a", "", "socks5代理认证示例username:password")
CmdExists.Flags().BoolVarP(&hideExists, "hide-exists", "e", false, "隐藏存在的域名")
CmdExists.Flags().BoolVarP(&hideNoExists, "hide-no-exists", "n", false, "隐藏不存在的域名")
CmdExists.Flags().IntVarP(&thread, "thread", "m", 10, "并发查询数")
CmdExists.Flags().StringVarP(&suffix, "suffix", "x", "", "域名后缀")
CmdExists.Flags().IntVarP(&retries, "retries", "r", 3, "重试次数")
Cmd.AddCommand(CmdExists)
10 months ago
}
var Cmd = &cobra.Command{
Use: "whois",
Short: "whois查询",
Long: "whois查询",
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.Help()
return
}
if !staros.Exists(output) {
output = ""
}
c := whois.NewClient()
8 months ago
if socks5 != "" {
var auth *proxy.Auth
if socks5Auth != "" {
up := strings.SplitN(socks5Auth, ":", 2)
if len(up) == 2 {
auth = &proxy.Auth{
User: up[0],
Password: up[1],
}
} else {
starlog.Errorln("socks5认证格式错误")
return
}
}
s5Dial, err := proxy.SOCKS5("tcp", socks5, auth, proxy.Direct)
if err == nil {
c.SetDialer(s5Dial)
} else {
starlog.Errorln("socks5代理错误:", err)
return
}
}
10 months ago
c.SetTimeout(time.Second * time.Duration(timeout))
for _, v := range args {
8 months ago
data, err := c.Whois(v, whoisServer...)
10 months ago
cmd.Println("Query:", v)
if err != nil {
cmd.Println("查询失败:", err)
cmd.Println("-----------------------------------------------------")
continue
}
3 months ago
if !hideFormat && !data.Exists() {
fmt.Printf("域名:\t%s 不存在\n", data.Domain())
}
if !hideFormat && data.Exists() {
fmt.Printf("域名名称:\t%s\n", data.Domain())
fmt.Printf("注册商:\t%s\n", data.Registar())
if data.HasRegisterDate() {
fmt.Printf("注册时间:\t%s\n", data.RegisterDate())
}
if data.HasExpireDate() {
fmt.Printf("到期时间:\t%s\n", data.ExpireDate())
}
if data.HasUpdateDate() {
fmt.Printf("更新时间:\t%s\n", data.UpdateDate())
}
for _, v := range data.Status() {
fmt.Printf("域名状态:\t%s\n", v)
}
if data.IanaID() != "" {
fmt.Printf("IANA ID\t%s\n", data.IanaID())
}
if data.Dnssec() != "" {
fmt.Printf("DNSSEC\t%s\n", data.Dnssec())
}
isShowContact := false
if data.RegisterInfo().Name != "" {
fmt.Printf("注册者:\t%s\n", data.RegisterInfo().Name)
isShowContact = true
}
if data.RegisterInfo().State != "" {
fmt.Printf("注册省份:\t%s\n", data.RegisterInfo().State)
isShowContact = true
}
if data.RegisterInfo().Country != "" {
fmt.Printf("注册国家:\t%s\n", data.RegisterInfo().Country)
isShowContact = true
}
if data.RegisterInfo().Email != "" {
fmt.Printf("注册邮箱:\t%s\n", data.RegisterInfo().Email)
isShowContact = true
}
if !isShowContact {
if data.AdminInfo().Name != "" {
fmt.Printf("注册者:\t%s\n", data.RegisterInfo().Name)
isShowContact = true
}
if data.AdminInfo().State != "" {
fmt.Printf("注册省份:\t%s\n", data.RegisterInfo().State)
isShowContact = true
}
if data.AdminInfo().Country != "" {
fmt.Printf("注册国家:\t%s\n", data.RegisterInfo().Country)
isShowContact = true
}
if data.AdminInfo().Email != "" {
fmt.Printf("注册邮箱:\t%s\n", data.RegisterInfo().Email)
isShowContact = true
}
}
for _, v := range data.NsServers() {
fmt.Printf("NS服务器\t%s\n", v)
}
for _, v := range data.NsIps() {
fmt.Printf("NS IP\t%s\n", v)
}
}
if showFull {
fmt.Println("")
fmt.Println(data.RawData())
}
10 months ago
cmd.Println("-----------------------------------------------------")
3 months ago
os.WriteFile(output+"/"+v+".txt", []byte(data.RawData()), 0644)
10 months ago
}
},
}
3 months ago
var CmdExists = &cobra.Command{
Use: "exists",
Short: "域名是否存在查询",
Long: "域名是否存在查询,可使用字典",
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.Help()
return
}
var of *os.File
var err error
if output != "" {
of, err = os.Create(output)
if err != nil {
starlog.Errorln("创建输出文件失败", err)
return
}
defer of.Close()
}
c := whois.NewClient()
if socks5 != "" {
var auth *proxy.Auth
if socks5Auth != "" {
up := strings.SplitN(socks5Auth, ":", 2)
if len(up) == 2 {
auth = &proxy.Auth{
User: up[0],
Password: up[1],
}
} else {
starlog.Errorln("socks5认证格式错误")
return
}
}
s5Dial, err := proxy.SOCKS5("tcp", socks5, auth, proxy.Direct)
if err == nil {
c.SetDialer(s5Dial)
} else {
starlog.Errorln("socks5代理错误:", err)
return
}
}
c.SetTimeout(time.Second * time.Duration(timeout))
var d domainList
if !useDict {
err = d.New("stdin", args)
} else {
err = d.New("file", args)
}
if err != nil {
starlog.Errorln("初始化域名列表失败", err)
return
}
if thread == 0 {
thread = 1
}
var wg = stario.NewWaitGroup(thread)
fin := false
for !fin {
wg.Add(1)
go func() {
defer wg.Done()
domain, err := d.Next()
if err != nil {
if err == io.EOF {
fin = true
}
return
}
if suffix != "" {
domain = domain + "." + suffix
}
var data whois.Result
for i := 0; i < retries; i++ {
data, err = c.Whois(domain, whoisServer...)
if err != nil {
continue
}
break
}
if err != nil {
starlog.Errorln("查询失败:", domain, err)
return
}
if !hideExists && data.Exists() {
fmt.Println(domain, "已注册")
if of != nil {
of.WriteString(domain + " 已注册\n")
}
}
if !hideNoExists && !data.Exists() {
fmt.Println(domain, "不存在")
if of != nil {
of.WriteString(domain + " 不存在\n")
}
}
}()
}
wg.Wait()
},
}
type domainList struct {
typed string
args []string
idx int
mu sync.Mutex
f *os.File
scanner *bufio.Reader
}
func (d *domainList) New(types string, args []string) error {
var err error
d.typed = types
d.args = args
switch d.typed {
case "file":
d.f, err = os.OpenFile(d.args[0], os.O_RDONLY, 0644)
if err != nil {
return err
}
d.scanner = bufio.NewReader(d.f)
case "stdin":
}
return err
}
func (d *domainList) Next() (string, error) {
d.mu.Lock()
defer d.mu.Unlock()
for {
switch d.typed {
case "file":
l, _, err := d.scanner.ReadLine()
if err == io.EOF {
if d.idx+1 >= len(d.args) {
d.f.Close()
return "", err
}
d.idx++
d.f.Close()
d.f, err = os.OpenFile(d.args[d.idx], os.O_RDONLY, 0644)
if err != nil {
return "", err
}
d.scanner = bufio.NewReader(d.f)
continue
}
return strings.TrimSpace(string(l)), nil
case "stdin":
if d.idx >= len(d.args) {
return "", io.EOF
}
d.idx++
return d.args[d.idx-1], nil
}
}
}