Configuring Custom Umask for SFTP Connections in OpenSSH Server


1 views

When working with SFTP servers using OpenSSH's sftp-server, many administrators encounter persistent umask issues. Unlike regular SSH sessions where umask settings from .profile or PAM configurations apply properly, SFTP connections often default to 022 regardless of system-wide settings.

The standard approaches - PAM configuration (/etc/pam.d/common-session) and shell profiles - don't work because:

  1. SFTP sessions are non-interactive and don't source user profiles
  2. sftp-server runs as a subsystem without full shell initialization
  3. PAM sessions might not be processed the same way for SFTP connections

Method 1: Subsystem Wrapper Script

Create a wrapper script that sets umask before executing sftp-server:

#!/bin/sh
umask 0002
exec /usr/lib/openssh/sftp-server "$@"

Then modify sshd_config:

Subsystem sftp /path/to/your/sftp-wrapper.sh

Method 2: ForceCommand in sshd_config

For specific users or groups, add to sshd_config:

Match Group sftponly
    ForceCommand umask 0002 && /usr/lib/openssh/sftp-server

Method 3: Using internal-sftp

Modern OpenSSH versions support internal SFTP implementation:

Subsystem sftp internal-sftp -u 0002
  • Verify permissions on wrapper scripts (must be executable)
  • Check SELinux/AppArmor contexts if security modules are enabled
  • Test with sftp -v user@host for debug output
  • Confirm the actual umask during SFTP sessions with !umask in sftp client

For a development team needing shared write access to uploaded files:

# /etc/ssh/sshd_config
Subsystem sftp /usr/local/bin/sftp-umask-wrapper

# /usr/local/bin/sftp-umask-wrapper
#!/bin/bash
umask 0002
/usr/lib/openssh/sftp-server

Remember to restart sshd after changes:

systemctl restart sshd



When working with OpenSSH's SFTP subsystem, many administrators encounter a frustrating behavior: the default umask (022) remains stubbornly persistent, ignoring system-wide PAM configurations or user shell profiles. This occurs because SFTP sessions don't initiate a full login shell environment.

The sftp-server process operates differently than standard SSH logins. Here's the critical sequence:

1. Client establishes SSH connection
2. SSH daemon executes sftp-server directly (not through user shell)
3. Session runs with default umask (022)
4. Traditional profile/PAM settings are bypassed

Method 1: ForceCommand Wrapper Script

Create a wrapper script that sets the umask before invoking sftp-server:

#!/bin/sh
umask 002
exec /usr/lib/openssh/sftp-server

Then modify sshd_config:

Subsystem sftp /usr/local/bin/sftp-wrapper

Method 2: AuthorizedKeysCommand Hook

For per-user control, leverage the authorized_keys command option:

command="umask 002 && /usr/lib/openssh/sftp-server" ssh-rsa AAAAB3Nza...

Method 3: Systemd Service Override (For System-Wide Changes)

Create an override for sshd.service:

[Service]
UMask=0002
Environment="UMASK=0002"

Then reload systemd:

systemctl daemon-reload
systemctl restart ssh

After implementation, verify with:

sftp user@host
> echo "test" > testfile
> ls -l testfile
-rw-rw-r-- 1 user user 5 May 1 10:00 testfile
  • Ensure wrapper scripts have execute permissions (chmod +x)
  • Check SELinux/AppArmor contexts if permissions fail
  • Restart SSH service after configuration changes
  • Test with different clients (OpenSSH sftp, FileZilla, etc.)

The wrapper method adds minimal overhead (one additional process fork). For high-volume SFTP servers, the systemd override provides the cleanest solution without process spawning overhead.