英文:
How to find the user that executed a program as root using Golang?
问题
我正在创建一个需要特权访问低于1024的网络端口的小程序,所以它需要以sudo方式运行。
如果实用程序的一部分需要知道调用应用程序的用户是谁,我需要一种查询实际用户的方法;使用OS/user
方法获取用户指向“系统管理员”或其他root用户,因为它在sudo上下文中运行。
在GoLang中,有没有一种方法可以获取以sudo方式运行应用程序的用户?(Go 1.4.2,在OS X 10.10.3上运行)。
英文:
I'm creating a small program that requires privileged access to a network port below 1024, so it runs with sudo.
If part of what the utility will need to do requires knowing who the user is that invoked the application, I would need a way to query who the actual user is; using the OS/user
method of getting the user points to "System Administrator" or other root user because it's running in a sudo context.
Is there a way in GoLang to pull the user who is running the application under sudo? (Go 1.4.2, running on OS X 10.10.3).
答案1
得分: 16
sudo命令会创建SUDO_UID
/SUDO_GID
和SUDO_USER
环境变量,其中包含调用sudo的账户的用户ID、组ID和用户名。在Go语言中,你可以使用os.Getenv()函数读取这些环境变量。
如果你只想在以root身份运行时信任这些变量,你可以通过判断os.Geteuid()函数的返回值是否为0来实现。
英文:
sudo creates the SUDO_UID
/SUDO_GID
and the SUDO_USER
environment variables for this, which contains the user id, group id and username of the account invoking sudo. See e.g. here
So in Go you can read those environment variables with os.Getenv().
You might want to trust those variables only if running as root, i.e. if os.Geteuid() returns 0
答案2
得分: 7
以下是我翻译好的内容:
这是我检查当前用户是否为root
的最新Golang版本go1.16.1
的方法:
package main
import (
"fmt"
"log"
"os/user"
)
func isRoot() bool {
currentUser, err := user.Current()
if err != nil {
log.Fatalf("[isRoot] 无法获取当前用户:%s", err)
}
return currentUser.Username == "root"
}
func main() {
fmt.Printf("我是root用户吗?%v", isRoot())
}
链接:https://play.golang.org/p/tRMR5IW6GAc
英文:
Here's how I check if the current user is root
in the latest Golang version go1.16.1
:
package main
import (
"fmt"
"log"
"os/user"
)
func isRoot() bool {
currentUser, err := user.Current()
if err != nil {
log.Fatalf("[isRoot] Unable to get current user: %s", err)
}
return currentUser.Username == "root"
}
func main() {
fmt.Printf("Am I root? %v", isRoot())
}
答案3
得分: 5
由于任何人都可以设置SUDO_UID
、SUDO_GID
和SUDO_USER
,攻击者可以导出这些变量,绕过您尝试实施的安全性。
我找到的方法是找到您当前运行的Go程序的进程ID(pid),获取拥有该pid的用户的名称,然后检查是否为root
。
import (
"fmt"
"os"
"os/exec"
"strconv"
)
func main() {
if getProcessOwner() == "root" {
fmt.Println("You're sudo!")
}
}
func getProcessOwner() string {
stdout, err := exec.Command("ps", "-o", "user=", "-p", strconv.Itoa(os.Getpid())).Output()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return string(stdout)
}
英文:
Since anyone can set SUDO_UID
, SUDO_GID
and SUDO_USER
, an attacker can just export those themselves and bypass the security you're trying to implement.
The way that I've found, is to find the pid of the Go program you're currently running, get the name of the user that owns that pid, then check if its root
.
import (
"fmt"
"os"
"os/exec"
"strconv"
)
func main() {
if getProcessOwner() == "root" {
fmt.Println("You're sudo!")
}
}
func getProcessOwner() string {
stdout, err := exec.Command("ps", "-o", "user=", "-p", strconv.Itoa(os.Getpid())).Output()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return string(stdout)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论