Nginx use subdomain as query parameter and rewrite URL - nginx

I'm trying to use subdomains as query parameter on the domain itself.
An example would be the following:
I want nginx to take ab.example.com and call example.com?key=ab, now the backend will return a specific config, which should be used for the subdomain "ab".
Afterwards the user should see the content (logo branding to be precise) of example.com?key=ab but in the client's URL field the ab.example.com should persist.
And all further requests should show for example ab.example.com/login instead of example.com/login.
I hope that what I have said is sufficiently understandable. I have tried various examples from the internet and tried to find some hints.
The nginx file looks like:
server {
listen 80;
listen [::]:80;
server_name www.example.com *.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com *.example.com;
ssl_certificate /path/to/certs/ssl.crt;
ssl_certificate_key /path/to/keys/ssl.key;
root /var/www/example_site;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
location / {
try_files $uri $uri/ /index.html =404;
error_page 404 =200;
}
}
I have already tried to map, but it redirects to a wrong domain:
map $host $subdomain {
~^(?<sub>.+)\.example\.com$ $sub;
}
And tried adding a static if statement in the server block, too:
if ($host = "ab.example.com") {
rewrite . ?key=ab;
}
An additional server block did not help either:
server {
listen 80;
listen [::]:80;
server_name www.ab.example.come ab.example.com;
rewrite ^ https://example.com/?key=ab permanent;
}
Does anyone see what I am doing wrong or what part of the documentation I should read again?

You just need to do it inside your own server_name directive. You can assign a variable in a regexp directly there. If you need a different behavior for www. subdomain just remove *.example.com from the block and add this one in another file:
server {
listen 80;
server_name ~^(?<subdomain>.+)\.example\.com$;
return 301 http://example.com$request_uri?key=$subdomain;
}
Note that I didn't use rewrite, which you shouldn't need. Using return performs better. 301 stands for the kind of redirect. And then, you use your server_name assigned variable to redirect where you need.

Related

NGINX why do I get ERR_CERT_COMMON_NAME_INVALID only on one of my domain names?

I have a really weird problem. I own multiple domains let's say example.com, example.pl, example.at, etc. My main domain is example.com, all the rest should be (and mostly are) redirected to example.com for which I own certificate (only for this one). Now what is strange is that if I go to whichever of my domains, doesn't matter if I use www or not, all these domains get properly redirected with code 301 to https://example.com. All except one - www.example.com - this one always gets 307 and ERR_CERT_COMMON_NAME_INVALID. I'm totally lost. Have anyone experienced something like this?
Here is my nginx sites-available config:
server {
listen 80;
server_name example.com;
location / {
return 301 https://example.com$request_uri;
}
}
server {
listen 443 ssl default_server;
server_name example.com;
include /etc/nginx/headers/headers.conf;
include /etc/nginx/ssl-options/options-ssl-nginx.conf;
ssl_dhparam /etc/nginx/ssl-options/ssl-dhparams.pem;
access_log /var/log/nginx/data-access.log combined;
if ($http_host = www.example.com){
return 303 https://example.com$request_uri;
}
if ($http_host != example.com){
return 303 https://example.com$request_uri;
}
location / {
root /usr/share/nginx/html;
try_files $uri /blog-build.html;
}
}

Rewriting wildcard domain with HTTPS

Is it possible to rewrite HTTPS wildcard Domains in nginx or should we create multiple structure /file for each domain?
Lets say i have follwing:
1. subdomain1.domain.com
2. subdomain2.domain.com
If i do not have HTTPS i used the following which works great:
server {
listen 443;
server_name *.domain.com;
charset utf-8;
}
No if i use HTTPS, i would have to write a new block like the following ( using letsencryt)
The following is just a test domain (only 1 domain )
server {
server_name test.me;
rewrite ^ https://test.me$request_uri? permanent;
}
server {
listen 443;
server_name test.me;
charset utf-8;
...
}
Is it possible to do the same for multiple domains?
server {
server_name .domain.com;
rewrite ^ https://.domain.com$request_uri? permanent;
}
server {
listen 443;
server_name *.domain.com;
charset utf-8;
...
}
I tried the above config but it doesnot work, it redirects me to
https://%2A.domain.com.domain.com/ (just for test)
Is it possible to do something like this ? or Should i have different block for every subdomain ?
Use one of the variables provided by nginx to extract the host name from the request line. For example $host (see this document for details):
server {
server_name .domain.com;
return 301 https://$host$request_uri;
}

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 URL masking to a different domain

There's a few similar questions on SO, but none exactly mine, and I've had no luck trying to adapt their answers so far.
I want to map the URL http://sub.example.com to https://123.12.12.12/path, such that the browser still shows the URL http://sub.example.com.
My Nginx config file looks like,
server {
listen 80;
server_name sub.example.com;
location / {
proxy_pass https://123.12.12.12;
rewrite ^/$ /path last;
}
}
The routing works here, but the URL displayed is http://sub.example.com/path. How do I make it display only http://sub.example.com?
server {
listen 80;
server_name sub.example.com;
location / {
proxy_pass https://123.12.12.12/path;
}
}
Thats how it works. If proxy_pass contains locations part - current location will be replaced to specified. http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
But it's help only for http request and http redirects. If application create html with links https://123.12.12.12 - it's still unchanged. In this case you can try ngx_http_sub_module.
I did like this:
server {
listen 80;
listen [::]:80;
listen 443 http2 ssl;
listen [::]:443 http2 ssl;
server_name domain1;
if ($request_method ~* OPTIONS|GET|HEAD) {
return 301 https://domain2$request_uri;
}
location ~* api {
proxy_pass https://domain2$request_uri;
}
}
Because post-requests will cause a 405 error when redirecting.

nginx order of server_name rewrite rules

I'm playing around with nginx rewrite rules using server and server_name. The documentation sounds simple and clear enough about the order of precedence, but I'm getting some slightly odd behaviour and want to check whether I missed anything.
I am trying to redirect anything other than www.domain.com (e.g. www.domain.net, www.domain.info) to www.domain.com. With the exception of www.domain.de to redirecto to www.domain.com/de.
I have the following rules:
server {
server_name domain.de www.domain.de;
rewrite ^(.*) http://www.domain.com/de$1 permanent;
}
server {
server_name _;
rewrite ^(.*) http://www.domain.com$1 permanent;
}
server {
listen 80;
server_name localhost domain.com www.domain.com;
...
}
However, it seems like with this ruleset, it will always redirect all non .com domains to www.domain.com/de. Whereas if I flip the first two server segments it works fine.
Am I doing something wrong? Why is the order of the rules important if the server names are explicitly specified?
The right configuration would be:
server {
listen 80;
server_name domain.de www.domain.de;
return 301 http://www.domain.com/de$request_uri;
}
server {
listen 80 default_server;
server_name _;
return 301 http://www.domain.com$request_uri;
}
server {
listen 80;
server_name "" localhost domain.com www.domain.com;
...
}
server_name _; is just a popular stub. The default value of the server_name directive is "" which handles requests without "Host" header. If client doesn't send it at all then server_name "" will leads to redirection loop in a configuration like yours.
Please, take a look at:
http://nginx.org/en/docs/http/request_processing.html
http://nginx.org/en/docs/http/server_names.html
http://nginx.org/en/docs/http/converting_rewrite_rules.html
Using server_name _; to mean 'this is the default server' is a common mistake. It has no special meaning, and you need to use the default_server flag on the listen directive to mark that second server as default:
server {
listen 80 default_server;
server_name _;
rewrite ^ http://www.domain.com$request_uri? permanent;
}

Resources