Nginx + ip_nonlocal_bind


#1

Greetings.

We would like to setup our Nginx instances in a HA pair. Using
Heartbeat, we have Nginx listening on virtual addresses on the active
server.

On the passive server, we cannot get Nginx to start up because those
virtual (or floating) address are not configured on the server until
Heartbeat detects a failover condition.

Is Nginx able to bind to a non-local IP address? We’ve tried setting the
ip_nonlocal_bind kernel option with no luck.

Some important information:

nginx -v

nginx version: nginx/0.7.53

Starting nginx: [emerg]: bind() to 213.167.72.152:80 failed (98: Address
already in use)

CentOS 5.3

server { listen 213.167.72.152:80 default;

Any other settings we should provide?

OT: Many thanks for the excellent software.

Thanks,

Griff


#2

i thought nginx listened on port 80 by default. couldn’t you just not
explicitly define it?

On Thu, Apr 30, 2009 at 11:26 PM, Tristan Griffiths


#3

On Fri, May 01, 2009 at 04:26:55PM +1000, Tristan Griffiths wrote:

Is Nginx able to bind to a non-local IP address? We’ve tried setting the
ip_nonlocal_bind kernel option with no luck.

Some important information:

nginx -v

nginx version: nginx/0.7.53

Starting nginx: [emerg]: bind() to 213.167.72.152:80 failed (98: Address
already in use)

This is because another process is laready listen on this address:port.

CentOS 5.3

server { listen 213.167.72.152:80 default;

Any other settings we should provide?

To listen on temporarily non configured addresses you may use something
like this:

server {
     listen  80;
}

server {
     listen 213.167.72.152:80 default;
     ...
}

server {
     listen 213.167.72.1:80 default;
     ...
}

nginx binds to *:80 only, but tests an address where a request comes to.


#4

On Fri, May 1, 2009 at 12:00 AM, Tristan Griffiths
removed_email_address@domain.invalid wrote:

http {
  server {

  •    listen 192.168.1.1:80 default;
    
  • Â Â Â Â listen 80 default;

  }
}

try that

also you could try dropping default. maybe the behavior will change. i
guess it depends if nginx will listen on new ips that are inherited
through heartbeat or not. i haven’t tried but i’ve never hit the
situation where i had to tell nginx to re-bind. but i may have never
-got- to that situation to begin with :stuck_out_tongue:


#5

On Thu, Apr 30, 2009 at 11:26 PM, Tristan Griffiths

Is Nginx able to bind to a non-local IP address? We’ve tried setting
already in use)
OT: Many thanks for the excellent software.
Yes, nginx does listen on port 80 by default.

Basically, we are trying to get nginx to listen on an IP address for
which the machine does not currently have (non-local).

Say we have a server with IP address 10.1.1.1, we want Nginx bound to IP
192.168.1.1 without complaining.

The idea being that in a failover situation, the IP 192.168.1.1 may end
up being assigned to the server by an external process like Heartbeat.

Even the most basic config (below) is not letting nginx start up on the
non-local IP.

user nginx;
worker_processes 4;
pid /var/run/nginx.pid;

error_log /var/log/nginx/error.log;

events {
worker_connections 1000;
}

http {
server {
listen 192.168.1.1:80 default;
}
}


#6

-----Original Message-----
From: removed_email_address@domain.invalid [mailto:removed_email_address@domain.invalid] On Behalf
Of

Heartbeat, we have Nginx listening on virtual addresses on the
active

Some important information:

nginx -v

nginx version: nginx/0.7.53

Starting nginx: [emerg]: bind() to 213.167.72.152:80 failed (98:
Address
already in use)

This is because another process is laready listen on this
address:port.
To listen on temporarily non configured addresses you may use
something

server {
     listen 213.167.72.1:80 default;
     ...
}

nginx binds to *:80 only, but tests an address where a request comes
to.

Hadn’t tried that. Works a treat.

Hope this helps someone else in future.

For SSL hosts, would we just “listen 443; ssl on;” (with a dummy
certificate)?

Thanks,

Griff


#7

On Fri, May 01, 2009 at 05:27:10PM +1000, Tristan Griffiths wrote:

Greetings.
Is Nginx able to bind to a non-local IP address? We’ve tried setting
already in use)

server {

to.

Hadn’t tried that. Works a treat.

Hope this helps someone else in future.

OK, however, with ip_nonlocal_bind nginx should bind() successfully
even to non existent addresses. You should look why bind() returned
(98: Address already in use).

For SSL hosts, would we just “listen 443; ssl on;” (with a dummy
certificate)?

Yes. Or you may combine SSL/non-SSL servers in one server:

   server {
        listen  80;
        listen  443 default ssl;

#8

-----Original Message-----
From: removed_email_address@domain.invalid [mailto:removed_email_address@domain.invalid] On Behalf
Of

Of

Heartbeat, we have Nginx listening on virtual addresses on the
setting

already in use)

server {

comes

For SSL hosts, would we just “listen 443; ssl on;” (with a dummy
certificate)?

Yes. Or you may combine SSL/non-SSL servers in one server:

   server {
        listen  80;
        listen  443 default ssl;

This is what I have now done, although I was being tripped up by the
“deferred” option defined in our virtual host listen directives.
Setting:

server { listen 80 default deferred; …

Seems to work.

Catch with combining SSL/non-SSL is that our backend app servers require
the X-FORWARDED_PROTO header to know if the client is getting an
encrypted connection. Is there a way around this?


#9

-----Original Message-----
From: removed_email_address@domain.invalid [mailto:removed_email_address@domain.invalid] On Behalf
Of

To: removed_email_address@domain.invalid

To: removed_email_address@domain.invalid

server.
ip_nonlocal_bind kernel option with no luck.

Any other settings we should provide?
listen 213.167.72.152:80 default;
to.
certificate)?
Setting:

server { listen 80 default deferred; …

Seems to work.

Catch with combining SSL/non-SSL is that our backend app servers
require
the X-FORWARDED_PROTO header to know if the client is getting an
encrypted connection. Is there a way around this?

Answered my own question…

proxy_set_header X-FORWARDED_PROTO $scheme;

Easy!

Thanks again Igor for fantastic software.