Nginx - sending a static file for a specific location - http

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 {}

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).

Serving static website in nginx, wrong path for static files

I'm trying to use nginx to serve a static website that was given to me. Its folder structure is like this:
static_website/
index.html
www.example.com/
resources.example.com/
uploads.example.com/
The index.html file in the root is the one generated by httrack and it simply contains a redirect to www.example.com/index.html.
Inside the folder www.example.com are all the html files, in the other two folders are the css, javascript and image files.
Here is the nginx configuration:
server {
index index.php index.html index.htm;
server_name example.com;
location / {
root /var/www/static_website/www.example.com;
try_files $uri $uri/ =404;
index index.html;
}
}
I can navigate through the pages, but the css, javascript and image files are not loaded.
The path to one of the css files inside the html is like this:
href="../resources.example.com/style.css"
The only way I managed to get this working was to have the have the url like this:
example.com/www.example.com/
This way, all the path are correct. I'd like to avoid this and have simply example.com.
Is there a way to do this?
It looks like the site was originally intended to operate with ugly URLs like //example.com/www.example.com/.
But the path-relative URIs for the resources should work just fine relative to /, you just need to provide a location block which matches /resources.example.com/.
For example:
location / {
root /var/www/static_website/www.example.com;
try_files $uri $uri/ =404;
index index.html;
}
location /resources.example.com/ {
root /var/www/static_website;
}
I originally commented that you should try this:
location ~ \.(css|js|jpg|png|svg)$ {
root /var/www/static_website;
}
Which achieves a similar goal, but Nginx will process prefix locations more efficiently that regular expression locations.
I want to share my experience with this problem for others encountering similar issues as the solution was not so obvious to me
My setup and problem in particular had to do with cloudlflare settings which i was using to leverage TLS instead of handling it on the origin server for one of my 2 sites. if you are serving your site from a CDN that supports encryption and you use nginx on your origin consider the following setup:
# static1.conf
{ server_name static1.com; root: /var/www/static1/public; listen 80; listen 443; }
# static2.conf - no tls setup in nginx, figured id let cloudflare handle it
{ server_name static2.com; root: /var/www/static2/public; listen 80; }
static1 was setup at the origin with letsencrypt to handle tls connections
static2 was setup at the origin without any tls configuration
from left to right, here are the appropriate cloudlfare TLS modes which allowed me to access the correct files thru nginx
The distinction between full and flexible is that full mode lets the origin handle the certificate.
Initially I had the static2 site misconfigured as full, which lacked a listen directive for 443 causing nginx to serve static1 instead.
I realize the original question has nothing to do with cdn's or cloudflare but this scheme / protocol mismatch cost me a few hours and I am hoping to save someone else from similar grief
Honestly I am surprised nginx doesn't stick to matching on server_name and that oit implicitly matches on scheme as a fallback (or atleast appears to), even without a default_server specified - and without any meaningful messages in the logs to boot! Debugging nginx is a nightmare sometimes.

Nginx: serving static files from multiple locations (probably very easy to solve)

I have a very simple case of serving static files via nginx yet I can't figure it out.
I want all URLs beginning with /static/ to serve static files from directory /foo/bar/dir1 and if the file isn't there, serve from /foo/bar/dir2, if not there, return 404.
So for example when handling URL /static/some/file.png I want nginx to first try
/foo/bar/dir1/some/file.png
and then
/foo/bar/dir2/some/file.png
I know I should probably use something like this
location /static/ {
try_files .... something .....
}
but the documentation on try_files is very unclear to me. I tried a lot of combinations but nothing seems to work. Multiple alias directives would do the job but it won't work. I think the solution must be very simple but I cant get it right. It's kind of hard to debug how nginx resolves all these locations and files...
You can customize the root (make sure to update the try_files after). And also make sure there is no root directive in location /
location ~* ^/static/(.+)$ {
root /;
try_files /foo/bar/dir1/some/$1 /foo/bar/dir2/some/$1 =404;
}
Edit: Removed the need of the static folder.

Nginx match location for root path and all other paths separately

I am running Play framework server behind nginx server. At the root path, I am serving static website and all other paths should be redirected to the Play server. I have the following default.conf file in /etc/nginx/conf.d (The system is RHEL 6.7)
# to match the root path only to serve static website
location = / {
root /usr/share/nginx/html;
index index.html index.htm;
# try_files $uri $uri.html $uri/ /index.html;
}
# to match the cms login page
location /cms/ {
proxy_pass http://localhost:9000/;
}
# to match all the requests from the cms
location / {
proxy_pass http://localhost:9000/;
}
However, this configuration doesn't match the root path request. It gives 404 error. However, if I remove the third location rule, then it serves the static page at the root path.
Also, I noticed that first time I tried this, it worked. But now, it's not working any more. Please help.
The result you are getting is most likely due to the 2nd and 3rd location blocks not having "index" directives set. Except for well understood specific reasons, such as overriding the default index file type(s), the "index" should always be set at least within the server context or, preferably, within the http context. Similarly, the "root" directive should be set in the server context.
With your config, when a request hits the 3rd location block, there is no information your what to do with it. Actually, the 2nd block should not be needed from what you have described.
Also, as you are proxying to what appears to be another webserver, you need to ensure that this has the equivalent of "index" and "root" set.
Not sure exactly how the backend you are using works with respect to these. If not configurable there, then you must ensure that that every request hitting it has the URI spelt out fully.
To start with, depending on how exactly things are set up on your server, I will move the "index" and "root" directives up to the "server" level

Nginx location block for specific path and certain file types

I am having trouble defining a location block for certain paths and file types.
I am using wordpress and using a plugin which generates dynamic sitemaps..It redirects to path like sitemapindex.xml, which do not actually exist and nginx is trying to serve it statically.
I need to be able to pass this to apache
I need to send anything that is http://example.com/blog/*.xml to apache. This is what i am trying, which does not work.. so for instance:
http://example.com/blog/post.xml or http://example.com/blog/sitemapindex.xml
nginx config
server {
location ~* ^/blog/*.xml$ {
include /etc/nginx/proxy_params;
proxy_pass http://127.0.0.1:8080;
}
}
what is the correct syntax
Thanks
I had similar problem with my images. In my applications, images were being served from two different locations.
You can specify different sources based on url pattern. Your solution would then look something like this.
location ~* ^/blog/.+\.(xml)$ {
root /some/path/;
expires 90d;
}
location ~* \.(xml|js|jpg|png|css|html|otf|eot|svg|ttf)$ {
root /some/other/path/;
expires 30d;
index index.html;
}
Gotta escape that period
server {
location ~* ^/blog/.*\.xml$ {
proxy_pass http://127.0.0.1:8080;
}
}

Resources