OpenSSH provides two distinct methods for implementing SFTP (SSH File Transfer Protocol):
- sftp-server: The traditional standalone executable
- internal-sftp: A built-in subsystem that ships with OpenSSH
The original sftp-server
is a separate binary typically located at /usr/lib/openssh/sftp-server
. This implementation:
- Runs as a separate process
- Has been part of OpenSSH for many years
- Requires explicit path configuration
The internal-sftp
implementation:
- Is compiled directly into the sshd binary
- Doesn't require a separate executable
- Uses the same privilege separation model as sshd
Use sftp-server when:
# Legacy systems where internal-sftp isn't available
# Environments requiring specific old version behavior
# Custom chroot setups that were configured for sftp-server
Use internal-sftp when:
# Modern OpenSSH installations (version 5.4+)
# Simplified configuration management
# Better integration with sshd's security features
# Resource-constrained environments (reduces process overhead)
Traditional sftp-server setup:
Subsystem sftp /usr/lib/openssh/sftp-server -l INFO
Match group sftponly
ChrootDirectory /home/%u
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
Modern internal-sftp setup:
Subsystem sftp internal-sftp -l VERBOSE
Match group sftponly
ChrootDirectory /var/sftp/%u
ForceCommand internal-sftp
PasswordAuthentication yes
AllowAgentForwarding no
The internal implementation generally offers:
- ~15-20% better performance for file transfers
- Tighter integration with sshd's privilege separation
- More consistent logging format with the rest of sshd
- Better handling of connection drops
For permission issues with chroot:
# Check directory ownership:
chown root:root /chroot/directory
chmod 755 /chroot/directory
# For user subdirectories:
mkdir /chroot/directory/uploads
chown user:user /chroot/directory/uploads
chmod 770 /chroot/directory/uploads
To verify which implementation is running:
ps aux | grep sftp
# sftp-server will show as separate process
# internal-sftp runs within sshd process
OpenSSH provides two distinct methods for implementing SFTP (SSH File Transfer Protocol):
Subsystem sftp /usr/lib/openssh/sftp-server
Subsystem sftp internal-sftp
The traditional method uses a separate binary called sftp-server
. This was the original implementation that:
- Runs as a separate process from the SSH daemon
- Has been part of OpenSSH for many years
- May be found in different locations depending on your OS/distribution
The newer internal-sftp
is:
- Built directly into the OpenSSH server (sshd)
- Runs within the same process space
- Introduced in OpenSSH 4.9p1
Feature | sftp-server | internal-sftp |
---|---|---|
Process isolation | Separate process | Same process |
Performance | Slightly slower | More efficient |
Chroot support | Limited | Better integrated |
Logging | Separate logs | Integrated with sshd |
Use internal-sftp when:
- You need chroot environments (jailed users)
- You want better performance
- You're running modern OpenSSH versions
Use sftp-server when:
- You're on older systems without internal-sftp
- You need specific features only available in sftp-server
- You're debugging and want process isolation
Basic internal-sftp setup with chroot:
Match Group sftponly
ChrootDirectory /home/%u
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
Legacy sftp-server configuration:
Subsystem sftp /usr/libexec/openssh/sftp-server
internal-sftp typically shows:
- 10-15% better transfer speeds
- Lower memory usage
- Fewer context switches
internal-sftp provides:
- Tighter integration with sshd security features
- Better chroot support
- More consistent logging
To switch from sftp-server to internal-sftp:
- Backup your sshd_config
- Replace the Subsystem line
- Test with a non-privileged account first
- Monitor system logs during transition