A note on php-fpm Chroot

php-fpm is a fcgi process manager. it supports chroot of worker processes by use of chroot directive for each pool.

in your php-fpm.conf:

; Chroot to this directory at the start. This value must be defined as an
; absolute path. When this value is not set, chroot is not used.
; Note: you can prefix with ‘$prefix’ to chroot to the pool prefix or one
; of its subdirectories. If the pool prefix is not set, the global prefix
; will be used instead.
; Note: chrooting is a great security feature and should be used whenever
;       possible. However, all PHP paths will be relative to the chroot
;       (error_log, sessions.save_path, …).
; Default Value: not set
;chroot =
;chroot = /opt/nginx-1.2.6/html
chroot = $prefix

Note that, we define $prefix as ‘/opt/nginx-1.2.6’ which is our Nginx Chroot env.
(see our other post on Nginx Chroot). and a few notes as below:

1> if we define the pool prefix to /opt/nginx-1.2.6 which is our chroot nginx root
and then define the pool chroot as $prefix, then in the chroot ‘echo file_get_contents(“http://www.google.com”);’ would work. this is because /opt/nginx-1.2.6 is
a chroot with necessary lib for name resove.

2> however if we change the php-fpm pool chroot to /opt/nginx-1.2.6/html the web document root.
now all php scripts get an file not found error.. this is because nginx is passing /opt/nginx-1.2.6/html as part of the script path to the php-fpm worker for processing…/opt/nginx-1.2.6/html is a valid path within chroot (remember our trick to build /opt/nginx-1.2.6/opt/nginx-1.2.6 to be effectively pointing to same place as /opt/nginx-1.2.6) and outside chroot too.

so to fix this, we need to make /opt/nginx-1.2.6/html/opt/nginx-1.2.6/html to effectively pointing to /opt/nginx-1.2.6/html and then php scripts work now. but ‘echo file_get_contents(“http://www.google.com”);’ does not work, as /opt/nginx-1.2.6/html is not well crafted chroot with necessary libs/configure etc. in it.

So our take is just chroot php-fpm worker process to the same chroot as our nginx chroot.

3> also noted a possible bug in php-fpm that, if we define pool chroot as $prefix/html for example, it actually still just chroot to $prefix

4. some dynamic lib are loaded not at start up of php-fpm, but only when a certain php function is invoked, e.g. iconv function, we need to track those cases and copy over needed libs into chroot directory too.

Leave a Reply

Your email address will not be published. Required fields are marked *

18 + 3 =