如何使用Golang找到以root身份执行程序的用户?

huangapple go评论84阅读模式
英文:

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_GIDSUDO_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())

}

https://play.golang.org/p/tRMR5IW6GAc

答案3

得分: 5

由于任何人都可以设置SUDO_UIDSUDO_GIDSUDO_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)
}

huangapple
  • 本文由 发表于 2015年4月20日 01:50:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/29733575.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定