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:
- sftp
- scp
- ssh hostname
- 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
insshd_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 meansumask 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.
I can suggest trying 2 things:
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 theForceCommand
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:
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:
If you only want this to apply to some users, you can use a
Match
block (this goes at the end of yoursshd_config
):If you want this to be user-controllable behavior, then you can use the
command=
option in anauthorized_key
file to select this behavior for specific keys. For example, while testing this out I added an entry to myauthorized_keys
file that looks something like this:And here are some results of my test:
Using
ssh
with no command:Using
ssh
with a command:Using
scp
:Using
sftp
: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.
I took a slightly different approach to centralize the setting.
This was added to
/etc/pam.d/common-session
:This was modified in
/etc/login.defs
: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.
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.
If
pam_umask
doesn't seem to affect your SFTP sessions, then check ifUsePam
is set toYes
in the/etc/ssh/sshd_config
file.If you have disabled password authentication and
UsePam
was set or defaulted toNo
. You may want to setChallengeResponseAuthentication No
in thesshd_config
file because otherwise you may inadvertently enable a password authentication through that system.An added note to user188737's answer above:
This may go without saying, but if you are not using the openssh-server package, and have manually compiled OpenSSH, make sure you "Enable PAM support" by passing the
--with-pam
configuration flag.Otherwise,
UsePAM=yes
in sshd_config, plus any changes to/etc/pam.d/*
will effectively be ignored bysshd
.It finally dawned on me why none of the recommended PAM solutions were having any affect testing via non-interactive SFTP connections...
Since umask is inherited from the parent process, on a Slackware system that uses
/etc/rc.d/rc.sshd
to start/stop/restart sshd, you could simply placeumask 0027
on a line by itself directly above "sshd_start" or "sshd_restart", or alternatively, at any point before the main execution section begins, in/etc/rc.d/rc.sshd
:Or, alternatively, at the top of the file:
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....
I have been struggling with this issue, specifically with file permissions after copying a file using scp, and it finally occurred to me to simply use ssh to change the permissions after the copy.
Here is the solution:
localhost$ scp filename remotehost:umask-test/filename
localhost$ ssh remotehost "chmod go+r umask-test/filename"
Best of all, no root access is necessary to effect this solution.