因为我的软件需要创建虚拟网卡, 软件就需要 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.
1
Buges 2022-06-20 17:27:08 +08:00 via Android
那就分开多个进程呗,这种事情在 Windows 上也很常见,很多程序都用一个带 UAC 盾牌的 xxxHelper.exe 处理特权操作,主程序无需 UAC 。Linux 也可以用一些 cap /euid 等机制提权,也可以在特权操作完成后调用 setuid 主动降权。
|
2
learningman 2022-06-20 17:29:51 +08:00
一般来说都是起一个有 root 权限的 daemon ,主进程在普通用户下面跑
|
3
jeesk OP |
5
helone 2022-06-20 19:19:56 +08:00
|
6
nuk 2022-06-20 19:30:50 +08:00
创建网卡用另外一个程序吧,感觉主要问题不是 root 获取不到剪贴板,而是为什么你的程序要用 root 运行。
|
9
nuk 2022-06-20 19:46:48 +08:00
@jeesk 所以把这部分拆开就好了噻,主程序就不用 root 权限了。像很多 vpn 程序,也就安装网卡的时候请求 root ,有网卡就不会要求 root 了。
|
11
ysc3839 2022-06-20 20:50:32 +08:00 via Android
Unix 系统不是有 seteuid 吗?确定是无效的?
|
12
jeesk OP |
13
jeesk OP |
14
virusdefender 2022-06-20 21:36:35 +08:00
启动一个 goroutine ,然后 runtime.LockOSThread ,然后 setuid ,这样不会影响主进程的 uid ,或者简单点开一个子命令
|
15
czyt 2022-06-21 09:12:19 +08:00
开两个进程,rpc 或者其他方式通信
|
16
tomychen 2022-06-21 14:50:39 +08:00
什么时候 Unix-like 切换权限变成这么大难题了?
sudo: 我是假的? chmod +x: 我可能被忽视了 |
17
jeesk OP 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 |
18
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 同理 |
19
jeesk OP @virusdefender 你这个说的设置 uid 是指的是设置 root 的 uid 吗
|
20
virusdefender 2022-06-22 13:29:53 +08:00
@jeesk set 成你想读取的用户的 uid 啊
|
21
jeesk OP @virusdefender macosx 上面不行的呀
|