Elastic Beanstalk Http Redirect to Https - amazon-web-services

I know this question has been asked before, but nothing seems to be working for me. I've tried multiple different things, such as the answers described in these questions:
How to get Elastic Beanstalk nginx-backed proxy server to auto-redirect from HTTP to HTTPS?
Redirecting EC2 elb from http to https
None of them seem to work. I'm an aws noob, so I'm not entirely sure how editing config files works - or if I've done something wrong.
My setup is the following:
Route 53 points to Elastic Beanstalk (nginx)
ELB port configuration with ACM certificate (using tcp/ssl as it makes my websockets work)
nodejs app on port 8080
My current nginx.config file in my .ebextensions folder (got this from this article):
files:
"/tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf" :
mode: "000755"
owner: root
group: root
content: |
upstream nodejs {
server 127.0.0.1:8081;
keepalive 256;
}
server {
listen 8080;
set $fixedWWW '';
set $needRedir 0;
# nginx does not allow nested if statements
# check and decide on adding www prefix
if ($host !~* ^www(.*)) {
set $fixedWWW 'www.';
set $needRedir 1;
}
# what about that https? the traffic is all http right now
# but elastic load balancer tells us about the original scheme
# using $http_x_forwarded_proto variable
if ($http_x_forwarded_proto != 'https') {
set $needRedir 1;
}
# ok, so whats the verdict, do we need to redirect?
if ($needRedir = 1) {
rewrite ^(.*) https://$fixedWWW$host$1 redirect;
}
location / {
proxy_pass http://nodejs;
proxy_set_header Connection "";
proxy_http_version 1.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;
}
gzip on;
}
But this doesn't seem to do anything. I've run out of ideas. I'm not sure whether I'm missing a step or something but I don't know what to do. As a workaround I've got my angularjs front end redirecting non-https requests, but this is too hacky and some of the DOM renders before the redirect, I'd like to redirect at the load balancer - where it should redirect.

It looks like you're trying to do both a redirect for non-WWW and for non-HTTPS connections. Have you tried the simpler case of just http:// -> https:// ?
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}
Sometimes it's easier to handle it via two redirects, one from HTTP to HTTPS and one from non-WWW to WWW. In fact, if you're going to register your site via HSTS (https-everywhere), they require this sort of approach.
Edit: Also, just noticed the first line of your config, you might want to try injecting the nginx file directly:
files:
"/etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf" :

It's pretty hard to update /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf" directly. I found this: https://github.com/awsdocs/elastic-beanstalk-samples/blob/master/configuration-files/aws-provided/security-configuration/https-redirect/nodejs/https-redirect-nodejs.config, which let's you set up the redirect, but that would have changed my other config files too much. The best way to go about it is create a redirect.config file in your .ebextensions folder:
container_commands:
https_redirect:
command: |
sed -i '/location \/ {/i \
set $redirect 0;\
if ($http_x_forwarded_proto != "https") {\
set $redirect 1;\
}\
if ($http_user_agent ~* "ELB-HealthChecker") {\
set $redirect 0;\
}\
if ($redirect = 1) {\
return 301 https://$host$request_uri;\
}\
' /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf```

Related

nginx url redirect to custom url

I have a domain binging a IP:
a.a.com -> 1.1.1.1
In 1.1.1.1 has a nginx , for access a.a.com/bbb/ to 2.2.2.2's django service.
`
#1.1.1.1
server {
listen 8090;
server_name localhost;
location /bbb/ {
proxy_pass 2.2.2.2:8000;
}
}
`
when I input a.a.com/bbb/, I can access, it's ok.
But when Django login's session timeout , It automatic redirect a.a.com:8090/bbb/.
I want to ask how to automatic redirect a.a.com/bbb/.
ps. the 8090 port cant access
Sorry my poor English , Thanks.
Use proxy_redirect off:
location /bbb/ {
proxy_pass 2.2.2.2:8000;
proxy_redirect off;
}
proxy_redirect off tells nginx that, if the backend returns an HTTP redirect, it should leave it as is. (By default, nginx assumes the backend is stupid and tries to be smart; if the backend returns an HTTP redirect that says "redirect to http://localhost:8000/somewhere", nginx replaces it with something similar to "http://yourowndomain.com/somewhere", or, in your case, "http://yourowndomain.com:8090/somewhere". Django is smart enough so there is no need for nginx to do such things.)

https to http redirect not working in nginx configuration using rewrite

To distribute load and implement security in our application we have taken elastic Load Balancer from amazon and SSL is configured on it.Now the redirection from http to https is not working in nginx configuration on server or instances which is attached on ELB.
Here is following nginx configuration:-
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name new.example.com;
access_log /var/log/nginx/domain-access.log;
location / {
proxy_read_timeout 90;
proxy_connect_timeout 90;
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_pass http://127.0.0.1:8000;
}
}
Firstly the server is not supporting https URLs then I add some proxy settings in configuration but now issue is that redirection is not working i have used the following commands in ngnix configuration to redirect http to https :-
#version 1
server{
return 301 https://$server_name$request_uri;
}
#version 2
server {
rewrite ^(.*) https://$host$1 permanent;
}
Application deployed on server is build using django framework.
When I've done something similar, then I've set up the ELB HTTPS to redirect to HTTP port 80 on the node. I've then set up a second nginx vhost on the node, e.g. on port 81, which directs to return 301 https://$server_name$request_uri; and set up the ELB http listener to redirect to that port (where $server_name obviously points to the domain CNAME of the ELB)
I then make sure that the instances behind the ELB cannot be accessed from outside my VPC using security groups.
If you are using Django, you can use it to do the redirection, this give a lot of flexibilty like enabling HTTPS redirects only on production server or choose which urls to redirect from:
# Honor the 'X-Forwarded-Proto' header for request.is_secure()
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
# Redirect to HTTPS in production
SECURE_SSL_REDIRECT = not DEBUG
# Disable redirection on this urls
SECURE_REDIRECT_EXEMPT = [
'^legacy/api/',
]

nginx rewrite url without causing redirect and proxy to backend app

I'm trying to achieve the below in nginx:
Hit nginx on http://<nginx-host>:81/admin/metrics and have nginx proxy it to http://127.0.0.1:8001 with the /admin/metrics rewritten to /metrics. The actual proxied admin app would receive http://127.0.0.1:8001/metrics.
So, http://<nginx-host>:81/admin/metrics => http://127.0.0.1:8001/metrics, and without causing a redirect.
This is what I have so far:
#admin app
upstream admin_backend {
server 127.0.0.1:8001;
keepalive 16;
}
#host /admin paths on another port
server {
listen 81;
#pass everything to backend admin app that matches /admin/* with /admin/ removed
location ~ /admin/ {
limit_except GET HEAD POST PUT { }
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_pass http://admin_backend;
rewrite ^/admin/(.*)$ /$1 last;
}
}
This is not working. nginx is not proxying the request back to the admin app and keeps returning a 404.
What am I missing here?
I cross-posted this question on the nginx users forum, and got a solution from nanaya (thank you!).
Basically, all I needed to do was replace last with break in the rewrite directive:
So,
rewrite ^/admin/(.*)$ /$1 last;
became
rewrite ^/admin/(.*)$ /$1 break;
redirect api and files request to backend
location ~ /api/ {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://server:8009;
rewrite ^/api/(.*)$ /$1 break;
}

Django + uwsgi + nginx + SSL

I am using Django on DotCloud which uses Django on top of uwsgi + nginx. I am trying to redirect all http traffic to https which is leading to a redirect loop. I am using the following http configuration
if ($http_x_forwarded_port != 443) { rewrite ^ https://$http_host/; }
It seems that Django doesn't understand that it is operating on https and the header is not preserved. It redirects https://url.com/ to http://url.com/accounts/login/ which is redirecting again and again leading to a redirect loop. I am not really an expert in nginx and do not understand it well enough. What can I be doing wrong?
In short how do I run redirect http to https in django running on top of uswsgi and nginx.
I needed a bit more to make Django aware that it should be using https.
In settings.py I added
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
And in the nginx configuration
location / {
proxy_set_header X-Forwarded-Proto https;
include uwsgi_params;
uwsgi_param UWSGI_SCHEME https;
uwsgi_pass_header X_FORWARDED_PROTO;
uwsgi_pass unix:///path/to/socket;
}
server {
listen 80;
server_name yourhttphost;
rewrite ^ https://yourhttpshost$request_uri? permanent; #301 redirect
}
server {
listen 443;
server_name yourhttpshost;
........
the rest
........
}
Using "if" in nginx config is a very bad idea!
if ( $scheme = "http" ) {
rewrite ^/(.*)$ https://$host/ permanent;
}

Django nginx and append slashes problem

I am trying to use nginx as a simple load balancer for django per Jacob Kaplan-Moss' example:
http://github.com/jacobian/django-deployment-workshop
http://python.mirocommunity.org/video/1689/pycon-2010-django-deployment-w
If I stop nginx and have apache listen on port 80 everything works fine. If I have apache listening to nginx my urls break.
When nginx is running, http://184.106../admin/ works, but http://184.106../admin (missing ending slash) breaks. It redirects to the name of the web server http://web1/admin/
I know it is nginx causing the issue because the redirect works fine in apache and django dev server.
Here is the nginx.conf that is running:
# Nginx conf (/etc/nginx/nginx.conf).
#
# Basic setup
#
user www-data;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
#
# Event/worker setup.
#
worker_processes 4;
events {
worker_connections 100;
}
#
# HTTP configuration
#
http {
include /etc/nginx/mime.types;
# HTTP upstream for load balancers.
# Replace the IPs below with IPs (or names) of your upstream Apaches
upstream sitename {
server 10.X.X.X:8000;
server 10.X.X.X:8000;
}
# The actual HTTP sever.
server {
listen 80;
# Don't proxy static files like robots.txt and favicon.ico.
location ~ ^/(favicon.ico|robots.txt|sitemap.xml)$ {
alias /home/web/static/$1;
}
# Serve media directly out of Nginx for performance
location /media {
alias /home/media;
}
# Proxy everything else to the backend
location / {
proxy_pass http://sitename;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header X-Handled-By $upstream_addr;
}
}
}
I had the exact same problem you had, following Jacob's nginx example, and not having a slash would cause improper redirects. pjmorse's response helped me, I set the server_name in the server block ( server { server_name: vasir.net; .... ) and it fixed the problem. However, I had to restart the server first and