I am currently facing a small problem using nginx to redirect to another host. I want to for example redirect https://service.company.com/new/test.html to https://new-service.company.com/test.html .
For now I have following configuration, which redirects me to https://new-service.company.com/new/test.html .
server {
# SSL
ssl_certificate /etc/nginx/cert/chained_star_company.com.crt;
ssl_certificate_key /etc/nginx/cert/star_company.com.key;
listen 443;
server_name service.company.com;
location /new/$1 {
return 301 $scheme://service-new.company.com/$1;
}
}
I also tried following with the same result:
return 301 $scheme://service-new.company.com/$request_uri
You want to rewrite the URI and redirect. You can achieve it using location and return directives, but a rewrite directive would be the simplest approach:
rewrite ^/new(.*)$ https://new-service.company.com$1 permanent;
See this document for more.
BTW, the problem with your location block solution, was the regular expression capture, wasn't. Use:
location ~ ^/new(.*)$ {
return 301 https://new-service.company.com$1$is_args$args;
}
See this document for more.
Related
Trying to do a simple redirect:
rewrite https://url.example.com(.*) https://example.com/plugins/url permanent;
Anytime url.example.com is hit, I want it to redirect to that specific path.
EDIT:
Will try to explain this better, as I'm trying to redirect to a specific domain from another.
server {
server_name example.com plugin.example.com;
root /home/www/example.com/public;
}
I see the location used for redirects such as:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
But not sure how to use it in my case, which is to change plugin.example.com to example.com/plugin.
For example:
http://plugin.example.com
https://plugin.example.com
https://plugin.example.com/blah
https://plugin.example.com/blah/more
All of these should redirect to:
https://example.com/plugin
If the original URL is https://url.example.com or https://url.example.com/ then the normalized URI used by the rewrite and location directives will be /. The scheme, host name and query string have all been removed.
To perform a permanent redirect to a URL with a different host name:
Using rewrite (see this document for details):
rewrite ^/$ https://example.com/foo permanent;
Or using location and return (see this document for details):
location = / {
return 301 https://example.com/foo;
}
The second solution is more efficient, as there are no regular expressions to process.
If the original URL includes a query string: The rewrite will append it automatically unless a trailing ? is added. The return will not, but can be added by appending $is_args$args.
If the scheme and host name are unchanged, then both statements can be simplified:
rewrite ^/$ /foo permanent;
Or:
location = / {
return 301 /foo;
}
Redirect from subdomain to subfolder on main site
Do you require a redirect from a subdomain to a subfolder on the main site?
This would be best accomplished by a separate server context, with the appropriate server_name specification.
Else, you could also do this with an if statement testing against $host.
As already pointed out elsewhere, rewrite directive operates based on $uri, which does not contain the hostname.
server_name-based matching (recommended):
Hardcoded redirect with a limited number of hostnames (recommended):
server {
server_name plugin.example.com;
return 301 $scheme://example.com/plugin$request_uri;
}
server {
server_name about.example.com;
return 301 $scheme://example.com/about$request_uri;
}
Regex-based redirect from any subdomain to the main domain:
server {
server_name ~^(?:www\.)?(?<subdomain>.*)\.example\.com$;
return 301 $scheme://example.com/$subdomain$request_uri;
}
Regex-based redirect from a limited number of subdomain to the main domain:
server {
server_name ~^(?:www\.)?(?<subdomain>plugin|about)\.example\.com$;
return 301 $scheme://example.com/$subdomain$request_uri;
}
if-based:
If-statement-based redirect with hardcoded hostnames:
server {
server_name .example.com;
…
if ($host = plugin.example.com) {
return 301 $scheme://example.com/plugin$request_uri;
}
if ($host = about.example.com) {
return 301 $scheme://example.com/about$request_uri;
}
…
}
If-statement-based redirect with a regex-based matching:
server {
server_name .example.com;
…
if ($host ~ ^(?:www\.)?(?<subdomain>plugin|about)\.example\.com$) {
return 301 $scheme://example.com/$subdomain$request_uri;
}
…
}
Please refer to http://nginx.org/r/server_name for more discussion of which option may be best for you.
You can create separate servers for example.com and plugin.example.com. And create redirect inside plugin.example.com server.
server {
server_name plugin.example.com;
return 301 https://example.com/plugin;
}
server {
server_name example.com;
root /home/www/example.com/public;
}
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.
I would like to know how to manipulate request_uri in my nginx config.
I am trying to redirect all traffics with uri domain1.com/post/{slug} to domain2.com/blog/{slug}.
Currently, I set up the following:
server {
listen 80;
server_name domain1.com;
return 301 $scheme://domain2.com/blog$request_url;
}
But the problem is domain1.com/post/{slug} is redirected to domain2.com/blog/post/{slug}, rather than domain2.com/blog/{slug}.
How can I proceed from here?
Use a rewrite ... permanent statement rather than the return statement.
rewrite ^/post(.*)$ $scheme://domain2.com/blog$1 permanent;
return 404;
Replace the return 404 with whatever the default case should be for URIs which do not begin with /post.
See this document for details.
I have been tasked with a couple project.
We have two directories on our server, one is
http://example.com/app
and the other is
http://example.com/fw
What I have been asked to do, is redirect from http to https if any visitor lands on a page in these two directories (app and fw)
Here is what I have done so far in the config file. When I added the lines to my config file below 'server' and restarted the site would not come back up. Unfortunately I don't have access to the log files. Appreciate anyone willing to take a look at this
location ~ ^/miner/memclub/.+\.html$ {
rewrite ^(.+)\.html$ /bootstrap.php?file=$1.html last;
rewrite ^(.+)\.phtml$ /bootstrap.php?file=$1.phtml last;
error_page 404 = /404.php;
}
server {
server_name site.org;
server_name *.site.org;
location /app {
if ( $scheme = http ) {
rewrite ^ https://site.org/app last;
}
}
}
First of all I don't think you can have 2 server_name, merge those two lines into one line
server_name example.com *.example.com;
And to do the https redirect i would recommend using 2 separate servers, you need one listening to port 443 anyway
server {
server_name example.com www.example.com; # which ever you are using
listen 443 ssl;
location / {
# all your https configuration
}
}
server {
server_name example.com www.example.com:
listen 80;
location /app {
return 301 https://$http_host$request_uri;
}
location /fw {
return 301 https://$http_host$request_uri;
}
location / {
# the rest of the non https configuration
}
}
I know you can merge both app and fw into one location, but I believe doing it without regex is faster, if you want to do it anyways here it is
location /(app|fw) {
return 301 https://$http_host$request_uri;
}
Each nginx config can act for a wide range of domains but I want to auto-redirect requests to the first domain name (the official one).
server {
server_name a.example.com b.example.com;
}
I want that if someone enters b.example.com/some, to go directly to a.example.com/some
This is pretty much the same thing as the GOOD example for http://wiki.nginx.org/Pitfalls#Server_Name. That is, you should use two servers:
server {
server_name b.example.com;
return 301 $scheme://a.example.com$request_uri;
# For pre-0.8.42 installations:
# rewrite ^ $scheme://a.example.com$request_uri? permanent;
}
server {
server_name a.example.com;
# Do stuff
}
To do this in a single server block, you can use an if and the $server_name variable:
server_name primary.tld secondary.tld;
if ($host != $server_name) {
rewrite ^ $scheme://$server_name permanent;
}
Or, to keep any query parameters:
server_name primary.tld secondary.tld;
if ($host != $server_name) {
rewrite ^/(.*) $scheme://$server_name/$1 permanent;
}
Here, $server_name refers to primary server name, which is the first name in the server_name directive, while $host refers to the hostname given in the HTTP request.
Note that the if statement in nginx configuration does not always do what you would expect and its use is discouraged by some. See also https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/
This answer was inspired by this answer to another question which uses a similar aproach.
Combined version of #kolbyjack and #Matthijs answers with one server block. This config will redirect all requests with Host header different from example.com and process only example.com requests.
server {
server_name example.com a.example.com b.example.com;
if ($host != $server_name) {
return 301 $scheme://$server_name$request_uri;
}
# processing requests to $server_name (example.com) only
...
}