Nginx - variable usage (set vs map) context and usage - variables

In Nginx configurations,
I do not know when / where I can use map or set.
I want to do something like this:
I tried using map:
map $host $proxy_destination_include {
default '/etc/nginx/conf.d/params/proxy.params/proxy_params_destination.conf';
}
Or tried using set:
server {
### I want to use this as either a variable / map ###
set $proxy_destination_include /etc/nginx/conf.d/params/proxy.params/proxy_params_destination.conf;
root /var/www/html;
location / {
set_proxy_header X-Forwarded-Location-Site 'static-value';
include $proxy_destination_include;
}
location /otherlocation {
set_proxy_header X-Forwarded-Location-Site 'static-value-2';
include $proxy_destination_include;
}
}
But I think map can only be used when a 'site request' is done? So since it has not been mapped Nginx cannot successfully compile its settings - sudo nginx -t fails
Is there any way to do this using Nginx and 'variables'?

Related

NGINX - Limit access to folder to a list of user from ldap authentication

A have an nginx reverse proxy behind ldap authentication.
I can read username in php from variable $_SERVER['PHP_AUTH_USER']. I think this means that username is passed from ldap to nginx and than to php.
Is it possible in nginx configuration to allow access to a folder only to a list of users?
UPDATE
In nginx the user is stored in $remote_user variable. Is it possible to compare $remote_user with a list of users stored in a file? And then deny or allow access to a folder?
UPDATE
Probably I have to use map directive, for example:
map $remote_user $allowed_user {
default 0;
user1 1;
user2 1;
}
and then test it in the appropriate location:
location /folder/ {
if($allowed_user != 1){
return 403;
}
proxy_pass http://site;
}
but when I do sudo nginx -t, I receive the following error:
nginx: [emerg] unknown directive "if($allowed_user" in /etc/nginx/nginx.conf:104
nginx: configuration file /etc/nginx/nginx.conf test failed
You can do it via map directive (please note that map translate definitions block should be placed in the http context outside the server block):
map $remote_user $deny
username1 0;
username2 0;
...
usernameN 0;
default 1;
}
server {
...
location /folder/ {
if ($deny) { return 403; }
...
}
}
You can pre-generate users list in the above form (username1 0; username 2 0; ...) and then include this list to the nginx configuration:
map $remote_user $deny {
include /path/userlist.txt;
default 1;
}
Whenever this user list file get changed you'd need to reload nginx configuration (nginx -s reload).

Get the original filename of symlinks in nginx

From another script i got some generated symlinks.
2QGPCKVNG1R -> /anotherdir/movie1.mp4
HJS7J9ND2L5 -> /anotherdir/movie2.mp4
LKA6A9LA7SK -> /anotherdir/movie3.mp4
Displaying these files in NGINX works fine, but I'd like to rename the files at download via content disposition.
Question is how do i get the original filename in nginx variable?
I'm not sure it is possible at all. Is that another script yours or under your control? You can generate an additional nginx config file with a map block with the same script where you can describe a ruleset for mapping an URI value to the Content-Disposition header value (or you can write an additional script to do it with readlink -f <symlink> command:
map $uri $content_disposition {
~/2QGPCKVNG1R$ movie1.mp4;
~/HJS7J9ND2L5$ movie2.mp4;
~/LKA6A9LA7SK$ movie3.mp4;
}
And then include that file to the main nginx config:
include /path/to/content-disposition-map.conf;
server {
...
add_header Content-Disposition $content_disposition;
Another way I see is to use lua-nginx-module and a LUA script like
map $symlink_target $content_disposition {
~/([^/]*)$ $1;
}
server {
...
set_by_lua_block $symlink_target {
local result = io.popen("/bin/readlink -n -f " .. ngx.var.request_filename)
return result:read()
}
add_header Content-Disposition $content_disposition;

How to create a CDN for an application running on localhost/Ip address without a domain (.com)

To improve the performance of the application , I want to host my static assets on CDN. But we have not yet created a domain using nginx. How to still use a cdn like - express-simple-cdn link -
https://www.keycdn.com/support/express-cdn-integration
i need to write this domainName.com in my app.js file of Angular app through which i host my application--
// Initialize Express in a variable in app.js
var app = express();
// Define Your CDN base path
var CDN = "https://assets.preisheld.ch";
// Register a local variable in your app which contains the CDN function
app.locals.CDN = function(path, type, classes, alt) {
if(type == 'js') {
return "<script src='"+CDN+path+"' type='text/javascript'></script>";
} else if (type == 'css') {
return "<link rel='stylesheet' type='text/css' href='"+CDN+path+"'/>";
} else if (type == 'img') {
return "<img class='"+classes+"' src='"+CDN+path+"' alt='"+alt+"' />";
} else {
return "";
}
};
How to utilize CDN in such a situation ?
So is there a dummy a place where you can create your domainName.com address for free while opening it in your local ip address
Yes! That's the hosts file. You can find it on your system here:
Windows: C:\Windows\System32\Drivers\etc\hosts
Linux: /etc/hosts
OS X: /private/etc/hosts
This file allows you to map arbitrary host names to network addresses, overriding anything that comes from DNS. For example:
127.0.0.1 yourproject.test
Now, if you go to http://yourproject.test in your browser, it will resolve to 127.0.0.1 and connect the web server running on your loopback address. If you're using IPv6, use ::1 instead of 127.0.0.1.
You can set any hostnames you want... even real ones that exist. However, it is strongly recommended that you use the .test top-level domain, as it's specifically reserved for testing purposes.

Disable a hash URL (like http://localhost/#/login) without changing frontend code

I want to disable a hash URL (like http://localhost/#/login)
But I can not change the frontend code.
Can I solve it in some other ways (like Nginx or Apache Config)?
According to the spec the hash part of the URI is processed on the client-side, and does not get sent to the server.
So, unfortunately not.
reference
It can redirect the #/foo hash URL in this demo
https://jsfiddle.net/yaoyuan/exLwhy57/1/
Install Nginx.
Use https://github.com/denji/homebrew-nginx for Mac
Install Nginx module for Mac
https://denji.github.io/homebrew-nginx/#modules
brew reinstall nginx-full --with-sub-module; Then we can use the sub_filter expression
https://nginx.org/en/docs/http/ngx_http_sub_module.html
delete the js code in demo1.we get demo2 https://jsfiddle.net/yaoyuan/exLwhy57/2/;
use this nginx config
location / {
root html; (use your folder)
index index.html index.htm;
sub_filter </head>
'</head><script>
function redirect() {
if (location.hash === "#/foo") {
window.location.replace("https://example.com");
}
}
window.onhashchange = function() {
if (location.hash === "#/foo") {
window.location.replace("https://example.com");
}
}
redirect();
</script>';
sub_filter_once on;
}
run nginx -c nginx.config to use this config
We can find a new snippet in the HTML, then we solve the question.

Using Varnish with multiple apache named vhosts

I'm implementing Varnish (4.0) for a server with lots (1000+) of named virtual hosts (on Apache), from which most of them point to the same IP- and web. I get Varnish to work fine with:
backend default {
.host = "127.0.0.1";
.port = "80";
}
sub vcl_recv {
if (req.http.host ~ "^www.domain1.de(:[0-9]+)?$") {
set req.http.host = "www.domain1.de";
} else if (req.http.host ~ "^www.domain2.de(:[0-9]+)?$") {
set req.http.host = "www.domain2.de";
}
....
....
set req.backend_hint = default;
}
but, to do this for 1000+ domains seems a bit odd. I don't need any special configuration for the sites, they have all the same backend.
If I don't add any specific configuration, I only get to the standard website (no matter what domain I enter).
Any hint on how to solve that?
Thanks!
If you wish to remove the port name for example, or need to do some changes in general to the req.http.host you can use the regsub() method in your varnish VCL:
set req.http.host = regsub(req.http.host , "(.*)(:[0-9]+|)" , "\1" );
This example removes the port number if present.
Please set up the regexp according to your needs as your question does not really state what you are trying to achieve.
Note that you can invoke the replacement strings via \N and not as $1 as some man pages suggest. (A bug has already been filed to address this issue.)
And for last a nice Varnish regexp cheat-sheet:
http://kly.no/varnish/regex.txt