nginxのリバースプロキシ設定で、転送先をIPではなくホスト名で指定していると、ある日突然エラーが発生する現象に遭遇しました。
ググると複数の記事が見つかったので、よくある現象?のようです。
リバースプロキシ設定
元々は↓のように設定していました。
proxy_pass
のところで、リクエストの転送先をホスト名で指定しています。
location ~ ^/hoge { proxy_pass https://example.com; }
この状態だとnginx起動時に転送先のIPがキャッシュされ、以降はキャッシュしたIPへ転送するようになるようです。
IPが変わってもキャッシュしているIPへ転送し続けるので、AWSのELBを使っていたりすると、IPが変わった際にエラーが起きてしまうことも。
それを回避するため、proxy_pass
と併せてresolverを設定しておきます。
resolverを設定する
resolverを設定すると↓のような感じに。
location ~ ^/hoge { resolver 10.0.0.2; set $host_name example.com; proxy_pass https://$host_name; }
resolverで指定するDNSのIPは、AWSの場合はVPCのネットワーク範囲+2とのこと。
AmazonProvidedDNS は Amazon DNS サーバーです。このオプションは、VPC のインターネットゲートウェイを介して通信する必要があるインスタンスに対して DNS を有効にします。文字列 AmazonProvidedDNS は、リザーブド IP アドレスで実行中の DNS サーバーにマップされ、VPC IPv4 ネットワークの範囲に 2 をプラスした値です。例えば、10.0.0.0/16 ネットワークの DNS サーバーの位置は 10.0.0.2 となります。
DHCP オプションセット - Amazon Virtual Private Cloud
デフォルトではTTLが切れたタイミングでDNSに問い合わせ。
resolverにvalid
を設定すると、任意のタイミングで問い合わせることができるようです。
ex. valid指定
location ~ ^/hoge { resolver 10.0.0.2 valid=5s; # 5秒ごとに問い合わせ set $host_name example.com; proxy_pass https://$host_name; }
nginxのバージョンによる?のか、nginx 1.6系、1.8系ではsetでホスト名を変数に入れないとエラーになるようです。
nginx 1.10.1では、setを使わずに指定しても設定できました。
参考
nginx proxy の名前解決問題、ファイナルアンサー? – 1Q77
Nginx のDNS 名前解決とS3 やELB へのリバースプロキシ :: by and for engineers
Nginxでproxy_passにホスト名を書いた時の名前解決のタイミング - (ひ)メモ