見出し画像

NGINXの設定 Tips 2

はじめに

皆様、あけましておめでとうざいます(もう2月ですが。。。)
今回もNginxのちょとしたTipsに触れたい思います。
かなり基本的な内容となっているので、すでにNginxを利用されている方には物足りないかもしれませんがお付き合い頂ければと思います。
なお前回の記事はこちらになります。(https://note.com/fair_tern448/n/n850954834104

設定ファイルをワイルドカードで読み込まない

実際に利用されている方はわかると思いますが、この手の設定ファイルは用途に応じて分割して管理することが多いです。
設定ファイルが追加された際も読み込まれるように、という意図だと思うのですが、ワイルドカードで設定ファイルを読み込んでいるケースを見かけます。
この場合、意図しない順番で読み込まれてる事もあるので、対象のファイル名はきちんと記載するようにしましょう。
どうしてもワイルドカードで読み込ませたい場合、意図した状態になっているかを後述のコマンドで確認するようにしましょう。

# NG
include /etc/nginx/conf.d/*.conf;

# OK
include /etc/nginx/conf.d/aaa.conf;
include /etc/nginx/conf.d/bbb.conf;
include /etc/nginx/conf.d/ccc.conf;

現在の設定を確認する

設定を変更している場合に、全てを適用した状態の設定を確認したい事があります。
この場合、以下のコマンドで分割ファイルを含めた状態の設定が適用された内容を確認することができます。

$ nginx -T

実行すると以下のような内容が出力されます

# configuration file /usr/local/etc/nginx/nginx.conf:

worker_processes  1;
.....
# configuration file /usr/local/etc/nginx/mime.types:
.....
# configuration file /usr/local/etc/nginx/conf.d/app.conf:
....

"configuration file xxxxx"として、設定ファイルがどの部分に読み込まれているかも確認できるので、設定全体を確認したい場合に便利なオプションとなっています。
なお、単純に構文なチェックだけであれば以下のコマンドで行えます。

$ nginx -t

nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful

mapを活用する

特定の条件で判定したいケースがあると思いますが、そういった場合はmapを利用することですっきりと記載する事ができます。
User-Agentを使ってOS判定するケースを例にとってみます。
どちらの結果は同じになりますが、mapを利用することで非常にシンプルな定義になることがわかると思います。

# ifの場合
server {
	listen 80;

	set $os "unknown";
	if ( $http_user_agent ~ Windows) {
	  set $os "Windows";
	}
	if ( $http_user_agent ~ iPhone) {
	  set $os "iOS";
	}
	if ( $http_user_agent ~ Android) {
	  set $os "Android";
	}
	location / {
	  return 200 "$os\n";
	}
}
# mapの場合
map $http_user_agent $os {
	default unknown;
	~Windows Windows;
	~iPhone iOS;
	~Android Android;
}

server {
	listen 80;
	location / {
		return 200 "$os\n";
	}
}

add_headerをネストさせない

add_header をネストして宣言した場合、最下層の宣言のみが適用されます。
(これは自分がNginxを使い始めた頃にハマり、気づきづらかったので紹介しました)

server {
    listen 80;
    add_header x-test-server "level-1";      # level:1
    set $val '1';

    location / {
      add_header x-test-nested1 "level-2-1"; # level:2
      if ($val) {
        add_header x-test-if "level-3";      # level:3
      }
      add_header x-test-nested2 "level-2-2"; # level:2
      return 200 "ok";
    }
}

この場合、最下層(level:3)に記載されている `x-test-if:level-3` のみがヘッダに設定されます。

$ curl --head http://localhost/
HTTP/1.1 200 OK
Server: nginx/1.23.4
Date: Wed, 07 Feb 2024 08:06:36 GMT
Content-Type: application/octet-stream
Content-Length: 3
Connection: keep-alive
x-test-if: level-3

マニュアルにも記載されていますが、個人的には少しわかりずらいかなと思っています。
以下、マニュアル(Module ngx_http_headers_module)からの抜粋です。

There could be several add_header directives. These directives are inherited from the previous configuration level if and only if there are no add_header directives defined on the current level.

Module ngx_http_headers_module

上記の設定で、ifブロックのadd_headerをコメントアウトすると、level:2でで宣言されているものが適用されます。
この動作からも最下層の設定のみが適用されるということが理解できると思います。

$ curl --head http://localhost/
HTTP/1.1 200 OK
Server: nginx/1.23.4
Date: Wed, 07 Feb 2024 08:07:02 GMT
Content-Type: application/octet-stream
Content-Length: 3
Connection: keep-alive
x-test-nested1: level-2-1
x-test-nested2: level-2-2

IPをキャッシュさせない

リバースプロキシを設定する際に proxy_passを利用しますが、ドメインをそのまま記載すると、設定ファイルの読み込み時に解決したIPがキャッシュされてしまいます。
接続先のIPが固定されていない場合は、この動作では問題となります。
この場合、ドメインを変数に設定しresolverでDNSを指定することで回避できます。

server {
....
    set $proxy_domain www.wingarc.com;
    location / {
        resolver xxx.xxx.xxx.xxx;
        proxy_ssl_server_name on;
        proxy_pass  https://$proxy_domain/;
    }
....
}

補足)
接続先がCloudFrontなどSNI対応の場合`proxy_ssl_server_name on;`を指定してください。

Enables or disables passing of the server name through TLS Server Name Indication extension (SNI, RFC 6066) when establishing a connection with the proxied HTTPS server.

https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_server_name

おまけ:ログのローテートタイミングを調整する

こちらはNginxの設定というよりはlogrotateの話になります。
一般的にはdailyなどでローテートをされていると思いますが、運用をしているとこれが問題となるケースがあります。
具体的には、一定間隔で(差分のある)ログファイルを別サーバにバックアップしている場合などです。
ログのバックアップは必須なので止められませんし、1日おきなどでのバックアップではログファイルがロストする可能性も高まります。
このような場合は、ローテートのタイミングを変更し、ログファイルの肥大化を防ぐことで改善することができます。
タイミングを見直す機会は多くなかったのですが、せっかくなので触れてみました。

最後に

基本的にはマニュアルやヘルプを見ればわかることなのですが、設定していて、うん?となる部分や、管理する上で気にして欲しいポイントには触れたつもりです。
簡単な記事ではありますが、まだ慣れていない方々の助けになれば幸いです。



この記事が気に入ったらサポートをしてみませんか?