Golang中Pledge的使用体验分享

Golang中Pledge的使用体验分享 我在文章中看到Golang支持OpenBSD Pledge:

http://undeadly.org/cgi?action=article&sid=20170323042425

这是否意味着只有为OpenBSD编写的代码才能使用它?

有人研究过这个吗?

谢谢。

3 回复

这是否意味着只有为OpenBSD编写的代码才能使用它?

是的。

系统调用仅在其实现的系统中可用。

虽然我还没有使用过 pledge,但我很喜欢这个想法。

// 代码示例保留原样

更多关于Golang中Pledge的使用体验分享的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


看起来我成功实现了对Go代码的"pledge"功能 🙂

package main
import "golang.org/x/sys/unix"
import "fmt"
import "os"
func main() {
err := unix.Pledge("stdio",nil)
if err != nil {
fmt.Println("pledge error: ", err)
}
fmt.Println("Ciao!")
os.Exit(0)
}

如果你尝试更改"stdio"参数,它将无法正常工作

你可以在Pledge函数中放入的参数是一个以空格分隔的列表,具体参数可以在这里找到: https://man.openbsd.org/pledge.2

当然,我是在OpenBSD系统上测试的,在那里运行正常。

在Go语言中,pledge 功能是通过 syscall 包提供的系统调用接口实现的,它允许程序在运行时限制自身可执行的系统操作,从而增强安全性。这并非仅限于OpenBSD代码;只要在支持 pledge 的系统(如OpenBSD)上运行Go程序,就可以使用它。不过,需要注意的是,pledge 是OpenBSD特有的功能,因此在其他操作系统(如Linux或Windows)上编译或运行时,相关代码可能无法工作或需要条件编译。

以下是一个简单的示例代码,展示如何在Go程序中使用 pledge 来限制程序仅允许标准I/O操作(如 stdio)。在实际应用中,你应根据程序需求调整承诺的权限。

package main

import (
    "fmt"
    "syscall"
)

func main() {
    // 在程序启动后调用pledge,限制只允许stdio操作
    // 参数为承诺的权限字符串,例如"stdio"表示只允许标准输入输出
    err := syscall.Pledge("stdio")
    if err != nil {
        fmt.Printf("Pledge failed: %v\n", err)
        return
    }

    // 此后程序只能执行与stdio相关的操作,如打印输出
    fmt.Println("Pledge applied successfully! Program is now restricted to stdio.")

    // 尝试执行其他操作(如文件访问)可能会失败,具体取决于pledge的设置
    // 例如,如果未包含"rpath",则文件读取会出错
}

在这个例子中,syscall.Pledge("stdio") 调用将程序限制为仅能使用标准I/O功能。如果程序试图执行超出此范围的系统调用(如网络访问或文件操作),系统可能会终止它。这有助于减少潜在的安全风险。

需要注意的是,pledge 的可用性取决于编译和运行环境:在OpenBSD上,你可以直接使用;在其他系统上,编译时可能会遇到未定义的错误。因此,建议使用构建标签进行条件编译,例如:

// +build openbsd

package main

import (
    "fmt"
    "syscall"
)

func main() {
    err := syscall.Pledge("stdio")
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }
    fmt.Println("Running with pledge on OpenBSD.")
}

通过这种方式,代码只在OpenBSD上编译和执行 pledge 相关部分,从而避免跨平台问题。总之,Go中的 pledge 是一个有用的安全特性,但需确保目标系统支持。

回到顶部