Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to trace where php5-fpm umask settings are coming from on ubuntu

I'd really appreciate any help in tracking down and diagnosing an umask issue on Ubuntu:

I'm running php5-fpm with Apache via proxy_fcgi. The process is running with a umask of 0022 (confirmed by having PHP send the results of umask() into a file [the result is '18' == 0022]). I'd like to change this to 0002, but can't track down where the umask is coming from.

Apache is set with umask 0002, and as a test, if I disable proxy_fcgi and run my test above, I get a file with u+g having rw access (and the file contents confirm the umask as '2' == 0002).

If I sudo -iu fpmuser and run umask the results are 0002.

System info:

  • PHP: 5.5.3-1ubuntu2.1
  • Apache: 2.4.6
  • Ubuntu: 13.10
  • PHP-PFM is listing using TCP ports (as Unix ports aren't yet working/support)

So far I've tried the following (each followed by a system restart and a retest):

  • adding umask 0002 to the start of /etc/init.d/php5-fpm
  • adding --umask 0002 into the start-stop-daemon calls in /etc/init.d/php5-fpm
  • adding umask 0002 to .profile in the home of the fpm user

Something is clearly adjusting the umask of the php-fpm process - so, how can I begin tracing what is forcing the umask 0022 onto the php-fpm process?

EDIT (1):

  • adjusting the system wide umask via /etc/login.defs (see How to set system wide umask?) affects the umask elsewhere (e.g. comannds via sudo now have a umask of 0002), but still php-fpm creates files with a umask of 0022. Note that I verified that session optional pam_umask.so was also present in /etc/pam.d/common-session-noninteractive and I tested umasks of 002 and 0002.

EDIT (2):

  • I have been able to replicate the issue using nginx and php5-fpm (using unix sockets set to listen mode '0666').
  • I would love to trace where the umask is coming from but I'd settle for some way to force it to what I want.
  • I should add that the first test was done on an Amazon Ubuntu 13.10 image. My tests in 'edit 2' where completed using a copy of the Ubuntu13.10 server ISO setup from scratch in a virtual machine. All installations were completed via apt-get rather than by downloading the source and building.

EDIT (3):

  • I have confirmed I can manipulate the umask manually by either of the following (verified by checking the permissions on the test file created):

    a. In a shell, set a umask then run /usr/sbin/php-fpm from the shell

    b. In a shell, run the following with whatever umask value I like:

     start-stop-daemon --start --quiet --umask 0002 --pidfile /var/run/php5-fpm.pid --exec /usr/sbin/php5-fpm -- --daemonize --fpm-config /etc/php5/fpm/php-fpm.conf
    
  • However this exact same command in the /etc/init.d/php5-fpm file fails to adjust the umask when running sudo service php5-fpm stop; sudo service php5-fpm start or at reboot.

like image 855
danielmerriott Avatar asked Jan 21 '14 04:01

danielmerriott


2 Answers

Not a solution for generically tracing where umask settings are coming from on ubuntu (the only way I've found so far is the good old hard work approach of replicating the issue, attempting to isolate it to a script or a function, then stepping back through each script/function that is called recursively) but a solution to the php5-fpm umask issue. I've found a lot of hits on google, stackoverflow, and elsewhere for the problem, but so far no solution. Hopefully this is useful for people.

Edit /etc/init/php-fpm.conf to include the line umask 0002 (or whatever umask you wish). My version of the file now looks like this:

# php5-fpm - The PHP FastCGI Process Manager

description "The PHP FastCGI Process Manager"
author "Ondřej Surý <[email protected]>"

start on runlevel [2345]
stop on runlevel [016]

### my edit - change umask setting
umask 0002

pre-start exec /usr/lib/php5/php5-fpm-checkconf

respawn
exec /usr/sbin/php5-fpm --nodaemonize --fpm-config /etc/php5/fpm/php-fpm.conf

Explanation

Having traced through the service command which launches php5-fpm at startup, it runs some checks (line 118 on my copy) for /etc/init/${SERVICE}.conf, along with verifying initctl is present and can report it's version. If these tests are passed then upstart is used which in the case of php5-fpm uses the /etc/init/php-fpm.conf file.

The ubuntu upstart site gives pretty clear instructions. In particular you can check out the upstart cookbook for the specifics you need.

As best I can work out that means that therefore the 'service' command was never actually running the start-stop-daemon … commands found in /etc/init.d/php5-fpm which is why my previous edits were having no effect. Instead it passes off to upstart (actually initctl) when you use something like service php5-fpm start, etc.

like image 157
danielmerriott Avatar answered Sep 27 '22 20:09

danielmerriott


If you use systemd, in the /etc/systemd/system directory, create a new directory called php7.2-fpm.service.d. The name of this directory will vary depending on your distro and PHP version. Run systemctl list-units --type=service | grep --ignore-case php to find out what to call it. Inside of this directory, place a file called umask.conf with the contents:

# /etc/systemd/system/php7.2-fpm.service.d/umask.conf
[Service]
UMask=0002

For the changes to take effect, run:

systemctl daemon-reload && systemctl restart php7.2-fpm

The benefit of this solution is that your customizations are not lost when packages get updated.

Explanation of how this works from the systemd manual:

Along with a unit file foo.service, a "drop-in" directory foo.service.d/ may exist. All files with the suffix ".conf" from this directory will be parsed after the file itself is parsed. This is useful to alter or add configuration settings for a unit, without having to modify unit files. Each drop-in file must have appropriate section headers. Note that for instantiated units, this logic will first look for the instance ".d/" subdirectory and read its ".conf" files, followed by the template ".d/" subdirectory and the ".conf" files there.

In addition to /etc/systemd/system, the drop-in ".d" directories for system services can be placed in /usr/lib/systemd/system or /run/systemd/system directories. Drop-in files in /etc take precedence over those in /run which in turn take precedence over those in /usr/lib. Drop-in files under any of these directories take precedence over unit files wherever located. Multiple drop-in files with different names are applied in lexicographic order, regardless of which of the directories they reside in.

like image 30
Алексей Присяжный Avatar answered Sep 27 '22 19:09

Алексей Присяжный