Can someone explain how sshd does privilege separation?

29266, the unprivileged child

This one is the privileged one, as the process title shows sshd: test [priv], the 29268 is unprivileged postauth child (user is already test instead of root).

But the main place where you can use privsep is before authentication:

root     11759  0.0  0.0  69928  6056 ?        Ss   Feb07   0:00 /usr/sbin/sshd -D
root     10071  0.2  0.0 119280  7096 ?        Ss   10:56   0:00  \_ sshd: unknown [priv]
sshd     10072  0.2  0.0  71272  3016 ?        S    10:56   0:00      \_ sshd: unknown [net] 

There you see the privileged process running under root privileges (10071) and net-child (sshd: user [net], running under sshd user, and usually under some sandbox which prevents most of the privilege escalation attacks, it there was a hole in the code.

So as already mentioned by tylerl, or you setuid is used to drop/change privileges from root to sshd or your user. But note that you need to point out to the correct process when trying to understand this constellation. Image is usually more than thousands words:

image

Where in the image corresponding to your example:

  • the first privileged is sshd daemon (your pid 28389)
  • the second one privileged is monitor (your pid 29266)
  • you don't have in your ps unprivileged network child (mind pid 10072)
  • the user privileged is child (your pid 29268)

Here's how you do it:

You start out with a parent process, running as root.

That process forks itself, creating two identical clones, only one of them is the parent and one is the child (fork returns the child's PID for the parent process, and 0 for the child). NB: fork is the libc function name, under the hood it calls clone which is the syscall provided by the kernel.

In the child, you next perform any privileged operations that need to happen, setting up the environment as desired.

Once all the prep work is done, the child process calls setuid (actually probably some combination of setreuid setregid and possibly a few other calls) to switch to the UID/GID of the new unprivileged process owner.

Lastly, the child calls exec (probably execle or similar) to run whatever program the child is supposed to be executing, replacing the current process space with the new one, though keeping the same UID/GID/PID that the child process had before.

Tags:

Ssh