Frage Wie erzwinge ich Nginx, um DNS (eines dynamischen Hostnamens) jedes Mal aufzulösen, wenn ich proxy_pass mache?


Ich benutze nginx / 0.7.68, läuft auf CentOS, mit der folgenden Konfiguration:

server {
    listen       80;
    server_name ***;
    index index.html index.htm index.php default.html default.htm default.php;

    location / {
            root   /***;
            proxy_pass   http://***:8888;
            index  index.html index.htm;
    }
    # where *** is my variables

Das proxy_pass gehört zu einem DNS-Record, dessen IP sich häufig ändert. Nginx speichert die veraltete IP-Adresse zwischen, was zu einer Anfrage an die falsche IP-Adresse führt.

Wie kann ich verhindern, dass Nginx die IP-Adresse zwischenspeichert, wenn sie veraltet ist?


36
2018-02-26 00:55


Ursprung


Wenn man durch die nginx-Quelle schaut, scheint es, dass nginx hartcodiert ist, um Verschlüsse für ihre TTL zu cachen - was ist die TTL auf Ihren dynamischen DNS? - lunixbochs
TTL auf meiner ddns ist 60s, der Standardwert von dyndns.com - xiamx
Siehe auch stackoverflow.com/questions/26956979/... - Cheekysoft


Antworten:


Es ist eine interessante Frage und AFAIK, die nicht gut funktionieren wird. Sie können versuchen, das zu verwenden stromaufwärts Modul und verwenden Sie die Richtlinien für Failover, um zu sehen, ob es als Hack funktioniert.

2018 edit: Viele Dinge haben sich geändert. Überprüfen Sie die Antwort von @ohaal, um echte Informationen darüber zu erhalten.


7
2018-02-26 01:19



Überraschenderweise, als ich zum Upstream wechselte, hat alles wie erwartet funktioniert. Ich werde das als richtige Antwort markieren - xiamx
Laut Dokumentation gibt es einen speziellen Upstream server Flagge resolve das ist nur in der kommerziellen Version verfügbar (siehe nginx.org/en/docs/http/ngx_http_upstream_module.html#server) - omribahumi
Hier ist ein Weg, es mit FREE Nginx zu tun, nur ein paar Tricks mit Resolver: distinplace.com/2017/04/19/nginx-resolver-explained (es ist auch in der Antwort unten angegeben, aber es wird nicht als richtige Antwort aus irgendeinem Grund akzeptiert?) - gansbrest
@gansbrest diese Seite scheint eine Art von Spam-Site zu sein? Ich würde bitten, dass Sie Ihre Antwort entfernen. - majikman


Akzeptierte Antwort funktionierte nicht für mich auf Nginx / 1.4.2.

Rahmen proxy_pass zu einer variablen Auflösung der DNS-Namen, da Nginx Variablen anders behandelt als statische Konfigurationen. [1]

Beispiel:

server {
    ...
    resolver 127.0.0.1;
    set $backend "http://dynamic.example.com:80";
    proxy_pass $backend;
    ...
}

Hinweis: Ein Resolver (z. B. der von Ihnen verwendete Name-Server) MUSS konfiguriert sein, damit dies funktioniert.

Standardmäßig speichert nginx Antworten mit dem TTL-Wert einer Antwort. Ein optional gültig Parameter erlaubt das Überschreiben: [2]

resolver 127.0.0.1 [::1]:5353 valid=30s;

Vor der Version 1.1.9 war das Einstellen der Cachingzeit nicht möglich, und Nginx hat immer Antworten für die Dauer von 5 Minuten zwischengespeichert.

Quellen:
[1] http://forum.nginx.org/read.php?2,215830,215832#msg-215832
[2] http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver


65
2018-05-04 09:59



Würde dies nicht eine DNS-Abfrage bei jeder einzelnen Anfrage erzwingen? das klingt nach einer schrecklichen Leistung ... - lucascaro
Nein, lies die Quelle. In such setup ip address of "foo.example.com" will be looked up dynamically and result will be cached for 5 minutes. Ich habe es der Klarheit halber hinzugefügt. - ohaal
Nachdem ich die meiste Zeit meines Tages damit verbracht habe - auf Ubuntu 12.04 mit nginx 1.1.19, set Innerhalb location funktioniert nicht richtig. In acht nehmen - omribahumi
Diese Lösung hat mit mir funktioniert, aber ich konnte keine Referenz für die 5 Minuten TTL finden. nginx.org/en/docs/http/ngx_http_core_module.html#resolver  By default, nginx caches answers using the TTL value of a response. An optional valid parameter allows overriding it: resolver 127.0.0.1 [::1]:5353 valid=30s; - Montaro
Hinweis: Für Docker liegt der DNS-Resolver bei 127.0.0.11. Für die Entwicklung verwende ich Folgendes: resolver 127.0.0.11 [::1]:5353 valid=15s; - Dalibor Filus


Es gibt wertvolle Informationen in Gansbrest Kommentar und ohaal Antwort.

Aber ich denke, es ist wichtig, diesen offiziellen Nginx-Artikel aus dem Jahr 2016 zu erwähnen, in dem das Nginx-Verhalten in dieser Angelegenheit und die möglichen Lösungen klar erläutert werden: https://www.nginx.com/blog/dns-service-discovery-nginx-plus/

Wir müssen in der Tat den "Domain - Namen in einer Variable setzen" und den Resolver Richtlinie.

Wenn Sie jedoch eine Variable verwenden, wird das Umschreibverhalten geändert. Möglicherweise müssen Sie die rewrite-Anweisung verwenden, dies hängt von Ihrem Standort und der Konfiguration von proxy_pass ab.

PS: hätte einen Kommentar gepostet, aber noch nicht genug Punkte ...


6
2018-06-23 21:37





Ich habe ein Skript gehackt, um einen conf.d-Ordner Upstream für DNS-Änderungen zu sehen und Nginx nach Erkennung neu zu laden. Es ist ein erster Durchlauf und kann sicherlich verbessert werden (im nächsten Durchlauf verwende ich nginx -T, um Upstreams spezifisch zu analysieren. Die gleiche Idee könnte für proxy_pass-Direktiven verwendet werden):

#!/bin/bash

get_upstreams() {
  local files=$@
  grep -hEo '(server\s+)[^:;]+' $files | cut -d' ' -f 2
}

resolve_hosts() {
  local hosts=$@
  for h in $hosts; do dig +short $h; done | sort -u
}

watch_dir=$1

[ -d $watch_dir ] || exit 2

upstreams=$(get_upstreams $watch_dir/*)
ips=$(resolve_hosts $upstreams)
if [ ! "$ips" ]; then
  echo "Found no resolvable hosts in $watch_dir files."
fi

host_hash=$(echo $ips | /usr/bin/sha512sum)

echo $host_hash
echo $ips

while [ -d $watch_dir ]; do
  sleep 30
  upstreams=$(get_upstreams $watch_dir/*)
  ips=$(resolve_hosts $upstreams)
  new_hash=$(echo $ips | /usr/bin/sha512sum)
  if [ "$host_hash" != "$new_hash" ]; then
    echo Detected an upstream address change.  $ips
    echo Reloading nginx
    echo $new_hash
    echo $ips
    /sbin/service nginx reload
    host_hash=$new_hash
  fi
done

0
2018-04-24 01:21