I am using Symfony2 (PHP) framework for my project and is having a small problem with regards to configuring my NGINX to catch request going to a 3rd party library I placed under "web" directory.
This is my configuration
server {
listen 80;
server_name test.com;
root /var/www/my-symfony-project/web;
rewrite ^/app\.php/?(.*)$ /$1 permanent;
location / {
index app.php;
try_files $uri #rewriteapp;
}
location #rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
location ~ ^/(app|app_dev|config)\.php(/|$) {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
As you may have noticed that the root is pointed in "/var/www/my-symfony-project/web" directory.
Now, the problem is that I have this "some-plugin" folder inside the "web" directory and there are PHP files from there that are not handled by the Symfony2 routing.
I actually made it work when I have the following "location" block inside the "server" block illustrated above.
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
}
It seems okay having this type of configuration at first but we realized that it accepts request to any "*.php" file to which we evaluated as a security breach.
Any suggestions?
Allowing access to .php files is usually not considered dangerous or a security breach, as long as the PHP files are executed and not served in their source form and, of course, don't print any sensitive information.
If either of the former are not the case, you should probably change your setup or your code.
Anyway, you should be able to restrict the .php file handling to /var/www/my-symfony-project/web/some-plugin by using the following as location:
location ~ ^/var/www/my-symfony-project/web/some-plugin/.*\.php$ {
# your rules here
}
This should match all files whose path starts with /var/www/my-symfony-project/web/some-plugin/ and end with .php in upper or lower case.
Related
I have created some Laravel routes with they have ".php" extention, such as
Route::get('/api/send.php', function(){
echo 'Hi There';
});
But when I open the route it shows 404 error in Nginx server... That is Nginx configurations
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/laravel/public;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
server_name xxx.xxx.xxx.xxx;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
What is the problem? I have used the same code it worked before..
Thanks
SOLVED
It solved by changing
try_files $fastcgi_script_name =404;
in /etc/nginx/snippets/fastcgi-php.conf to
try_files $fastcgi_script_name /index.php?$query_string;
This is a very common problem with nginx configured to serve PHP applications, especially Laravel. You can reproduce it on sites like laravel.com, e.g: laravel.com/example.php.
The default configuration (what you're probably using in snippets/fastcgi-php.conf) is this:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
And fastcgi_script_name is...
request URI or, if a URI ends with a slash, request URI with an index file name configured by the fastcgi_index directive appended to it. This variable can be used to set the SCRIPT_FILENAME and PATH_TRANSLATED parameters that determine the script name in PHP. For example, for the “/info/” request with the following directives
That means, when a request URI contains .php it is treated as if it is a request for a PHP file, and if that PHP file doesn't exist an error is returned by nginx -- it never reaches your application.
The solution is to force fastcgi_script_name to always equal your application's entry point, in this case that's index.php. You can either edit snippets/fastcgi-php.conf or add it into your location block like this:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
}
Your application will now receive every request, including those that have .php in the path.
I have a project running under php, but I have a third party subfolder(download folder) that I want to add into the current project.
Meaning, root folder = testlaravel =>www.testlaravel.com
with sub folder = testlaravel/download => www.testlaravel.com/download
Is there anyway I can do this?
Are you using Apache or Nginx ? If Apache, you need to config your vhost file to serve Laravel from a sub-folder. Particularly, you need to configure that when testlaravel.com/download URI is requested, it should be served using /home/testlaravel/download/public directory (basically different root/home location).
You also need to use mod_rewrite to rewrite your URL requests to the sub-folder be served from index.php from above location (and also prettify URLs).
Similarly, your configuration in vhost for your main website will be different (so there will be 2 configurations, one for your main website and one for laravel requests)
The above should work just fine since its done same way in Nginx, for which I have included a full example of how its conf file should look
Here is how I setup-ed my location block which is working for me perfectly:
location ^~ /facebookschedule {
alias /home/netcans/facebookschedule/public;
try_files $uri $uri/ #foobar;
location ~ \.php {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(.*)$;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/wwww/facebookschedule/public/index.php;
}
}
location #foobar {
rewrite /facebookschedule/(.*)$ /facebookschedule/index.php?/$1 last;
}
Source: http://shubhank.gaur.io/setup-laravel-5-in-subfolder-with-nginx/
I am using the following configuration, which is simpler than most other published solutions, and which does not require any paths/folders to be hard-coded.
We simply prefix all requests with public/ and then remove it from SCRIPT_NAME so that the application can autodetect its environment correctly.
location ~ /myproject/(.*) {
rewrite /myproject(.*) /myproject/public/$1 break;
try_files $uri /myproject/public/index.php$is_args$args;
location ~ /index\.php$ {
include /etc/nginx/fastcgi.conf;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_param SCRIPT_NAME /myproject/index.php;
}
}
Some PHP URLs are being downloaded instead of executed by Nginx. I have an existing web application which is functioning fine. I'm tasked with adding additional mounted applications within folders of the primary application. Each of these applications has its own front controller index.php script.
For this setup, I've created symlinks inside $document_root/app, and the symlinks point to a folder containing an index.php front controller.
When I navigate to most URLs, everything works fine, the primary application front controller is executed, and I get expected results. When I navigate to a non-existent app, I get 404 Not Found from nginx, which is expected. But when I navigate to one of the applications, the browser downloads the application front controller.
root /my/web/root;
location / {
try_files $uri
/$server_name$uri
/shared$uri
/index.php$is_args$args;
}
location ~ [^/]\.php(/|$) {
disable_symlinks off;
fastcgi_split_path_info ^(.+\.php\b)(.*)$;
fastcgi_param SERVER_NAME $host;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME /index.php;
fastcgi_index index.php;
include fastcgi.conf;
fastcgi_pass php-fpm;
}
location ~ ^/app/([a-z-]+)(/.*)?$ {
try_files $uri
/app/$1/index.php$is_args$args
=404;
}
URL which triggers download: /app/my-app/ (exists)
URL which 404s: /app/foo/ (does not exist)
URL which executes: /foo
The .php file needs to be processed by the location ~ [^/]\.php(/|$) block. You have a common document root which makes things simpler.
However, look at this document regarding the location directive.
You will see that the regex locations are considered in order and the first matching location will be used to process the request.
In short, you need to place the location ~ [^/]\.php(/|$) block before any other conflicting regex location, if you want your .php files to be processed correctly.
I'm trying to set up an nginx environment where legacy code and new MVC-style code can co-exist, so that I can gradually refactor it page by page. The legacy code needs an older version of PHP (it runs best on 5.3, but I had trouble compiling that, so I went with 5.4 and will fix anything that breaks), but it is easily distinguishable by URL, because it has literal file names like http://sub.domain.com/search.php?category=4, etc. instead of new style like http://sub.domain.com/search/category/4 - the key difference is the presence of .php.
The new code runs fine with the following in the nginx config:
server {
listen 80;
server_name *.myproject.dev;
root /var/www/myproject/public;
index index.php index.html index.htm;
try_files $uri $uri/ #rewrite;
location #rewrite {
rewrite ^/(.*)$ /index.php?_url=/$1;
}
location ~ ^(.+\.php)(/.*)?$ {
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
}
}
(I will admit that I don't completely understand all that code - it came from various guides and such.)
With the help of this great tutorial I compiled and installed PHP 5.4 in its own location listening on port 9001. It works fine using a separate domain for the old code, but what I want to do is use a single domain, but call the old code if .php is found in the URL, and do the requisite rewrite on anything else and use the new code. I found this post on ServerFault and tried incorporating its ideas in my situation like this:
server {
listen 80;
server_name *.myproject.dev;
root /var/www/myproject/public;
index index.php index.html index.htm;
try_files $uri $uri/ #rewrite;
location #rewrite {
rewrite ^/(.*)$ /index.php?_url=/$1;
}
location ~ ^(.+\.php)(/.*)?$ {
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
# Anything with ".php" is directed to the old codebase
location ~* \.php {
root /var/www/myproject/oldcode;
fastcgi_pass 127.0.0.1:9001;
}
}
}
But the rewrite adds index.php to the new code, so in the end, everything matches the .php test, which is not the intent. I tried putting those final four lines earlier in the file with several variations, but that didn't help (either a blank page or still only going to the old code location, depending on the details). Does someone know enough about nginx config syntax to help me rearrange it so that it does what I want?
If your new code only uses /index.php and without any path_info, you could use a prefix location:
location ^~ /index.php { ... }
location ~* \.php { ... }
The first location takes precedence due to the ^~ operator. Or an exact match (which also takes precedence):
location = /index.php { ... }
location ~* \.php { ... }
I am attempting to configure an Nginx server block in such a manner that it achieves two objectives:
To have a subdomain example.domain.com that serves an index page and pages from various paths such as /app1 and /app2; with all of these pages/paths sharing a common root of /srv/www/example.
To have the subdomain in the previous objective serve pages from a path such as /app3, but in this case having a root of /srv/www/example/app3/web.
I was able to achieve the first and second objectives, but never at the same time. Some resources I have made use of include:
Programming Junk: Nginx multiple sites in subdirectories
Martin Fjordvald: How to solve “No input file specified" with PHP and Nginx
CakePHP in a subdirectory using nginx (Rewrite rules?)
Here is my current configuration that is currently only serving the index, /app1, and /app2 correctly as a result of moving the root directive up out of the location / { directive.
server {
listen 80;
root /srv/www/example;
index index.php index.html index.htm;
server_name example.domain.com;
location /app3/ {
root /srv/www/example/app3/web;
try_files #app3 #app3;
}
location ~ /app3/.+\.(jpg|jpeg|gif|css|png|svg|js|ico|)$ {
root /srv/www/example;
}
location #app3 {
include /etc/nginx/fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_param SCRIPT_FILENAME /srv/www/example/app3/web/index.php;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /srv/www/example/app3/web;
}
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
}
What do I need to change to achieve both objectives in a single server block? If there is some way to get this working with multiple server blocks that both access the same subdomain and listen on the same port that would also be acceptable.