Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I've been searching for a way to setup OpenSSH's umask to 0027 in a consistent way across all connection types.

By connection types I'm referring to:

  1. sftp
  2. scp
  3. ssh hostname
  4. ssh hostname program

The difference between 3. and 4. is that the former starts a shell which usually reads the /etc/profile information while the latter doesn't.

In addition by reading this post I've became aware of the -u option that is present in newer versions of OpenSSH. However this doesn't work.

I must also add that /etc/profile now includes umask 0027.

Going point by point:

  • sftp - Setting -u 0027 in sshd_config as mentioned here, is not enough.

If I don't set this parameter, sftp uses by default umask 0022. This means that if I have the two files:

-rwxrwxrwx 1 user user 0 2011-01-29 02:04 execute
-rw-rw-rw- 1 user user 0 2011-01-29 02:04 read-write

When I use sftp to put them in the destination machine I actually get:

-rwxr-xr-x 1 user user 0 2011-01-29 02:04 execute
-rw-r--r-- 1 user user 0 2011-01-29 02:04 read-write

However when I set -u 0027 on sshd_config of the destination machine I actually get:

-rwxr--r-- 1 user user 0 2011-01-29 02:04 execute
-rw-r--r-- 1 user user 0 2011-01-29 02:04 read-write

which is not expected, since it should actually be:

-rwxr-x--- 1 user user 0 2011-01-29 02:04 execute
-rw-r----- 1 user user 0 2011-01-29 02:04 read-write

Anyone understands why this happens?

  • scp - Independently of what is setup for sftp, permissions are always umask 0022. I currently have no idea how to alter this.

  • ssh hostname - no problem here since the shell reads /etc/profile by default which means umask 0027 in the current setup.

  • ssh hostname program - same situation as scp.


In sum, setting umask on sftp alters the result but not as it should, ssh hostname works as expected reading /etc/profile and both scp and ssh hostname program seem to have umask 0022 hardcoded somewhere.

Any insight on any of the above points is welcome.

EDIT: I would like to avoid patches that require manually compiling openssh. The system is running Ubuntu Server 10.04.01 (lucid) LTS with openssh packages from maverick.

Answer: As indicated by poige, using pam_umask did the trick.

The exact changes were:

Lines added to /etc/pam.d/sshd:

# Setting UMASK for all ssh based connections (ssh, sftp, scp)
session    optional     pam_umask.so umask=0027

Also, in order to affect all login shells regardless of if they source /etc/profile or not, the same lines were also added to /etc/pam.d/login.

EDIT: After some of the comments I retested this issue.

At least in Ubuntu (where I tested) it seems that if the user has a different umask set in their shell's init files (.bashrc, .zshrc,...), the PAM umask is ignored and the user defined umask used instead. Changes in /etc/profile did't affect the outcome unless the user explicitly sources those changes in the init files.

It is unclear at this point if this behavior happens in all distros.

share|improve this question
    
Unode: "I would like to avoid patches that require manually compiling openssh." Why? –  desasteralex Jan 29 '11 at 8:13
4  
@desasteralex - Because (if possible) I would like to avoid having the additional maintenance/administration task that comes with having source based packages and because I find it hard to believe that there is no other way to change umask other than patching openssh. Specially considering this is a rather basic security aspect on any system. –  Unode Jan 31 '11 at 14:35
1  
After altering /etc/pam.d/sshd (and login), and restarting ssh, I see no behavioral change. Are there other needed changes implied but not mentioned here? –  Steve Clay Jul 30 '11 at 23:27
    
@mrclay - Do you have UsePAM yes in your sshd_config ? –  Unode Jul 31 '11 at 15:24
1  
To solve the user's .bashrc problem, try aliasing away the umask command in your /etc/profile. Something like alias umask=/bin/true –  Tobia Mar 18 '13 at 10:22

7 Answers 7

up vote 15 down vote accepted
+50

I can suggest trying 2 things:

  1. pam_umask
  2. LD_PRELOAD wrapper (self-written?)
share|improve this answer
    
+1, pam_umask seems to be by far the simplest solution –  Flexo Feb 2 '11 at 11:49
    
pam_umask does the trick. Edited question to reflect and elaborate the answer –  Unode Feb 2 '11 at 17:25
    
Just use stackoverflow.com/q/10220531/220060. However be careful, if you mistype something, you lock yourself out of the server. Always check if you can login again before closing your current session. –  nalply Aug 28 at 9:05

Here is a solution that will let you do what you want on a per-user basis. It uses only native sshd features and does not require mucking about with locally maintained patches. This solution takes advantage of the ForceCommand behavior of sshd to insert an environment-setup script into every ssh connection, and then run the original command.

First, create a script somewhere on your system with the following contents:

#!/bin/sh

umask 0027
exec /bin/sh -c "${SSH_ORIGINAL_COMMAND:-$SHELL}"

For the purposes of this example I'll assume you've called this /usr/bin/umask-wrapper.

Now, you have a few options in setting this up. If you want this to be a mandatory configuration for all users (which seems a little unlikely), you can modify your sshd configuration to include the following:

ForceCommand /usr/bin/umask-wrapper

If you only want this to apply to some users, you can use a Match block (this goes at the end of your sshd_config):

Match User user1,user2
ForceCommand /usr/bin/umask-wrapper

If you want this to be user-controllable behavior, then you can use the command= option in an authorized_key file to select this behavior for specific keys. For example, while testing this out I added an entry to my authorized_keys file that looks something like this:

command="/home/lars/bin/umask-wrapper" ssh-rsa AAAAB3NzaC1 ... umask-test

And here are some results of my test:

Using ssh with no command:

localhost$ ssh remotehost
remotehost$ touch umask-test/file1
remotehost$ ls -l umask-test/file1
-rw-r-----. 1 lars lars 0 Feb  2 06:02 file1

Using ssh with a command:

localhost$ ssh remotehost touch umask-test/file2
localhost$ ssh remotehost ls -l umask-test/file2
-rw-r-----. 1 lars lars 0 Feb  2 06:03 file2

Using scp:

localhost$ touch file3
localhost$ ls -l file3
-rw-r--r--  1 lars  staff  0 Feb  2 06:03 file3
localhost$ scp file3 remotehost:umask-test/file3
localhost$ ssh remotehost ls -l umask-test/file3
-rw-r-----. 1 lars lars 0 Feb  2 06:03 file3

Using sftp:

localhost$ sftp remotehost
sftp> put file3 umask-test/file4
sftp> ls -l umask-test/file4
-rw-r-----    0 500      500             0 Feb  2 06:05 umask-test/file4

And there you have it. I believe this is the behavior you were looking for. If you have any questions about this solution I would be happy to provide additional details.

share|improve this answer
    
Although this method seems to work, it looks a bit of a maintenance nightmare. Still, +1 for cases where pam cannot be used. –  Unode Feb 2 '11 at 17:24
3  
I don't know that it's all that difficult to maintain. The primary advantage over a PAM-based solution is that it doesn't require any special privileges -- you can set this up for your own account without administrator intervention. –  larsks Feb 2 '11 at 17:56
    
I was thinking in terms of keeping a selected list of users, but indeed I didn't notice the aspect of this working on plain user setup. When I first read it I thought ForceCommand was "required" and not "one way of setting it up". command= is indeed a neat feature of ssh. –  Unode Feb 2 '11 at 19:00

I took a slightly different approach to centralize the setting.

This was added to /etc/pam.d/common-session:

session    optional     pam_umask.so

This was modified in /etc/login.defs:

UMASK           0027
share|improve this answer

I've gotten pam_umask to work with ssh, but not with scp or sftp.

The wrapper method also does nothing for sftp or scp. I'm not sure 027 is a good example since most distros have umask set to that already. Try with 002 and see if that works.

share|improve this answer

Programs that don't set their own umask inherit the umask of the application that started it. Stop sshd completely, set your umask to 0027, then start it again. (You can add the umask command in the init script for future reboots.)

Tested to work with scp.

share|improve this answer
    
Sorry DerfK but this was one of the first things I've tried without success. All login shells have umask 0027 (if they read /etc/profile) but restarting ssh doesn't affect scp nor ssh. –  Unode Jan 29 '11 at 3:20

If pam_umask doesn't seem to affect your SFTP sessions, then check if UsePam is set to Yes in the /etc/ssh/sshd_config file.

If you have disabled password authentication and UsePam was set or defaulted to No. You may want to set ChallengeResponseAuthentication No in the sshd_config file because otherwise you may inadvertently enable a password authentication through that system.

share|improve this answer

I have just tested a possible improvement to larsks sshd_config options on solaris 11

Setup a group with the users to be managed and move the script into the config file itself, in my case I wanted to set the umask to 0002.

the resulting configuration becomes....

Match Group managedgroup
ForceCommand /bin/sh -c 'umask 0002; ${SSH_ORIGINAL_COMMAND:-$SHELL}'
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.