Nginx location: 403 error / File not found - nginx

I set up my domain on my server using nginx. So far so good my homepage works. But now I wanna add some locations for later test of programming. My plan is to call diffrent projects like mydomain.com/php/myprogramm.php
So I add some folder in /var/www/mydomain.com/php (my side index is in /var/www/mydomain.com/html)
Entering www.mydomain.com/php/ leads to an 403 error and mydomain.com/php/myprogramm.php says File not found...
this is my nginx file:
server {
listen 80 default_server;
#listen [::]:80 default_server ipv6only=on;
# Make site accessible from http://localhost/
server_name mydomain.com www.mydomain.com;
location / {
root /var/www/mydomain.com/html;
index index.html index.htm;
}
location /php/ {
root /var/www/mydomain.com;
}
location /js/ {
root /var/www/mydomain.com;
}
location /node/ {
root /var/www/mydomain.com;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
#
# # With php5-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# # With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
Of course when I set up my domain I also set sudo chown -R www-data:www-data /var/www/mydomain.com/html and sudo chmod 755 /var/www
Some ideas someone? :/

Problems analysis
The first golden rule is:
nginx always serves request from a single location only. (Re-)read http://nginx.org/en/docs/http/request_processing.html.
Based on your configuration:
Requests to (www.)mydomain.com/php/<whatever> for files not ending with .php will be served by location /php/ from /var/www/mydomain.com/php/<whatever>
Requests to (www.)mydomain.com/<whatever>.php will be served by location ~\.php$ from <default root ('html' by default)>/<whatever>.php
The first problem here is that you are not serving .php files from where you think you are. Learn from location documentation how the location block serving a request is chosen.
You will note that the 'File not found' error was not an nginx error, but a message generated by PHP. That helps to know whether the problem comes from (frontend or backend).
Now about that 403: it seems nginx has trouble accessing the location where it is supposed to serve content from. Check /var/www/mydomain.com/php/ (directory + contents) rights.
Proposed pieces of advice
Your configuration looks suboptimal.
If you use the same root in lots of location blocks, why not moving it one level upper so it becomes the default (which yo ucan override in specific locations where needed)?
You can used nested locations, ie to solve you PHP files serving problem. Note that it is always a good idea to enclose regex locations inside prefix locations (What is the difference? Read location documentation). The reason is regex locations are order-sensitive, which is bad for maintenance. Prefix locations are not since only the longest match with a request URI will be chosen.
Here is a propsed updated version of part of your configuration:
root /var/www/mydomain.com;
location / {
root /var/www/mydomain.com/html;
index index.html index.htm;
}
location /php/ {
location ~ \.php$ {
# Useless without use of $fastcgi_script_name and $fastcgi_path_info
# Moreover, requests ending up here always end with .php...
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
# You seem to have copy-pasted this section without understanding it.
# Good understanding of what happens here is mandatory for security.
}
}
I suggest you read the documentation about fastcgi_split_path_info, $fastcgi_script_name and $fastcgi_path_info.

For my testing right now I fixed the issue quite simply.
I forogt to check my php.ini and change the cgi.fix_pathinfo to 0
Also I changed the group for my folders (still had root inside) to www-data.
At the end I updated my configuration: I set root /var/www/mydomain.com; in my server block (server{})
That's all I did.
But I will keep your advice in mind for later issues.
Thanks for your help I appreciate it.

Related

Nginx trying to load image files from server root rather then project root location

Quick question, shouldn't be too hard... hopefully.
I'm running Nginx with two Laravel projects being hosted. The following directories are where they are being stored.
/var/www/site.kara
/var/www/site.arkmanager
The location of the projects are http://10.0.0.2/kara and http://10.0.0.2/arkmanager.
The site.kara laravel project is loading images just fine. However I have an issue with the site.arkmanager locating images in my CSS file. It is also having issues loading FontAwesome webfonts files as well, due to the css code looking in the root of the server and not in the project directory. (CSS Code Below) I look at the console and there is an error...
So, according to this error its trying to get the image file from the server root directory? It isn't adding the /arkmanager portion of the image location... the image location is: http://10.0.0.2/arkmanager/images/app/hero-background.png. So I'm thinking that I screwed up my NGINX default file somehow, even though its not giving me any errors when running sudo nginx -t. A little bit of insight would be helpful in solving this issue.
My CSS class property, if its relevant to the problem, putting here just in case:
#hero {
width: 100%;
height: 100vh;
background: url("/images/app/hero-background.png") top center;
background-size: cover;
position: relative;
}
Here is my /etc/nginx/sites-available/default file contents. I am not running SSL due to the fact that this is a local server (second computer) inside my internal network and not available to the public.
# HTTP Server Block
server {
# Port that the web server will listen on.
listen 80 default_server;
# Root Folder
root /var/www/;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
# IP ADDRESS
server_name _;
# Root Location
location / {
# URLs to attempt, including pretty ones.
try_files $uri $uri/ /index.php$is_args$args;
}
# Karas Worlds Nested Location
location /kara {
alias /var/www/site.kara/public/;
try_files $uri $uri/ #kara;
# PHP FPM configuration.
location ~ \.php$ {
#Include Fast CGI Snippets
include snippets/fastcgi-php.conf;
# Define the PHP Script Filename
fastcgi_param SCRIPT_FILENAME $request_filename;
# With php-fpm (or other unix sockets)
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
}
location #kara {
rewrite /kara/(.*)$ /kara/index.php?/$1 last;
}
# End Karas World Nested Location
# Ark Manager Nested Location
location /arkmanager {
alias /var/www/site.arkmanager/public/;
try_files $uri $uri/ #arkmanager;
# PHP FPM configuration.
location ~ \.php$ {
#Include Fast CGI Snippets
include snippets/fastcgi-php.conf;
# Define the PHP Script Filename
fastcgi_param SCRIPT_FILENAME $request_filename;
# With php-fpm (or other unix sockets)
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
}
location #arkmanager {
rewrite /arkmanager/(.*)$ /arkmanager/index.php?/$1 last;
}
# Ark Manager Nested Location
# PHP FPM configuration.
location ~ \.php$ {
#Include Fast CGI Snippets
include snippets/fastcgi-php.conf;
# With php-fpm (or other unix sockets)
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
# We don't need .ht files with nginx.
location ~ /\.ht {
deny all;
}
}
Also side note here is a screenshot of my npm run dev command running and compiling successfully, just in case anyone thought that the CSS file might have been borked.
This is what what the application looks like on my local dev machine:
https://prnt.sc/vtu6f6
https://prnt.sc/vtu6y0
This is what it looks like on the local ubuntu server running nginx:
https://prnt.sc/vtu6r5
https://prnt.sc/vtu77h

rewrite rules for nginx and Codeigniter

I have implemented a php application in codeigniter and now want to deploy it to the nginx server. Before deploying I checked my nignx configuration on my localhost using MAMP server. It is working correctly. But, this configuration is not working on the live server. As a beginner in nginx, I am not understanding where is the mistake here. In live server, I can not write in the main nginx.conf file. I have a separate configuration file like "abc" for my application "abc". And all my application files are under "abc/xyz" directory. Here is my sample confuguration,
location /abc {
root /srv/www/htdocs/apps/;
index index.html index.htm index.php;
location /xyz {
try_files $uri $uri/ /abc/xyz/index.php;
}
location ~ \.php(\/(\w+))*$ {
try_files $uri =404;
rewrite (.+)\.php(\/(\w+))*$ $1.php break;
include /etc/nginx/fastcgi_params;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Here, I can see my welcome page https://myapplication/abc/xyz. But if I want to navigate other pages like https://myapplication/abc/xyz/other_pages, it is showing "404 Page not found". I have checked the other solutions but none of them is not working in this case. Thanks in advance for the help!
The location /xyz block is nested within the location /abc block. The nested block is required to precess URIs with a prefix of /abc/xyz.
If there are other regular expression location blocks surrounding your location /abc block, you should use the^~` modifier.
For example:
location ^~ /abc {
...
location /abc/xyz {
...
}
...
}
See this document for more.
Sorry for the late answer. It was actually very silly mistake. My controller page name was in small character. This is why it was not working. My configuration is okay. The first letter of the controller page should be in capital character. For example, my controller name is Home. So my php file name must be Home.php not home.php.

Yii2 adanced application and nginx configuration (index directive configuration)

I'm trying to build proper server configuration for nginx serving Yii2 advanced template where backend hosted in a subfolder inside same domain name as frontend.
In this case path_to_yii2 contains whole Yii2 application template and we have these requirements:
path_to_yii2/frontend/web -> should be webroot of / location
path_to_yii2/backend/web -> should be webroot of /backend location
Static content in both folders should be properly served. PHP files should work in both cases.
I wrote and tested such configuration:
server {
listen 80;
server_name localhost;
root <path_to_yii2_application>;
location ~* ^/backend/(.+)$ {
try_files /backend/web/$1 /backend/web/$1/ /backend/index.php?$args;
index /backend/$1/index.php; # not working in case of exact /backend/ request
location ~* ^/backend/(.+\.php)$ {
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/backend/web/$1;
}
}
location / {
try_files /frontend/web/$uri /index.php?$args;
index /$uri/index.php; # not working at all, but / location is served by php even without this line
}
location ~ \.php$ {
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/frontend/web/$fastcgi_script_name;
}
}
And I have some unresolved problems with such configuration. I tested six different options:
FRONTEND:
Static content under / location should be served directly from frontend/web subfolder of yii2 application folder.
Nonexistent content here should be redirected to frontend/web/index.php?$args and served using ~ .php$ location with fastcgi.
Directories under / location should return indexes, if needed served with ~ .php$ location and fastcgi.
BACKEND:
Static content under /backend location should be served directly from backend/web subfolder of yii2 application folder.
Nonexistent content here should be redirected to backend/web/index.php?$argsand served using ~ .php$ location with fastcgi.
Directories under /backend location should return their indexes, if needed served with ~ .php$ location and fastcgi.
I have troubles with directories and their indexes (3 and 6).
First of all, directories for frontend section not working at all, seems that index /$uri/index.php; is wrong for some reason.
Secondly, directories for backend working except exact /backend/ url. Nginx doesn't serve index directive in =/backend/ case.
As a temporarily workaround for backend I added few lines for this exact url:
location = /backend {
return 301 https://$server_name/backend/index.php;
}
location = /backend/ {
return 301 https://$server_name/backend/index.php;
}
How to fix these indexes correctly and what I'm doing wrong?
P.S. There are some similar questions, like Migrating Yii2 from Apache to Nginx - failed on backend app (doesn't provide correct answer, recommends using subdomain) and Nginnx config for Yii 2 Advanced App Template (suggested to move backend content inside yii2 application to frontend folder). I believe that nginx configuration is a proper way of congiguring yii2-application template.
There is also https://github.com/mickgeek/yii2-advanced-one-domain-config repositary which not works in nginx > 1.8.1.
Interesting that apache just needs a symbolic link to make this work. Nginx before 1.8.1 too.
Yii2 application template can be git cloned from here: https://github.com/yiisoft/yii2-app-advanced.git

"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;

Non-www to www domain using Nginx on Ubuntu 12.04 LTS on Ec2 instance

After seeing this post http://www.ewanleith.com/blog/900/10-million-hits-a-day-with-wordpress-using-a-15-server I changed my server from apache2 to nginx. I am no computer geek just, savvy. I followed the steps. After that, the site was perfect, except for one thing: non-www to www thing. I searched all over the net on how to do this. I tried the modrewrite thing they said but just getting worst. For now, it is directed to www because I use wordpress and set it in general settings http://www.pageantly.com. Yet, I have static directories and it is in plain non-www. Please take a look on my default.conf in /etc/nginx/conf.d/ as well as the tutorial with link above:
server {
server_name pageantly.com www.pageantly.com;
root /var/www/;
listen 8080;
## This should be in your http block and if it is, it's not needed here.
index index.html index.htm index.php;
include conf.d/drop;
location / {
# This is cool because no php is touched for static content
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~ \.php$ {
fastcgi_buffers 8 256k;
fastcgi_buffer_size 128k;
fastcgi_intercept_errors on;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/dev/shm/php-fpm-www.sock;
}
# BEGIN W3TC Page Cache cache
location ~ /wp-content/w3tc/pgcache.*html$ {
add_header Vary "Accept-Encoding, Cookie";
}
[...]
}
# END W3TC Page Cache core
}
Ideally, each domain (sub-domains included) should have a separate server block. Going by that, your configuration would look like:
# Following block redirects all traffic coming to pageantly.com to www.pageantly.com
server {
server_name pageantly.com;
listen 8080;
# Send a 301 permanent redirect to any request which comes on this domain
return 301 http://www.pageantly.com$request_uri;
}
# Following block handles requests for www.pageantly.com
server {
server_name www.pageantly.com;
listen 8080;
root /var/www;
[...] # all your default configuration for the website
}
Another unclean and inefficient way to achieve this would be to introduce an if statement which reads domain value and branches flow accordingly either to redirect traffic (in case of pageantly.com) or to process requests (in case of www.pageantly.com) but I would recommend you avoid going by that route.
Hope this helps.
If you are using Route 53 on AWS; then you do NOT have to do any such thing. On Route53 itself we can create an alias and configure so that non-www is redirected to www.

Resources