In Unix-like systems, /var/empty
is a special directory commonly used by sshd
(OpenSSH daemon) as a secure chroot directory for privilege separation. This directory is intentionally empty and owned by root with strict permissions (typically 755 or 750) to prevent unauthorized access.
The SSH daemon employs /var/empty
as part of its security model:
- Privilege Separation: When sshd starts, it creates an unprivileged child process that handles network communications
- Chroot Jail: The unprivileged process gets chrooted to
/var/empty
, limiting its filesystem access - Attack Surface Reduction: Even if compromised, the process can't access sensitive system files
Here's how sshd typically configures this in its source code (simplified example):
/* From OpenSSH privilege-sep.c */
#define PRIVSEP_PATH "/var/empty"
void
privsep_preauth_child(void)
{
if (chroot(PRIVSEP_PATH) != 0)
fatal("chroot(\"%s\"): %s", PRIVSEP_PATH, strerror(errno));
/* Drop privileges and chdir to root of chroot */
if (chdir("/") != 0)
fatal("chdir(\"/\"): %s", strerror(errno));
}
To properly set up this directory on a Linux system:
# Create the directory (if not exists)
sudo mkdir -p /var/empty
# Set correct ownership and permissions
sudo chown root:root /var/empty
sudo chmod 755 /var/empty
# Verify SELinux context if applicable
sudo restorecon -Rv /var/empty
If sshd fails to start due to /var/empty
problems:
# Check directory existence and permissions
ls -ld /var/empty
# Typical error in /var/log/secure:
# "Missing privilege separation directory: /var/empty"
# Debug with strace
strace -f -e trace=file,process /usr/sbin/sshd -D -d
Never place any files in /var/empty
:
- An empty directory is security feature, not a bug
- Some systems use
/var/run/sshd
or/empty
instead - Cloud images might need manual creation of this directory
Some Linux distributions implement variations:
# FreeBSD-style (more secure) approach:
mkdir -p /var/empty
chmod 711 /var/empty
# Systemd-based systems might use:
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755
For containerized environments, ensure the directory exists in your Dockerfile:
RUN mkdir -p /var/empty && \
chown root:root /var/empty && \
chmod 755 /var/empty
In Unix/Linux systems, /var/empty
is a special directory created specifically for sshd (OpenSSH daemon) to implement privilege separation - a security mechanism where processes run with minimal required permissions. This directory is typically:
- Owned by root:root
- Set with 711 permissions (drwx--x--x)
- Empty by design (no files/subdirectories)
When sshd starts, it creates an unprivileged child process that handles network communications. This child process:
int main(int argc, char **argv) {
/* Privilege separation */
if (privsep_chroot) {
if (chroot("/var/empty") == -1)
fatal("chroot(\"/var/empty\"): %s", strerror(errno));
if (chdir("/") == -1)
fatal("chdir(\"/\"): %s", strerror(errno));
}
/* Rest of the daemon code */
}
The directory serves three key security purposes:
- Chroot jail: Limits filesystem access during privilege separation
- Attack surface reduction: Even if compromised, attacker finds no utilities
- Process isolation: Prevents privilege escalation attempts
Some systems may need manual setup. Here's how to create it properly:
# mkdir -p /var/empty
# chown root:root /var/empty
# chmod 711 /var/empty
# ls -ld /var/empty
drwx--x--x 2 root root 4096 Jan 1 00:00 /var/empty
Common issues and solutions:
Issue | Solution |
---|---|
Directory missing | Create as shown above |
Wrong permissions | chmod 711 /var/empty |
Not empty | Remove all contents |
For SELinux systems, additional context may be needed:
# semanage fcontext -a -t sshd_var_empty_t "/var/empty(/.*)?"
# restorecon -Rv /var/empty