fabr
fabr

Reputation: 23

Update nginx dynamically

I have an online software running in my own local server with a fixed IP address to internet.

I am considering to hire a small proxy server with nginx/ubuntu, cloud based, to receive traffic and then forward it to my local server. Therefore I would be benefited from that cloud host protections (DDoS, etc) on top of my firewall appliance, and I could also get two dynamic IP connections instead of one fixed IP (stability improvement).

In this scenario, how could I keep the cloud nginx .conf files automatically updated? Or maybe there is a flaw in this setup?

Thanks in advance.

Upvotes: 0

Views: 2817

Answers (1)

sebres
sebres

Reputation: 820

You need to call nginx -s reload or kill -s HUP $(cat /run/nginx.pid) to force nginx instance reload its configuration. You can do this after your dynamic IP gets updated (e. g. touch some URL as callback on router side with knocking on proxy server, causing such command invocation there).

[UPD] This can be an nginx location which would invoke some script (php, perl, python, etc) for instance via fastcgi or directly (e. g. lua) updating your address in some include file and triggering reload signal.

For example in case of lua-script your nginx.conf may look like this:

# list of backend hosts referenced by dynamic IPs (updated in secret-update-my-ip):
upstream backend {
  include /etc/nginx/my-backend-srv.conf;
}
# location referencing backend:
location ~ \.php$ {
  fastcgi_pass   backend;
  # ...
}

# ...

location = /secret-update-my-ip {
  auth_basic "Technical user area";
  #... provide auth-setting here (file, etc) ...
  content_by_lua_block {
    -- write upstream server with IP of requesting host - $remote_addr:
    local f = io.open("/etc/nginx/my-backend-srv.conf", "w")
    f:write("server " .. ngx.var.remote_addr .. ":8080;\n")
    f:close()
    -- signaling reload:
    os.execute("nginx -s reload")
  }
}

Since this include (/etc/nginx/my-backend-srv.conf) is a normal nginx config-file which can be included somewhere in your nginx, you can store the IP as a variable declaration (like
"set $my_ip "..ngx.var.remote_addr..";\n") and include it in server or location section to be usable there as $my_ip variable.
To update your dynamic IP, it is enough to invoke URI https://host.example.com/secret-update-my-ip (with username and password valid in the location) from the local host (or router) every time its IP becomes changed.
As afore-mentioned knocking (no matter web-, url- or port-range based) you can use some external program, for instance fail2ban monitoring some logs (e. g. noticed your knocking URL call) and reacting with actions similar to action.d/nginx-block-map.conf which is also changing some include (in that case a map) and reloading nginx.

Another way would be to implement or use Dyn-DNS service, for example install own DNS server somewhere, create some FQDN mapping like my-dynamic-backend.ns.example.com with small TTL and update IP of this host to your dynamic IP every time it gets changed (and better with cache invalidation of DNS server).
Then you were able to use it as hostname in upstream or proxy_pass directives, see https://serverfault.com/questions/240476/how-to-force-nginx-to-resolve-dns-of-a-dynamic-hostname-everytime-when-doing-p/593003#593003

Just note that both methods can cause certain unavailability due to some latency between IP switch and full update and refresh of IP on proxy side.

Upvotes: 1

Related Questions