Nginx pnp4nagios with php5-fpm - nginx

I have been going at this for a day now. And I think it's time to ask for help now.
I'm moving our nagios to nginx. I have nagios running as well as a django application I recently developed. Pnp4nagios is giving me some troubles though. I have the following configuration in Nginx.
location ~ ^(/pnp4nagios/.*\.php)(.*)$ {
root /usr/share/pnp4nagios/html;
include /etc/nginx/fastcgi_params;
rewrite ^/pnp4nagios/(.*)$ /$1 break;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param SCRIPT_FILENAME /usr/share/pnp4nagios/html/$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
}
This results in this:
As you can see, pnp4nagios thinks that its index.php lives in 172.16.10.28/index.php But this isn't true. It is a sub-page (or whatever i should call it?). I want it to point to 172.16.10.28/pnp4nagios/index.php but I have no clue how I can do this in my nginx config. I would prefer not to change anything in pnp4nagios. But if it's only one or a few lines it's a compromise I'm willing to make. I already have an index.php in my "root" url. That's why I want a subfolder.
The examples that have lead me to this aproach are:
Example1
Example2
So to recap what I want (or what I think that I need) is to go from this: img src="/index.php... to img src="/pnp4nagios/index.php...
PS. I didn't have enough points to create a pnp4nagios tag

This worked for me:
location /pnp4nagios {
alias /usr/share/pnp4nagios/html;
}
location ~ ^(/pnp4nagios.*\.php)(.*)$ {
root /usr/share/pnp4nagios/html;
include /etc/nginx/fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_pass 127.0.0.1:9000;
}

You've got a rewrite in your configuration that strips php4nagios path component. Therefore it's not surprising to see the reference to /index.php. You should verify the resulting CGI variables using an info.php page in the appropriate directory. The offending line is:
rewrite /pathinfo/(.*)/ $1 break;

Related

Is it possible to set up multiple server blocks on NGINX without multiple domains

I have a subdomain labs.mydomain.com which I'd like to host several web apps that I develop on different folders: labs.mydomain.com/app1, labs.mydomain.com/app2, labs.mydomain.com/app3. I'd like it to be the same domain separated by folders instead of creating a new subdomain for each one, just like in the example above.
The problem is that I use some framework on each project so I'd have to map /app1 to /app1/public and /app2 to app2/public.
Does NGINX accepts server_name to be like labs.mydomain.com/app1?
Is it possible to do so? If not, what would be the best alternative?
Nginx doesn't support labs.mydomain.com/app1 as server_name.
But you can use location directive to configure rules for your directories. Example bellow:
location /app1 {
alias /var/www/app1/public/;
}
location ~ ^/app1/(.+\.php)$ {
alias /var/www/app1/public/$1;
fastcgi_pass 127.0.0.1:8888;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;
}

Nginx rewrite rule to PHP that also allows .php in the URI

Slightly unusual question, hopefully with a simple answer! (I'm new to Nginx)
I have an old PHP system running on Apache and I'd like to bring it over to Nginx, but my issue is that some of it needs to be rewritten back to a single handler file (/handler.php) and some of it wants to execute the actual files. The tricky part seems to be that almost all routes end in .php whether they reference an actual PHP file or not.
For example, /foo.php might be an actual file that executes its own code, but /bar.php might not exist and therefore wants to call /handler.php. There are also instances of routes of the form /bar (without the .php extension) that also want to call /handler.php.
There are lots of all types in the system (far, far more than I'd like to manually code for). Is there a solution to this in Nginx?
The server block currently contains something like:
location / {
try_files $uri $uri/ /handler.php$is_args$args;
}
include /etc/nginx/sites.d/*.conf;
and sites.d/php.conf currently looks something like:
location ~ \.php$
{
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
But this treats all routes with .php extensions as actual files and just gives me the standard "No input file specified." error for any that don't exist (performs no rewrite). No problem if there is no .php extension, they call /handler.php without issue.
So in summary, with this almost default setup:
/foo.php - works (actual file)
/bar.php - fails (no file)
/bar - works (no file)
If I only had the "no-file" type I could update the php.conf to something like "location ~ \handler.php$", but in this case it means all actual .php files just trigger a download (i.e. /foo.php fails).
Any help is appreciated! Thanks in advance.
In your location block matching .php You can test if the file actually exists and redirect to handler.php if it's not there:
location ~ \.php$ {
if (!-f $request_filename) {
rewrite ^.*\.php$ /handler.php last;
}
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
Updated example
Alternative location rule using try_files (as suggested by OP):
location ~ \.php$ {
try_files $uri /handler.php$is_args$args;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
With the first version using rewrite you can do substitution from regex matches. But try_file I think is the recommended method of testing for file existence. Thank you to the OP for suggesting an improved alternative.

"No input file specified" with php Fast/CGI

I am trying to set a config for Nginx and am facing some issues.
In my sites-available there is default file which contains the below code:
server {
server_name www.test.com test.com;
access_log /sites/test/logs/access.log;
error_log /sites/test/logs/error.log;
root /sites/test;
location ~ / {
index index.php
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
Above code works perfectly when I write URL
www.test.com/service/public/
when I write
www.test.com/service/public/testservice (testservice is folder within public) it says No input file specified.
How can this be fixed?
I tried below, but no luck
http://nginxlibrary.com/resolving-no-input-file-specified-error/
http://blog.martinfjordvald.com/2011/01/no-input-file-specified-with-php-and-nginx/
You must add "include fastcgi.conf" in
location ~ \.$php{
#......
include fastcgi.conf;
}
Resolving "No input file specified" error
If you are using nginx with php-cgi and have followed the standard procedure to set it up, you might often get the “No input file specified” error. This error basically occurs when the php-cgi daemon cannot find a .php file to execute using the SCRIPT_FILENAME parameter that was supplied to it. I’ll discuss about the common causes of the error and it’s solutions.
Wrong path is sent to the php-cgi daemon
More often than not, a wrong path (SCRIPT_FILENAME) is sent to the fastCGI daemon. In many of the cases, this is due to a misconfiguration. Some of the setups I have seen are configured like this :
server {
listen [::]:80;
server_name example.com www.example.com;
access_log /var/www/logs/example.com.access.log;
location / {
root /var/www/example.com;
index index.html index.htm index.pl;
}
location /images {
autoindex on;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/example.com$fastcgi_script_name;
include fastcgi_params;
}
}
Now, there are many things wrong with this configuration. An obvious and glaring issue is the root directive in the location / block. When the root is defined inside the location block, it is available/defined for that block only. Here, the location /images block will not match for any request because it does not have any $document _root defined and we will have to redundantly define root again for it. Obviously, the root directive should be moved out of the location / block and defined in the server block. This way, the location blocks will inherit the value defined in the parental server block. Of course, if you want to define a different $document_root for a location, you can put a root directive in a location block.
Another issue is that the value of the fastCGI parameter SCRIPT_FILENAME is hard-coded. If we change the value of the root directive and move our files somewhere else in the directory chain, php-cgi will return a “No input file specified” error because will not be able to find the file in the hard-coded location which didn’t change when the $document_root was changed. So, we should set SCRIPT_FILENAME as below :
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
We should keep in mind that the root directive should be in the server block or else, only the $fastcgi_script_name will get passed as the SCRIPT_FILENAME and we will get the “No input file specified” error.
source(Resolving "No input file specified" error)
Simply restarting my php-fpm solved the issue. As i understand it's mostly a php-fpm issue than nginx.
Same problem.
Cause : My root wasn't specified in open_basedir.
Fix : Adding my site root directory in :
/etc/php5/fpm/pool.d/mysite.conf<br>
by adding this directive :
php_value[open_basedir] = /my/root/site/dir:/other/directory/allowed
I solved it by replacing
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
$document_root with C:\MyWebSite\www\
fastcgi_param SCRIPT_FILENAME C:\MyWebSite\www\$fastcgi_script_name;
I tried all the settings above but this fixed my problem.
You have to define nginx to check if the php file actually exists in that location. I found try_files $uri = 404; solving that problem.
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_index index.php;
}
This answers did not help me, my php adminer showed me "No input file specified" error anyway.
But I knew I changed php-version before.
So, I found the reason: it is not nginx, it is php.ini doc_root parameter!
I found
doc_root =
in php.ini and changed it to
;doc_root =
After this patch my adminer work good.
This is likely because with the trailing slash, NGinx tries to find the default index file which is probably index.html without configuration. Without the trailing slash it tries to match the file testservice which he can't find. Either this and/or you don't have any default index file in the testservice folder.
Try adding this line to your server configuration :
index index.php index.html index.htm; // Or in the correct priority order for you
Hope this helps!
Edit
My answer is not very clear, see this example to understand what I mean
listen 80;
server_name glo4000.mydomain.com www.glo4000.mydomain.com;
access_log /var/log/nginx/glo-4000.access.log;
error_log /var/log/nginx/glo-4000.error_log;
location / {
root /home/ul/glo-4000/;
index index.php index.html index.htm;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/tmp/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/ul/glo-4000/$fastcgi_script_name;
}
}
I tried all the options mentioned above, but found finally the solution.
On my server the .php file was set to be readable by everyone, but it worked when I set the php-fpm to run under same user as nginx. I changed it in /etc/php/7.2/fpm/pool.d/www.conf and in the configuration file I set
user = nginx
group = nginx
and then reloaded the php-fpm process
Hope this helps
server {
server_name www.test.com test.com;
access_log /sites/test/logs/access.log;
error_log /sites/test/logs/error.log;
root /sites/test;
location ~ / {
index index.php
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME `$document_root/service/public$fastcgi_script_name`;
}
Same problem.
Reason old open_basedir settings copied with a rogue user.ini file in a backup
Solution delete it
Okay,
I assume you using php7.2 (or higher) on Ubuntu 16 or higher
if none of this worked, you must know nginx-fastCGI uses different pid and .sock for different sites hosted on the same server.
To troubleshoot 'No input file specified' problem, you must tell the nginx yoursite.conf file which one of the sock file to use.
Uncomment the default fastcgi_pass unix:/var/run/php7.2-fpm.sock Make sure you have the following directives in place on the conf file,
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri /index.php =404;
#fastcgi_pass unix:/var/run/php7.2-fpm.sock;
fastcgi_pass unix:/var/php-nginx/158521651519246.sock/socket;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
have a look at the list of sock and pid files using ls -la /var/php-nginx/(if you have recently added the file, it should be the last one on the list)
3.copy the filename of the .sock file (usually a 15 digit number) and paste it to your location ~ \.php directive
fastcgi_pass unix:/var/php-nginx/{15digitNumber}.sock/socket;
and restart nginx.
Let me know if it worked.
I had the same Error and my Problem was, that I had my php-file in my encrypted home-directory. And I run my fpm with the www-data user and this user can't read the php-files even if the permissions on the file were right. The solutioin was that I run fpm with the user who owns the home-directory. This can be changed in folowing file:
/etc/php5/fpm/pool.d/www.conf
hope this will help you :)
My case: SELinux was enabled and denying php-fpm from executing my scripts.
Diagnosis: Temporarilly disable SELinux and see if the problem goes away.
$ sudo setenforce permissive
### see if PHP scripts work ###
$ sudo setenforce enforcing
Solution: Put the PHP directory in the httpd_sys_content_t context. You can use chcon or make the change persistent via semanage:
$ sudo semanage fcontext -a -t httpd_sys_content_t "/srv/myapp(/.*)?"
$ sudo restorecon -R -F /srv/myapp
You can use the context httpd_sys_rw_content_t where write permissions are needed.
use in windows
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
wasn't putting -b
php-cgi.exe -b 127.0.0.1:9000
For localhost - I forgot to write in C:\Windows\System32\drivers\etc\hosts
127.0.0.1 localhost
Also removed proxy_pass http://127.0.0.1; from other server in ngnix.conf
Alright I'm a noob but just to share what I encountered.
I set up Laravel Forge with Linode to run a static website from my github repo.
SSH into my Linode and verified that my html was updated however, upon visiting the public ip of my linode I saw the error msg 'No input file specified.
Went to Nginx configuration file in my forge and deleted the word 'public' so now its
root /home/forge/default;
restarted nginx server within forge and deployed again and now it can be accessed.
It is possible that PHP-FPM service is not started or is listening on some other port than 9000.
If someone is still having trouble with it ... I solved it by correcting it this way:
Inside the site conf file (example: /etc/nginx/conf.d/SITEEXAMPLE.conf) I have the following line:
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name;
The error occurs because my site is NOT in the "/usr/share/nginx/html" folder but in the folder: /var/www/html/SITE/
So, change that part, leaving the code as below. Note: For those who use the site standard in /var/www/html/YOUR_SITE/
fastcgi_param SCRIPT_FILENAME /var/www/html/YOUR_SITE/$fastcgi_script_name;

Certain URLs don't go through PHP-FPM

I'm having a lot of trouble setting up my nginx server with my PHP RESTful API. I have the following blocks in my server{} block:
location / {
rewrite ^/v1/* /v1/api.php last;
rewrite ^/* /index.php last;
}
location * .*\.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
}
However.. these seem not to be functioning properly. Basicly, I want every URL starting with /v1/ to be rewritten to /v1/api.php, and anything else to /index.php.
This seems to be working partially. Sometimes it actually does go to api.php, but sometimes it just seems to download the file instead of processing it through PHP-FPM. How would I fix this?
Downloading a file means not being passed to the php engine, so I assume the problem is in that block definition
replace
location * .*\.php$ {
with
location ~ \.php$ {
And probably it will work.

Nginx odd caching or something after enabling php?

I'm not really sure what to consider this under, or the cause, so I'm sorry if the title is misleading.
I just installed Nginx for the first time and out of curiosity tried to see if I could get some popular forum software to work properly. I first tried installing Vbulletin 4, as this is what one community I host uses. PHP is being handled by php-fpm. I could get any custom page to display some simple php echo I just wrote, with any filename or directory. http://example.com/test/test.php or http://example.com/test.php, for instance.
However, when I went to try to install vbulletin through their install script, located at http://example.com/install/install.php, the file would just download. I double and triple checked the Nginx config for this domain, and everything seemed like it should work.
After downloading install.php a few times, I decided to attempt visiting the page in a Chrome Incognito window. Lo and behold, the install.php page no longer downloaded and the installer was prompting me for my customer id # as it should have. Then I go back to my main Chrome (not in incognito) window and try to visit the install page again, install.php gets downloaded again!
Here's the config I was using at the time:
server {
listen ip:80;
server_name my.domain.com;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
root /usr/share/nginx/html;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
}
}
Any insight on the cause of this issue? I can't imagine why it would serve a download of the php file for one session and then actually serve the dynamic content for another. I don't want any files accidentally getting downloaded by some random user.
Your fastcgi_params look a little off. You have set PATH_INFO as the script name.
Try:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $document_root

Resources