vsftpd-2.2.0pre1 and network separation

Following on from vsftpd-2.1.2, I've just released vsftpd-2.1.0pre1:


This further plays with the new Linux container flags: this time, CLONE_NEWNET. This flag creates a process with a separate (and empty) list of network devices and bindings. A process isolated in such a way can create network sockets but any attempt to e.g. do an IPv4 connect() to localhost (or any other destination) will get ENETUNREACH.

CLONE_NEWNET is a very new facility and is not yet generally available in Linux distributions. For example, Fedora 11 offers it whereas Ubuntu 9.04 does not.

When available, vsftpd uses CLONE_NEWNET for the unprivileged protocol handler processes (both pre- and post-login). This means a compromised handler process will no longer get access to sensitive networks such as localhost or behind the firewall. This is on top of existing restrictions on the filesystem, local processes and local IPC.

The use of CLONE_NEWNET does provide some design challenges -- fundamentally, the protocol handler needs to be able to connect() out to handle the PORT command. Also, the listening sockets handling PASV need access to network interfaces. vsftpd solves this by re-using its privileged helper architecture. The creation of any data channel network socket is now a privileged operation. The privileged side enforces that a connect() may only be performed back to the real FTP client machine. It hands the resulting socket to the unprivileged protocol handler which then gets to use it as normal since it is already bound to a real network interface and connected. I've checked that attempts to shutdown() and connect() such a socket result in EISCONN so hopefully there is no way to abuse the connected socket on the untrusted side to bypass the CLONE_NEWNET setup. Input welcome. This was fun :)