Unlocking the Power of Linux Capabilities: Exposing Port 80 without Root Access
Tags: networking, linuxcapabilities, linux, security
Published: 2023-04-18 05:46:37

---
title: Unlocking the Power of Linux Capabilities: Exposing Port 80 without Root Access
published: true
date: 2023-04-10 10:14:53 UTC
tags: networking,linuxcapabilities,linux,security
canonical_url: 
---

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](https://cdn-images-1.medium.com/max/1024/1*lN5b01DMrSkQHaeOLFFw0w.png)
_sudo setcap ‘cap_net_bind_service=+ep’ port80server_

![getcap ./port80server](https://cdn-images-1.medium.com/max/904/1*XT4a-0VRRlzo9SLLapxaXA.png)
_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
```

![curl -v http://localhost/](https://cdn-images-1.medium.com/max/1024/1*K35kl_cAatRPAs-NVkq7bw.png)
_curl -v http://localhost/_

![Visit localhost](https://cdn-images-1.medium.com/max/1024/1*QOJmZg-pvfoe6ijmKoKeJQ.png)

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

* * *