ftpfirewallnixosvsftpd

Running an ftp server on nixos


I would like to run an ftp server on a nixos host. I am using vsftpd, though could use something else if that would make a difference.

The ftp works fine on localhost, but the firewall is blocking me for remote usage. I have allowed TCP port 21, but that is not enough.

How should I configure the firewall to allow ftp connections (including writing to the ftp server)?

Here is the code that I currently have:

{
networking.firewall = { allowedTCPPorts = [ 20 21 ];
#                        connectionTrackingModules = [ "ftp" ];
                      };

  services.vsftpd = {
    enable = true;
#   cannot chroot && write
#    chrootlocalUser = true;
    writeEnable = true;
    localUsers = true;
    userlist = [ "martyn" "cam" ];
    userlistEnable = true;
  };
}

With the above, any use of ftp from off-host fails:

ftp> put dead.letter
200 PORT command successful. Consider using PASV.
425 Failed to establish connection.

Use of passive mode (e.g., with ftp -p) doesn't seem to help here:

ftp> put dead.letter
227 Entering Passive Mode (192,168,0,7,219,202).
ftp: connect: Connection timed out

Testing on a throwaway host with the firewall disabled

networking.firewall.enable = false;

Allows ftp -p to work; though of course turning off the firewall is not an attractive option.

Thanks for any help and pointers,


Solution

  • In passive mode the client will connect to the server with a second connection, that is used to transfer "things" (directory listings, files). In your case:

    227 Entering Passive Mode (192,168,0,7,219,202)
    

    The server requested the client to connect to it on port 219 * 256 + 202 = 56266.

    This port is choosen by vsftpd dynamically and is not open in your firewall. You have to fix vsftpd to a fixed port for the passive connection and open this connection in the firewall.

    vsftpd has two configuration options to set this: pasv_max_port and pasv_min_port. You should be able to set them in services.vsftpd.extraConfig. You probably want to open a small range of ports and open these in the firewall.