I'm no nginx professional or amateur for that mater, just know how to google a lot and I need help finishing of a reverse proxy.
What I currently have a main server that handles connections which then hands the client to one of 8 backend servers that deliver the stream in either TS or HLS. I want to put a proxy at the front that acts as the main server but also delivers the stream (like an edge server i guess, but no caching) so that the origin servers are hidden.
I have got it to work with TS, but I can't for the life of me workout how to get it to work with HLS no matter how much I packet capture. It pulls the manifest fine but unlike with TS it isn't pulling the segments from the origin servers.
Here is the code I've done so far (could probably be cleaner but this was all done with google)
server {
listen 80;
server_name proxy_IP_here;
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_buffering off;
location ~ .(m3u8|mpd)$ {
proxy_pass backend_IP_for_Main;
proxy_intercept_errors on;
error_page 301 302 307 = #handle_redirects;
}
}
location / {
proxy_pass backend_IP_for_Main;
sub_filter 'dns_i_have_it_fildering_here' 'proxy_IP_here';
sub_filter_once off;
sub_filter_types text/javascript application/json;
proxy_intercept_errors on;
error_page 301 302 307 = #handle_redirects;
}
location #handle_redirects {
set $saved_redirect_location '$upstream_http_location';
proxy_pass $saved_redirect_location;
}
}
If I remove
proxy_intercept_errors on;
error_page 301 302 307 = #handle_redirects;
that from the .mm3u8 location block HLS will work but will be delivered directly by the origin server to the end client and not through the proxy.
Any help greatly appreciated.
Thanks in advance.
Related
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;
}
this is my config:
server {
listen 80;
server_name ~^(?<sb>.+)\.a\.b\.c\.com$;
access_log /data/logs/nginx/tas.access.log main;
location / {
proxy_intercept_errors on;
proxy_pass http://b.c/a/$sb/;
proxy_set_header Host $host;
proxy_redirect off;
}
}
and browser report to many redirects.
If, as you say, you want to proxy to localhost:8082, you need to say so in the proxy_pass line:
server {
listen 80;
server_name ~^(?<sb>.+)\.a\.b\.c\.com$;
access_log /data/logs/nginx/tas.access.log main;
location / {
proxy_intercept_errors on;
proxy_pass http://localhost:8082/a/$sb/;
proxy_set_header Host $host;
proxy_redirect off;
}
}
Without all of the information, it's hard to guess what's going on. Based on the comments, my guess is that you are using virtual hosting so that the upstream site is also served by the same nginx. So this line is the problem:
proxy_set_header Host $host;
The nginx variable $host is pointing to the current Host header (which matches the server_name). So if you set the same host header for the upstream again, then nginx will find the same location block above because nginx relies on the Host header to find the proper server. Thus the redirect loop.
Set
proxy_set_header Host your_upstream_server_name
will fix it then.
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.
So I got the tcp module for nginx all set up and am trying to use this with private_pub (faye) for websockets. As of now I'm getting very slow loading from faye and a 502 Bad Gateway errors. Everyone points towards configuring it like so:
I have this in my nginx.conf:
tcp {
timeout 1d;
websocket_read_timeout 1d;
websocket_send_timeout 1d;
upstream websockets {
server 199.36.105.34:9292;
check interval=300 rise=2 fall=5 timeout=1000;
}
server {
listen 9200;
server_name 2u.fm;
timeout 43200000;
websocket_connect_timeout 43200000;
proxy_connect_timeout 43200000;
so_keepalive on;
tcp_nodelay on;
websocket_pass websockets;
}
I've tried every variation of that on the web. I want to be able to hit it from my domain "2u.fm/faye" but the only way I can get that to work is to do a proxy inside my http block:
location /faye {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://127.0.0.1:9200;
break;
}
Adding that makes it work at 2u.fm/faye but now I'm back at square one, still getting super slow responses and 502 Bad Gateway's. Which I think makes sense as it's routing through http still and not directly to tcp. I've tried hitting 199.36.105.34:9200 directly but I get no response.
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...