Failed to make 404 page in tornado with nginx - nginx

I tried to make custom 404 page for tornado and want to deploy it with nginx but failed.
here is my domain.conf(included by nginx.conf)
server {
listen 80;
server_name vm.tuzii.me;
client_max_body_size 50M;
location ^~ /app/static/ {
root ~/dev_blog;
if ($query_string) {
expires max;
}
}
location = /favicon.ico {
rewrite (.*) /static/favicon.ico;
}
location = /robots.txt {
rewrite (.*) /static/robots.txt;
}
error_page 404 /404.html;
location /404.html {
root /home/scenk;
internal;
}
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://frontends;
}
}
But after reload nginx, nothing happen. It seems like tornado catch the 404error before nginx.
I have no idea to solve this problem.
PS. I just want to make 404error by nginx. But not rewrite 'write_error' in tornado source.
Environment: Ubtuntu 12.04 Tornado2.4.1 runsite with supervisor by Nginx 4 process.

I ran into the same problem and what you actually need is this set:
proxy_intercept_errors on;
From nginx proxy module documentation:
proxy_intercept_errors
Syntax: proxy_intercept_errors on | off
Default: off
Context: http
This directive decides if nginx will intercept responses with HTTP status codes of 400 and higher.
By default all responses will be sent as-is from the proxied server.
If you set this to on then nginx will intercept status codes that are explicitly handled by an error_page directive. Responses with status codes that do not match an error_page directive will be sent as-is from the proxied server.

Finailly solve this problem. Because
proxy_pass_header Server;
So the real TornadoServer is sent. To hide real server, simply change
proxy_pass_header User-Agent;
That's all.

Related

Nginx in docker routing multiple applications

I have 3 apps that are located in 3 different sites:
auth (localhost:59500)
manage (localhost:59501)
files (localhost:59502)
Manage and files are accessed from a menu in auth
I can access them individually. However, I am unsure of how to set this up in nginx.
This is what I have currently in my nginx conf:
upstream auth {
server auth.web;
}
upstream manage {
server manage.web;
}
upstream files {
server files.web;
}
server {
listen 80;
server_name localhost;
server_tokens off;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
location /{
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_pass http://auth/;
}
location /auth/{
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_pass http://auth/;
}
location /manage/{
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_pass http://manage/;
}
location /files/{
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_pass http://files/;
}
}
My nginx is configured to run on http://localhost:9190
Currently, when I run http://localhost:9190, I get to auth without any issue and am able to login.
However, if I try to access http://localhost:9190/manage/Home, I am able to load the page but all my css shows the error 404. If any error appears, it doesnt go back to http://localhost:9190/manage/Home. Instead, it kicks me back to http://localhost:9190/Home
EDIT:
I have tried this but my css and js scripts still aren't loading. However, I am able to navigate to the manage app
location ^~ /manage{
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_pass http://manage/manage;
}
location ^~ /manage/{
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_pass http://manage/manage/;
}
EDIT2:
I realized that the error css and js files had a Content-Type of text/html
The files that managed to load somehow had application/javascript or text/css
Not sure how to change that.
I managed to find out the answer. There were two changes that needed to happen.
In my webapp, I needed to set a Pathbase in my Startup
app.UsePathBase("/manage");
Then in Nginx,
I needed to set the name in the location like this:
location /Manage/{
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_pass http://manage_svr/Manage/;
}

Odoo Nginx force users to use subdomain URL

I am using Odoo 10. I have implemented subdomain using Nginx with below script and it is working fine. However When I type IP address with port number like http://444.444.444.44:8085/web/database/manager, still im able to access this page. I want users forcibly use subdomain only as I provided xxx.mydomain.com. How can I achieve this plz help.
My script for each of my subdoain URL is as follows:
server {
listen 80;
listen [::]:80;
server_name xxx.mydomain.org;
root /usr/share/nginx/html;
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://127.0.0.1:8085;
proxy_redirect off;
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 $scheme;
proxy_connect_timeout 2000;
proxy_send_timeout 2000;
proxy_read_timeout 2000;
send_timeout 2000;
}
location ~* /web/database/manager {
deny all;
}
location ~* /web/database/selector {
deny all;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
Instead of of listening on every interface for Odoo process, use only localhost 127.0.0.1 interface to listen. To achieve that, modify the Odoo configuration file *.conf and add the following:
xmlrpc_interface = 127.0.0.1
Save the conf file and restart Odoo process. By default Odoo process listens to all interface, but this particular line in configuration file will ensure that Odoo process listens to 127.0.0.1 only, so anyone trying to browse from http://444.444.444.44:8085 will not find any response.

How to redirect all incoming http request to a specific url in nginx config file?

I know , I know. This question is asked too many times and I've researched it alot as well. But every solution on internet lead me to dead end.
I want to redirect all the incoming http-request to a specific url/domain.
For example if someone type - www.test.com or simply test.com in browser's url-bar, it should redirect the user to http://test.com/home .
This is what I've been trying to achieve from last 3 days, not sure what I'm doing wrong. This is my server-block.
server {
listen 80;
server_name test.com;
port_in_redirect off;
# server_name_in_redirect off;
client_max_body_size 20M;
location / {
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 $scheme;
proxy_redirect off;
proxy_pass http://localhost:8000/ ;
proxy_read_timeout 90;
return 301 http://test.com/home;
}
}
This above configuration is giving me error - too many redirection on browser when I'm trying to access the website.Also removing return statement giving me page not found error and not changing/redirecting the url to http.test.com/home.
PS - I'm running another different website as well on this same server on port 443(https) & that is working absolutely well. I'm running a Spring-boot application.
A help is highly appreciated.
You write too many codes related to redirection, that's why showing this error.
Change your server block like below.
server {
listen 80;
server_name test.com www.test.com;
client_max_body_size 20M;
#return 301 http://test.com/home$request_uri;
}
location ~ ^/(?!home) {
return 301 http://test.com/home$request_uri;
}
location /home {
root /var/www/test.com/html/;
index index.html index.htm;
}

Configure nginx proxy_pass with two parallel locations

Let's say we have the following quite minimal nginx.conf:
server {
listen 443 default ssl;
location /api/v1 {
proxy_pass http://127.0.0.1:8080;
}
}
Now, I'm trying to use nginx itself as an event-source. Another component in my system should be aware of any HTTP requests coming in, while ideally not blocking the traffic on this first proxy_pass directive.
Is there any possibility to have a second proxy_pass which "just" forwards the HTTP request to another component as well while completely ignoring the result of that forwarded request?
Edit: To state the requirement more clearly: What I want to achieve is that the same HTTP requests are sent to two different backend servers, only one of them really handling the connection in terms of nginx. The other should just be an "event ping" to notify the other service that there has been a request.
This can be done using echo_location directive (or similar, browse the directives) of the 3rd party Nginx Echo Module. You will need to compile Nginx with this module or use Openresty which is Nginx bundled with useful stuff such as this.
Outline code:
server {
[...]
location /main {
echo_location /sub;
proxy_pass http://main.server:PORT;
}
location /sub {
internal;
proxy_pass http://alt.server:PORT;
}
}
There is also the now undocumented post_action directive which does not require a third party module:
server {
[...]
location /main {
proxy_pass http://main.server:PORT;
post_action #sub;
}
location #sub {
proxy_pass http://alt.server:PORT;
}
}
This will fire a subrequest after the main request is completed. Here is an old answer where I recommended the use of this: NGinx - Count requests for a particular URL pattern.
However, this directive has been removed from the Nginx documentation and further usage of this is now a case of caveat emptor. Four years on from 2012 when I gave that answer, I wouldn't recommend using this.
I know this is done but I'd like to answer with the new, updated answer since it's turning up in searches 3 years later. The mirror module works wonderfully. I got this from the nginx docs so I assume it's official and available.
server {
[...]
location /main {
mirror /mirror
proxy_pass http://main.server:PORT;
}
location /mirror {
proxy_pass http://alt.server:PORT;
}
}
It's the big advantage of nginx: you can serve from multiple backend servers. You must just include one more location, referenced by another direction. Here you got a sample of my sites-available/default, that servers from fastcgi (monodevelop), glassfish (java), static content & special error threatment. Hope it helps.
#fastcgi
location ~* \.(aspx)$ {
root /home/published/;
index Default.aspx;
fastcgi_index Default.aspx;
fastcgi_pass 127.0.0.1:9000;
include /etc/nginx/fastcgi_params;
}
#Glassfish
location /GameFactoryService/ {
index index.html;
add_header Access-Control-Allow-Origin $http_origin;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-NginX-Proxy true;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:18000/GameFactoryService/;
}
#static content
location / {
root /usr/share/nginx_static_content;
}
error_page 500 501 502 503 504 505 506 507 508 509 510 511 /50x.html;
#error
location = /50x.html {
add_header Access-Control-Allow-Origin $http_origin;
internal;
}

nginx not serving my error_page

I have a Sinatra application hosted with Unicorn, and nginx in front of it. When the Sinatra application errors out (returns 500), I'd like to serve a static page, rather than the default "Internal Server Error". I have the following nginx configuration:
server {
listen 80 default;
server_name *.example.com;
root /home/deploy/www-frontend/current/public;
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 5;
proxy_read_timeout 240;
proxy_pass http://127.0.0.1:4701/;
}
error_page 500 502 503 504 /50x.html;
}
The error_page directive is there, and I have sudo'd as www-data (Ubuntu) and verified I can cat the file, thus it's not a permission problem. With the above config file, and service nginx reload, the page I receive on error is still the same "Internal Server Error".
What's my error?
error_page handles errors that are generated by nginx. By default, nginx will return whatever the proxy server returns regardless of http status code.
What you're looking for is proxy_intercept_errors
This directive decides if nginx will intercept responses with HTTP
status codes of 400 and higher.
By default all responses will be sent as-is from the proxied server.
If you set this to on then nginx will intercept status codes that are
explicitly handled by an error_page directive. Responses with status
codes that do not match an error_page directive will be sent as-is
from the proxied server.
You can set proxy_intercept_errors especially for that location
location /some/location {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 5;
proxy_read_timeout 240;
proxy_pass http://127.0.0.1:4701/;
proxy_intercept_errors on; # see http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors
error_page 400 500 404 ... other statuses ... =200 /your/path/for/custom/errors;
}
and you can set instead 200 other status what you need
People who are using FastCGI as their upstream need this parameter turned on
fastcgi_intercept_errors on;
For my PHP application, I am using it in my upstream configuration block
location ~ .php$ { ## Execute PHP scripts
fastcgi_pass php-upstream;
fastcgi_intercept_errors on;
error_page 500 /500.html;
}
As mentioned by Stephen in this response, using proxy_intercept_errors on; can work.
Though in my case, as seen in this answer, using uwsgi_intercept_errors on; did the trick...

Resources