When running a web server or any other program that requires listening on a low port (below 1024) in Linux, it is common to run it as a privileged user, usually as root. Running as root, however, can pose a security risk as any vulnerability in the program or its dependencies can lead to full system compromise.
One alternative to running as root is to use Linux capabilities. Linux capabilities provide a fine-grained way to grant specific privileges to a program without granting full root access. One such capability is CAP_NET_BIND_SERVICE, which allows a program to bind to any network port without requiring root privileges.
In this tutorial, we will learn how to use CAP_NET_BIND_SERVICE to run a web server listening on port 80 without requiring root privileges.
Prerequisites
Before we get started, we need to ensure that the setcap command is available on our system. This command is typically included in the libcap2-bin package, which can be installed using the following command:
sudo apt-get install libcap2-bin
Setting CAP_NET_BIND_SERVICE Capability
The first step is to compile our program and set the CAP_NET_BIND_SERVICE capability on it. Here is a sample Go program that listens on port 80 and serves a "Hello, world!" message:
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
// Define the handler function
handler := func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, world!")
}
// Register the handler with the http server
http.HandleFunc("/", handler)
// Start the http server
log.Fatal(http.ListenAndServe(":80", nil))
}
To set the CAP_NET_BIND_SERVICE capability on this program, we can use the setcap command as follows:
sudo setcap 'cap_net_bind_service=+ep' port80server
sudo setcap ‘cap_net_bind_service=+ep’ port80server
This command grants the CAP_NET_BIND_SERVICE capability to the port80service program, allowing it to bind to any network port without requiring root privileges.
Running the Program
Now that we have set the CAP_NET_BIND_SERVICE capability on our program, we can run it without root privileges. Here is how we can run our program:
./port80server
curl -v http://localhost/
The program should start running and listening on port 80. To verify that it is running correctly, open a web browser and visit http://localhost/. You should see the "Hello, world!" message displayed in the browser.
Conclusion
In this tutorial, we learned how to use Linux capabilities to run a program that listens on port 80 without requiring root privileges. By using CAP_NET_BIND_SERVICE, we were able to grant the necessary privileges to our program without granting full root access, which helps to reduce the security risk.
While this tutorial focuses on running a web server on port 80, the same technique can be used for any other program that requires binding to a low port. Just remember to set the appropriate capability and test that the program is running correctly
Top comments (0)