如何通过 golang 使用 vpn?

2015-01-22 12:40:07 +08:00
 yuhua
现在我的服务器上挂了5个vpn(pptp),ppp0~ppp5
我想启动5个进程,每个进程使用不同的vpn
proc0 -> ppp0
proc1 -> ppp1
proc2 -> ppp2
proc3 -> ppp3
proc4 -> ppp4
用c的话可以通过SO_BINDTODIVICE实现
现在想用golang的net包来实验,有哪位大牛实现过的?求教
5692 次点击
所在节点    问与答
5 条回复
nybux
2015-01-22 13:54:45 +08:00
用Dialer进行连接,Dialer的LocalAddr设置接口指定的IP,如果不确定ip,可以通过InterfaceByName来获取
yuhua
2015-01-22 15:29:36 +08:00
ief, err := net.InterfaceByName(netInterface)
if err != nil {
fmt.Println(err)
}
addrs, err := ief.Addrs()
if err != nil {
fmt.Println(err)
}
fmt.Println(addrs[0])
tcpAddr := &net.TCPAddr{
IP: addrs[0].(*net.IPNet).IP,
}
fmt.Println(tcpAddr)
d := net.Dialer{LocalAddr: tcpAddr}

conn, err := d.Dial("tcp", addr)
if err != nil {
fmt.Println(err)
return nil, err
}

我试过了,貌似这样不行。一定要通过底层是setsockopt的方法
同样情况下python使用s.setsockopt(socket.SOL_SOCKET, 25, "ppp0"+'\0')通过了测试
nybux
2015-01-22 15:48:25 +08:00
那就用cgo,自己先创建个socket出来,然后用new.FileConn+os.NewFile包装出一个net.Conn对象出来
yuhua
2015-01-22 17:37:06 +08:00
哎..还是太麻烦点了。后来考量下业务觉得改用python估计问题也不大。还是谢谢啦~
mitch
2019-06-26 16:27:46 +08:00
今天遇到同样问题,简单搜索了一下,go 1.11 发布后事情简单了点,net 的 dialer 里增加了 Control 的 handler 方便对 socket 进行操作,如下:

---------------------------------

net.Dialer{
Control: func(network, address string, c syscall.RawConn) error {
return c.Control(func(fd uintptr) {
err := syscall.SetsockoptString(int(fd), syscall.SOL_SOCKET, 25, "ppp0")
if err != nil {
log.Printf("control: %s", err)
return
}
})
},
}

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/164438

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX