Description
⚠️ This issue respects the following points: ⚠️
- This is a bug, not a question or a configuration issue.
- This issue is not already reported on Github (I've searched it).
Bug description
We're getting a "no such file or directory" error when trying to get/put data with a S3FS-backed user in case the temporary root directory does not exist and the user's activity is recent.
Steps to reproduce
- Configure a user with S3FS VFS (I believe it will work for any non-local VFS since it will try to create a pipe, I have only tested it with S3 though)
- Connect through SFTP for the first time with the user -> everything works well
- Disconnect
- Remove the temporary directory that was created on the local filesystem (exemple /srv/sftpgo/data/myuser)
- Connect again through SFTP with the same user -> you are now unable to use get/put commands
Expected behavior
Commands should not fail to execute
SFTPGo version
Data provider
postgresql
Installation method
Other
Configuration
SFTPGO_DATA_PROVIDER__DRIVER: postgresql
SFTPGO_DATA_PROVIDER__HOST: "sftpgo-db-1"
SFTPGO_DATA_PROVIDER__PORT: "5432"
SFTPGO_DATA_PROVIDER__NAME: "sftpgo"
SFTPGO_DATA_PROVIDER__USERNAME: "sftpgo"
SFTPGO_DATA_PROVIDER__PASSWORD: "sftpgo"
SFTPGO_DATA_PROVIDER__CREATE_DEFAULT_ADMIN: "true"
SFTPGO_DEFAULT_ADMIN_USERNAME: "admin"
SFTPGO_DEFAULT_ADMIN_PASSWORD: "admin"
SFTPGO_SFTPD__LOGIN_BANNER_FILE: "banner.txt"
SFTPGO_SFTPD__KEYBOARD_INTERACTIVE_AUTHENTICATION: "false"
SFTPGO_HTTPD__BINDINGS__0__ENABLE_WEB_CLIENT: "false"
SFTPGO_HTTPD__BINDINGS__0__ENABLED_LOGIN_METHODS: "1" # OIDC for admin
SFTPGO_HTTPD__BINDINGS__0__OIDC__CLIENT_ID: "<client id>"
SFTPGO_HTTPD__BINDINGS__0__OIDC__CLIENT_SECRET: "<client secret>"
SFTPGO_HTTPD__BINDINGS__0__OIDC__CONFIG_URL: "https://sftpgo-ak-server-1:9443/application/o/sftpgo/"
SFTPGO_HTTPD__BINDINGS__0__OIDC__REDIRECT_BASE_URL: "http://127.0.0.1:8080"
SFTPGO_HTTPD__BINDINGS__0__OIDC__USERNAME_FIELD: "preferred_username"
SFTPGO_HTTPD__BINDINGS__0__OIDC__SCOPES: "openid,profile,email,offline_access,sftpgo"
SFTPGO_HTTPD__BINDINGS__0__OIDC__ROLE_FIELD: "sftpgo_role"
SFTPGO_HTTPD__BINDINGS__0__OIDC__DEBUG: "true"
#### HARDENING ####
# - Disable support for ECDSA, this is less secure than EDDSA (Ed25519). Also available algorithms are reported by ssh-audit as supposedly backdoored by the NSA.
# - Disable any NIST curves, for the same "backdoor" reason as above.
# - Enable SHA512 KEX and MAC algorithms even if they are slower.
SFTPGO_SFTPD__HOST_KEYS: "id_rsa, id_ed25519"
SFTPGO_SFTPD__HOST_KEY_ALGORITHMS: "rsa-sha2-512, rsa-sha2-256, ssh-ed25519"
SFTPGO_SFTPD__KEX_ALGORITHMS: "curve25519-sha256, diffie-hellman-group14-sha256, diffie-hellman-group-exchange-sha256"
SFTPGO_SFTPD__MACS: "hmac-sha2-256-etm@openssh.com, hmac-sha2-256, hmac-sha2-512-etm@openssh.com, hmac-sha2-512"
#### RATE LIMITING ####
# Limit to 10 requests per second per IP
SFTPGO_COMMON__RATE_LIMITERS__0__AVERAGE: "10"
SFTPGO_COMMON__RATE_LIMITERS__0__PERIOD: "1000" # 1 second
SFTPGO_COMMON__RATE_LIMITERS__0__TYPE: "2" # 2 = per-IP limit
SFTPGO_COMMON__RATE_LIMITERS__0__PROTOCOLS: "SSH"
Relevant log output
sftp> get file
Fetching /file to file
remote open "/file": Failure
{"level":"error","time":"2025-01-16T00:28:27.570","sender":"SFTP","connection_id":"SFTP_eafb6f53c25ca7e201d81e36de74be6336c626c42755d8b1a2cf799fde7d80ec_1","message":"generic path error: open /srv/sftpgo/data/myuser/pipefile989012594: no such file or directory"}
What are you using SFTPGo for?
Private user, home usecase (home backup/VPS)
Additional info
In my understanding, the root cause of the issue is in the User.CheckFsRoot
function (internal/dataprovider/user.go:243
). In case the last activity of the user is recent, the function will return before the call to User.checkRootPath
and the directory will no be created, preventing any subsequent pipe creation.
I believe that when temp_path
is specified in the config file, the issue is not present, however I haven't tested it (since I'm not sure about the security implications of using this option).
One obvious fix would be to always run User.checkRootPath
regardless of the user's last activity (but maybe this can have a bad impact on performance?), another one could be to ensure dirPath
exists before creating a pipe (internal/vfs.go:77
), or any other solution you may think of.
I would be happy to try to implement any fix you find appropriate and open an MR. Don't hesitate to reach out if you have any question