Nginx proxy_pass to directory in if statement - nginx

what i want to do is reverse proxy b.com/c/d/1.jpg directory with a.com/1.jpg
location / {
proxy_ssl_server_name on;
if (!-e $request_filename) {
# below will cause error: cannot have URI part in location given by regular expression, or inside named location, or inside \"if\" statement,
# proxy_pass https://b.com/c/d;
proxy_pass https://b.com;
}
}
can anyone help? how to do this on right way. THX.

Replace if (!-e $request_filename) with a try_files statement, and place the proxy_pass into a named location. Use rewrite...break to adjust the URI before it's passed upstream.
For example:
location / {
try_files $uri $uri/ #proxy;
}
location #proxy {
rewrite ^/(.*)$ /c/d/$1 break;
proxy_ssl_server_name on;
proxy_pass https://b.com;
}

Related

problem using variable in nginx location directive

good evening. i have a question regarding nginx and it is related to the location directive. i currently have this configuration in nginx
server {
server_name ~^(?<account>.+)\.domain\.com$;
root /var/www/html/folder-frontend/;
index index.html;
error_log /var/log/nginx/$account-access.log;
access_log /var/log/nginx/$account-access.log;
location / {
try_files $uri /index.html;
}
location /$account-backend/ {
proxy_pass http://service-backend/;
proxy_set_header HOST $account-backend.domain.co;
proxy_http_version 1.1;
}
}
this means that I have several domains with the ending tenant.domain.com(app1.domain.com, app2.domain.com). with the expression (?.+) I am getting part of the string in the url that interests me and then in the location directive use it to make a proxypass and redirect the requests. but this is not working, I know because when I put in the location what interests me (in this case would be location /app1-backend/) if redirects to the backend service that I have listening in another nginx.
My doubt is, can I use a variable in the location directive of nginx? I tried it that way specified and it does not work.
No, you can't use a variable as location directive argument, even in a regex matching ones. You can try a workaround like
server {
server_name ~^(?<account>.+)\.domain\.com$;
root /var/www/html/folder-frontend/;
index index.html;
error_log /var/log/nginx/$account-access.log;
access_log /var/log/nginx/$account-access.log;
location / {
try_files $uri /index.html;
}
location ~ ^/(?<prefix>[^.]+)-backend(?<suffix>/.*) {
if ($prefix != $account) {
return 404;
}
proxy_pass http://service-backend$suffix$is_args$args;
proxy_set_header HOST $prefix-backend.domain.co;
proxy_http_version 1.1;
}
}

nginx url rewrite getting failed

I am trying to migrate my .htaccess rules to nginx. I have tried almost all the questions on SO & url rewriter as well but not getting success. In short i want to convert following dynamic urls:
from
[1] - https://vc.test/results.php?url=ngo-service
[2] - https://vc.test/jobs.php?d=17&t=oil-&-gas
[3] - https://vc.test/jobs.php?d=17
To
[1] - https://vc.test/ngo-service
[2] - https://vc.test/17/oil-&-gas
[3] - https://vc.test/17
Request help to sort out this issue.
My nginx effort
server {
listen 127.0.0.1:80;
listen 127.0.0.1:443 ssl http2;
ssl_certificate_key "d:/winnmp/conf/opensslCA/selfsigned/vc.test+4-key.pem";
ssl_certificate "d:/winnmp/conf/opensslCA/selfsigned/vc.test+4.pem";
server_name vc.test;
root "d:/winnmp/www/vc";
## Access Restrictions
allow 127.0.0.1;
deny all;
autoindex on;
location / {
index index.html index.htm index.php;
try_files $uri $uri.html $uri/ #extensionless-php;
if ($query_string ~* "fbclid="){
rewrite ^(.*)$ /$1? redirect;
break;
}
if ($query_string ~* "url="){
rewrite ^(.*)$ /%1? redirect;
rewrite ^/(.*)$ /results.php?url=$1 permanent;
break;
}
rewrite ^/([0-9]+)/(.*)?$ jobs.php?d=$1&t=$2 break;
rewrite ^/([0-9]+)?$ jobs.php?d=$1 break;
}
location #extensionless-php {
rewrite ^(.*)$ $1.php last;
}
location ~ \.php$ {
try_files $uri =404;
include nginx.fastcgi.conf;
include nginx.redis.conf;
fastcgi_pass php_farm;
fastcgi_hide_header X-Powered-By;
}
}
I don't know what your if ($query_string blocks are for, so I will ignore them.
Use rewrite...last if the rewritten URI is to be processed in a different location block, for example with URIs ending with .php. All Nginx URIs begin with a leading /, for example, use /jobs.php and not jobs.php.
You can place your list of rewrite statements in the location / block, and they will be evaluated in order until a match is found. If no match is found, the try_files statement will be evaluated. That's just how the rewrite module works!!
However, the 1st rewrite rule is too general and may break some of the URIs intended to be fulfilled by the try_files statement. A better solution may be to put all of the rewrite statements into the same named location block.
For example:
index index.html index.htm index.php;
location / {
try_files $uri $uri.html $uri/ #rewrite;
}
location #rewrite {
if (-f $document_root$uri.php) {
rewrite ^ $uri.php last;
}
rewrite ^/([0-9]+)/(.+)$ /jobs.php?d=$1&t=$2 last;
rewrite ^/([0-9]+)$ /jobs.php?d=$1 last;
rewrite ^/([^/]+)$ /results.php?url=$1 last;
return 404;
}
location ~ \.php$ {
try_files $uri =404;
...
}
See this caution on the use of if.

Nginx mp4 hotlink protection doesnt work

I am trying to block hotlinking of my mp4 with nginx "valid_referers" :
valid_referers none blocked mysite.com;
if ($invalid_referer) {
return 403;
}
But it doesnt work at all, the mp4 still display on the websites who are stealing the video and if I put some random domain instead of "mysite.com" the video still work.
If it can help, this is what my server conf file look like :
server {
listen 80;
server_name dl.mysite.com;
root /home/videos;
index index.php index.html;
autoindex off;
location ~ /\. {
deny all;
}
# serve static files directly
location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
access_log off;
expires max;
}
# streaming
location ~ \.mp4$ {
valid_referers none blocked mysite.com;
if ($invalid_referer) {
return 403;
}
gzip off;
gzip_static off;
mp4;
mp4_buffer_size 1M;
mp4_max_buffer_size 300M;
}
location ~ .flv$ {
flv;
}
# removes trailing slashes
if (!-d $request_filename)
{
rewrite ^/(.+)/$ /$1 permanent;
}
# canonicalize codeigniter url end points
if ($request_uri ~* ^(/lobby(/index)?|/index(.php)?)/?$)
{
rewrite ^(.*)$ / permanent;
}
# removes trailing "index" from all controllers
if ($request_uri ~* index/?$)
{
rewrite ^/(.*)/index/?$ /$1 permanent;
}
# unless the request is for a valid file (image, js, css, etc.), send to bootstrap
if (!-e $request_filename)
{
rewrite ^/(.*)$ /index.php?/$1 last;
break;
}
# catch all
error_page 404 /index.php;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_read_timeout 600;
include fastcgi_params;
}
}
I am doing something wrong ?
I had the same problem in past. I thought it was not working, but actually, it was working. Just make sure you are not allowing anyone except you.
Sometimes leechers try null or empty referrers to bypass this and there is no possible solution to this. One possible solution I can suggest to block the resource directory. See https://www.atulhost.com/hotlink-protection-nginx this man explained everything in a simple way.

Nginx Proxy_pass try_files drop to location handler

I'm running into small hick up with try_files in combination with proxy_pass (or alias for that matter).
Current config:
location /staticsrv {
alias /var/www/static/trunk/;
#proxy_pass http://static.localtest.nl/;
}
location ~ ^/staticsrv/images/gallery/(.*)$ {
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^(.*)$ /index.php/?c=media&m=index&imag=$uri;
}
However for every file it gets dropped to the rewrite rule as it doesn't exist.
Is there a "trick" (read correct config) to fix my misfortune? Or is it just not possible? Both domains will eventually be on the same server so we can work with alias and proxy_pass.
Thanks in advance
Your location ~ ^/staticsrv/images/gallery/(.*)$ needs a root or an alias to construct a local path for try_files to try. Also, you do not necessarily need a regular expression here:
location /staticsrv/images/gallery/ {
alias /var/www/static/trunk/images/gallery/;
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^ /index.php/?c=media&m=index&imag=$uri last;
}
proxy_pass will not work with try_files as one deals with remote content and the other with local content.
I try to avoid using alias and try_files in the same location block because of this open bug.
A possible work around would be to use another intermediate URI that closely matches the document root:
location /staticsrv/images/gallery/ {
rewrite ^/staticsrv(.+)$ /trunk$1 last;
}
location /trunk {
internal;
root /var/www/static;
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^ /index.php/?c=media&m=index&imag=$uri last;
}

nginx location directive not working as expected

The following configuration will rewrite /admin while proxy_pass /core, I can't figure out the reason. Any hint on this? Similar case like this Nginx: location regex for multiple paths with backend .
location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /\#$1 break;
}
}
location ~ ^/(admin|core)/ {
proxy_pass http://127.0.0.1:8080/$1;
}
Using try_files will simplify things.
location /
try_files $uri $uri/ =404;
}
location ~ ^/(?:admin|core)/ {
proxy_pass http://127.0.0.1:8080;
}
Try this variant:
location ~ ^/(admin|core)(.*)$ {
proxy_pass http://127.0.0.1:8080/$1;
}

Resources