vsFTP Permission Issue

I’m trying to set up vsftp in my NixOS config. My current configuration for it is

services.vsftpd = {
    enable = true;
    localUsers = true;
    userlist = ["tim"];
    writeEnable = true;
    localRoot = "/var/ftp";
  };

My intention is to have my user (tim) be able to get and put files in /var/ftp. The problem is that when I attempt to put a file, I get the following error:

553 Could not create file.

I’ve tried various combinations of permissions and owner for the directory /var/ftp to no avail. I’ve made both my user (tim) and user vsftpd the owner and have also tried setting permissions to 777 but nothing seems to work.

Here’s a sample of a session in case it reveals any issues:

[tim@washburne:~]$ ftp localhost
Connected to localhost.
220 (vsFTPd 3.0.5)
Name (localhost:tim):
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> put /home/tim/Desktop/test.txt
200 EPRT command successful. Consider using EPSV.
553 Could not create file.
ftp>

Any help is greatly appreciated.

Does the server log any errors?

journalctl --unit 'vsftpd.service' --follow

Yes:

[tim@washburne:/var]$ journalctl --unit 'vsftpd.service' --follow
Dec 21 08:13:07 washburne systemd[1]: Started Vsftpd Server.
Dec 21 20:25:33 washburne vsftpd[508072]: [tim] OK LOGIN: Client "::1"
Dec 21 20:25:45 washburne vsftpd[508074]: [tim] FAIL UPLOAD: Client "::1", "/home/tim/Desktop/test.txt", 0.00Kbyte/sec

I’m not sure there’s anything telling there though.

It worked for me to grant filesystem access for the local user, e.g. via a group:

containers.example-system = {
  autoStart = true;
  ephemeral = true;

  config = {
    users.users.example-user = {
      isNormalUser = true;
      password = "example-password";
      extraGroups = [ "vsftpd" ];
    };

    systemd.tmpfiles.rules = [ "d /var/ftp 2770 vsftpd vsftpd - -" ];

    services.vsftpd = {
      enable = true;
      writeEnable = true;
      localUsers = true;
      localRoot = "/var/ftp";
      extraConfig = ''
        local_umask=007
      '';
    };
  };
};
$ date > example-file
$ ftp --passive example-user@localhost
Connected to localhost.
220 (vsFTPd 3.0.5)
331 Please specify the password.
Password: 
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> pwd
257 "/var/ftp" is the current directory
ftp> put example-file
229 Entering Extended Passive Mode (|||29727|)
150 Ok to send data.
226 Transfer complete.
26 bytes sent in 3.8e-05 seconds (668 kbytes/s)
ftp> 221 Goodbye.
$ sudo nixos-container root-login example-system
[root@example-system:~]# ls -lha /var/ftp
total 4.0K
drwxrws---  2 vsftpd       vsftpd  60 Dec 27 11:10 .
drwxr-xr-x 10 root         root   260 Dec 27 11:09 ..
-rw-rw----  1 example-user vsftpd  26 Dec 27 11:10 example-file

The manual says local_root can fail silently, so maybe have a look at pwd?

I’m still experiencing this problem after making the following changes in an effort to duplicate as closely as I can your setup:

  • Added my user to the vsftpd group; it was not previously.
  • Used passive mode to connect.
  • Added the extraConfig section.

Thanks for the help @_Andrew. I’m going to try updating my system tomorrow and then I’ll try again.

@_Andrew thanks again for the help with this. I was able to eventually upgrade my system and now it works as expected.