使用 Go 以编程方式在 Linux 中安全地挂载网络位置

Programatically mount network location securely in Linux with Go

在 Linux 中,我可以像这样使用 Go 以编程方式安装网络位置:

func main() {
  var user, pass string
  fmt.Println("username:")
  fmt.Scanln(&user) // ignore errors for brevity
  fmt.Println("password:")
  fmt.Scanln(&pass)

  cmd := exec.Command("mount", "-t", "cifs", "-o", "username="+user+",password="+pass, "//server/dir", "media/dir")
  cmd.Run()
}

问题:

  1. 如果不使用 sudo
  2. 提升权限,我无法 运行
  3. 用户名和密码将由用户提供。这似乎很不安全。 任何人都可以确认这种方法的安全性或危险性吗?

下面是一个类似的变量方法:

cmd := exec.Command("mount", "-t", "cifs", "-o", "username=$USER,password=$PASS", "//server/dir", "media/dir")
cmd.Env = []string{"USER="+user, "PASS="+pass}
cmd.Run()

那行不通。 exec.Command() 函数似乎转义了美元符号,因此环境变量中的值没有被替换。所以这似乎表明这里正在进行某种安全或逃避。

编辑 etc/fstab 文件 将允许我 运行 mount 而无需 sudo 但我需要 sudo 编辑 fstab 文件,回到第一个问题。

我们可以使用 gvfsuserspace 中挂载共享,这意味着我们不需要使用 sudo 提升权限。 gio命令可用于此。

为简洁起见,下面的代码片段排除了错误处理:

cmd := exec.Command("gio", "mount", "smb://server/share")
inPipe, _ := cmd.StdinPipe()
cmd.Start()

// Get credentials whichever way you find best, including scanning the Stdin.
// Concatenate them together with line breaks in between and a line break at the end.
auth := "Username\nDomain\nPassword\n"
inPipe.Write([]byte(auth))

// Wait for the command to finish.
cmd.Wait()

扫描 Stdin 似乎是一种可接受的捕获凭据的方式,因为这就是 gio 命令的工作方式。