SFTP Transactions – Proper Way to Set the Umask

permissionssshfs

My goal is to allow all users who are members of the "team" group to edit (r/w) the same set of remote files — normal work collaboration — using a local mount point. I have tried NFS and SSHFS using ACLs without success yet. Here I am trying to get SSHFS working by making the umask correct (which, in theory, should solve the problems I'm experiencing).

Updated description of problem:

user1, user2, and user3 all log into the same client computer. All are members of group "team". The client computer mounts a share via SSHFS. Client and server run Arch Linux (updated a couple days ago). The Client runs KDE desktop. The SSHFS mount is done via user3@sshfsrv with option allow_other.

On the server, the shared directory has permissions user3 (owner) rwx and group (team) rwx, while other have r-x permissions. The gid sticky bit is set with chmod g+s. We removed all ACLs for the umask-focused configuration.

First problem:

user2 scans a document with XSane (a Gnome app) and attempts to save it in Shared1 directory, which is part of the SSHFS mount point. The save operation fails due to permissions. A 0 byte file is written. The permissions on that file are owner (user3) rw and group (team) read only (and other none). user2 can save the scanned document to their home directory.

The terminal works as expected:

In a terminal, user2 can touch a document in the Shared1 directory and the permissions are:

-rw-rw---- 1 user3 team 6 Sep 23 19:41 deleteme6.txt

We get the correct g+rw permissions. Note that ownership is user3 while this is user2 creating the file. In /etc/fstab, the mount is specified as:

user3@sshfsrv:/home/common /home/common fuse.sshfs x-systemd.automount,_netdev,user,follow_symlinks,identityfile=/home/user3/.ssh/id_rsa,allow_other,default_permissions               0 0

In the terminal, and with a text editor (Kate in KDE), the users can collaborate on files that were created in Shared1 as expected. Any user in group "team" can create and save a file in Shared1 via nano text editor, and any other user in the group can edit / update it.

Second problem:

As a temporary workaround I tested saving the scanned images to user2's home directory, then moving them to the Shared1 directory using Dolphin File manager. Permissions errors prevent this, and sometimes it crashes Dolphin.

I can show the same result by moving text files in the terminal:

[user2@client2 Shared1]$ echo user2 > /home/user2/MoveMe/deleteme7.txt
[user2@client2 Shared1]$ mv /home/user2/MoveMe/deleteme7.txt .
mv: preserving times for './deleteme7.txt': Operation not permitted
mv: preserving permissions for ‘./deleteme7.txt’: Operation not permitted

The two errors above appear to be key to understanding the problem. If I change the mount specification to use user2@sshfsrv those errors go away for user2 but then user1 and user3 experience them. The only user that doesn't have the problem is the one used in the mount specification. (I had expected the allow_other mount option would prevent this, but it doesn't. Also using root in the mount specification doesn't seem to help.)

Removing the mount option default_permissions eliminates these errors, but it also eliminates all permissions checking. Any user in any group can read and write files in Shared1, which does not meet our requirements.

sftp-server umask setting:

As sebasth says below, when sftp-server is used, the umask in /etc/profile or ~/.bashrc isn't used. I found that the following specification in /etc/ssh/sshd_config is a good solution for setting the umask:

Subsystem sftp internal-sftp -u 0006

I do not want to use the umask mount option for sshfs (in /etc/fstab) as that does not give the desired behavior.

Unfortunately, the above "-u" flag, while required, doesn't (yet) fully resolve my problem as described above.

New Update:

I have enabled pam_umask, but that alone doesn't resolve the issue. The above "-u" option is still required and I do not see that pam_umask adds anything additional that helps resolve this issue. Here are the configs currently used:

/etc/pam.d/system-login
session    optional   pam_umask.so

/etc/login.defs
UMASK           006

The Shared1 directory has these permissions, as shown from the server side. The gid sticky bit is set with chmod g+s. We removed all ACLs. All files within this directory have g+rw permissions.

drwxrwsr-x  1 user3   team          7996 Sep 23 18:54 .

# cat /etc/group
team:x:50:user1,user2,user3

Both client and server are running OpenSSH_7.5p1, OpenSSL 1.1.0f dated 25 May 2017. This looks like the latest version.

On the server, systemctl status sshd shows Main PID: 4853 (sshd). The main proc status shows a umask of 022. However, I will provide the process info for the sftp subsystem further below, which shows the correct umask of 006.

# cat /proc/4853/status
Name:   sshd
Umask:  0022
State:  S (sleeping)
Tgid:   4853
Ngid:   0
Pid:    4853
PPid:   1
TracerPid:      0
Uid:    0       0       0       0
Gid:    0       0       0       0
FDSize: 64
Groups:  
NStgid: 4853
NSpid:  4853
NSpgid: 4853
NSsid:  4853
VmPeak:    47028 kB
VmSize:    47028 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:      5644 kB
VmRSS:      5644 kB
RssAnon:             692 kB
RssFile:            4952 kB
RssShmem:              0 kB
VmData:      752 kB
VmStk:       132 kB
VmExe:       744 kB
VmLib:      6260 kB
VmPTE:       120 kB
VmPMD:        16 kB
VmSwap:        0 kB
HugetlbPages:          0 kB
Threads:        1
SigQ:   0/62965
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000001000
SigCgt: 0000000180014005
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
Seccomp:        0
Cpus_allowed:   3f
Cpus_allowed_list:      0-5
Mems_allowed:   00000000,00000001
Mems_allowed_list:      0
voluntary_ctxt_switches:        25
nonvoluntary_ctxt_switches:     2

We need to look at the sftp-server process for this client. It shows the expected umask of 006. I'm not sure if the GID is correct. 1002 is the GID for the user3 group. The directory specifies team group (GID 50) rwx.

# ps ax | grep sftp*
5112 ?        Ss     0:00 sshd: user3@internal-sftp


# cat /proc/5112/status
Name:   sshd
Umask:  0006
State:  S (sleeping)
Tgid:   5112
Ngid:   0
Pid:    5112
PPid:   5111
TracerPid:      0
Uid:    1002    1002    1002    1002
Gid:    1002    1002    1002    1002
FDSize: 64
Groups: 47 48 49 50 51 52 1002 
NStgid: 5112
NSpid:  5112
NSpgid: 5112
NSsid:  5112
VmPeak:    85280 kB
VmSize:    85276 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:      3640 kB
VmRSS:      3640 kB
RssAnon:             980 kB
RssFile:            2660 kB
RssShmem:              0 kB
VmData:     1008 kB
VmStk:       132 kB
VmExe:       744 kB
VmLib:      7352 kB
VmPTE:       184 kB
VmPMD:        12 kB
VmSwap:        0 kB
HugetlbPages:          0 kB
Threads:        1
SigQ:   0/62965
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000180010000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
Seccomp:        0
Cpus_allowed:   3f
Cpus_allowed_list:      0-5
Mems_allowed:   00000000,00000001
Mems_allowed_list:      0
voluntary_ctxt_switches:        8
nonvoluntary_ctxt_switches:     0

Original Question – can probably skip this after the above updates

I am sharing the Shared1 directory from the SSHFS file server to various client machines. All machines use Arch Linux and BTRFS. pwck and grpck report no errors on both client and server.

My goal is to allow all users in the team group to have rw permissions in the Shared1 directory. For unknown reasons, I am not able to achieve this goal. Some group members are experiencing permission denied errors (on write), as I will show below.

What am I overlooking? (I have checked all the related questions on unix.stackexchange.com and I still did not resolve this issue.)

Server:

[user2@sshfsrv Shared1]$ cat /etc/profile
umask 006

[user2@sshfsrv Syncd]$ whoami
user2

[user2@sshfsrv Syncd]$ groups
team user2

[user2@sshfsrv Syncd]$ cat /etc/fuse.conf 
user_allow_other

[root2@sshfsrv Syncd]# cat /proc/18940/status
Name:   sshd
Umask:  0022

Note below that the setgid bit (chmod g+s) is initially set:

[user1@sshfsrv Syncd]$ ls -la
total 0
drwxrws--x 1 user1 limited     170 Aug 29 09:47 .
drwxrwxr-x 1 user1 limited      10 Jul  9 14:10 ..
drwxrwsr-x 1 user2 team       7892 Sep 22 17:21 Shared1

[root@sshfsrv Syncd]# getfacl Shared1/
# file: Shared1/
# owner: user2
# group: team
# flags: -s-
user::rwx
group::rwx
other::r-x

[user2@sshfsrv Shared1]$ umask -S
u=rwx,g=rx,o=x

[user2@sshfsrv Shared1]$ sudo chmod g+w .

[user2@sshfsrv Shared1]$ umask -S
u=rwx,g=rx,o=x

NOTE: Even after the above step, there are still no group write permissions.

[user2@sshfsrv Shared1]$ touch deleteme2.txt
[user2@sshfsrv Shared1]$ echo deleteme > deleteme2.txt 
[user2@sshfsrv Shared1]$ cat deleteme2.txt 
deleteme
[user2@sshfsrv Shared1]$ ls -la deleteme2.txt 
-rw-r----- 1 user2 team 9 Sep 22 17:55 deleteme2.txt

[user2@sshfsrv Shared1]$ getfacl .
# file: .
# owner: user2
# group: team
# flags: -s-
user::rwx
group::rwx
other::r-x

[root@sshfsrv Syncd]# chmod g-s Shared1/
[root@sshfsrv Syncd]# ls -la
drwxrwxr-x 1 user2      team         7944 Sep 22 17:54 Shared1

Client

[user2@client2 Shared1]$ cat /etc/fstab
user3@sshfsrv:/home/common /home/common fuse.sshfs x-systemd.automount,_netdev,user,follow_symlinks,identityfile=/home/user3/.ssh/id_rsa,allow_other,default_permissions               0 0

[user2@client2 Shared1]$ cat /etc/profile
umask 006

[user2@client2 Shared1]$ cat /etc/fuse.conf 
user_allow_other

[user2@client2 Shared1]$ groups
team user2

[user2@client2 Shared1]$ echo deleteme > deleteme2.txt
bash: deleteme2.txt: Permission denied

[user2@client2 Shared1]$ touch deleteme3.txt
touch: setting times of 'deleteme3.txt': Permission denied

[user2@client2 Shared1]$ ls -la
total 19520
drwxrwsr-x 1 user2 team       7918 Sep 22 17:51 .
drwxrws--x 1 user1 limited     170 Aug 29 09:47 ..
-rw-r----- 1 user3 team          0 Sep 22 17:51 deleteme3.txt

Best Answer

The general solution is to add the following line to /etc/ssh/sshd_config on Arch Linux:

Subsystem sftp internal-sftp -u 0002

However, the gotcha for me was that users of group "team" had a ForceCommand defined in that same config file. For these users, the ForceCommand was overriding the specification listed above.

The solution was to add the same "-u" flag on the ForceCommand

Match Group team
   ForceCommand internal-sftp -u 0002 

Then run:

systemctl restart sshd.service

It is important to note that using the sshfs mount option umask is not recommended. It did not produce the desired behavior for me.

References:

The umask option for sshfs goes down to the underlying fuse layer where it's handled wrongly. afaict the advice is to avoid it. – Ralph Rönnquist Jun 17 '16 at 7:56 Understanding sshfs and umask

EDIT:

while this solution works on the command line and with some desktop apps (e.g., KDE's Kate text editor), it does not work correctly with many desktop applications (including KDE's Dolphin file manager, XSane, etc.). So this turned out not to be a good overall solution.

Related Question