nginx + varnish redirect server IP to url - redirect

i have nginx on port 8080 sitting behind varnish running on port 80. there is only one website on my server. the problem is you can access it by server's IP address too, instead of just url. google indexed this ip and i am afraid of problems with duplicate content.
how do i redirect requests going to IP address to my URL? i tried this code, but it ended up with loop redirects error.
server {
listen 180.10.1.1:80;
server_name 180.10.1.1;
rewrite .* http://www.mysite.com$request_uri permanent;
}
thanks
edit:
rest of vcl
server {
listen 8080;
server_name site.com;
access_log /var/log/nginx/localhost.access.log;
error_page 502 /502.html;
## Default location
location / {
root /home/site.com/public_html;
index index.php;
...

There's a couple of ways to solve this. If Nginx is also serving site.com when you visit the server IP Address then you should adjust the Nginx config so any requests which are directed at the IP address redirect to site.com. Then restart both Nginx and Varnish.

ok the problem was "180.10.1.1:" in the listen directive. i kept there only "listen 80" and now it works fine :)

Related

Nginx redirect *:port to subdomain

I'm working with Nginxand I want to know how can I redirect all request with a specific port to a subdomain ?
This is my default.conf :
server{
listen 80 default_server;
server_name localhost;
location / {
root /usr/share/nginx/html;
}
}
server{
listen 80;
server_name blog.mydomain.com;
location / {
proxy_pass http://my-ip:8080;
}
}
So with this I have the default mydomain.com serve the html folder, and a subdomain blog.mydomain.com serve an application running port 8080.
My problem is when I try to access directly my-ip:8080, or mydomain.com:8080 or blog.mydomain.com:8080 the server serve the application running port 8080 and I want to redirect all these requests to blog.mydomain.com without the :8080.
How can I do that ? Automatically redirect to blog.mydomain.com if I specify :8080 in the url ?
When you use my-ip:8080 or mydomain.com:8080, you call directly your application, not nginx. The issue I see here is not "my webapp doesn't redirect to nginx" but "I have a proxy but my webapp is directly accessible from the internet".
A clean way to fix it is to hide your application from the internet and let nginx be the only way to contact it. Configure your application to listen on localhost (it looks like it listens on * or 0.0.0.0, meaning all interfaces). Then, tell nginx to proxy requests to http://localhost:8080;.
If you really want to keep your application listening on *:8080, you can add a HTTP header in nginx (like X-Forwarded-For with proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;) and detect it in your application. Without it, redirect to nginx. Note that anyone can add HTTP headers...
There is two solutions for your problem:
If you can change code of application then you can handle HTTP request in application. You should be able get information about port from headers.
If you cannot change code of application but you can change port on which application is listening, then you can do redirect in nginx. To do this, you need start listening on port 8080 in nginx and redirect it to 80, and on 80 port you change proxy_pass to new port of application.

nginx reverse proxy a REST service alternate 200 and 404 responses for same uri

the nginx.conf:
server {
listen 8080;
}
server {
listen 80;
server_name localhost;
location / {
root /test/public;
index index.html index.htm;
}
location /api {
proxy_pass http://localhost:8080;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
the request and reponse headers are almost plain, no auth/session/cache parameters involved.
For same uri, first request will return successfully, while second will return 404, and so on.
I've tried disabling proxy buffering, but has no effect.
I'm 99.99% sure you have IPv6 enabled. In that case localhost resolves into two IP addresses 127.0.0.1 and [::1] and nginx balancing requests between them.
http://nginx.org/r/proxy_pass:
If a domain name resolves to several addresses, all of them will be used in a round-robin fashion.
On the other hand, you have listen 8080; directive that tends to listens only to IPv4 addresses (depends on OS, nginx version and other environment).
You could solve you problem in several ways:
use explicit IPv4 address proxy_pass http://127.0.0.1:8080;
use explicit IPv4 and IPv6 listen listen [::]:8080 ipv6only=off;
I observed the same problem in a docker enviroment. But the reason was independed from nginx. I just made a stupid copy-paste-mistake.
The setting:
I deployed the docker container by several docker-compose files. So I have following structure:
API-Gateway-Container based on nginx which references to
Webserver 1 based on nginx and
Webserver 2 based on nginx
Each of them has its own docker and docker-compose file. Because the structure of the compose-files for Webserver1 and Webserver2 is very similiar, I copied it and replaced the container name and some other stuff. So far so good. Starting and stopping the containers was no problem, watching them by docker container ls shows no abnormality. Accessing Webserver1 and Webserver2 by http://localhost:<Portnumber for server> was no problem, but accessing Webserver1 through the api gateway leads to alternating 200 and 404 responses, while Webserver2 works well.
After days of debugging I found the problem: As I mentioned I copied the docker-compose file from Webserver1 for Webserver2 and while I replaced the container name, I forgot to replace the service name. My docker-compose file starts like
version: '3'
services:
webserver1:
image: 'nginx:latest'
container_name: webserver2
...
This constellation also leads to the described behavior.
Hope, someone can save some days or hours by reading this post ;-)
André
Well. In my case, the problem was pretty straightforward. What was happening was, I had about 15 server blocks, and the port that I setup for my nodejs proxy_pass was already being used on some old server block hiding in my enabled servers directory. So nginx randomly was proxy passing to the old server which was not running and the one I just started.
So I just greped for the port number in the directory and found 2 instances. Changed my port number and the problem was fixed.

nginx https redirect from IP to IP (not to server name)

I am using a block to redirect all http traffic to https. Simple stuff. However, if I address the server directly by IP, it always redirects to the server_name given. If I do not give a server_name, it does not redirect. This is highly undesirable, as I may be on a LAN where a domain name would go unresolved. Here is my redirect block:
server {
listen 80 default_server; ## listen for ipv4; this line is default and implied
return 301 https://$server_name$request_uri;
}
It redirects to server_name because you set it up like that.
Look at your return 301 https://$server_name$request_uri;. Either you replace $server_name by $host or by the IP you want to redirect to.

AWS : ELB : Route 53 : Nginx : naked domain redirect

Setup
I have two rails app instances running in Opsworks Layer.
I am using Route 53 and an ELB to route traffic to my Layer.
Objective
To redirect naked domain traffic to my www domain.
chicken.com -> www.chicken.com
What I tried
I Alter my nginx conf (on one instance) to solve this problem. I added the following:
server {
listen 80;
server_name chicken.com;
return 301 $scheme://www.chicken.com$request_uri;
}
... rest of config here
Result
Instance is no longer hittable by its IP.
ELB marked the instance I had altered as "Out of Service" since it could no longer be reached by IP (the health check fails).
Question
How can I route naked domains to www domains yet keep my ELB health checks happy?
The ELB health check expects a 200 response. Are you checking against chicken.com instead of www.chicken.com? A redirect page is not sufficient for the health check.
To have both the redirect and provide a 200 response for the ELB check (coming from an internal IP), use the following config:
server {
listen 80;
server_name chicken.com;
return 301 $scheme://www.chicken.com$request_uri;
}
server {
listen 80 default_server;
server_name www.chicken.com;
...
Note the default_server option. If not set, the first server defined is the default one. See the nginx docs for details.

NGINX - redirect all unconfigured subdomains

I'm happy to join community and want to share with you with my little problem.
I've got wildcard entry for example.com in my DNS which points all subdomains to some machine
* IN A 172.172.172.172
While NGINX configuration for this domain contains only actively used subdomain names
server {
listen 10.0.0.1:80;
server_name example.com www.example.com
moskva.example.com www.moskva.example.com
tokyo.example.com www.tokyo.example.com;
...
}
What I want to achieve is directing all unconfigured subdomains like 'mistake.example.com' to specific address.
Is there any elegant way of solving this problem?
Best Regards
Arek
This will instruct the site to redirect any unmatched traffic to example.com
server {
listen 80 default_server;
return 301 http://example.com;
}
You can set a default server section like this:
server {
listen 10.0.0.1:80 default_server;
server_name _;
...
}