用于扫描内网网段内所有主机信息,
用到了 nmap , redis, json,
// 1分钟到2分钟左右 package main import ( "encoding/json" "fmt" "strings" "sync" "time" "github.com/Ullaakut/nmap" "github.com/gomodule/redigo/redis" ) var ( ListHostIP []string wg sync.WaitGroup rwlock sync.RWMutex ) type Port struct { Id uint16 `json:"id"` Name string `json:"name"` State string `json:"state"` } type HostInfo struct { Ip string `json:"ip"` OsName string `json:"os_name"` Ports []*Port `json:"ports"` } // 初始化连接池 func initPool(server, pass string, database int) *redis.Pool { return &redis.Pool{ // 设置最大空闲 MaxIdle: 64, // 设置最大活跃数 0代表无限 MaxActive:0, // 闲置空闲时间,单位秒 IdleTimeout:3600, Dial: func() (redis.Conn, error) { conn, err := redis.Dial("tcp", server, redis.DialReadTimeout(time.Second*10), redis.DialConnectTimeout(time.Second*30), redis.DialPassword(pass), redis.DialDatabase(database), ) if err != nil { fmt.Println("ERROR: fail init redis pool:", err.Error()) return nil, fmt.Errorf("ERROR: fail init redis pool: %s", err.Error()) } return conn, err }, } } func main() { start := time.Now() // redis创建连接池 ip, pass ,db pool := initPool("192.168.1.5:6379","",11) // 池子的关闭 defer pool.Close() // 从池子取连接 conn:=pool.Get() // 当前一个连接的关闭,用完即放回去池子并不是真的关闭 defer conn.Close() go func() { // 清理在线列表 rep ,err := redis.Values(conn.Do("lrange","iplist",0,-1)) for _, v := range rep { _,err = conn.Do("del",v.([]byte)) } _,err = conn.Do("del","iplist") if err != nil{ fmt.Println("del err ",err) } }() // nmap -O 192.168.0.0/24 scanner, err := nmap.NewScanner( nmap.WithTargets("192.168.1.0/24"), nmap.WithPingScan(), ) if err != nil { fmt.Println("unable to create nmap scanner: %v", err) } result, _, err := scanner.Run() if err != nil { fmt.Println("run nmap scan failed: %v", err) } for _, host := range result.Hosts { // 查询出所有在线 IP ip := fmt.Sprintf("%s", host.Addresses[0]) // 返回给数组 ListHostIP=append(ListHostIP,ip) } for _,ip := range ListHostIP{ // 遍历每个ip 开启多个 goroutine go func(ip string) { defer wg.Done() data := HostsInfo(ip) rwlock.RLock() if data != ""{ fmt.Println(ip) _, err = conn.Do("set", ip, data) _, err = conn.Do("rpush","iplist", ip) if err != nil{ fmt.Println("set err ",err) } } rwlock.RUnlock() }(ip) wg.Add(1) } // 等待所有完成 wg.Wait() fmt.Println( time.Now().Sub(start)) } // 扫描具体信息 func HostsInfo(ips string) (data string) { scanner, err := nmap.NewScanner( nmap.WithTargets(ips), // 开启快速查询 -F //nmap.WithFastMode(), // 标准查询 -O nmap.WithOSDetection(), ) if err != nil { fmt.Println("unable to create nmap scanner: %v", err) } result, _, err := scanner.Run() if err != nil { fmt.Println("run nmap scan failed: %v", err) } // 初始化结构体 hosts := new(HostInfo) for _, host := range result.Hosts { // 过滤 主机 条件 for _, match := range host.OS.Matches { os_name := match.Name if strings.Contains(os_name,"Linux") && !strings.Contains(os_name,"Android"){ rwlock.Lock() hosts.OsName = match.Name hosts.Ip = ips rwlock.Unlock() // 查主机 端口 和服务 信息 for _, port := range host.Ports { if port.Service.Name != "" { rwlock.Lock() hosts.Ports = append(hosts.Ports, &Port{ Id: port.ID, State: port.State.State, Name: port.Service.Name, }) rwlock.Unlock() } } } } } if hosts.Ports != nil{ json_data, _ := json.Marshal(hosts) return string(json_data) } return "" }
原文:https://www.cnblogs.com/huidou/p/14701393.html