Table of Contents
In this tutorial I will share the steps to set umask for SFTP connections. I will not go into the details on what is umask and how to set umask in Linux. You can follow the respective articles added in the hyper links.
Why do we need to set different umask for SFTP?
By default umask is applied to entire system. But additionally we can control custom umask per user by specifying the value inside
.bashrc file of respective user's home folder.
But when we are doing SFTP and especially chroot based SFTP then we don't have access to user's home folder so the custom umask is not applied.
Now consider a scenario where system wide the umask is set to 077 but for a certain user we want to set umask as 022 so this can not be done by modifying user's
How to set SFTP umask per user and group?
As per the help page of SFTP we can use
-u flag to provide a custom umask.
-u umask Sets an explicit umask(2) to be applied to newly-created files and directories, instead of the user's default mask.
1. My Lab Environment
I have a SSHD service running on Port 22 on a Linux server with default umask as
077. So any file which is created on this server will have
600 permission i.e. no read, write and execute permission for others.
[root@sftp-server ~]# umask 0077 [root@sftp-server ~]# touch /tmp/index.html [root@sftp-server ~]# ls -l /tmp/index.html -rw-------. 1 root root 0 Jan 21 12:55 /tmp/index.html
Now we have a requirement to give read permission to any file which is copied via SFTP. To achieve this I will modify the umask for incoming connections via SFTP for this directory.
2. Verify the umask before applying the changes
We will use
amit user for our SFTP testing who is part of
Let's verify the permission of files getting created currently with default umask of 077 via SFTP. I will trigger a PUT operation for /tmp/index.html inside /opt/storage:
~]# sftp email@example.com:storage/ <<< $'put /tmp/index.html' firstname.lastname@example.org's password: Connected to 220.127.116.11. Changing to: /storage/ sftp> put /tmp/index.html Uploading /tmp/index.html to /storage/index.html /tmp/index.html
Verify the permission of
index.html inside the sftp share:
[root@sftp-server ~]# ls -l /opt/storage/ total 529 -rw-------. 1 amit sftpusers 541497 Jan 21 12:58 index.html
As expected the file got created with
600 because of default umask
077 of the system.
3: Apply custom umask to SFTP
To apply custom umask for all incoming SFTP connections you can modify Subsystem as shown below in
Subsystem sftp internal-sftp -u 027
Or to modify umask per user or group you can use
ForceCommand in the following :
AllowGroups sftpusers ForceCommand internal-sftp -u 0027 AllowUsers deepak ForceCommand internal-sftp -u 0022
Here we are applying umask of
027 for all connections from
pgwsftpusers group and
022 to user
Next restart the sshd service to activate the changes:
[root@sftp-server ~]# systemctl restart sshd
4: Verify the changes
I will delete the previously created file on the sftp server so that we can verify the permission properly:
[root@sftp-server ~]# rm -f index.html
Next let's re-attempt to copy our file using SFTP:
[root@sftp-client ~]# sftp email@example.com:storage/ <<< $'put /tmp/index.html' firstname.lastname@example.org's password: Connected to 18.104.22.168. Changing to: /storage/ sftp> put /tmp/index.html Uploading /tmp/index.html to /storage/index.html /tmp/index.html 100% 529KB 96.2MB/s 00:00
Verify the permission
[root@sftp-server ~]# ls -l /opt/storage/ -rw-------. 1 amit sftpusers 541497 Jan 21 13:01 index.html
The permission still shows 600, so our changes are not working?
There is one more thing which we must know here:
If the system's default umask is higher compared to what is provided for SFTP then we have to make sure that the file we are planning to copy has higher permission.
This is because setting a custom umask can strip down permissions of a file based on it's value but it will not add additional permission to the file. So in this case, our source file
/tmp/index.html has below permission:
[root@sftp-client ~]# ls -l /tmp/index.html -rw-------. 1 root root 541497 Dec 21 10:29 /tmp/index.html
Hence after copying the file, the same permission is retained as umask
027 can strip down the permission of a file to
640 but it will NOT add read permission to the file which has
Let me show you how this would work.
[root@sftp-client ~]# chmod 644 /tmp/index.html [root@sftp-client ~]# ls -l /tmp/index.html -rw-r--r--. 1 root root 541497 Dec 21 10:29 /tmp/index.html
As you can see I have given read permission to group and others on my client. I have deleted this file from the sftp-server. Now let's retry the SFTP:
[root@sftp-client ~]# sftp email@example.com:storage/ <<< $'put /tmp/index.html' firstname.lastname@example.org's password: Connected to 22.214.171.124. Changing to: /opt/storage/ sftp> put /tmp/index.html Uploading /tmp/index.html to /opt/storage/index.html /tmp/index.html 100% 0 0.0KB/s 00:00
Verify the permission on the SFTP folder:
[root@sftp-server /]# ls -l /opt/storage/ total 151 -rw-r-----. 1 amit sftpusers 0 Jan 21 13:18 index.html
Now we have proper permission as per our custom SFTP we had set for
What is NEXT
- Linux sftp restrict user to specific directory | setup sftp chroot jail
- 10 single line SFTP commands to transfer files in Unix/Linux
- Automate SFTP using shell script with password in Linux/Unix
We explained that the umask value of the operating system and the umask value of sftp may be different. This is important for security. At the end of this article, you have provided file/directory creation with limited privileges of the user that comes with SFTP.
For more information on SFTP, you can get help from the man page:
foc@fedora:~$ man sftp-server sftp-server — OpenSSH SFTP server subsystem SYNOPSIS sftp-server [-ehR] [-d start_directory] [-f log_facility] [-l log_level] [-P denied_requests] [-p allowed_requests] [-u umask] [-m force_file_perms] sftp-server -Q protocol_feature ...
Or type a question mark(?) in the console with connected via SFTP:
sftp> ? Available commands: bye Quit sftp cd path Change remote directory to 'path' chgrp [-h] grp path Change group of file 'path' to 'grp' chmod [-h] mode path Change permissions of file 'path' to 'mode' chown [-h] own path Change owner of file 'path' to 'own' df [-hi] [path] Display statistics for current directory or ... rmdir path Remove remote directory symlink oldpath newpath Symlink remote file version Show SFTP version !command Execute 'command' in local shell ! Escape to local shell ? Synonym for help