In Nginx, I want to redirect the sub-domain request with request-uri to sub-domain but if there is no request-uri in it should redirect to main domain - nginx

My problem statement :
my domain : example.com
sub-domain : main.example.com
when we will access:
1. http://main.example.com/xyz or https://main.example.com/xyz :
It must be redirect to https://main.example.com/xyz
http://main.example.com or https://main.example.com :
It must be redirect to https://www.example.com
I am using nginx. What will be configuration file for Nginx server?
My current setting is :
server{
listen 443;
ssl on;
ssl_certificate /var/www/html/demo.crt;
ssl_certificate_key /var/www/html/demo.key;
server_name main.example.com$request_uri;
location / {
root /var/www/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
server {
listen 80;
server_name main.example.com$request_uri;
return 301 https://main.example.com$request_uri;
}
server {
listen 80;
server_name main.example.com;
return 301 https://www.example.com;
}
server {
listen 443;
server_name main.example.com;
return 301 https://www.example.com;
}

Try
server{
listen 80;
listen 443 ssl;
server_name main.example.com;
ssl_certificate /var/www/html/demo.crt;
ssl_certificate_key /var/www/html/demo.key;
location / {
proxy_pass https://www.example.com;
}
location ~ ^(/.+) {
return 301 https://main.example.com$1;
}
}
http://nginx.org/en/docs/http/configuring_https_servers.html#single_http_https_server

Related

Nginx - redir only non-www to www, leave other subdomains intact (ignore subdomains)

what I try to achieve (redirecting only non-www to www - ignoring all subdomains)
example.com > https://www.example.com
example.com/query-string > https://www.example.com/query-string
http://example.com > https://www.example.com
https://example.com > https://www.example.com
es.example.com > https://es.example.com
http://es.example.com > https://es.example.com
http://es.example.com/query-string > https://es.example.com/query-string
...
My version is 1.22.1.
What I got so far:
server {
listen 80;
listen [::]:80;
server_name *.example.com;
return 301 https://$host$request_uri;
}
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/key.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/ca.pem;
ssl_stapling_verify on;
server_name example.com;
#return 301 https://www.example.com$request_uri;
return 301 https://www.$host$request_uri;
}
server {
server_name www.example.com;
access_log /var/log/nginx/example.com.access.log rt_cache;
error_log /var/log/nginx/example.com.error.log;
root /var/www/example.com/htdocs;
index index.php index.html index.htm;
include ...
}
Second server block don't work. This
return 301 https://www.example.com$request_uri;
does not work because it redirs all subdomains to www (https://de.example.com > https://www.example.com)
This
return 301 https://www.$host$request_uri;
does not work even it redirs non-www do www version but in the same time it redirs all subdomains to www.subdomain (https://de.example.com > https://www.de.example.com).
I think the problem is in the server_name of the second server block. Any ideas how to solve this?
Try to use this config:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 80;
server_name "~(?<!www)\.example\.com$";
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
return 301 $scheme://www.$host$request_uri;
}
server {
listen 443 ssl;
server_name *.example.com;
...
}

HTTPS redirect www to non www

I got 2 domains and its supposed to work from same directory. While redirecting from http with/without www works perfectly, https www to non www don't work. Here is my config file:
server {
listen 80;
server_name domain1.com www.domain1.com;
return 301 https://domain1.com$request_uri;
}
server {
listen 80;
server_name domain2.com www.domain2.com;
return 301 https://domain2.com$request_uri;
}
server {
listen 443 ssl;
server_name www.domain1.com;
return 301 https://domain1.com$request_uri;
ssl_certificate /etc/letsencrypt/live/domain1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain1.com/privkey.pem;
}
server {
listen 443 ssl;
server_name www.domain2.com;
return 301 https://domain2.com$request_uri;
ssl_certificate /etc/letsencrypt/live/domain1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain1.com/privkey.pem;
}
server {
listen 443 ssl;
server_name domain1.com;
root /var/www/domain1.com;
index index.php index.html index.htm;
ssl_certificate /etc/letsencrypt/live/domain1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain1.com/privkey.pem;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
}
}
server {
listen 443 ssl;
server_name domain2.com;
root /var/www/domain1.com;
index index.php index.html index.htm;
ssl_certificate /etc/letsencrypt/live/domain1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain1.com/privkey.pem;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
}
}
Can you tell me what could be wrong with it? SSL certificate domain1.com have got inside certificates for all domains, include with/without WWW.
In case if someone will face to same issue, removal of "ssl" abbreviate fixed it. So instead of listen 443 ssl; in 301 server blocks change to listen 443;

Nginx re-directions from "www" to "non www" and from "http" to "https"?

I have my app hosted in the base URL: https://myapp.com/
Now I want to add re-directions from "www" to "non www" / "http" to "https", where:
https://myapp.com/
https://www.myapp.com/
http://myapp.com/
http://www.myapp.com/
Last 3 URLs should 301 redirect to the first one.
Right now second URL is not redirected and the last 2 are redirected using a 307 redirection instead of 301.
Here is my nginx configuration:
server {
listen 80;
server_name myapp.com www.myapp.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name myapp.com www.myapp.com;
server_tokens off;
ssl_certificate /etc/nginx/conf.d/self-signed-fullchain.pem;
ssl_certificate_key /etc/nginx/conf.d/self-signed-privkey.pem;
include /etc/nginx/conf.d/options-ssl-nginx.conf;
ssl_dhparam /etc/nginx/conf.d/ssl-dhparams.pem;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~ ^/(api)/ {
proxy_pass http://myapp:3000;
}
}
So how can I actually do this?
Just add one more server block with server_name www.myapp.com;, and add redirect:
return 301 https://myapp.com$request_uri;
Edit main server block to server_name myapp.com;
Should be something like that:
server {
listen 80;
server_name myapp.com www.myapp.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name www.myapp.com;
server_tokens off;
ssl_certificate /etc/nginx/conf.d/self-signed-fullchain.pem;
ssl_certificate_key /etc/nginx/conf.d/self-signed-privkey.pem;
include /etc/nginx/conf.d/options-ssl-nginx.conf;
ssl_dhparam /etc/nginx/conf.d/ssl-dhparams.pem;
return 301 https://myapp.com$request_uri;
}
server {
listen 443 ssl;
server_name myapp.com;
server_tokens off;
ssl_certificate /etc/nginx/conf.d/self-signed-fullchain.pem;
ssl_certificate_key /etc/nginx/conf.d/self-signed-privkey.pem;
include /etc/nginx/conf.d/options-ssl-nginx.conf;
ssl_dhparam /etc/nginx/conf.d/ssl-dhparams.pem;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~ ^/(api)/ {
proxy_pass http://myapp:3000;
}
}

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 will rewirte image domain http to https, But I don't want the static server as https

I have a wordpress website with https protocol by configuring the nginx 301 redirect:
server {
listen 80;
server_name xxx.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name xxx.com;
ssl_certificate conf.d/xxx.crt;
ssl_certificate_key conf.d/xxx.key;
}
And my article has some image links with static server like:
http://yyy.com/1.png
But when i access this article: it will be https://yyy.com/1.png, How do I configure the nginx that can still use http for the image static server?
You would do that using below config
server {
listen 80;
server_name xxx.com;
location ~* \.(png|ico|jpeg)$ {
root <your root folder>;
try_files $uri =404;
}
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl;
server_name xxx.com;
ssl_certificate conf.d/xxx.crt;
ssl_certificate_key conf.d/xxx.key;
}

Resources