使用Golang在Linux中实现SMB共享列表

使用Golang在Linux中实现SMB共享列表 你好,

过去一周我一直在寻找一种方法,能够从一台Linux机器上列出Windows机器某个IP地址上的所有SMB共享目录。对于从挂载点开始及之后的所有交互,我一直在使用SMB2-Go库。我的问题始于不知道你想要挂载和交互的共享是什么。

给定一个IP地址,我希望能够列出该机器上所有可用的共享,这样的事情可能吗?我为此需要的WinAPI是来自netapi32.dll的ShareEnum,但是这样的交互如何从一台Linux机器上完成呢?

任何帮助都将不胜感激!

谢谢

2 回复

你能说明一下你使用的是哪个 SMB 库吗?

没关系,我从另一个帖子中看到是:GitHub - hirochachacha/go-smb2: 用 Go 编写的 SMB2/3 客户端库。

更多关于使用Golang在Linux中实现SMB共享列表的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Linux上通过Golang获取远程Windows主机的SMB共享列表,可以使用github.com/hirochachacha/go-smb2库配合github.com/stacktitan/smb/smb进行发现。以下是实现方案:

package main

import (
    "fmt"
    "log"
    "github.com/stacktitan/smb/smb"
)

func listSMBShares(ip string) ([]string, error) {
    // 配置SMB连接参数
    options := smb.Options{
        Host:        ip,
        Port:        445,
        Domain:      "",
        Workstation: "",
        User:        "", // 匿名访问
        Password:    "",
    }

    // 建立会话
    session, err := smb.NewSession(options, false)
    if err != nil {
        return nil, fmt.Errorf("连接失败: %v", err)
    }
    defer session.Close()

    // 枚举共享列表
    shares, err := session.ListSharenames()
    if err != nil {
        return nil, fmt.Errorf("枚举共享失败: %v", err)
    }

    return shares, nil
}

func main() {
    shares, err := listSMBShares("192.168.1.100")
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println("可用的SMB共享:")
    for _, share := range shares {
        fmt.Printf(" - %s\n", share)
    }
}

如果需要认证访问,可以这样配置:

func listSMBSharesWithAuth(ip, user, password string) ([]string, error) {
    options := smb.Options{
        Host:        ip,
        Port:        445,
        User:        user,
        Password:    password,
        Domain:      "WORKGROUP", // 根据实际情况调整
        Workstation: "",
    }
    
    session, err := smb.NewSession(options, true) // true表示需要认证
    if err != nil {
        return nil, err
    }
    defer session.Close()
    
    return session.ListSharenames()
}

对于更复杂的场景,可以直接使用SMB协议底层操作:

import (
    "github.com/hirochachacha/go-smb2"
    "github.com/hirochachacha/go-smb2/ntlm"
)

func listSharesViaSMB2(ip, user, password string) {
    conn, err := net.Dial("tcp", ip+":445")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    // NTLM认证
    auth := &ntlm.NTLMSSPClient{
        User:     user,
        Password: password,
    }
    
    smb2Conn, err := smb2.NewConn(conn, auth)
    if err != nil {
        log.Fatal(err)
    }
    defer smb2Conn.Logoff()

    // 枚举共享(需要实现SMB Tree Connect枚举)
    // 这里需要进一步实现SMB协议级别的共享发现
}

安装依赖:

go get github.com/stacktitan/smb
go get github.com/hirochachacha/go-smb2

注意事项:

  1. 目标主机需要启用SMBv1(NetShareEnumAll)或SMBv2/3的发现功能
  2. 防火墙需要开放445端口
  3. 匿名访问可能被禁用,需要提供有效凭据
  4. 某些共享(如ADMIN$、C$)需要管理员权限

这种方法完全在用户空间实现,不依赖Windows API或netapi32.dll,适合在Linux环境中使用。

回到顶部