When implementing forced SFTP access on CentOS 6 with OpenSSH 5.3p1, many administrators encounter the misleading error:
error: subsystem: cannot stat /usr/libexec/openssh/sftp-server
subsystem request for sftp failed, subsystem not found
Despite the file existing at the specified path, the SSH daemon fails to recognize it. This typically indicates a deeper configuration issue rather than a missing binary.
The root cause often stems from two competing configurations:
# Original problematic configuration
Subsystem sftp /usr/libexec/openssh/sftp-server
Match user USERNAME
ForceCommand internal-sftp
The conflict arises because internal-sftp
doesn't use the external binary path, yet the Subsystem directive still points to it. Here's how to verify your actual sftp-server path:
# Find the correct sftp-server path
$ find / -name sftp-server 2>/dev/null
$ ls -la /usr/libexec/openssh/sftp-server
For forced SFTP to work properly, you need to modify your /etc/ssh/sshd_config
as follows:
# Correct configuration for forced internal SFTP
Subsystem sftp internal-sftp
Match Group sftpusers
ChrootDirectory /home/%u
ForceCommand internal-sftp
X11Forwarding no
AllowTcpForwarding no
Key changes include:
- Replacing the binary path with
internal-sftp
in Subsystem - Using group matching instead of individual users
- Adding security restrictions
After making changes, always:
# Check config syntax
$ sudo sshd -t
# Restart service
$ sudo service sshd restart
# Test connection
$ sftp username@localhost
If you must use the external binary (unlikely in modern systems), ensure proper SELinux contexts:
# For systems requiring external binary
$ sudo restorecon -v /usr/libexec/openssh/sftp-server
$ sudo chmod 755 /usr/libexec/openssh/sftp-server
Then modify the Subsystem line to match your verified path.
If issues persist, check:
- SELinux status with
getenforce
- File permissions on home directories
- AppArmor/selinux logs in
/var/log/audit/audit.log
- SSH debug output with
ssh -vvv
When attempting to restrict users to SFTP-only access on CentOS 6 with OpenSSH 5.3p1, many administrators encounter the particularly stubborn error:
error: subsystem: cannot stat /usr/libexec/openssh/sftp-server: No such file or directory
subsystem request for sftp failed, subsystem not found
The paradox occurs when the file clearly exists at the specified path but the SSH daemon fails to recognize it. Let's dissect this behavior.
The conflict stems from an incompatibility between these two configuration elements:
Subsystem sftp /usr/libexec/openssh/sftp-server
Match user USERNAME
ForceCommand internal-sftp
Here's what's happening:
- The Subsystem directive points to the external binary
- ForceCommand internal-sftp tries to use the built-in implementation
- The SSH daemon gets confused between these conflicting instructions
For modern OpenSSH versions (4.9+), the proper approach is:
# Comment out or remove the Subsystem line
# Subsystem sftp /usr/libexec/openssh/sftp-server
Match User restricted_user
ChrootDirectory /home/%u
ForceCommand internal-sftp
X11Forwarding no
AllowTcpForwarding no
PermitTTY no
After modifying the configuration:
- Restart SSH:
service sshd restart
- Test SFTP access:
sftp restricted_user@localhost
- Verify shell access is blocked:
ssh restricted_user@localhost
If you must keep the external sftp-server:
Subsystem sftp /usr/libexec/openssh/sftp-server
Match User restricted_user
ForceCommand /usr/libexec/openssh/sftp-server
ChrootDirectory /home/%u
Remember to set proper permissions:
chown root:root /home/restricted_user
chmod 755 /home/restricted_user
When troubleshooting:
- Check SSH daemon logs:
tail -f /var/log/secure
- Run in debug mode:
/usr/sbin/sshd -d
- Verify file permissions:
ls -la /usr/libexec/openssh/