improve drop root code and move it to a separate file
This commit is contained in:
parent
8cf7b02e1b
commit
0f48c7479f
|
@ -0,0 +1,105 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/user"
|
||||
"strconv"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// Drop root privileges.
|
||||
func dropPrivileges(userToSwitchTo string) {
|
||||
|
||||
// Check if we have root privileges.
|
||||
var rootUser = false
|
||||
var rootPrimaryGroup = false
|
||||
var rootSupplementaryGroup = false
|
||||
|
||||
// Check UID and EUID.
|
||||
if syscall.Getuid() == 0 || syscall.Geteuid() == 0 {
|
||||
rootUser = true
|
||||
}
|
||||
// Check GID and EGID.
|
||||
if syscall.Getgid() == 0 || syscall.Getegid() == 0 {
|
||||
rootPrimaryGroup = true
|
||||
}
|
||||
// Check supplementary groups.
|
||||
groups, err := syscall.Getgroups()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, groupID := range groups {
|
||||
if groupID == 0 {
|
||||
rootSupplementaryGroup = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if userToSwitchTo == "" {
|
||||
|
||||
if rootUser {
|
||||
fmt.Println("When running as root, use the -u option to switch to an unprivileged user.")
|
||||
os.Exit(1)
|
||||
} else if rootPrimaryGroup || rootSupplementaryGroup {
|
||||
fmt.Println("The user running the program is in the root group;")
|
||||
fmt.Println("use the -u option to switch to an unprivileged user.")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
} else { // userToSwitchTo != ""
|
||||
|
||||
// Get user and group IDs for the user we want to switch to.
|
||||
userInfo, err := user.Lookup(userToSwitchTo)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
// Convert group id and user id from string to int.
|
||||
gid, err := strconv.Atoi(userInfo.Gid)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
uid, err := strconv.Atoi(userInfo.Uid)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
// If the user we want to switch to has root privileges, stop execution.
|
||||
if uid == 0 || gid == 0 {
|
||||
fmt.Println("Running as root is not allowed.")
|
||||
os.Exit(1)
|
||||
}
|
||||
// Unset supplementary group IDs.
|
||||
err = syscall.Setgroups([]int{})
|
||||
if err != nil {
|
||||
fmt.Println("Failed to unset supplementary group IDs: " + err.Error())
|
||||
if rootSupplementaryGroup {
|
||||
fmt.Println("Failed to drop root privileges. Exiting...")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
// Set group ID (real and effective).
|
||||
err = syscall.Setgid(gid)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to set group ID: " + err.Error())
|
||||
if rootPrimaryGroup {
|
||||
fmt.Println("Failed to drop root privileges. Exiting...")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
// Set user ID (real and effective).
|
||||
err = syscall.Setuid(uid)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to set user ID: " + err.Error())
|
||||
if rootUser {
|
||||
fmt.Println("Failed to drop root privileges. Exiting...")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
50
server.go
50
server.go
|
@ -14,11 +14,7 @@ import (
|
|||
"log"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/user"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -304,51 +300,7 @@ func main() {
|
|||
}
|
||||
defer ln.Close()
|
||||
|
||||
// Drop root
|
||||
if syscall.Getuid() == 0 { // running as root
|
||||
if userToSwitchTo == "" {
|
||||
fmt.Println("When running as root, use the -u option to switch to an unprivileged user.")
|
||||
os.Exit(1)
|
||||
}
|
||||
// Get user and group IDs for the user we want to switch to.
|
||||
userInfo, err := user.Lookup(userToSwitchTo)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
// Convert group id and user id from string to int.
|
||||
gid, err := strconv.Atoi(userInfo.Gid)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
uid, err := strconv.Atoi(userInfo.Uid)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if uid == 0 {
|
||||
fmt.Println("WARNING: running as root is not recommended!")
|
||||
}
|
||||
// Unset supplementary group IDs.
|
||||
err = syscall.Setgroups([]int{})
|
||||
if err != nil {
|
||||
fmt.Println("Failed to unset supplementary group IDs: " + err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
// Set group ID.
|
||||
err = syscall.Setgid(gid)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to set group ID: " + err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
// Set user ID.
|
||||
err = syscall.Setuid(uid)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to set user ID: " + err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
dropPrivileges(userToSwitchTo)
|
||||
|
||||
log.Println("Server started")
|
||||
|
||||
|
|
Loading…
Reference in New Issue