NGINX Location Blocks for PHP subpaths - php

I am trying to filter a path to specifically do the following (in this order I think):
Allow all traffic from everywhere in the world to the path /PROD/index.php?/report (and anything after /report like the examples below) and block traffic to anywhere else
ALLOW: /PROD/index.php?/report
ALLOW: /PROD/index.php?/report/
ALLOW: /PROD/index.php?/report/werwf
DENY: /PROD/index.php?/{anything else}
Allow all traffic from any IP address in the range we own (denoted by x.x.x.x/16)
The current NGINX config I have is:
server {
listen 443 http2 ssl;
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
ssl_certificate /etc/nginx/ssl/fsmunkireport.stockton.edu.cer;
ssl_certificate_key /etc/nginx/ssl/fsmunkireport.stockton.edu.key;
#ssl_dhparam /etc/nginx/ssl/dhparam.pem;
location = / {
return 301 https://fqdn/PROD/index.php?;
}
location ~ ^\/PROD\/index.php\?\/report(.*) {
allow all;
index index.php;
autoindex on;
location ~* \.php$ {
try_files $uri =404;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME /secure/PPRD/$fastcgi_script_name;
include fastcgi_params;
include fastcgi.conf;
}
}
location /PROD {
allow x.x.x.x/16;
deny all;
index index.php;
autoindex on;
location ~* \.php$ {
try_files $uri =404;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME /secure/PPRD/$fastcgi_script_name;
include fastcgi_params;
include fastcgi.conf;
}
}
}
The issue I am running into is filtering through that php subpath. Since it isn't a literal directory I think I am just confusing myself. Basically at this point all traffic is allowed via NGINX which isn't the desired behavior.
Any assistance would be greatly appreciated.

Related

NGINX config for php backend and JS frontend

I'm trying to serve my frontend app under /, but have requests for /oauth2 pass off to a php backend. Here is my latest nginx config attempt:
upstream dockerphp {
server backendphp:9000;
}
server {
listen 80;
server_name localhost;
index index.html;
root /application/frontend/build;
location /oauth2 {
root /application/public;
index index.php;
try_files $uri $uri/ /index.php$is_args$args;
#try_files /index.php$is_args$args =404;
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass dockerphp;
fastcgi_index index.php;
}
}
location / {
try_files $uri $uri/ /index.html;
}
}
I've tried just about every combination of config I can think of and just can't get it to work. Most of the time I end up with 404s.
Both my nginx and php docker containers have the same /application directory mounted.
With the above config, any requests to /oauth2/blah are being picked up by the location block at the bottom and therefore back to my frontend. This is probably my biggest problem - the /oauth2 location block to my mind is more "specific" so why isn't it "winning"?
I tried the commented out try_files line instead (to see whether index.php being the "fallback" value had an effect on specificity), and nginx just started downloading the index.php file rather than passing on the request. Help?
This is the approach that I use:
attempt to serve js / static pages first
if 1.) fails, pass to PHP backend
define a location for handling .php
upstream dockerphp {
server backendphp:9000;
}
server {
listen 80;
server_name localhost;
index index.html;
root /application/frontend/build;
location / {
try_files $uri $uri/ #php;
}
location #php {
root /application/public;
index index.php;
try_files $uri $document_root/index.php?$query_string;
# $document_root/index.php is the important part due to how root and alias directives work
}
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass dockerphp;
fastcgi_index index.php;
}
}
The location /oauth2 only wins when the URL you try is exactly website.com/oauth2. Add ^~ and the route will win all of the URLs starting with /oauth2, like this:
location ^~ /oauth2 {
For reference I eventually found a simple working solution (below).
upstream dockerphp {
server backendphp:9000;
}
server {
listen 80;
server_name localhost;
index index.html;
root /application/frontend/build;
location / {
try_files $uri $uri/ /index.html;
}
location /oauth2 {
try_files $uri $uri/ #php;
}
location #php {
include /etc/nginx/fastcgi_params;
fastcgi_pass dockerphp;
fastcgi_param SCRIPT_FILENAME /application/public/index.php;
}
}

apache website to NGINX website

So recently my company started running websites on nginx instead of apache. Our application makes use of codeigniter.
So after uploading the source code a lot of url's werent working and i managed to get everything to work for codeigniter.
But we have a part of the website that doesnt work and also isnt codeigniter its a piece of code by itself /simplesaml/module.php/saml/sp/saml2-acs.php/surfconext-uvt. It used to create simplesaml requests and login.
The config file right now is:
server
{
listen X.X.X.X:443 ssl http2;
server_name X;
access_log /var/log/nginx/domains/X.log;
access_log /var/log/nginx/domains/X.nl.bytes bytes;
error_log /var/log/nginx/domains/X.nl.error.log;
root /home/u10024/domains/X.nl/private_html;
index index.php index.html index.htm;
location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ {
expires max;
log_not_found off;
}
location /simplesaml {
rewrite ^/simplesaml/(.*) /simplesamlphp/www/$1 break;
}
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$
{
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include /etc/nginx/fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/nginx_limits.conf;
if (-f $request_filename)
{
fastcgi_pass unix:/usr/local/php71/sockets/u10024.sock;
}
}
ssl on;
ssl_certificate /usr/local/directadmin/data/users/u10024/domains/X.nl.cert.combined;
ssl_certificate_key /usr/local/directadmin/data/users/u10024/domains/X.nl.key;
include /usr/local/directadmin/data/users/u10024/nginx_php.conf;
include /etc/nginx/webapps.ssl.conf;
}
I know close to nothing about nginx and am struggling to understand what i need to do here... Some help would be highly appreciated.

When should I use php-fpm, php-cli, php-mbstring with phpmyadmin/nginx config

After following many tutorials on nginx for a basic phpymadmin setup, I have concluded that I am confused as to why certain tutorials recommend certain php modules while others do not.
My working configuration is with php7-fpm, php7-mbstring.
server {
listen 80;
listen [::]:80;
server_name name ip;
root /var/www/html/phpmyadmin;
index index.php;
location / {
try_files $uri $uri/ =404;
}
location ~ ^/(.*\.php)$ {
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $request_filename;
include /etc/nginx/fastcgi_params;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_index index.php;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
Most tutorials suggest php-fpm, php-cli, and another module.
Do I need these, and why would I need these modules for phpmyadmin?
Is my nginx configuration the correct way to have it function properly (not the most secure), or should I add any other locations/modules to my nginx configuration such as,
location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
root /path/;

Does nginx fastcgi_pass support variables?

I would like to use dynamic host resolution with nginx and fastcgi_pass.
When fastcgi_pass $wphost:9000; is set in the conf then nginx displays the error
[error] 7#7: *1 wordpress.docker could not be resolved (3: Host not found),
but when I set fastcgi_pass wordpress.docker:9000;it is working except for the fact the that after a wordpress restart nginx still points to an old ip.
server {
listen [::]:80;
include /etc/nginx/ssl/ssl.conf;
server_name app.domain.*;
root /var/www/html;
index index.php index.html index.htm;
resolver 172.17.42.1 valid=60s;
resolver_timeout 3s;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args; ## First attempt to serve request as file, then as directory, then fall back to index.html
}
#error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
set $wphost wordpress.docker;
# pass the PHP scripts to FastCGI server listening on wordpress.docker
location ~ \.php$ {
client_max_body_size 25M;
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass $wphost:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
}
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
access_log off;
log_not_found off;
expires 168h;
}
# deny access to . files, for security
location ~ /\. {
access_log off;
log_not_found off;
deny all;
}
}
I have different virtual host configuration where I use proxy_pass http://$hostname; and in this setup everything is working as expected and the host is found.
After trying different options I wonder if fastcgi_pass does support variables
It does work if you pass the upstream as a variable instead, for example:
upstream fastcgi_backend1 {
server php_node1:9000;
}
upstream fastcgi_backend2 {
server php_node2:9000;
}
server {
listen 80;
server_name _;
set $FASTCGI_BACKEND1 fastcgi_backend1;
set $FASTCGI_BACKEND2 fastcgi_backend2;
location ~ ^/site1/index.php$ {
fastcgi_pass $FASTCGI_BACKEND1;
}
location ~ ^/site2/index.php$ {
fastcgi_pass $FASTCGI_BACKEND2;
}
}

How to correctly configure Nginx for PHP (Yii framework and Zurmo)

I am trying to setup Zurmo CRM on my local machine (Win8x64). After installing all the requirements I want to get started with the actual installation. The problem is that it seems the paths are not correctly passed from NGinx to FastCGI PHP. Here is my Nginx serve configuration:
server {
listen 80;
server_name zurmo.local;
root html/zurmo.local;
set $index "index.php";
charset utf-8;
location / {
index index.html $index;
try_files $uri $uri/ /$index?$args;
}
location ~ ^/(protected|framework|themes/\w+/views) {
deny all;
}
location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
try_files $uri =404;
}
location ~ \.php {
fastcgi_split_path_info ^(.+\.php)(.*)$;
set $fsn /$index;
if (-f $document_root$fastcgi_script_name){
set $fsn $fastcgi_script_name;
}
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fsn;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fsn;
}
location ~ /\.ht {
deny all;
}
}
As a result, when I make a call to zurmo.local (which is added to hosts file) i get "This webpage has a redirect loop" with a URI that looks like this http://zurmo.local/app/app/ [...] /app/app/index.php If instead of $document_root$fsn and I comment the PATH_INFO and PATH_TRANSLATED than I get No input file specified. with a URI that looks like http://zurmo.local/app/app/index.php
Looking further into it, when I have added access_log html/zurmo.local/logs/access.log; the Nginx error.log shows me the following: [timestamp] [emerg] 4064#3660: CreateFile() "[path to stack]\nginx/html/zurmo.local/logs/access.log" failed (3: The system cannot find the path specified). As you can see the directory separator is not consistent.
One last note, my Nginx home directory is situated at nginx/html which is in fact a smlink to of ../home This is purely for keeping my file structure in a way that fits my day to day work.
How can I correctly configure Nginx in order to proceed (with the Zurmo installation) ?
I know this is an old question, but here is what I have done to make nginx + zurmo work.
server {
listen 80;
server_name zurmo.local;
root /home/www/zurmo.local;
access_log /var/log/nginx/zurmo.access.log main;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ ^/(protected|framework|themes/\w+/views) { deny all; }
location ~ /\. { deny all; access_log off; log_not_found off; }
location = /favicon.ico { log_not_found off; access_log off; }
location ~ \.(js|css|png|jpg|gif|ico|pdf|zip|rar)$ {
try_files $uri =404;
}
location ~ \.php {
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_read_timeout 600s;
fastcgi_send_timeout 600s;
}
}
I don't think you need the if() statement in your *.php block. In my nginx setups that's all i ever needed:
# Process PHP files
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# Include the standard fastcgi_params file included with nginx
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
}

Categories