John Greene
John Greene

Reputation: 2606

NGINX bind to a specific network interface, regardless of IP address

Is there a way to make Nginx 1.11 bind to a specific interface regardless of the IP address?

I've got a home gateway to an ISP provider; it uses DHCP client to obtain its dynamic IP address. I do not know what that IP address is at NGINX configuration time.

Surely, there must be a way to make such a fine HTTP server bind to a specific network interface? I know that Apache can.

Upvotes: 11

Views: 22398

Answers (2)

puchu
puchu

Reputation: 3662

Comment from author:

The other interfaces are related to enterprise network (which has its own web server), test network (which has none), and a virtual network for the virtual host farm (which runs Apache). Hence, the need to bind this Nginx specifically to the external interface.

It is not possible using vanilla nginx. Moover it is not possible with almost any application.

There are 2 ways of archiving this goal on Linux:

  1. Add default route with high metric to any routing table that points to the specific interface + patch nginx to use setsockopt SO_BINDTODEVICE.
  2. Add default route with high metric to new routing table that points to the specific interface, add cgroup, add fwmark for packets from this group, route all packets using specific mark to specific interface, assign cgroup to nginx.

The first solution is very straightforward, but it requires you to patch nginx. You may do it here. The problem is that you need to get specific interface name from settings. But you need another patch that will let you to store interface name in settings and pass it to ngx_event_connect_peer.

The second solution is universal, but it requires you to understand iptables and cgroups. The example is here.

Upvotes: 1

Alex Howansky
Alex Howansky

Reputation: 53626

Edit your startup sequence to run a command or script that captures the interface's IP address and writes it to a file in the format listen <ip>:80 or whatever port you want:

echo "listen $(ip -o -4 a s eth0 | awk '{ print $4 }' | cut -d/ -f1):80;" > /path/to/some/file

Then just have your nginx config include that file:

include /path/to/some/file;

Obviously, you'll need to make sure the IP capture occurs before the nginx startup does.

Upvotes: 8

Related Questions