I have a Rails app with an NGINX reverse proxy behind an AWS ELB. I am terminating SSL on the ELB and I have NGINX configured to force any attempt at HTTP to rewrite as HTTPS. This setup works fine, but I'm also serving the site through ECS, and since the ELB health check is on HTTP port 80, when it gets the redirect and returns 301, the ELB health check fails and the instance is deregistered.
How do I set up NGINX to send all but the health check file through HTTPS?
Here is my server block from nginx.conf:
server {
listen 80;
server_name localhost;
root /var/www/html;
location ~ ^elbcheck\.html$ {
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://rails_app;
break;
}
location / {
proxy_redirect off;
proxy_next_upstream error;
if ($http_x_forwarded_proto != "https") {
rewrite ^ https://$host$request_uri? permanent;
}
try_files $uri $uri/ #proxy;
}
location ~* \.(jpg|jpeg|svg|png|gif|ico|css|js|eot|woff|woff2|map)$ {
proxy_cache APP;
proxy_cache_valid 200 1d;
proxy_cache_valid 404 5m;
proxy_ignore_headers "Cache-Control";
expires 1d;
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 https;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://rails_app;
}
location #proxy {
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 https;
proxy_pass http://rails_app;
}
}
I had the same problem, and found this answer somewhere on the internet (don't have the source anymore, it was a while ago)
server {
listen 80;
set $redirect_to_https 0;
if ($http_x_forwarded_proto != 'https') {
set $redirect_to_https 1;
}
if ($request_uri = '/status') {
set $redirect_to_https 0;
}
if ($redirect_to_https = 1) {
return 301 https://$host$request_uri;
}
...
}
Found a simple answer that worked great at this post. Here is what #ceejayoz suggested there:
server {
location /elb-status {
access_log off;
return 200;
}
}
Seems to be working--ECS hasn't terminated my service due to failed health checks anymore.
Related
I have been trying to solve this issue for quite awhile now. Bots are hitting my sites hard with INVALID HOST HEADERS and Nginx forwards these requests to Gunicorn/Django. I need to stop them at Nginx. I have tried every solution I can find on SO, and elsewhere, but none seem to work for my setup.
Nginx.conf:
upstream backend_server {
server backend:8000;
}
upstream backend_asgi {
server backend_asgi:8001;
}
server {
listen 80;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location ~* ^/(api|admin|static|v2) {
return 301 https://$host$request_uri;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.site *.example.site;
ssl_certificate /etc/letsencrypt/live/example.site/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.site/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location /ws/ {
proxy_pass http://backend_asgi;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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-Host $server_name;
}
location ~ ^/v2(?:/(.*))?$ {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /v2/index.html =404;
}
location /backend_static/ {
alias /backend/assets/;
}
location /media/ {
alias /backend/media/;
}
location ~* ^/(api|admin) {
proxy_pass http://backend_server$request_uri;
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 $https;
proxy_connect_timeout 360s;
proxy_read_timeout 360s;
}
location / {
proxy_pass http://backend_server$request_uri;
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 $https;
proxy_connect_timeout 360s;
proxy_read_timeout 360s;
# Set upload size for videos to be 500MB
client_max_body_size 500M;
}
}
What can i add to my Nginx configuration to stop invalid host headers, given that I have a wildcard subdomain and bots are also using HOST HEADERS w/ subdomains?
I would like to implement a reverse proxy which redirect request of http://www.dummy.com/foo/bar/test to http://127.0.0.1/hello/world. I have tried to add rewrite before the pass and it seems not working ...
server {
listen 80;
listen [::]:80;
server_name www.dummy.com;
# access_log /var/log/nginx/upstream_log.log
location / {
root /usr/share/nginx/html/dummy;
}
location /foo/bar/test {
rewrite ^/foo/bar/test /hello/world break;
proxy_pass http://127.0.0.1/;
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;
access_log /var/log/nginx/upstream_log.log upstream_logging;
}
}
Is there something missing or wrongly configured?
The above config works as expected... The other server was misconfigured when I test the above configuration.
I have nginx installed on port 80 and a node application on port 2368 behind nginx
nginx configuration looks like this
server {
server_name domain.com www.domain.com;
listen 80;
location / {
proxy_pass http://localhost:2368;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
}
This configuration works exactly as expected. For example / request turns into http://localhost:2368/, and /post/mypost turns into http://localhost:1234/post/mypost etc.
What I want is that only / request turned into http://localhost:2368/latestpost/. And all other requests are handled the same way as in example above. Thnx!
You could use rewrite directive:
server {
server_name domain.com www.domain.com;
listen 80;
location / {
rewrite ^/$ /latestpost/ break;
proxy_pass http://localhost:2368;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
}
or in separate location:
server {
server_name domain.com www.domain.com;
listen 80;
location = / {
rewrite ^.* /latestpost/;
}
location / {
proxy_pass http://localhost:2368;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
}
Second variant is slightly more efficient as it will not try rewrite every request. But difference will be unnoticeable, I guess.
I am having issues getting my nginx + tomcat 7 reverse proxy setup working.
Basically I want https://192.168.10.101 to serve content from the upstream cluster/webapp/; However I am getting a 404 page from my applicaton.
Any hints on whats going wrong would be greatly appreciated.
My configuration is given below.
server {
server_name 192.168.10.101;
access_log /var/log/nginx/mysite-access.log;
listen 443;
ssl on;
ssl_certificate /etc/nginx/ssl/mysite.crt;
ssl_certificate_key /etc/nginx/ssl/private/mysite_pvt.key;
location / {
proxy_redirect off;
proxy_pass https://tccluster/webapp/;
rewrite_log on;
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_max_temp_file_size 0;
}
}
upstream tccluster {
server 192.168.56.103:8443;
server 192.168.56.104:8443;
}
Finally figured it out. The app has a filter that redirects to /webapp/index.html , which made nginx make the request for /webapp/webapp/index.html which was giving the 404.
I added a rewrite rule
location / {
proxy_pass https://backend/webapp/;
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;
rewrite ^/webapp/(.*)$ /$1 last;
}
And this seems to be working for now !
full nginx config to pass to tomcat context :
server {
listen 80; # e.g., listen 192.168.1.1:80; In most cases *:80 is a good idea
listen [::]:80;
server_name tomcat-context.domain.com ;
# individual nginx logs for this vhost
access_log /var/log/nginx/tomcat-context_domain_access.log main;
error_log /var/log/nginx/tomcat-context_domain_error.log;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/www;
}
location / {
proxy_pass http://127.0.0.1:10080/tomcat-context/;
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;
rewrite ^/tomcat-context/(.*)$ /$1 last;
}
location /tomcat-context {
rewrite ^/tomcat-context(.*)$ $1 redirect;
}
}
I've deployed a Rails app to a VPS server, and I'm using the Nginx/Unicorn combo, everything works fine, except that for some reason beyond my understanding, the Omniauth callbacks redirect wrong,
ie.
http://unicorn/users/auth/linkedin/callback?oauth_token=95218ed3-b426-45ab-b022-693d2a2447cb&oauth_verifier=25955
it should instead be:
http://my-real-domain.com/users/auth/linkedin/callback?oauth_token=95218ed3-b426-45ab-b022-693d2a2447cb&oauth_verifier=25955
What's wrong? why is the callback using the name of the upstream defined in nginx?
upstream unicorn {
server unix:/tmp/unicorn.todo.sock fail_timeout=0;
}
server {
listen 80;
listen [::]:80 ipv6only=on default_server;
root /home/deploy/work/project/current/public;
index index.html index.htm;
server_name my-real-domain.com;
try_files $uri/index.html $uri #unicorn;
location #unicorn {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://unicorn;
}
error_page 500 502 503 504 /500.html;
location ~ ^/assets/ {
expires 1y;
add_header Cache-Control public;
add_header ETag "";
break;
}
}
Could you please help me? I need to know how to overcome this wrong redirection.
Thanks in advance!
Nginx doesn't pass the host header by default, you have to tell it to:
location #unicorn {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://unicorn;
}
Otherwise which host the request was sent to gets lost.