Niginx location with cache for a specific url with params - caching

I'd like to use nginx cache for a specific url only
The url is /ajax/airport and must contain the parameter ?geoloc=1.
Cache is working fine, the only issue I'm facing is to get it working for an url containing the given parameters.
Here is my nginx site.conf file:
server {
listen 80;
server_name _;
server_tokens off;
location /ajax/airport.php {
if ($args_geoloc = 1) {
proxy_pass http://127.0.0.1:8080/ajax/airport.php;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache my-cache;
proxy_cache_valid 300s;
#proxy_no_cache $cookie_PHPSESSID;
#proxy_cache_bypass $cookie_PHPSESSID;
proxy_cache_key "$scheme$host$request_uri";
add_header X-Cache $upstream_cache_status;
add_header LEM airport;
}
}
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header LEM all;
}
}
server {
listen 8080;
.. usual location handeling ...
And the error I get:
nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /etc/nginx/sites-enabled/site.com.conf:8
Thank you for your help!

Simply use proxy_no_cache and proxy_cache_bypass instead of if, testing the value of $arg_geoloc (not $args_geoloc) with map directive.
map $arg_geoloc $bypass {
default 1;
1 0;
}
server {
...
location /ajax/airport.php {
...
proxy_no_cache $bypass;
proxy_cache_bypass $bypass;
...
# No need to add /ajax/airport.php in proxy_pass
proxy_pass http://127.0.0.1:8080;
}
...
}
Nginx also allows to test several parameters with proxy_no_cache and proxy_cache_bypass. If you need something like that just put the parameters one after another:
proxy_no_cache $cookie_PHPSESSID $bypass_cache;
proxy_cache_bypass $cookie_PHPSESSID $bypass_cache;

Related

NGINX as reverse proxy - forwarding not working

I've the following:
HTTPS access to a NAS or something like that.
NGINX as reserve proxy as container
Container with a Tomcat as appcontainer.
NAS forwards HTTPS request as HTTP to NGINX container. Then NGINX container forwards HTTP request to my appcontainer.
I can access to my appcontainer login page but after login a POST is made as follows
Nginx access.log
POST /foo/login.do HTTP/1.1" 302 0 "https://nas.dns.server/foo/login.do
In localhost_access.log in appcontainer tomcat shows
POST /foo/doLogin.do HTTP/1.0" 302
And request as HTTP to the NAS
It seems that is ignoring X-Forwarded-Proto header.
My nginx.conf is configured as follows:
server {
listen 80;
server_name $hostname;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
error_log /dev/stdout info;
access_log /dev/stdout;
client_max_body_size 100M;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;
resolver 127.0.0.11 valid=30s;
sendfile on;
location /foo {
proxy_set_header Origin "";
set $appcontainer http://appcontainer:8080;
proxy_pass $appcontainer;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $https; #I’ve also tested with $scheme
}
}
Thanks
Having a look to the Developer Tool of Chrome in the Network tab in can see that for the call of login.do there is Request URL: https://entry.proxy.url/foo/doLogin.do but in the Response Headers I can see what is generating the problem Location: http://proxy.entry.url/foo/login.do that must be Location: https://proxy.entry.url/foo/login.do .
I've tried doing redirection as proxy_redirect http://entry.proxy.url/ https://csprocure.ciport.be/; in the location and it works.
So location is set as:
location /foo {
proxy_set_header Origin "";
set $appcontainer http://appcontainer:8080;
proxy_redirect http://proxy.entry.url/ https://proxy.entry.url/;
proxy_pass $appcontainer;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $https; #I’ve also tested with $scheme
}

Plesk forbidden 403 getting bootstrap style (nginx)

I have PLESK installed in my host and I create a subdomain "app.mysite.com". In this subdomain, I upload my codeigniter proyect with this structure:
When I try to access "css" folder to get boostrap.min.css file (app.mysite.com/css/bootstrap/css/bootstrap.min.css), I get this forbidden error:
This is the additional directives for HTTP of this site:
And this other one is for HTTPS:
This website, redirect automatically from HTTP to HTTPS.
To finish, I add this code to additional nginx directives:
Other test
I try changing "additional nginx directive", to remove index.php from the URL:
But no style files are loaded and codeigniter read the url as controller call returning "404 page not found":
Please, I need help with this issue and how to configure correctly nginx to access css/, js/ and img/ folders files.
Thank you
/EDIT
I find the nginx.conf file of app.mysite.com subdomain:
#ATTENTION!
#
#DO NOT MODIFY THIS FILE BECAUSE IT WAS GENERATED AUTOMATICALLY,
#SO ALL YOUR CHANGES WILL BE LOST THE NEXT TIME THE FILE IS GENERATED.
server {
listen 206.189.5.184:443 ssl http2;
server_name app.mysite.com;
server_name www.app.mysite.com;
server_name ipv4.app.mysite.com;
ssl_certificate /opt/psa/var/certificates/scfMQnEev;
ssl_certificate_key /opt/psa/var/certificates/scfMQnEev;
ssl_client_certificate /opt/psa/var/certificates/scfcJsJQ3;
client_max_body_size 128m;
root "/var/www/vhosts/mysite.com/app.mysite.com";
access_log "/var/www/vhosts/system/app.mysite.com/logs/proxy_access_ssl_log";
error_log "/var/www/vhosts/system/app.mysite.com/logs/proxy_error_log";
location / {
proxy_pass https://206.189.5.184:7081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
access_log off;
}
location ~ ^/(plesk-stat|awstats-icon|webstat|webstat-ssl|ftpstat|anon_ftpstat) {
proxy_pass https://206.189.5.184:7081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
access_log off;
}
location #fallback {
proxy_pass https://206.189.5.184:7081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
access_log off;
}
location ~ ^/(.*\.(ac3|avi|bmp|bz2|css|cue|dat|doc|docx|dts|eot|exe|flv|gif|gz|htm|html|ico|img|iso|jpeg|jpg|js|mkv|mp3|mp4|mpeg|mpg|ogg|pdf|png|ppt|pptx|qt|ra$
try_files $uri #fallback;
}
location ~ ^/~(.+?)(/.*?\.php)(/.*)?$ {
alias /var/www/vhosts/mysite.com/web_users/$1/$2;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass "unix:///var/www/vhosts/system/app.mysite.com/php-fpm.sock";
include /etc/nginx/fastcgi.conf;
}
location ~ ^/~(.+?)(/.*)?$ {
proxy_pass https://206.189.5.184:7081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
access_log off;
}
location ~ \.php(/.*)?$ {
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass "unix:///var/www/vhosts/system/app.mysite.com/php-fpm.sock";
include /etc/nginx/fastcgi.conf;
}
location ~ /$ {
index "index.html" "index.cgi" "index.pl" "index.php" "index.xhtml" "index.htm" "index.shtml";
}
add_header X-Powered-By PleskLin;
include "/var/www/vhosts/system/app.mysite.com/conf/vhost_nginx.conf";
}
server {
listen 206.189.5.184:80;
server_name app.mysite.com;
server_name www.app.mysite.com;
server_name ipv4.app.mysite.com;
client_max_body_size 128m;
return 301 https://$host$request_uri;
}

Maintaining structure with Nginx and multiple NodeJS applications

I'm trying to host multiple Node JS servers proxied through Nginx, which is working correctly. One server is hosted at '/', with another hosted at, for example, '/one'. The relevant Nginx config for this setup is below.
upstream host_com {
server 127.0.0.1:3000;
keepalive 8;
}
upstream one_host_com {
server 127.0.0.1:3010;
keepalive 8;
}
server {
listen 80;
access_log /var/log/nginx/host.log;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://host_com/;
proxy_redirect off;
}
location /one {
rewrite ^(/one)+/(.*)$ /$2 break;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $proxy_host; #$http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://one_host_com/;
proxy_redirect off;
}
}
However, when I do an AJAX call from the '/one' testbed, like below:
$.getJSON( '/get_stuff', function(data) { .. });
The post goes to '/get_stuff' when I want it to go to '/one/get_stuff'. How can I get Nginx to direct to NodeJS but still maintain the location? Is there a better way to implement this?
Try removing the leading slash in your JavaScript, e.g. $.getJSON( 'get_stuff', function(data) { .. });. By including the leading slash you are asking for a path at the root of the domain but I think you want the path relative to the url you are presently at.

nginx conditional proxy pass

i am trying to configure nginx to proxy pass the request to another server,
only if the $request_body variable matches on a specific regular expression.
My problem now is, that I don't how to configure this behaviour exactly.
I am currently down to this one:
server {
listen 80 default;
server_name test.local;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
if ($request_body ~* ^(.*)\.test) {
proxy_pass http://www.google.de;
}
root /srv/http;
}
}
but the problem here is, that root has always the upperhand.
the proxy won't be passed either way.
any idea on how I could accomplish this?
thanks in advance
try this:
server {
listen 80 default;
server_name test.local;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
if ($request_body ~* ^(.*)\.test) {
proxy_pass http://www.google.de;
break;
}
root /srv/http;
}
}
Nginx routing is based on the location directive which matches on the Request URI. The solution is to temporarily modify this in order to forward the request to different endpoints.
server {
listen 80 default;
server_name test.local;
if ($request_body ~* ^(.*)\.test) {
rewrite ^(.*)$ /istest/$1;
}
location / {
root /srv/http;
}
location /istest/ {
rewrite ^/istest/(.*)$ $1 break;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://www.google.de;
}
}
The if condition can only safely be used in Nginx with the rewrite module which it is part of. In this example. The rewrite prefixes the Request URI with istest.
The location blocks give precedence to the closest match. Anything matching /istest/ will go to the second block which uses another rewrite to remove /istest/ from the Request URI before forwarding to the upstream proxy.

Nginx Proxy for a GitHub Page?

We have a blog that we host on github with Jekyll; it is there : http://blog.superfeedr.com
Ideally, I want it to be at http://superfeedr.com/blog/ because we need to add some AJAX and we need to avoid the "Same Origin Policy" problems.
We use Nginx on our "main" webserver, and I have the following setup :
location /blog/ {
proxy_pass http://blog.superfeedr.com/;
proxy_redirect off;
proxy_max_temp_file_size 0;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
Unfortunately, as you can see if you go to http://superfeedr.com/blog/ this obviously doesn't work. Oddly enough, we're redirected to Github's homepage.
PS: obviously, we could host the blog on our main server, but the goal is to host it on a different host so that we can almost guarantee it to be online if the site is down...
First, nginx does not send Host header to the blog.superfeedr.com. This makes it send all the required headers:
proxy_set_header Host blog.superfeedr.com;
proxy_set_header X-Host blog.superfeedr.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Second, some url rewriting required. By some weird reason this depends on the version of nginx you are using. Anyway,
for 0.6.x (0.6.32 for me) this should work:
location /blog {
rewrite ^/blog(.*)$ /$1 last;
error_page 402 = #blog;
return 402;
}
location #blog {
proxy_pass http://blog.superfeedr.com;
# the rest of proxying parameters should be here
proxy_set_header Host blog.superfeedr.com;
proxy_set_header X-Host blog.superfeedr.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
You also need to cover all the paths the blog refers to (css, images etc), e.g.
location /css {
error_page 402 = #blog;
return 402;
}
For 0.7.59:
location /blog {
set $blog 1;
rewrite ^/blog(.*)$ /$1 last;
}
location /css {
set $blog 1;
error_page 402 = #blog;
return 402;
}
location / {
if ($blog) {
error_page 402 = #blog;
return 402;
}
# here is where default settings for / should be
root /usr/local/www/nginx/;
}
location #blog {
proxy_pass http://blog.superfeedr.com;
# the rest of proxying parameters should be here
proxy_set_header Host blog.superfeedr.com;
proxy_set_header X-Host blog.superfeedr.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Another way to do this (but without involving nginx) could be with a DNS directive. I think most DNS services offer URL forward service.
For example, in hover.com, first add blog with A directive to 64.99.80.30 under DNS tab, and then in the Forward tab, add blog forward to http://superfeedr.com/blog/
In dnsimple.com, it's simpler, just add blog URL record to forward to http://superfeedr.com/blog/
These forwards, I believe, also work for https:// type URLs.

Resources