2016-03-12 22 views
0

我想測試/自動化一些倉庫,基本流程是這樣的:是否有辦法chroot /沙箱去os.exec調用(防止室射頻/)

repos := []string{"repo 1", "repo 2", ...} 
for r := range repos { 
    // git clone the repo 
    // cd repo dir 
    // make test 
    // make build 
    // ... 
} 

我做這與使用os.exec調用所有的一系列命令GO,是這樣的:

exec.Command("sh", "-c", "git clone project") 

到目前爲止好,但我想知道是否有保證/防止在Makefile文件的東西誤寫的方式這可能會做類似rm -rf /。並打破我的主機。

基本上我想使用系統庫/工具,但限制/ chroot只輸出到一個特定的workdir,以便我可以避免預先爲此構建一個chroot。

一個可行的解決方案是使用一個FreeBSD jail,但我想知道是否有替代/安全的方式來做到這一點,而不需要容器,virtualbox等;並使用基本的Mac OS X工作站。這樣任何人都可以「安全」地運行&測試而不用擔心。

任何想法?

+0

你需要什麼樣的沙箱?你需要沙盒只是文件系統或其他東西,如網絡套接字? – fntlnz

+0

有一個名爲syscall的軟件包,它具有一個Chroot功能,可以執行您所需要的功能:https://golang.org/pkg/syscall/ – robbrit

+0

我只需要沙盒用於文件系統 – nbari

回答

0

你應該使用os.Setuid/os.Setgid(example.go)罰款:

package main 

import (
    "log" 
    "flag" 
    "os" 
    "os/exec" 
    "syscall" 
) 

func main() { 
    var oUid = flag.Int("uid", 0, "Run with User ID") 
    var oGid = flag.Int("gid", 0, "Run with Group ID") 
    flag.Parse() 

    // Get UID/GUID from args 
    var uid = *oUid 
    var gid = *oGid 

    // Run whoami 
    out, err := exec.Command("whoami").Output() 
    if err != nil { 
     log.Fatal(err) 
     return 
    } 

    // Output whoami 
    log.Println("Original UID/GID whoami:", string(out)) 
    log.Println("Setting UID/GUID") 

    // Change privileges 
    err = syscall.Setgid(gid) 
    if err != nil { 
     log.Println("Cannot setgid") 
     log.Fatal(err) 
     return 
    } 

    err = syscall.Setuid(uid) 
    if err != nil { 
     log.Println("Cannot setuid") 
     log.Fatal(err) 
     return 
    } 

    // Execute whoami again 
    out, err = exec.Command("whoami").Output() 
    if err != nil { 
     log.Fatal(err) 
     return 
    } 
    log.Println("Changed UID/GID whoami:", string(out)) 


    // Do some dangerous stuff 
    log.Println("Creating a executable file within /bin should fail...") 
    _, err = os.Create("/bin/should-fail") 
    if err == nil { 
     log.Println("Warning: operation did not fail") 
     return 
    } 

    log.Println("We are fine", err) 
} 

我也建議閱讀有關設置GID/UID正確(https://unix.stackexchange.com/questions/166817/using-the-setuid-bit-properly,在C)。哦!它需要在uid之前設置gid,因爲如果不這樣做,示例會失敗。

您應該使用root權限執行example.go,並分別爲帶有標誌-gid,-uid的命令指定無特權的gid/uid。

sudo go run example.go -uid <unprivileged id> -gid <unprivileged id>