Privilege Separated OpenSSH
We use an unprivileged child process to contain and restrict the
effects of programming errors. A bug in the unprivileged child
process does not result in a system compromise. In other words, the
goal is complete privilege separation within in
Privilege separation uses two processes: The privileged parent process
that monitors the progress of the unprivileged child process. The
child process is unprivileged. This is achieved by changing its uid/gid
to an unused user and restricting its file system access via chroot()
to /var/empty. It is the only process that processes
network data. The privileged parent can be modelled by a very small
finite-state machine so that it is easy to reason about the code
that is being executed with privileges.
A well defined interface between privileged parent and unprivileged
child allows the child to delegate operations that require privileges
to the parent. Successful authentication is determined by the parent
Communication between the privileged and the unprivileged process is
achieved by pipes. Shared memory stores state that can not be
otherwise exported. The child has to ask the privileged parent to
determine if authentication was successful or not.
If the child process gets corrupted and believes that the remote user
has been authenticated, access will not be granted unless the parent
has reached the same decision.
Previously any corruption in the sshd could lead to
an immediate remote root compromise if it happened before authentication,
and to local root compromise if it happend after authentication.
Privilege Separation will make such
compromise very difficult if not impossible.
Privilege separation is a powerful principle to improve cyber security that can also be applied
to other authentication services.
- 2002-03-18: Privilege Separated OpenSSH
has been integrated into the OpenBSD cvs repository.
- 2002-03-16: User feedback has identified a few minor problems
that are being fixed now.
- 2002-03-15: Finalized version. Looking for
- 2002-03-14: Minor bug fixes. Pretty stable, running on all my
- 2002-03-13: SSHv1 is privilege separated, too.
BSD-auth is supported and other authentication systems
should operate under privilege separation soon.
- 2002-03-12: All of OpenSSH is completely
privilege separated. In order to get privilege separation
after the authentication, the operating system needs to support
file descriptor passing. If no file descriptor passing is avaiable,
the privilege separation will stop after authentication was
- SSH v2 only:
The privilege separation works for protocol
v2 only at the moment. SSH v1 protocol is
currently being worked on.
- 2002-03-11: Pre-authentication is completely privilege separated.
After authentication was successful the unprivileged child exports
its cryptographic and compression state to the privileged parent which
OpenSSH needs to keep track of the current IV, and for
stream ciphers of the whole key state. Currently, I
obtain the context from the EVP_CIPHER_CONTEXT structure.
Compression State Export:
I had to create two shared memory maps. Override the
allocation functions from zlib to allocate from the
first memory map. Override the allocation functions for
the first memory map to allocate entries from the second
memory map. When the process exists you have all the
control structures from the first memory map stored in
the second memory map and can use the information in the
second map to completely sync state for the first map
This is completely transparent
as the zlib library provides hooks for private allocation
The source code is available in the OpenBSD CVS respository.
has helped with writing code for privilege separation and his
suggestions have improved its quality significantly.
Maintaining portability is a high priority. The interface to the
shared memory is very well abstracted and should be easy to
re-implement on operating systems that do not support anonymous memory
The portable OpenSSH supports Privilege Separation. A few issues
with some operating systems are still being worked on.