Nginx as proxy : how to exclude specific folder under https but not under http - nginx

I can rewrite some specific http folders to https folders, but i can't rewrite all https except these specific folders from https to http; i'm stuck in a loop
Using NGinx 1.12 as a proxy, handling both http and https
i have one server section to handle http 80 and one server section to handle https (i know they can be together in the same section).
both of them are beginning that way
location / {
proxy_pass
server {
listen 80;
i have
location ~ ^/(xxx|yyy|zzz)/.*$ {
rewrite ^ https://www.example.com$uri permanent;
}
and anytime i'm in http, it is redirecting to https fine for the xxx,yyy and zzz folders. so far, so good.
but under server {
listen 443 ssl;
, i would like to redirect everything except the xxx,yyy,zzz folder to go back to http.
I did try to do the reverse in the https section meaning :
location / {
rewrite ^ http://www.example.com$uri permanent;
}
and
location ~ ^/(xxx|yyy|zzz)/.*$ {
#do nothing
}
but it is not working, either i get a 404 error or a loop

The only solution i found as Nginx is a proxy is making Apache handling the redirect on its side.
so,
a. nginx 80 is redirecting to nginx 443 specific folders.
b. all https is redirect by nginx 443 to apache 443, and then in apache 443 conf i do a test, if it the specific folders, i stop, and otherwise i redirect to nginx 80.
It's working, but i'm sure it is possible to make nginx handle it and avoid this 1 loop. if someone as a beautiful answer :-)

Related

DDEV: Redirect http to https using nginx-fpm and on various domains

I'm moving some small websites in production to DDEV and, some of them has multiple domains with a 301 redirection to the main HTTPS site.
This config was working well with the "natural" Nginx when I was using a .conf file to manage the domains that should be redirect to the main site on this way:
server {
listen 80;
server_name .domain1.com
.domain2.com
.domain3.com
;
return 301 https://www.maindomain.com;
}
I tried to create a new domains.conf file and add it inside the .ddev/nginx_full directory to be loaded in the restart process but seems the Nginx didn't recognize such file.
In the main "natural" Nginx config file I has this server to redirect all requests coming from HTTP to HTTPS:
server {
listen 80;
access_log off;
error_log off;
server_name maindomain.com www.maindomain.com;
return 301 https://www.$host$request_uri;
}
I tried to add these configs inside the .ddev/nginx_full/nginx-site.conf file but the server start to be crazy, doing sometimes infinite redirections and sometimes, not recognize the domains.
Inside the config.yaml file I have:
additional_fqdns:
- domain1.com
- domain2.com
- domain3.com
- maindomain.com
- www.maindomain.com
use_dns_when_possible: false
I'm sure that's a "right way" to handle this situation but, looking the docs, I didn't find and answer for that. On this way, I ask if someone here have the catch for that.
Thanks a lot
I think this will work for you.
Add the file .ddev/nginx/redirect.conf with these contents:
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}
This uses a DDEV nginx snippet, it could also be done with a full nginx config.
The ddev-router acts as a reverse proxy that terminates SSL/443 and passes along requests on port 80 to the web container.
You see the infinite redirects because it sees the request always on port 80.

Nginx rewrite sends traffic to IP address, not URL

I have nginx set up as a reverse proxy for a docker microservice. There's a location block that rewrites the url from /wrong to /right:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name example.com;
location /right {
proxy_pass http://microservice_servers;
}
location /wrong {
rewrite ^/wrong/(\w+) /right/$1 redirect;
}
}
What this is intended to do is rewrite the url from https://example.com/wrong/otherstuff to https://example.com/right/otherstuff.
What actually happens though, is that it rewrites to http://<ip_address>/right/otherstuff.
(One possible complicating factor is that I don't have control of the certs for this site. Those are controlled by the client, who puts them on an app gateway in front of our server. So my nginx config only handles http traffic at port 80, no https from 443. I'm not sure if that's actually relevant, but just in case, there it is.)
I've tried an assortment of changes to the rewrite block, including adding $server_name, changing the flag to last (returns the right content but doesn't change the url), and changing the flag to break (which does not return the expected content).
Any idea what's going on here?
By default, your rewrite...redirect statement will generate a 302 response with the full URL specified in an HTTP Location response header.
You can confirm this using curl -I https://example.com/wrong/otherstuff.
Nginx fills in the protocol and domain name, based on the original request. This server block receives requests over http and we can infer from your question that the Host header uses its IP address.
You either need to specify the full URL in the rewrite statement:
rewrite ^/wrong/(\w+) https://example.com/right/$1 redirect;
Alternatively, use relative URLs:
absolute_redirect off;
See this document for details.

Nginx redirect not applied

I am configuring an nginx server at the moment and I have two domain types:
www.example.com
example.com
On the server I added a new server block with the following code to redirect every incoming requests to the domain without www.
server {
server_name www.example.com;
return 301 $scheme://example.com$request_uri;
}
The problem is that I only got HTTP 200 instead of 301.
The changed file is: /etc/nginx/sites-enabled/default
What am I missing? I did exactly how the documentation says in Digital Ocean.

nginx rewrite for subsubdomains to subdomains

We have an application where we use subdomains for each of our customer's installations. so we have customer1.ourapp.com, customer2.ourapp.com, customer3.ourapp.com and so on.
Because of security we want to redirect all http to https, since we have a wildcard SSL certificate.
Also, some customers are not that tech savvy and add www to their domain name, so then you get things like: http://www.customer1.ourapp.com or https://www.customer1.ourapp.com. In those cases the SSL certificate isn't valid because of the subsubdomain.
I'm trying to write the vhost config for nginx to make the correct redirect in these two cases. I got the http to https redirect to work with:
server {
listen 80;
server_name *.ourapp.com;
#Rewrite all nonssl requests to ssl.
return 301 https://$host$request_uri$is_args$args;
}
correct url's use:
server {
listen 443;
server_name *.ourapp.com;
#Rest of config
}
Made an attempt for the subsub domains, but it's not matching:
server {
server_name "~^(.*)\.(.*)\.ourapp\.com$";
return 301 https://$2.ourapp.com$request_uri;
}
Any idea how to get this working?
Wildcarded server takes precedence over regexp'ed one and matches 'www...' too.
You can use one definition for both cases:
server_name ~ ^(?:.*\.)?(.*)\.ourapp\.com$;
return 301 https://$1.ourapp.com$request_uri;

Forcing HTTPS when using opsworks nginx and ELB to terminate SSL

Using Opsworks standard setup/recipes for a Rails app served via Unicorn/nginx layer. SSL is terminated at the Elastic Load Balancer - so traffic to the rails app from ELB is always http. So far so good. I would like to have any request to http://domain.com to be redirected to https://domain.com
ELB has two listeners - one with port 80, and one 443.
I know that if I were running my own nginx I could setup a redirect rule... However, i want to stay within the opsworks way of doing things if possible.
I think the only way to do this in OpsWorks is to create a custom recipe that modifies /etc/nginx/sites-available/#{application}. In your custom cookbook:
somecookbook/recipes/nginx.rb
node[:deploy].each do |application, deploy|
service "nginx" do
supports :status => true
action :nothing
end
# Add HTTP => HTTPS redirect
template "/tmp/http_redirect.conf" do
source "nginx/http_redirect.conf.erb"
end
execute "redirect HTTP to HTTPS" do
cwd "/etc/nginx/sites-available"
command "cat #{application} /tmp/http_redirect.conf > /tmp/#{application}.conf && cat /tmp/#{application}.conf > #{application}"
notifies :restart, "service[nginx]", :immediately
end
end
end
Then in the config:
somecookbook/templates/default/nginx/http_redirect.conf.erb
server {
listen 80;
rewrite ^(.*) https://$host$1 permanent;
}
I'm pretty sure you have to use nginx on your app server to handle the redirect http -> https.
Here are a two methods to solve this.
redirect all requests from 80 to https:
server {
listen 80;
return 301 https://example.com/$request_uri;
}
ELB supports a header called X-FORWARDED-PROTO.
All HTTPS requests going through the ELB will have the value of X-FORWARDED-PROTO = “HTTPS” :
server {
listen 80;
location / {
if ($http_x_forwarded_proto != 'https') {
rewrite ^ https://$host$request_uri? permanent;
}
}
}

Resources