stuck on nginx location directive - nginx

I am working on windows and using Winginx, modifying the nginx.conf file under conf folder. I have changed up the server block listening to port as follows:
server{
listen 127.0.0.1:80;
log_not_found off;
charset utf-8;
access_log logs/access.log main;
location /images/ {
root home/localhost/public_html;
index index.php index.html;
}
}
The images folder is under the home folder in winginx and is added as a domain through the hostseditor. However, when I use the URL http://images, I get the 404 error.
If the location directive is changed to:
location / {
}
Everything works fine then. Neither do any regular expressions work except if I match the '/'. I have read up on location directive but could not find any relevant reason. Would be great help if anyone could point out the error. Thanks.

The reason is that the location directive matches URI (absolute path of the Request-URI to be more precise), not Host.
When you use http://images, your browser sends request like this:
GET / HTTP/1.1
Host: images
Notice that request URI is /.

Related

Prevent NGINX from serving local index.html instead of passing to proxied server

Found other similar questions, but none seem to work in my circumstance.
I am attempting to proxy from NGINX to an IIS server which is hosting an archived website in its entirety. The site is coded with some hard index.html links and I don't want to go in and modify the site at all.
Any time the site is called with the /index.html in the URL directly it appears that NGINX is not proxying the location, but instead serving out a local index.html page.
Additionally, I am trying to default instead of to the index.html page when no page is entered (i.e. domain only) instead to pass to a default.htm page (set as default in IIS) which provides a disclaimer page that will require reading before continuing on to the original index.html of the website.
This is my nginx configuration file for the site. I do not want to change my overall structure around because it is what multiple sites use. I need a solution that I can add in.
upstream my_backend {
server 10.10.10.102:1011;
include snippets/shared_upstream_settings.conf;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name server.mydomain.com;
include snippets/shared_server_proxy_settings.conf;
location #proxy {
proxy_pass http://my_backend;
}
location / {
satisfy any;
allow 10.16.0.0/24;
deny all;
auth_basic "Authorized Users Only";
auth_basic_user_file secure/.htpasswd;
auth_request /auth-1;
try_files $uri #proxy;
}
(I don't believe any of the includes should matter for this particular issue)
This configuration works for about 15 other sites I have, but none of them apparently have a hardcoded index.html. Until today I never realized that NGINX will not proxy a direct link to index.html. So I need to either disable or work around that "feature" as well as direct no indicated pages to the disclaimer page.
thanks
The $uri argument in your try_files statement instructs Nginx to test for the existence of a file before branching to the #proxy block. There exists a local index.html file that satisfies that test.
You have two options:
Replace the try_files $uri #proxy; line with proxy_pass http://my_backend; as there is no need for a separate location #proxy block.
Or:
If you want to keep the second location block, change the try_files statement to:
try_files __nonexistent__ #proxy;
try_files requires a minimum of two arguments. All arguments before the final argument are filenames to be tested. __nonexistent__ is just one such name that probably does not exist on your file system (and also helps to document the author's intent).

Nginx reverse proxy return 502

I'm very new to nginx and server game and i'm trying to setup a reverse proxy. Basically what i need is when i enter my server ip it should open a particular website (Ex: https://example.com).
So for example if i enter my ip (Ex: 45.10.127.942) it should open the website example.com , but the url should remain as http://45.10.127.942.
I tried to set my server configuration as follows but it returns a 502 error.
server {
listen 80;
location / {
proxy_pass http://example.com;
}
}
It returns a 502 error. Can you please explain what i need to do?
You can have something like this in your configuration file:
server {
root /var/www/html;
server_name _;
location / {
try_files $uri $uri/ /index.html;
}
}
Place the index.html file in root folder specified.
Then just restart the NGINX and it should work.
What is the problem with your configuration file is you should not proxy_pass.
If you want to open the other website, you should have DNS record pointing to that IP. What actually happens is the thing you are trying to do is known as CLICKJACKING. For more details, search CLICKJACKING on google and you will find a lot of references.

How to route different webservers to different URL using nginx

creating a website for my self and need to host projects.
Basically, i hhave different projects with different framework. ie, Flask, Django, Node.JS and some html file projects. I would like to host them at projects.domain.com/<project name>
I tried to set server_name projects.domain.com/asdf but in error.log it says, server name "projects.domain.com/asdf" has suspicious symbols
Next up, i tried to nest location blocks (which i presume isn't how its supposed to be)
location /asdf {
location /static/ {
root blah blah;
}
location / {
..
proxy_pass http://localhost:3000 ;
}
}
But, this errors out saying location static is outside asdf
Some suggested to alias instead of root in the location /static/ block, but that doesnt work too.
Any help is appreciated :)
First of all a server_name can not contain URI segments. So a hostname or IP should be used as a value.
If you want to mix different local directories and proxy-locations a configuration could look like this.
Notice: Your location URI (/one, /two) will be appended to the root path.
The root directive can be used in every location block to set the document root.
http://nginx.org/en/docs/http/ngx_http_core_module.html#root
This is the reason why alias exists. With alias the location will not be part of the directory path. Check this out:
http://nginx.org/en/docs/http/ngx_http_core_module.html#alias
server {
server_name project.domain.com;
listen 80;
location / {
proxy_pass http://localhost:3000;
}
location /one/ {
alias/var/www/html/project1/;
index index.html;
}
location /two/ {
alias/var/www/html/project2/;
index index.html;
}
}

How can I hide a file from the browser, yet still use it on the webserver with NGINX?

Here's my scenario:
I have a vagrant cloud set up at an IAAS provider. It uses a .json file as its catalog to direct download requests from vagrant over to their corresponding .box files on the server.
My goal is to hide the .json file from the browser so that a surfer cannot hit it directly at, say: http://example.com/catalog.json and see the json output as that output lists the url of the box file itself. However, I still need vagrant to be able to download and use the file so it can grab the box.
In the NGINX docs, it mentions the "internal" directive which seems to offer what I want to do via try_files, but I think I'm either mis-interpreting what it does or just plain doing it wrong. Here's what I'm working with as an example:
First, I have two sub-domains.
One for the .json catalog at: catalog.example.com
A second for the box files at: boxes.example.com
These are mapped, of course, to respective folders on the server, etc.
With that in mind, in sites-available/site.conf, I have the following server blocks:
server {
listen 80;
listen [::]:80;
server_name catalog.example.com;
server_name www.catalog.example.com;
root /var/www/catalog;
# Use try_files to trigger internal directive to serve json files
location / {
try_files $uri =404;
}
# Serve json files to scripts only with content type header application/json
location ~ \.json$ {
internal;
add_header Content-Type application/json;
}
}
server {
listen 80;
listen [::]:80;
server_name boxes.example.com;
server_name www.boxes.example.com;
root /var/www/boxes;
# Use try_files to trigger internal directive to serve json files
location / {
try_files $uri =404;
}
# Serve box files to scripts only with content type application/octet-stream
location ~ \.box$ {
internal;
add_header Content-Type application/octet-stream;
}
}
The NGINX documentation for the internal directive states:
Specifies that a given location can only be used for internal requests. For external requests, the client error 404 (Not Found) is returned. Internal requests are the following:
requests redirected by the error_page, index, random_index, and try_files directives;
Based on that, my understanding is that my server blocks grab any path for those sub-domains and then, passing it through try_files, should make that available when called via vagrant, yet hide it from the browser if I hit the catalog or a box url directly.
I can confirm that the files are not accessible from the browser; however, they're also unaccessible to vagrant as well.
Am I mis-understanding internal here? Is there a way to achieve my goal?
Make sure for the sensitive calls the server listens on localhost only
Create a tunnel between the machine running vagrant (using an arbitrary port) and your IAAS provider machine (on the web server port, for example).
Create a user on your IAAS machine who is only allowed to interact with the forwarded web-server port (via sshd_config)
Use details from below
https://askubuntu.com/questions/48129/how-to-create-a-restricted-ssh-user-for-port-forwarding
Reference the tunneled server using http://:/path in both your catalog.json url and your box file url
Use a server block in your NGINX config which listens to the 127.0.0.1:80 only and doesn't use server_name. You can even add default_server to this so that anything that doesn't match other virtual host will hit this block
Use two locations in your config with different roots to serve files from /var/www/catalog and /var/www/boxes respectively.
Set regex locations for your .json and .box files and use a try_files block to accept the $uri or redirect to 444 (so you know it hit your block)
Deny the /boxes and /catalog otherwise.
See the below nginx config for example
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com;
server_name www.example.com;
root /var/www;
location ~ /(catalog|boxes) {
deny all;
return 403;
}
}
server {
listen 80;
listen [::]:80;
server_name store.example.com; # I will use an eCommerce platform eventually
root /var/www/store;
}
server {
listen 127.0.0.1:80;
listen [::]:80;
root /var/www;
location ~ \.json$ {
try_files $uri $uri/ =444;i
add_header Content-Type application/json;
}
location ~ \.box$ {
try_files $uri $uri/ =444;
add_header Content-Type octet/stream;
}
location ~ /(catalog|boxes) {
deny all;
return 403;
}
}
I think all you need here is to change the access level to the file. There is 3 access level (execute, read and write) you can remove the execute access level from your file. On the server consul run the command:
chmod 766 your_file_name
you can see:
here
and here
for more information.

Nginx - sending a static file for a specific location

I'm using nginx as a proxy (with location /) and trying to serve a static image for hotlink protection redirects under another location block. The following is what I am using to try to serve the image. I've moved the root directive outside of the location block which was necessary for nginx to build a proper path for some reason.
location = /hotlink.png {
autoindex off;
try_files hotlink.png hotlink.png
}
However, when I look at the log, it is still looking for an index.html by appending the URI to the root path: {root}/hotlink.png/index.html.
I simply want it to only send the file {root}/hotlink.png when /hotlink.png is matched and that's it.
Why is it still looking for an index with autoindex off? How can I fix this or is there a better way to handle this case in general?
After changing gears and coming back to this, I got it working by simply moving the autoindex off directive outside of the location block as well. It works with or without the try_files directive. I left it out for terseness and to avoid redundancy
root /path/to/static/files;
autoindex off;
location / {
# proxy
}
location = /hotlink.png {}

Resources