최근이 문제를 해결하기 위해 Go에는 필요한 모든 조각이 있습니다. 이 샘플에서는 한 걸음 더 나아가 SSL을 구현했습니다. 기본적으로 포트를 열어 UID를 감지하고, 0이면 원하는 사용자를 찾고 UID를 얻은 다음 glibc 호출을 사용하여 프로세스의 UID 및 GID를 설정합니다. 필자는 포트를 바인딩 한 직후에 setuid 코드를 호출하는 것이 가장 좋습니다. 권한을 삭제할 때 가장 큰 차이점은 http.ListenAndServe (TLS)를 사용할 수 없다는 것입니다. 헬퍼 함수 - 수동으로 net.Listener를 별도로 설정 한 다음 포트가 바인딩 된 후 http.Serve를 호출하기 전에 setuid를 호출해야합니다.
이 방법은 더 이상 고려하지 않고 높은 포트의 "개발"모드에서 UID! = 0처럼 실행할 수 있기 때문에 잘 작동합니다. 이것은 단지 스텁 일 뿐이라는 것을 기억하십시오. 설정 파일에서 주소, 포트, 사용자, 그룹 및 TLS 파일 이름을 설정하는 것이 좋습니다.
package main
import (
"crypto/tls"
"log"
"net/http"
"os/user"
"strconv"
"syscall"
)
import (
//#include <unistd.h>
//#include <errno.h>
"C"
)
func main() {
cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
if err != nil {
log.Fatalln("Can't load certificates!", err)
}
var tlsconf tls.Config
tlsconf.Certificates = make([]tls.Certificate, 1)
tlsconf.Certificates[0] = cert
listener, err := tls.Listen("tcp4", "127.0.0.1:445", &tlsconf)
if err != nil {
log.Fatalln("Error opening port:", err)
}
if syscall.Getuid() == 0 {
log.Println("Running as root, downgrading to user www-data")
user, err := user.Lookup("www-data")
if err != nil {
log.Fatalln("User not found or other error:", err)
}
// TODO: Write error handling for int from string parsing
uid, _ := strconv.ParseInt(user.Uid, 10, 32)
gid, _ := strconv.ParseInt(user.Gid, 10, 32)
cerr, errno := C.setgid(C.__gid_t(gid))
if cerr != 0 {
log.Fatalln("Unable to set GID due to error:", errno)
}
cerr, errno = C.setuid(C.__uid_t(uid))
if cerr != 0 {
log.Fatalln("Unable to set UID due to error:", errno)
}
}
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("Hello, world!"))
})
err = http.Serve(listener, nil)
log.Fatalln(err)
}
출처
2018-02-26 15:26:03
Jon
선호하는 방법은 프로그램이 완전한 루트 기능을 사용하지 않고 올바른 포트에 바인딩하는 것을 허용하는 Linux 기능을 사용하는 것입니다. – JimB
당신이 실제로 링크 할 수있는 문제는 가능한 여러 가지 해결 방법/솔루션 IIRC가 있습니다. – Carpetsmoker
Setuid가 golang에서 예상대로 작동하지 않았습니다. 이러한 해결 방법은 행동의 일관성을 높이는 것이 었습니다. 그러나 결국 그들은 성공을 보장하지 못했습니다. 즉, setuid를 호출 한 후에도 루트가 될 수 있습니다. 그렇기 때문에이 기능을 사용하지 않도록 결정했습니다. linux-capabilities에 관해서 : 당신은 여기서 정확히 무엇을 제안하겠습니까? – user2089648