Nginx redirect to https issues - nginx

I been struggling for a while to find a solution for a problem that I have:
I need to redirect all http request to https excepting a specific page under a certain location.
I have the following:
server {
listen 80;
listen 443 ssl;
server_name myserver;
root /var/www/example.org/htdocs;
index index.html;
.
.
}
I can't use:
server {
listen 80;
server_name my.domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name my.domain.com;
.
.
}
I found a good solution in here
The problem with the solution is that the redirect gets into an infinitive loop, the solution is something like, after my changes:
map $uri $example_org_preferred_proto {
default "https";
~^/post/ "http";
}
server {
listen 80;
listen 443 ssl;
server_name example.org;
root /var/www/example.org/htdocs;
if ($example_org_preferred_proto = "https") {
return 301 $example_org_preferred_proto://example.org$request_uri;
}
}
I understand logic of the problem:
I get a request like: http://wwww.example.com/test -> redirects to https://wwww.example.com/test
Now I get a request like: https://wwww.example.com/test -> redirects to https://wwww.example.com/test
Now I get a request like: https://wwww.example.com/test -> redirects to https://wwww.example.com/test and got into a loop ....
I need a way to stop after redirect one time.

server {
listen 80;
server_name wwww.example.com;
root /var/www/example.org/htdocs;
location /test {
try_files $uri $uri/ =404;
}
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl;
## here goes other ssl staff which you can find by link:
## https://gist.github.com/paskal/628882bee1948ef126dd
server_name example.org;
root /var/www/example.org/htdocs;
location /test {
try_files $uri $uri/ =404;
}
location / {
return 301 https://$server_name$request_uri;
}
}
Best solution is simplest one. You need to serve only one location and redirect anything else - so do it.
If you have problem with using two server blocks, please describe it in detail.

Related

404 a directory in nginx server block

In my /conf.d/ folder I have a .conf file as follows:
server {
listen 80;
listen [::]:80;
return 301 https://www.example.com$request_uri;
}
You can see that it redirect any http traffic to https, that is fine.
However, there are certain http URLs, like http://www.example.com/profile/(.*) that I want to 404 immediately, without the redirect to the https version first.
I have tried variants of the following code with no success, the URL, eg http://www.example.com/profile/abc123, is always redirected to the https version.
server {
listen 80;
listen [::]:80;
location ~* ^/profile/ {
return 404;
}
return 301 https://www.example.com$request_uri;
}
Note that I want to capture example.com/profile/ and any pages that match that, eg example.com/profile/abc123 etc
Thank you.
server {
listen 80;
listen [::]:80;
location ~ ^/profile/ {
return 404;
}
server_name example.com *.example.com;
location ~ ^/ {
return 301 https://www.example.com$request_uri;
}
}

How to redirect traffic nginx in dynamic mode

In my nginx server , I want to do this:
mydomain.com/api/xxxx
redirect to mynewdomain.com/api/testing/xxxx
I try to do by different ways but no ones works for me, always return a 502 error;
First way
server {
listen 80;
server_name mydomain.com;
# Nginx conf
location /api/ {
return 301 https://mynewdomain.com/api/testing/$uri;
}
}
Second way
server {
listen 80;
server_name mydomain.com;
# Nginx conf
location /api/(.*) {
proxy_pass https://mynewdomain.com/api/testing/$args_v;
}
}
And I tryed to only redirect to specific direction and this works, but i don't want to hardcode all petitions to redirect,
Static redirect
server {
listen 80;
server_name mydomain.com;
# Nginx conf
location /api/ {
proxy_pass https://mynewdomain.com/api/testing/redirect1;
}
Any help for make this dynamic?
location ~ ^/api/(.*) {
return 301 https://mynewdomain.com/api/testing/$1;
}
Try this, because $uri also includes /api.

Nginx TLS-SNI: Use hostname dependent SSL for HTTPS

I need to use two different ssl certs with nginx pointing to the same app.
https://domain1.com points to 1.1.1.1
https://domain2.com points to 1.1.1.1
.
.
.
.
https://domainN.com points to 1.1.1.1
Tried the following:
server {
listen 80;
server_name domain1.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name domain1.com;
root /app/dist;
index index.html;
ssl_certificate /etc/nginx/ssl/d1/certificate.crt;
ssl_certificate_key /etc/nginx/ssl/d1/private.key;
location / {
try_files $uri $uri/ /index.html;
}
}
server {
listen 80;
server_name domain2.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name domain2.com;
root /app/dist;
index index.html;
ssl_certificate /etc/nginx/ssl/d2/certificate.crt;
ssl_certificate_key /etc/nginx/ssl/d2/private.key;
location / {
try_files $uri $uri/ /index.html;
}
}
This doesn't work, it just loads the first cert resulting in invalid cert when accessed using the second domain.
The domain certs can't be combined.
I can't spin two different instances for nginx as the case needs to help me out with n-Domains pointing to same IP preferably using one nginx server.
Is there a way out?
Thanks to Richard Smith for pointing out just the right stuff!
So, to setup nginx to use different cert-key pair for domains pointing to the same nginx we have to rely on TLS-SNI (Server Name Indication), where the domain name is sent un-encrypted text as a part of the handshake. This helps nginx to decide which cert-key pair to use for the incoming secure request.
More can be read about SNI here.
Moving on to the configuration.
server {
listen 80;
server_name domain1.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name domain1.com;
root /app/dist;
index index.html;
ssl_certificate /etc/nginx/ssl/d1/certificate.crt;
ssl_certificate_key /etc/nginx/ssl/d1/private.key;
location / {
try_files $uri $uri/ /index.html;
}
}
server {
listen 80;
server_name domain2.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name domain2.com;
root /app/dist;
index index.html;
ssl_certificate /etc/nginx/ssl/d2/certificate.crt;
ssl_certificate_key /etc/nginx/ssl/d2/private.key;
location / {
try_files $uri $uri/ /index.html;
}
}
The above config forwards HTTP (80) for both domain1 and domain2 to respective HTTPS (443) server blocks, where respective cert-key pairs are loaded.
The HTTPS (443) request is handled directly.
nginx decides which block to hit by picking the server name using SNI.

Nginx: Redirect all but one

I have the following http config:
server {
listen 80;
server_name example.com;
# Necessary for Let's Encrypt Domain Name ownership validation
location /.well-known/acme-challenge/ {
root /home/vagrant/.well-known/acme-challenge/;
}
return 301 https://$host$request_uri;
}
I would like http://example.com/.well-known/acme-challenge/filename to serve /home/vagrant/.well-known/acme-challenge/filename while every other http request should be redirected to https.
I thought Nginx would process rules in their order, if matches, uses it, otherwise continues. But apparently not. How can I achieve what I want ?
You should move that redirect to be in the "/" block:
location / {
return 301 https://$host$request_uri;
}
They do process in order, but yours is outside of any location block, so likely is taking precedence.
According to nginx, putting root xxx in a location block is a pitfall.
After some struggle, here's my working config:
server {
listen 80;
server_name example.com;
root /vagrant/www/current/public;
# Necessary for Let's Encrypt Domain Name ownership validation
location /.well-known/acme-challenge/ {
try_files $uri /dev/null =404;
}
location / {
return 301 https://$host$request_uri;
}
}

Nginx server block

Hy everyone,
I have a little problem with nginx server block and I hope that someone from here will know the solution to it.
This is how my configuration looks like:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://www.example.com;
}
server{
listen 80;
server_name *.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name .example.com;
...
}
So the first block is normal http redirecting to https second is catching subdomains and third is where location blocks are etc.
My problem is that when the second block catches the request would like to add /admin to URL so it would be subdomain.example.com/admin but i have to check if it already has /admin so i don't get something like this subdomain.example.com/admin/admin.
I tried server_name *.example.com$ and server_name ~.example.com(=<id>.*) then if ($id = '') and hundreds of combinations and didn't get anything usefull.
Did anyone here had similar problem and solved it?
server {
listen 80;
server_name *.example.com;
if ($request_uri !~ ^/admin/) {
return 301 https://$host/admin$request_uri;
}
return 301 https://$host$request_uri;
}

Resources