rafamiga
unread,Jan 18, 2012, 8:02:58 AM1/18/12Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Sign in to report message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to highload-php-en
I'm having a very strange problem with php-fpm 5.3.8 in Apache2.2.
This is my Apache config:
DocumentRoot /home/app/php/php
FastCgiExternalServer /home/httpd/html/php/php-handler -idle-timeout
300 -socket /var/run/php-fpm-php.sock
AddHandler php5-fcgi .php
Action php5-fcgi /php-handler
Alias /php-handler /home/httpd/html/php/php-handler
/home/app/php/php is a document root for the PHP application I'm
trying to run. Actually it's a link to a directory buried down there
in chroot, /home/httpd/html/php/home/httpd/html/php to be precise.
Don't ask why I use this strange, long path, but it works, and the
path might be /chroot/php as well, it doesn't matter as long chroot
(directory exists/filesystem is mounted) at /home/httpd/html/php,
doesn't it?
Anyway, I've set FastCgiExternalServer to some path other than docroot
because if I use identical paths Apache will feed every file through
the socket, even CSS and GIFs, which, basically, is not what I hope to
achieve. 8^)
This simple test works great:
$ /bin/echo -ne "GET /test0.php HTTP/1.1\r\nHost: xxxxxxxxxxxxxxxx\r\n
\r\n" | nc localhost 8080|head -15
HTTP/1.1 200 OK
Date: Wed, 18 Jan 2012 12:32:57 GMT
Server: Apache/2
Cache-Control: max-age=18000
Expires: Wed, 18 Jan 2012 17:32:57 GMT
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
2000
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/
xhtml1-transitional.dtd">
<html><head>
<style type="text/css">
body {background-color: #ffffff; color: #000000;}
body, td, th, h1, h2 {font-family: sans-serif;}
Basically, phpinfo shows up beautifuly. But when I try to run a PHP
script from a drectory under chroot I get:
$ /bin/echo -ne "GET /test2/test2.php HTTP/1.1\r\nHost:
xxxxxxxxxxxxxxxx\r\n\r\n" | nc localhost 8080
HTTP/1.1 404 Not Found
Date: Wed, 18 Jan 2012 12:34:21 GMT
Server: Apache/2
Cache-Control: max-age=18000
Expires: Wed, 18 Jan 2012 17:34:21 GMT
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
0
I've traced the FPM worker process and I see this:
a "good" call:
read(3, "\r\21DOCUMENT_ROOT/home/app/php/php", 32) = 32
read(3, "\1\4\0\1\0\"\0\0", 8) = 8
read(3, "\17\36SCRIPT_FILENAME/home/httpd/html/php/test0.php", 47) =
47
read(3, "\1\4\0\1\0\22\0\0", 8) = 8
read(3, "\v\5REMOTE_PORT41822", 18) = 18
read(3, "\1\4\0\1\0\30\0\0", 8) = 8
read(3, "\f\nREDIRECT_URL/test0.php", 24) = 24
read(3, "\1\4\0\1\0\25\0\0", 8) = 8
read(3, "\n\nSCRIPT_URL/test0.php", 22) = 22
read(3, "\1\4\0\1\0001\0\0", 8) = 8
read(3, "\n%SCRIPT_URIhttp://xxxxxxxxxxxxxxxx/test0.php", 49) = 49
read(3, "\1\4\0\1\0\32\0\0", 8) = 8
read(3, "\21\7GATEWAY_INTERFACECGI/1.1", 26) = 26
read(3, "\1\4\0\1\0\31\0\0", 8) = 8
read(3, "\17\10SERVER_PROTOCOLHTTP/1.1", 25) = 25
read(3, "\1\4\0\1\0\23\0\0", 8) = 8
read(3, "\16\3REQUEST_METHODGET", 19) = 19
read(3, "\1\4\0\1\0\16\0\0", 8) = 8
read(3, "\f\0QUERY_STRING", 14) = 14
read(3, "\1\4\0\1\0\27\0\0", 8) = 8
read(3, "\v\nREQUEST_URI/test0.php", 23) = 23
read(3, "\1\4\0\1\0#\0\0", 8) = 8
read(3, "\v\26SCRIPT_NAME/php-handler/test0.php", 35) = 35
read(3, "\1\4\0\1\0\0\0\0", 8) = 8
clock_gettime(CLOCK_MONOTONIC, {582840, 996581876}) = 0
setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={60, 0}}, NULL) =
0
rt_sigaction(SIGPROF, {0x5b0980, [PROF], SA_RESTORER|SA_RESTART,
0x2b35bb70e2d0}, {0x5b0980, [PROF], SA_RESTORER|SA_RESTART,
0x2b35bb70e2d0}, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [PROF], NULL, 8) = 0
open("/home/httpd/html/php/test0.php", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=20, ...}) = 0
clock_gettime(CLOCK_MONOTONIC, {582840, 996842876}) = 0
getcwd("/home/httpd/html/php"..., 4095) = 21
Cool, chroot path /home/httpd/html/php/test0.php does exist and FPM
gets a file from there:
# chroot /home/httpd/html/php/
bash-3.2# ls -la /home/httpd/html/php/test0.php
-rw-r--r-- 1 20114800 20114800 20 Jan 18 05:22 /home/httpd/html/php/
test0.php
But when I request a file from "test2" directory ["GET /test2/test2.php
\r\n..."] the trace looks different:
read(3, "\r\21DOCUMENT_ROOT/home/app/php/php", 32) = 32
read(3, "\1\4\0\1\0\"\0\0", 8) = 8
read(3, "\17\32SCRIPT_FILENAME/home/httpd/html/php/test2", 43) = 43
read(3, "\1\4\0\1\0\22\0\0", 8) = 8
read(3, "\v\5REMOTE_PORT41918", 18) = 18
read(3, "\1\4\0\1\0\36\0\0", 8) = 8
read(3, "\f\20REDIRECT_URL/test2/test2.php", 30) = 30
read(3, "\1\4\0\1\0\25\0\0", 8) = 8
read(3, "\n\tGEOIP_ADDR127.0.0.1", 21) = 21
read(3, "\1\4\0\1\0\34\0\0", 8) = 8
read(3, "\n\20SCRIPT_URL/test2/test2.php", 28) = 28
read(3, "\1\4\0\1\0007\0\0", 8) = 8
read(3, "\n+SCRIPT_URIhttp://xxxxxxxxxxxxxxxx/test2/test2.php", 55) =
55
read(3, "\1\4\0\1\0\32\0\0", 8) = 8
read(3, "\21\7GATEWAY_INTERFACECGI/1.1", 26) = 26
read(3, "\1\4\0\1\0\31\0\0", 8) = 8
read(3, "\17\10SERVER_PROTOCOLHTTP/1.1", 25) = 25
read(3, "\1\4\0\1\0\23\0\0", 8) = 8
read(3, "\16\3REQUEST_METHODGET", 19) = 19
read(3, "\1\4\0\1\0\16\0\0", 8) = 8
read(3, "\f\0QUERY_STRING", 14) = 14
read(3, "\1\4\0\1\0\35\0\0", 8) = 8
read(3, "\v\20REQUEST_URI/test2/test2.php", 29) = 29
read(3, "\1\4\0\1\0\37\0\0", 8) = 8
read(3, "\v\22SCRIPT_NAME/php-handler/test2", 31) = 31
read(3, "\1\4\0\1\0\25\0\0", 8) = 8
read(3, "\t\nPATH_INFO/test2.php", 21) = 21
read(3, "\1\4\0\1\0,\0\0", 8) = 8
read(3, "\17\33PATH_TRANSLATED/home/app/php/php/test2.php", 44) = 44
read(3, "\1\4\0\1\0\0\0\0", 8) = 8
lstat("/home/app/php/php/test2.php", 0x7fff36823420) = -1 ENOENT (No
such file or directory)
stat("/home/app/php/php", 0x7fff36825620) = -1 ENOENT (No such file or
directory)
stat("/home/app/php", 0x7fff36825620) = -1 ENOENT (No such file or
directory)
stat("/home/app", 0x7fff36825620) = -1 ENOENT (No such file or
directory)
I have no idea why FPM tries to get a filename from NON-chroot path
and why the directory is stripped. It seems that FPM tried to open a
filename pointed to by PATH_TRANSLATED env var. Why? And notice the
SCRIPT_FILENAME which is... a directory, not a file.
I can set Apache like this:
DocumentRoot /home/app/php/php
FastCgiExternalServer /home/httpd/html/php -idle-timeout 300 -
socket /var/run/php-fpm-php.sock
RewriteRule ^/(.*)\.php$ /home/httpd/html/php/$1.php [L]
No Action nor AddHandler nor Alias used. It works, the RewriteRule
above takes care of passing this request to a handler. Still, it works
only for top-level paths:
$ /bin/echo -ne "GET /test0.php HTTP/1.1\r\nHost: php.xxxxxxxxxxxxxxxx
\r\n\r\n" | nc localhost 8080|head -15
HTTP/1.1 200 OK
Date: Wed, 18 Jan 2012 12:43:39 GMT
Server: Apache/2
Cache-Control: max-age=18000
Expires: Wed, 18 Jan 2012 17:43:39 GMT
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
2000
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/
xhtml1-transitional.dtd">
<html><head>
<style type="text/css">
body {background-color: #ffffff; color: #000000;}
body, td, th, h1, h2 {font-family: sans-serif;}
read(3, "\r\21DOCUMENT_ROOT/home/app/php/php", 32) = 32
read(3, "\1\4\0\1\0\"\0\0", 8) = 8
read(3, "\17\36SCRIPT_FILENAME/home/httpd/html/php/test0.php", 47) =
47
read(3, "\1\4\0\1\0\22\0\0", 8) = 8
read(3, "\v\5REMOTE_PORT42110", 18) = 18
read(3, "\1\4\0\1\0\25\0\0", 8) = 8
read(3, "\n\tGEOIP_ADDR127.0.0.1", 21) = 21
read(3, "\1\4\0\1\0\26\0\0", 8) = 8
read(3, "\n\nSCRIPT_URL/test0.php", 22) = 22
read(3, "\1\4\0\1\0001\0\0", 8) = 8
read(3, "\n%SCRIPT_URIhttp://xxxxxxxxxxxxxxxx/test0.php", 49) = 49
read(3, "\1\4\0\1\0\32\0\0", 8) = 8
read(3, "\21\7GATEWAY_INTERFACECGI/1.1", 26) = 26
read(3, "\1\4\0\1\0\31\0\0", 8) = 8
read(3, "\17\10SERVER_PROTOCOLHTTP/1.1", 25) = 25
read(3, "\1\4\0\1\0\23\0\0", 8) = 8
read(3, "\16\3REQUEST_METHODGET", 19) = 19
read(3, "\1\4\0\1\0\16\0\0", 8) = 8
read(3, "\f\0QUERY_STRING", 14) = 14
read(3, "\1\4\0\1\0\27\0\0", 8) = 8
read(3, "\v\nREQUEST_URI/test0.php", 23) = 23
read(3, "\1\4\0\1\0\27\0\0", 8) = 8
read(3, "\v\nSCRIPT_NAME/test0.php", 23) = 23
read(3, "\1\4\0\1\0\0\0\0", 8) = 8
clock_gettime(CLOCK_MONOTONIC, {583395, 860114876}) = 0
setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={60, 0}}, NULL) =
0
rt_sigaction(SIGPROF, {0x5b0980, [PROF], SA_RESTORER|SA_RESTART,
0x2b35bb70e2d0}, {0x5b0980, [PROF], SA_RESTORER|SA_RESTART,
0x2b35bb70e2d0}, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [PROF], NULL, 8) = 0
open("/home/httpd/html/php/test0.php", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=20, ...}) = 0
clock_gettime(CLOCK_MONOTONIC, {583395, 860385876}) = 0
getcwd("/home/httpd/html/php"..., 4095) = 21
chdir("/home/httpd/html/php") = 0
Good, SCRIPT_FILENAME is what it should be. But with test2/test2.php
it fails but for a different cause:
$ /bin/echo -ne "GET /test2/test20.php HTTP/1.1\r\nHost:
xxxxxxxxxxxxxxxx\r\n\r\n" | nc localhost 8080
HTTP/1.1 404 Not Found
Date: Wed, 18 Jan 2012 12:44:40 GMT
Server: Apache/2
Cache-Control: max-age=18000
Expires: Wed, 18 Jan 2012 17:44:40 GMT
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
19
No input file specified.
read(3, "\r\21DOCUMENT_ROOT/home/app/php/php", 32) = 32
read(3, "\1\4\0\1\0\"\0\0", 8) = 8
read(3, "\17\32SCRIPT_FILENAME/home/httpd/html/php/test2", 43) = 43
read(3, "\1\4\0\1\0\22\0\0", 8) = 8
read(3, "\v\5REMOTE_PORT42168", 18) = 18
read(3, "\1\4\0\1\0\25\0\0", 8) = 8
read(3, "\n\tGEOIP_ADDR127.0.0.1", 21) = 21
read(3, "\1\4\0\1\0\34\0\0", 8) = 8
read(3, "\n\20SCRIPT_URL/test2/test2.php", 28) = 28
read(3, "\1\4\0\1\0007\0\0", 8) = 8
read(3, "\n+SCRIPT_URIhttp://xxxxxxxxxxxxxxxxxxxxxxxxx/test2/
test20.php", 55) = 55
read(3, "\1\4\0\1\0\32\0\0", 8) = 8
read(3, "\21\7GATEWAY_INTERFACECGI/1.1", 26) = 26
read(3, "\1\4\0\1\0\31\0\0", 8) = 8
read(3, "\17\10SERVER_PROTOCOLHTTP/1.1", 25) = 25
read(3, "\1\4\0\1\0\23\0\0", 8) = 8
read(3, "\16\3REQUEST_METHODGET", 19) = 19
read(3, "\1\4\0\1\0\16\0\0", 8) = 8
read(3, "\f\0QUERY_STRING", 14) = 14
read(3, "\1\4\0\1\0\35\0\0", 8) = 8
read(3, "\v\20REQUEST_URI/test2/test20.php", 29) = 29
read(3, "\1\4\0\1\0\23\0\0", 8) = 8
read(3, "\v\6SCRIPT_NAME/test2", 19) = 19
read(3, "\1\4\0\1\0\25\0\0", 8) = 8
read(3, "\t\nPATH_INFO/test2.php", 21) = 21
read(3, "\1\4\0\1\0/\0\0", 8) = 8
read(3, "\17\36PATH_TRANSLATED/home/httpd/html/php/test20.php", 47) =
47
read(3, "\1\4\0\1\0\0\0\0", 8) = 8
lstat("/home/httpd/html/php/test2", {st_mode=S_IFDIR|S_ISGID|0755,
st_size=4096, ...}) = 0
clock_gettime(CLOCK_MONOTONIC, {583449, 31099876}) = 0
setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={60, 0}}, NULL) =
0
rt_sigaction(SIGPROF, {0x5b0980, [PROF], SA_RESTORER|SA_RESTART,
0x2b35bb70e2d0}, {0x5b0980, [PROF], SA_RESTORER|SA_RESTART,
0x2b35bb70e2d0}, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [PROF], NULL, 8) = 0
open("/home/httpd/html/php/test2", O_RDONLY) = 4
fstat(4, {st_mode=S_IFDIR|S_ISGID|0755, st_size=4096, ...}) = 0
close(4) = 0
It seems that with this setup the PATH_TRANSLATED env var [which maps
to chrooted path perfectly] is OKAY but FPM is trying to open
SCRIPT_FILENAME which is... a directory the requested script it in!
And WHY FPM is ignoring PATH_TRANSLATED now?
I'm stuck. The later method works for me better, but WHY ON EARTH I
GET 404 or "No input file specified"?
I've tried even this:
RewriteRule ^/(.*)\.php$ /home/httpd/html/php/$1.php
[E=SCRIPT_FILENAME:/home/httpd/html/php/$1,L]
But it doesn't work, it gets overwritten by Apache.
Any help, any ideas?
This is my php-fpm chroot-revelant configuraion options in fpm config:
chroot = /home/httpd/html/php
chdir = /home/httpd/html/php