When working with OpenSSH's SFTP implementation (particularly internal-sftp
), there's significant confusion around how file permissions are handled during uploads. The key question is whether the server applies the configured umask or preserves client-side permissions during put
operations.
Testing with OpenSSH 5.9 on RHEL 6.2 reveals:
# On client
touch MYFILE
mkdir MYDIR
chmod 600 MYFILE
chmod 700 MYDIR
# SFTP operations
sftp> mkdir testdir # 775 (umask 0002 applied)
sftp> put MYFILE # 600 (client permissions preserved)
sftp> put -r MYDIR # 700 (client permissions preserved)
The OpenSSH SFTP protocol implements the SSH File Transfer Protocol which includes extensions for permission preservation. The behavior differs between:
- New directory creation: Follows server umask
- File upload (
put
): Preserves client permissions - Recursive upload (
put -r
): Preserves directory permissions
Several approaches were tested without success:
# Option 1: internal-sftp umask flag
Subsystem sftp internal-sftp -u 0002
# Option 2: PAM configuration (in /etc/pam.d/sshd)
session optional pam_umask.so umask=0002
For enforcing server-side permissions:
# Post-upload permission reset script
#!/bin/bash
inotifywait -m -e close_write --format %f /chroot/upload/ | while read FILE
do
chmod 640 "/chroot/upload/$FILE"
done
Or using ForceCommand
with a wrapper:
# In sshd_config
ForceCommand /usr/local/bin/sftp-wrapper
# sftp-wrapper content
#!/bin/sh
umask 0027
exec /usr/lib/openssh/sftp-server "$@"
Documented changes in OpenSSH behavior:
Version | Behavior |
---|---|
OpenSSH 5.4+ | Added -u umask flag |
OpenSSH 6.0+ | More consistent permission handling |
OpenSSH 7.4+ | Added PermitUserEnvironment options |
For production systems requiring strict permission control:
- Upgrade to OpenSSH 7.4+ for better permission management
- Combine
internal-sftp
with filesystem ACLs - Implement post-upload hooks for permission normalization
When working with OpenSSH's SFTP implementation (particularly version 5.9 on RHEL 6.2), there's significant confusion around how file permissions are handled during transfers. The key question revolves around whether the server applies the configured umask or preserves client-side permissions when files are uploaded.
From practical testing with a chrooted environment using internal-sftp
subsystem:
# Sample test observations
1. mkdir → New directory respects umask (002)
2. put MYFILE → Preserves client permissions (600)
3. put -r MYDIR → Preserves directory permissions (700)
Several approaches exist for permission control:
internal-sftp -u 0002
(umask specification)- PAM configuration in
/etc/pam.d/sshd
- Wrapper scripts for
sftp-server
OpenSSH implements SFTP protocol extensions that transfer file metadata including permissions. This behavior appears hardcoded in the OpenSSH implementation:
// Simplified representation of OpenSSH's SFTP server logic
if (client_sends_permissions) {
apply_client_permissions();
} else {
apply_umask();
}
For those needing umask enforcement:
- Post-upload permission reset:
# Example inotifywait solution inotifywait -m -e close_write /chroot/path | while read path action file do chmod 640 "$path$file" done
- Forced umask via PAM:
# /etc/pam.d/sshd addition session optional pam_umask.so umask=0022
Behavior differs across OpenSSH versions:
Version | Behavior |
---|---|
<5.4 | No umask support |
5.4-7.4 | Umask applies to new files only |
7.5+ | More consistent umask application |
For RHEL 6.2 environments:
- Combine PAM umask with post-upload scripts
- Consider upgrading to newer OpenSSH versions if possible
- Document the behavior clearly for users