go使用DialTimeout实现TCP端口扫描

前言

大家好,我是小小孩子们,我们在日常的开发学习部署中,都会遇到项目启动失败的情况,这时候我们就需要端口扫描,判断端口是否正常之后再进行下一步排查,而有的工具并不能很好的满足我们的需求,比如扫描1-655535端口,有的工具不支持,有的需要等待很长时间才会返回数据,所以我们可以选择自己动手去开发自己适合自己的工具。

代码已经部署在小小API(api-m.com)上了,大家可以使用API接口直接调用,具体调用方式请点击链接查看

https://api-m.com/doc/portscan

为了安全性考虑,接口只开放了扫描常用的端口

代码实现

实现思路

  1. 使用 net 包下面的 DialTimeout 方法,因为他增加了超时功能,可以避免端口为关闭状态时我们的代码运行过长
  2. 使用 go 的多并发,同时进行发送 TCP 数据包操作
  3. 使用 sync.WaitGroup 创建等待组,实现端口扫描完毕后,再退出执行

常用端口扫描

package main

import (
    "fmt"
    "net"
    "sync"
    "time"
)

// 声明一个等待组
var wg sync.WaitGroup

// Portscan 端口扫描
func main() {
    portArr := [8]string{"21", "22", "80", "443", "3006", "6379", "8888", "8080"}
    for _, val := range portArr {
        wg.Add(1)
        go func(address string) {
            _, err := net.DialTimeout("tcp", address, 1*time.Second)
            if err == nil {
                fmt.Println(address + "开启")
            }

            // 使用defer, 表示函数完成时将等待组值减1
            defer wg.Done()
        }("122.228.216.223:" + val)

    }
    wg.Wait()
}

image-20230219113858478.png

全端口扫描

我们将 for range 替换为 for 即可实现全端口扫描

package main

import (
    "fmt"
    "net"
    "strconv"
    "sync"
    "time"
)

// 声明一个等待组
var wg sync.WaitGroup

// Portscan 端口扫描
func main() {
    for i := 1; i < 65536; i++ {
        wg.Add(1)
        go func(address string) {
            _, err := net.DialTimeout("tcp", address, 1*time.Second)
            if err == nil {
                fmt.Println(address + "开启")
            }

            // 使用defer, 表示函数完成时将等待组值减1
            defer wg.Done()
        }("baidu.com:" + strconv.Itoa(i))
    }

    wg.Wait()
}
最后修改:2023 年 08 月 27 日
如果觉得我的文章对你有用,请随意赞赏