go 程序进程权限的问题

2022-06-20 17:14:01 +08:00
 jeesk

因为我的软件需要创建虚拟网卡, 软件就需要 root 权限运行。 有个需求可以读取 macosx 的剪贴板, 这个时候坑就来了, 发现 macosx 的剪贴板做了用户隔离的,root 用户读取不到普通用户的剪贴板。 这就形成了一个死局。哈哈, 这个坑是苹果出来的。

  1. 我想知道能不能够实现一个 go 程序,能够隔离出运行的权限。 把某一段代码的权限降级成 user 用户, 而创建网卡的程序为 root 用户?
  2. 有 Macosx 在 root 用户无法获取剪贴板, 大家有什么好的方案吗? 
  
  
  
  刚才我已经给 https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard 仓库的 2 位开发者发邮件了,不知道能不能获得他们的帮助。 哎,哎,哎。

MacOSX- pasteboard readme 文件。

  
The pasteboard service in Mac OS X is registered in a "bootstrap
namespace" (see Apple’s [TN2083][9]). The namespaces exist in
a hierarchy: “higher” namespaces include access to “lower”
namespaces. A process in a lower namespace can not access higher
namespaces. So, all process can access the lowest, “root” bootstrap
namespace, but only processes in a higher namespace can access that
namespace. Processes created as a part of a Mac OS X login session
are automatically included in the user’s “per-user” bootstrap
namespace. The pasteboard service is only available to processes in
the per-user bootstrap namespace.
2430 次点击
所在节点    Go 编程语言
21 条回复
Buges
2022-06-20 17:27:08 +08:00
那就分开多个进程呗,这种事情在 Windows 上也很常见,很多程序都用一个带 UAC 盾牌的 xxxHelper.exe 处理特权操作,主程序无需 UAC 。Linux 也可以用一些 cap /euid 等机制提权,也可以在特权操作完成后调用 setuid 主动降权。
learningman
2022-06-20 17:29:51 +08:00
一般来说都是起一个有 root 权限的 daemon ,主进程在普通用户下面跑
jeesk
2022-06-20 17:40:19 +08:00
@Buges
@learningman 两位大佬, 没太懂具体怎么操作, 有没有这方便的资料, 因为我也是临时安排处理问题, 以前没这方面经验的。
flynaj
2022-06-20 19:12:28 +08:00
@jeesk #3 就是需要 root 权限的那部分离出来单独做一个程序,然后主程序调用。
helone
2022-06-20 19:19:56 +08:00
nuk
2022-06-20 19:30:50 +08:00
创建网卡用另外一个程序吧,感觉主要问题不是 root 获取不到剪贴板,而是为什么你的程序要用 root 运行。
jeesk
2022-06-20 19:34:11 +08:00
@nuk 因为创建网卡需要 root
jeesk
2022-06-20 19:36:21 +08:00
@helone 创建网卡我用的是 golang 呀, 不是普通命令
nuk
2022-06-20 19:46:48 +08:00
@jeesk 所以把这部分拆开就好了噻,主程序就不用 root 权限了。像很多 vpn 程序,也就安装网卡的时候请求 root ,有网卡就不会要求 root 了。
helone
2022-06-20 19:47:11 +08:00
@jeesk 。。。你就不能写成俩程序,都可以是 GO 写的啊,命令行调用另一个程序执行不就完了嘛
ysc3839
2022-06-20 20:50:32 +08:00
Unix 系统不是有 seteuid 吗?确定是无效的?
jeesk
2022-06-20 21:20:54 +08:00
@ysc3839
@helone
@nuk
@helone
@flynaj 我们用的这个库, 创建一张虚拟网卡, 然后在虚拟网卡上面做数据转发处理。 主要是获取 ifce 对象进行读写监听流量。
jeesk
2022-06-20 21:21:15 +08:00
virusdefender
2022-06-20 21:36:35 +08:00
启动一个 goroutine ,然后 runtime.LockOSThread ,然后 setuid ,这样不会影响主进程的 uid ,或者简单点开一个子命令
czyt
2022-06-21 09:12:19 +08:00
开两个进程,rpc 或者其他方式通信
tomychen
2022-06-21 14:50:39 +08:00
什么时候 Unix-like 切换权限变成这么大难题了?

sudo: 我是假的?
chmod +x: 我可能被忽视了
jeesk
2022-06-21 15:18:03 +08:00
ifce, err := water.New(water.Config{
DeviceType: water.TAP,
})
if err != nil {
log.Fatal(err)
}
var frame ethernet.Frame
n, err := ifce.Read([]byte(frame))
if err != nil {
log.Fatal(err)
}

这里的 ifce 对象我们用来接收数据, 但是 water.New 需要 root 权限创建。 所以你们说的子命令我个人感觉完全不行。 @virusdefender 大佬说的 lockOsThread 我还没有测试过, 我看看行不行。

@tomychen
tomychen
2022-06-21 17:49:13 +08:00
```
user@debian:/tmp$ cat test.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
system("id");
setuid(1000);
setgid(1000);
system("id");

}
user@debian:/tmp$ sudo ./test
uid=0(root) gid=0(root) groups=0(root)
uid=1000(user) gid=0(root) groups=0(root)
```
MAC 同理
jeesk
2022-06-22 10:59:22 +08:00
@virusdefender 你这个说的设置 uid 是指的是设置 root 的 uid 吗
virusdefender
2022-06-22 13:29:53 +08:00
@jeesk set 成你想读取的用户的 uid 啊

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

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

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

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

© 2021 V2EX