为了账号安全,请及时绑定邮箱和手机立即绑定

如何安全地将 net.Listener() 的 FD 传递给子进程?

如何安全地将 net.Listener() 的 FD 传递给子进程?

Go
长风秋雁 2021-06-18 09:07:34
我已经被这个问题困扰了几个小时:我有一个主进程作为 TCP 服务器,主进程调用 Fork(),将其 net.Listener() 的 FD 传递给子进程。然后子进程可以使用 net.Filelistener() 来继承这个 FD。我通过很多开源代码研究过这个问题,也做了一些实验。但不幸的是,这些解决方案目前都没有让我满意,因为它们不可移植,您还需要许多危险的低级工作。如果有任何解决方案可以将 net.Listener() 的 FD 安全地传递给子进程,我很高兴知道。我现在尝试过的:环境值,不可移植,会导致许多 FD 的混乱,不安全,因为可以从外部更改。Dup FD & ClearFD_CLOEXEC然后是 exec/fork,可移植但不受 Go API 支持,syscall.NoCloseOnExec()提交给开发团队的更改被拒绝,因为他们希望保持系统调用干净。设置SO_REUSEADDR以便子进程可以立即侦听端口,在此之前关闭父进程的侦听器。失败,不可移植,Go API 不支持,也不安全。exec.Command.ExtraFiles(), 不知道如何从子进程中获取继承的 FD,我需要一个配置文件来保存 FD 和名称吗?此解决方案也有一个错误,请阅读 exec 的文档以获取更多详细信息。好吧,我已经为这个问题编写了一个简单的测试用例(使用解决方案 4):https://github.com/reckhou/go-fd-pass-test还包括 OS X 和 Linux 上的 2 个可执行文件。我尝试了 Go 1.1 & Go 1.1.1,但这个问题仍然存在。
查看完整描述

2 回答

?
撒科打诨

TA贡献1934条经验 获得超2个赞

最简单的方法是在 exec.Cmd 的 ExtraFiles 字段中传递侦听器。


父母的例子:


var l *net.TCPListener

cmd := exec.Command(...)

f, err := l.File()

cmd.ExtraFiles = []*os.File{f}

孩子的例子:


l, err := net.FileListener(os.NewFile(3, "listener"))

您可能还想对此进行概括并让孩子接受 PROGRAMNAME_LISTENER_FD 作为环境变量。然后在启动子进程之前,父进程将环境变量设置为 3。


查看完整回答
反对 回复 2021-06-21
?
catspeake

TA贡献1111条经验 获得超0个赞

我正在寻找相同的方法来监听环回地址并读取数据并发送到 WINDOWS 中的 exec 命令。


任何建议,因为 Windows 不支持 UNIX 中的文件描述符,我们按照以下步骤操作


服务:=“:1200”tcpAddr,错误:= net.ResolveTCPAddr(“tcp”,服务)


listener, err := net.ListenTCP("tcp",tcpAddr)

if err != nil {

    return "", err

}


defer listener.Close()

file, err := listener.File()   --> unix supports file descriptor / how about in windows ??

if err != nil {  

    return "", err

}

cmd := exec.Command( execname)


cmd.ExtraFiles = []*os.File{file} --> 在 unix 中它支持 / 在 windows 中如何添加数据???


cmd.Start()


查看完整回答
反对 回复 2021-06-21
  • 2 回答
  • 0 关注
  • 178 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信