Problem Statement

In Unix, a process needs special permission to bind() to a privileged port, which means one < 1024.

However, running with more permissions than necessary is dangerous. Normally an application will drop all permissions other than the ones necessary. For a network application, this procedure would be something like:

  1. Drop all permissions other than the ability to bind() to a specific port.
  2. bind() to that port.
  3. Drop permission to bind to a privileged port.

The problem with this approach in BIND 10 is that we are running multiple processes, and want to be able to restart a process that has failed. This means that the boss process cannot do the last step, and must keep permission to bind() to privileged ports.

Proposed Solution

The proposed solution is to create a special process that only has the ability to bind to privileged ports. When a BIND 10 process needs a port, the boss process requests one and gets it from that process.

The algorithm for the boss process will be:

  1. Drop all permissions other than the ability to setuid(), chroot(), and bind() to a specific port.
  2. Create the PrivilegedSocketCreator process in a sandbox.
  3. Drop remaining permissions via setuid() to non-root user.

The "sandbox" described should be as secure as possible. This means:

  • Create a pair of pipe() channels.
  • Create a temporary directory.
  • Change to the directory.
  • fork() a new process.
  • In the child process:
    • Change to the directory.
    • chroot() to the directory.
    • Drop permission to chroot().
    • Close all file descriptors except half of the pipe() channels.
  • In the parent process:
    • Change back out of the directory.
    • Unlink the directory.
    • Close half of the pipe() channels.

Some helpful hints are here:

It would be better to be able to setuid() but we need to keep permission to bind() new ports.

When a client needs a socket bound on a privileged port, it asks the boss process. The boss process then writes a request for a new socket down the pipe to the PrivilegedSocketCreator containing:

16 bytes of IP address (IPv4 are 0-padded)
 4 bytes of port

Even though it is not a strict requirement for BIND 10, a benefit of this model is that we can always change the port and interface in use at runtime.

Questions & Proposed Answers

Should the PrivilegedSocketCreator be written using C++ or Python? Python is less code, and therefore simpler, but then requires a Python interpreter. C++ is recommended.

Should the PrivilegedSocketCreator run if no privileged ports are needed? By default yes, since it is possible the administrator will want to use such a port later. If an administrator wants to run with absolute minimal risk, then it can be disabled completely.

Should the PrivilegedSocketCreator provide any statistics or other information about it's operation? No, since all communication is done via the boss process, the boss can provide this information.

System-Specific Techniques


On Linux we can use capabilities. There is a Python module for it:


Solaris has a least privilege model

Last modified 9 years ago Last modified on Feb 25, 2011, 3:00:56 PM

Attachments (1)

Download all attachments as: .zip