DEV Community

Siva
Siva

Posted on • Originally published at towardsdev.com on

Unlocking the Power of Linux Capabilities: Exposing Port 80 without Root Access

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


Enter fullscreen mode Exit fullscreen mode

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))
}


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

sudo setcap ‘cap_net_bind_service=+ep’ port80server
sudo setcap ‘cap_net_bind_service=+ep’ port80server

getcap ./port80server
getcap ./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


Enter fullscreen mode Exit fullscreen mode

curl -v http://localhost/
curl -v http://localhost/

Visit 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)