FileMakerServer での nginx チューニング

# はじめに
## 前書き
* 本記事は [FileMaker Advent Calendar 2022](https://qiita.com/advent-calendar/2022/filemaker) 22 日目の記事です。

https://qiita.com/advent-calendar/2022/filemaker

## 対象読者
* [Claris FileMaker Server](https://www.claris.com/ja/filemaker/server/) で [nginx](https://www.nginx.co.jp/) を運用している人

## 前提
* [前編記事 - FileMakerServer での nginx チューニングをするための前準備](https://qiita.com/Hi_Noguchi/items/52ce42c85a30bf6f3b39) を読まれていること。

https://qiita.com/Hi_Noguchi/items/52ce42c85a30bf6f3b39


# nginx のチューニング
## ファイルの分割
* さて、前編記事からの続きです。チューニングに入っていきましょう
* まずはファイルが長大になりすぎるのを避けて運用をしやすくするために、分割しておきます
* どこで分割するのがよいかというと、以下のあたり、 `sorce_charset utf-8;` と `server {` との間あたりにするのがよいでしょう

```nginx:fms_nginx.conf
### 前略 ###

proxy_request_buffering off; # we dont wait until the whole request is completed

charset utf-8;
source_charset utf-8; 

server {
  listen 80;

  # Add headers for Cross-Origin Resource Sharing (CORS) policies

### 後略 ###
```

* 分割をおこなうために `fms_nginx_custom.conf` という別ファイルを一つ作成します

```sh
cd /opt/FileMaker/FileMaker\ Server/NginxServer/conf/
sudo touch fms_nginx_custom.conf
```

* 作成したファイルに対して権限まわりの設定をおこないます
  * デフォルトであれば user が `fmserver` で group が `fmsadmin` のはず

```sh
sudo chown fmserver:fmsadmin fms_nginx_custom.conf
sudo chmod 755 fms_nginx_custom.conf
```

* これで準備完了なので、`fms_nginx.conf` の中身、上記に示した `server {` 以下の記述を `fms_nginx_custom.conf` に転記してきます
  * 末尾に http ディレクティブの閉じタグがあるので、そこの処理だけ要注意です
  * 読むのが難しければ、後の方で全行記述しますので、そこから転記してしまってください
* さらに `fms_nginx.conf` の末尾で `fms_nginx_custom.conf` を読み込む宣言をします

```nginx
include "/opt/FileMaker/FileMaker Server/NginxServer/conf/fms_nginx_custom.conf";
```

* OS 再起動により nginx の設定を再読み込みした後、`sudo systemctl status com.filemaker.nginx.start` でエラーが出ていないことが確認できればヨシです
  * OS 再起動以外の nginx の設定再読込方法が見つかり次第、記述変更します……
* この時点で、それぞれのファイルの中身は以下のようになります
  * 要は http ディレクティブ内にある server ディレクティブのみを切り分けたかたちです

```nginx:fms_nginx.conf
# Claris nginx conf
user       fmserver fmsadmin;
worker_processes  5;  ## Default: 1

events {
  worker_connections  4096;  ## Default: 1024
}

http {
 include "/etc/nginx/mime.types"; 
 map $http_upgrade $connection_upgrade {
   default upgrade;
   '' close;
 }

 # hide nginx version
 server_tokens off;

 # Set website folder
 root "/opt/FileMaker/FileMaker Server/NginxServer/htdocs/httpsRoot";

 access_log "/opt/FileMaker/FileMaker Server/NginxServer/logs/access.log"; # this can be set 'off' to improve performance
 error_log "/opt/FileMaker/FileMaker Server/NginxServer/logs/error.log";
 
 # Enable SSL
 ssl_certificate     "/opt/FileMaker/FileMaker Server/CStore/serverCustom.pem";
 ssl_certificate_key "/opt/FileMaker/FileMaker Server/CStore/serverKey.pem";
 ssl_password_file   "/opt/FileMaker/FileMaker Server/CStore/.passphrase";

 ssl_protocols TLSv1.2 TLSv1.3; 
 ssl_prefer_server_ciphers on;
 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:!DH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;

 # Optimize session cache
 ssl_session_cache   shared:SSL:40m;
 ssl_session_timeout 4h;
 
 # Enable session tickets
 ssl_session_tickets on;

# Admin can enable gzip compression if needed   
 # compression
#  gunzip on;
#  gzip on;

 # Compress all the following MIME-types.
#  gzip_types
#   application/atom+xml
#   application/geo+json
#   application/javascript
#   application/x-javascript
#   application/json
#   application/ld+json
#   application/manifest+json
#   application/rdf+xml
#   application/rss+xml
#   application/vnd.ms-fontobject
#   application/wasm
#   application/x-web-app-manifest+json
#   application/xhtml+xml
#   application/xml
#   font/eot
#   font/otf
#   font/ttf
#   image/bmp
#   image/svg+xml
#   image/gif
#   image/jpeg
#   image/png
#   image/tiff
#   image/webp
#   image/x-icon
#   video/3gpp
#   video/avi
#   video/mp4
#   video/mpeg
#   video/ogg
#   video/quicktime
#   video/webm
#   text/cache-manifest
#   text/calendar
#   text/css
#   text/javascript
#   text/markdown
#   text/plain
#   text/xml
#   text/vcard
#   text/vnd.rim.location.xloc
#   text/vtt
#   text/x-component
#   text/x-cross-domain-policy;

#  gzip_proxied  no-cache no-store private expired auth;
#  gzip_min_length 1000;

 # set payload limit
 # currently, we have no limit. Admin can set to 20G, 200M or any value based on business spec
 client_max_body_size 0;

 proxy_request_buffering off; # we dont wait until the whole request is completed

 charset utf-8;
 source_charset utf-8;

include "/opt/FileMaker/FileMaker Server/NginxServer/conf/fms_nginx_custom.conf";
}
```

```nginx:fms_nginx_custom.conf
server {
    listen 80;

    # Add headers for Cross-Origin Resource Sharing (CORS) policies
    add_header 'Access-Control-Allow-Origin' $hostname;
    add_header 'Access-Control-Allow-Credentials' 'True';
    add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization';

    ## http conf based on cert
    include "/opt/FileMaker/FileMaker Server/NginxServer/conf/fms_https.conf";	# HTTP conf  
 }

 server {
   listen 443 ssl http2;
   listen [::]:443 ssl http2;

   index index.html index.htm index.nginx-debian.html;
   
   add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

   # Prevent Clickjacking attack
   add_header X-Frame-Options "SAMEORIGIN";
  
   # Prevent cross-site scripting (XSS) attack
   add_header X-XSS-Protection "1; mode=block";
 
   add_header X-Content-Type-Options nosniff;
 
   # add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval';" always;
   
   # Add headers for Cross-Origin Resource Sharing (CORS) policies
   add_header 'Access-Control-Allow-Origin' $hostname;
   add_header 'Access-Control-Allow-Credentials' 'True';
   add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization';
   
## below config from httpd mod_proxy conversion

    location ^~ /fmi/fmwd_help/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:16021/fmi/fmwd_help/;
      proxy_set_header Host $host;
    }

    location ^~ /fmi/conf {
      deny all;
      return 403;
    }

## Support XML on Linux on premise
#    location ^~ /fmi/xml {
#      deny all;
#      return 403;
#    }

    ## FAC admin console
    include "/opt/FileMaker/FileMaker Server/NginxServer/conf/fms_fac.conf";


## below config from httpd httpd-proxy conversion
    location ^~ /fmws {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:1895/fmws;
      proxy_set_header Host $host;
    }

    location ^~ /docws {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:1895/docws;
      proxy_set_header Host $host;
    }

    location ^~ /hss/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:1895/hss/;
    }

    location ^~ /Streaming/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:1895/Streaming/;
    }

    location ^~ /Streaming_SSL/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:1895/Streaming_SSL/;
    }

    location ^~ /oauth/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:1895/oauth/;
    }

    location ^~ /fmds/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:16005/fmds/;
    }

    location ^~ /admin-server/adminhelper {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:16001/admin-server/adminhelper;
    }

    location ^~ /fmi/data/ {
      proxy_set_header X-Forwarded-Proto https;
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:3000/fmi/data/;
    }

    location ^~ /fmi/odata/ {
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-Proto https;
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:3001/fmi/odata/;
    }

## below config from httpd httpd-proxy-fmiwebd conversion

    location ^~ /fmi/webd/PUSH {
      proxy_pass "http://127.0.0.1:16021/fmi/webd/PUSH";
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection  $connection_upgrade;
      proxy_set_header Host $http_host;
    }

    # mwpe
    location ^~ /fmi/mwpem/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:16002/fmswpem/;
      proxy_http_version 1.1;
    }

    location ^~ /fmi/mwpew/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:16002/fmswpew/;
      proxy_http_version 1.1;
    } 

    location ^~ /fmi/ {
      proxy_set_header X-Forwarded-Proto https;   # MWPE need this for redirect
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:16021/fmi/;
      proxy_http_version 1.1;
      proxy_set_header Connection "";
      # Set cookie expiration date (12 hours in seconds), path and httponly
      proxy_cookie_path /fmi "/; Secure; HttpOnly; Max-Age=43200";
    }

#   location / {
     # First attempt to serve request as file, then
     # as directory, then fall back to displaying a 404.
#     try_files $uri $uri/ =404;
#   }
 }
```

* そしてこの後、実際に弄るのは `fms_nginx.conf` のみとなります


# nginx チューニング
## 参考記事の紹介
* 以前、私自身が [そこそこなスペックのサーバにおけるnginxチューニングの一例](https://qiita.com/Hi_Noguchi/items/9e099420cc3934c43f00) という記事を書いたことがあります

https://qiita.com/Hi_Noguchi/items/9e099420cc3934c43f00

* 今回はこれを参考にしつつチューニングすることにしますので、ぜひご一読ください

## user
* それでは `fms_nginx.conf` に記載されている上から順に見ていくことにします
* まず最初に user ですが、これは nginx がどの user / group を使用するかという宣言です
* ここを変えてしまうとトラブル発生してしまうので、一切弄らないようにしてください

```nginx
# Claris nginx conf
user       fmserver fmsadmin;
```

## worker_processes
* 実質的なカスタマイズ項目としては、こちらからになります
* これは CPU コア数以下に設定しておく必要があります
* しかし FileMaker Server で与えられていたデフォルト設定は `5` となっていましたね

```nginx:before
worker_processes  5;  ## Default: 1
```

* この時点で、もし CPU コア数 4 以下のサーバ環境だとアウトです
* ここの値は `auto` を取ることができて、CPU コア数に応じて可変的にやってくれるので `auto` にしておくのが無難です

```nginx:after
worker_processes  auto;
```

### worker_rlimit_nofile
* こちらはデフォルトで設定されていません
* まず、設定のため OS 全体でのファイルディスクリプタ数を確認します

```sh
cat /proc/sys/fs/file-max
```

* これで出てきた数字と、次に設定する `worker_connections` の値から算出します
* ちなみに手元の GCE 環境だと `9223372036854775807` といった法外な値が出てきてしまったので、`worker_connections` の 4 倍くらいの値にすることにします

```nginx:after
worker_processes  auto;
worker_rlimit_nofile 21000;
```


## worker_connections
* 次は event ディレクティブ内に入ります
* ここの値は `4096` で無難なところと思いますので、そのままにします
* サーバスペックに合わせて上げても構いませんが、その場合は上記の `worker_rlimit_nofile` も合わせて変更するとよいでしょう

```nginx
events {
  worker_connections  4096;
}
```

## multi_accept
* どれくらいカリカリにチューニングしたいか次第なのですが、もし WebDirect サーバで多くのリクエストを捌きたいのでしたら、この値を on にしておくことをオススメします
* が、そもそも WebDirect で同時アクセス受け付ける数って、いくら多くても 1,000 くらいでしょうから、なくても全然問題ないと思います

```nginx:after
events {
  worker_connections  4096;
  multi_accept on;
}
```

## use
* こちらは `epoll` を指定しておくのが無難です

```nginx:after
events {
  worker_connections  4096;
  use epoll;
}
```

## http ディレクティブ内でスキップしてよいところ
* 続いて http ディレクティブに移りますが、上からしばらくはスキップしてしまって構わないです。設定はデフォルトのままで

```nginx
 include "/etc/nginx/mime.types";
 map $http_upgrade $connection_upgrade {
   default upgrade;
   '' close;
 }

 # hide nginx version
 server_tokens off;

 # Set website folder
 root "/opt/FileMaker/FileMaker Server/NginxServer/htdocs/httpsRoot";

 access_log "/opt/FileMaker/FileMaker Server/NginxServer/logs/access.log"; # this can be set 'off' to improve performance
 error_log "/opt/FileMaker/FileMaker Server/NginxServer/logs/error.log";

 # Enable SSL
 ssl_certificate     "/opt/FileMaker/FileMaker Server/CStore/serverCustom.pem";
 ssl_certificate_key "/opt/FileMaker/FileMaker Server/CStore/serverKey.pem";
 ssl_password_file   "/opt/FileMaker/FileMaker Server/CStore/.passphrase";

 ssl_protocols TLSv1.2 TLSv1.3;
 ssl_prefer_server_ciphers on;
 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:!DH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;

 # Optimize session cache
 ssl_session_cache   shared:SSL:40m;
 ssl_session_timeout 4h;

 # Enable session tickets
 ssl_session_tickets on;
```

## gzip まわり
* で、 gzip による圧縮まわりがばっさりコメントアウトされてしまっているので、ここはコメントインしておいた方が良いでしょう

```nginx:before
# Admin can enable gzip compression if needed
 # compression
#  gunzip on;
#  gzip on;

 # Compress all the following MIME-types.
#  gzip_types
#   application/atom+xml
#   application/geo+json
#   application/javascript
#   application/x-javascript
#   application/json
#   application/ld+json
#   application/manifest+json
#   application/rdf+xml
#   application/rss+xml
#   application/vnd.ms-fontobject
#   application/wasm
#   application/x-web-app-manifest+json
#   application/xhtml+xml
#   application/xml
#   font/eot
#   font/otf
#   font/ttf
#   image/bmp
#   image/svg+xml
#   image/gif
#   image/jpeg
#   image/png
#   image/tiff
#   image/webp
#   image/x-icon
#   video/3gpp
#   video/avi
#   video/mp4
#   video/mpeg
#   video/ogg
#   video/quicktime
#   video/webm
#   text/cache-manifest
#   text/calendar
#   text/css
#   text/javascript
#   text/markdown
#   text/plain
#   text/xml
#   text/vcard
#   text/vnd.rim.location.xloc
#   text/vtt
#   text/x-component
#   text/x-cross-domain-policy;

#  gzip_proxied  no-cache no-store private expired auth;
#  gzip_min_length 1000;
```

* 設定や圧縮対象は以下の通りで問題ないと思います
* `gzip_types` に画像の類を含めていませんが、そもそも画像は既に圧縮されているべきところで、ここで圧縮しても効果薄なことが多いというか本質的ではないので、含めないのが妥当です

```nginx:after
  gzip on;
  gzip_vary on;
  gzip_disable "MSIE [1-6]\.";
  gzip_proxied expired no-cache no-store private auth;
  gzip_min_length 1024;
  gzip_comp_level 6;
  gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript;
```

## client_max_body_size
* これについては Claris の中の人もコメントでこう書かれていますね

```nginx
# currently, we have no limit. Admin can set to 20G, 200M or any value based on business spec
client_max_body_size 0;
```

* 以前の Web サーバであった apache は、この制限をしていないため、同様に nginx においても制限しないように、このままにしておくのが無難と考えられます

## proxy_request_buffering
* こちらも Claris の中の人のコメントがありますが、特別な事情でもない限り on にする必要はないでしょう

```nginx
proxy_request_buffering off; # we dont wait until the whole request is completed
```

## charset, source-charset
* 文字コードです、特に変えるべきではありません

```nginx
charset utf-8;
source_charset utf-8;
```

## sendfile
* さて、ここからは記述にない項目となります
* kernel の sendfile を使用するかどうか、で、 I/O の最適化がはかられるようにんるため on にしておくのが良いでしょう

```nginx:after
sendfile on;
```

## tcp_nopush
* パケットの効率化のために on にします

```nginx:after
tcp_nopush on;
```

## tcp_nodelay
* こちらもパケット送信効率化のために on

```nginx:after
tcp_nodelay on;
```

## keepalive_timeout
* 20 秒にしておいて害はないはず

```nginx:after
keepalive_timeout 20;
```

## client_header_timeout
* 同上

```nginx:after
client_header_timeout 20;
```

## client_body_timeout
* 同上

```nginx:after
client_body_timeout 20;
```

## send_timeout
* 同上

```nginx:after
send_timeout 20;
```

## reset_timedout_connection
* タイムアウトしたコネクションについてはサクサクとリセットしてよいでしょう

```nginx:after
reset_timedout_connection on;
```

# nginx チューニングまとめ
* 最終的には以下のようになります

## fms_nginx.conf

```nginx:fms_nginx.conf
# Claris nginx conf
user       fmserver fmsadmin;
worker_processes  auto;
worker_rlimit_nofile 21000;


events {
  worker_connections  4096;
  use epoll;
}


http {
  include "/etc/nginx/mime.types";
  map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
 }

  # hide nginx version
  server_tokens off;

  # Set website folder
  root "/opt/FileMaker/FileMaker Server/NginxServer/htdocs/httpsRoot";

  access_log "/opt/FileMaker/FileMaker Server/NginxServer/logs/access.log"; # this can be set 'off' to improve performance
  error_log "/opt/FileMaker/FileMaker Server/NginxServer/logs/error.log";

  # Enable SSL
  ssl_certificate     "/opt/FileMaker/FileMaker Server/CStore/serverCustom.pem";
  ssl_certificate_key "/opt/FileMaker/FileMaker Server/CStore/serverKey.pem";
  ssl_password_file   "/opt/FileMaker/FileMaker Server/CStore/.passphrase";

  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers on;
  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:!DH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;

  # Optimize session cache
  ssl_session_cache   shared:SSL:40m;
  ssl_session_timeout 4h;

  # Enable session tickets
  ssl_session_tickets on;

  # gzip
  gzip on;
  gzip_vary on;
  gzip_disable "MSIE [1-6]\.";
  gzip_proxied expired no-cache no-store private auth;
  gzip_min_length 1024;
  gzip_comp_level 6;
  gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript;

  # set payload limit
  # currently, we have no limit. Admin can set to 20G, 200M or any value based on business spec
  client_max_body_size 0;

  proxy_request_buffering off; # we dont wait until the whole request is completed

  charset utf-8;
  source_charset utf-8;

  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  keepalive_timeout 20;
  client_header_timeout 20;
  client_body_timeout 20;
  send_timeout 20;
  reset_timedout_connection on;


  include "/opt/FileMaker/FileMaker Server/NginxServer/conf/fms_nginx_custom.conf";
}
```

## fms_nginx_custom.conf
* なお Claris の中の人が書いたものそのままという感じで、インデントや半角スペースの整形はしていません
* ちょっと余分な半角スペース多すぎ！　インデントちゃんと揃えよう！　って思いました

```nginx:fms_nginx_custom.conf
server {
    listen 80;

    # Add headers for Cross-Origin Resource Sharing (CORS) policies
    add_header 'Access-Control-Allow-Origin' $hostname;
    add_header 'Access-Control-Allow-Credentials' 'True';
    add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization';

    ## http conf based on cert
    include "/opt/FileMaker/FileMaker Server/NginxServer/conf/fms_https.conf";	# HTTP conf  
 }

 server {
   listen 443 ssl http2;
   listen [::]:443 ssl http2;

   index index.html index.htm index.nginx-debian.html;
   
   add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

   # Prevent Clickjacking attack
   add_header X-Frame-Options "SAMEORIGIN";
  
   # Prevent cross-site scripting (XSS) attack
   add_header X-XSS-Protection "1; mode=block";
 
   add_header X-Content-Type-Options nosniff;
 
   # add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval';" always;
   
   # Add headers for Cross-Origin Resource Sharing (CORS) policies
   add_header 'Access-Control-Allow-Origin' $hostname;
   add_header 'Access-Control-Allow-Credentials' 'True';
   add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization';
   
## below config from httpd mod_proxy conversion

    location ^~ /fmi/fmwd_help/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:16021/fmi/fmwd_help/;
      proxy_set_header Host $host;
    }

    location ^~ /fmi/conf {
      deny all;
      return 403;
    }

## Support XML on Linux on premise
#    location ^~ /fmi/xml {
#      deny all;
#      return 403;
#    }

    ## FAC admin console
    include "/opt/FileMaker/FileMaker Server/NginxServer/conf/fms_fac.conf";


## below config from httpd httpd-proxy conversion
    location ^~ /fmws {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:1895/fmws;
      proxy_set_header Host $host;
    }

    location ^~ /docws {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:1895/docws;
      proxy_set_header Host $host;
    }

    location ^~ /hss/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:1895/hss/;
    }

    location ^~ /Streaming/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:1895/Streaming/;
    }

    location ^~ /Streaming_SSL/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:1895/Streaming_SSL/;
    }

    location ^~ /oauth/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:1895/oauth/;
    }

    location ^~ /fmds/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:16005/fmds/;
    }

    location ^~ /admin-server/adminhelper {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:16001/admin-server/adminhelper;
    }

    location ^~ /fmi/data/ {
      proxy_set_header X-Forwarded-Proto https;
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:3000/fmi/data/;
    }

    location ^~ /fmi/odata/ {
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-Proto https;
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:3001/fmi/odata/;
    }

## below config from httpd httpd-proxy-fmiwebd conversion

    location ^~ /fmi/webd/PUSH {
      proxy_pass "http://127.0.0.1:16021/fmi/webd/PUSH";
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection  $connection_upgrade;
      proxy_set_header Host $http_host;
    }

    # mwpe
    location ^~ /fmi/mwpem/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:16002/fmswpem/;
      proxy_http_version 1.1;
    }

    location ^~ /fmi/mwpew/ {
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:16002/fmswpew/;
      proxy_http_version 1.1;
    } 

    location ^~ /fmi/ {
      proxy_set_header X-Forwarded-Proto https;   # MWPE need this for redirect
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://127.0.0.1:16021/fmi/;
      proxy_http_version 1.1;
      proxy_set_header Connection "";
      # Set cookie expiration date (12 hours in seconds), path and httponly
      proxy_cookie_path /fmi "/; Secure; HttpOnly; Max-Age=43200";
    }

#   location / {
     # First attempt to serve request as file, then
     # as directory, then fall back to displaying a 404.
#     try_files $uri $uri/ =404;
#   }
 }
```

# おわりに
## 雑感
* 前後編あわせて、ほんと疲れた……！　先人いなくて道なき道をゆく感じ、最近やってなかったので、まあ、楽しくはありましたが、それ以上に時間がなくて時間がなくて……
* Claris 公式でもう少し nginx まわりについてサポートしてあげた方がよいのではないでしょうか……！　というか、して！　いや、あるいは依頼いただいたら公式記事でも書きますよ。お仕事お待ちしております（ダイマ）
* というかそもそも nginx の設定変更の反映方法がまだ OS 再起動しか見えていないので、あらためて何とかしたいと思います。分かったら記事更新します
* もしかしたら FileMaker Server の ver.up などで `fms_nginx.conf` は上書きされてしまう可能性もなきにしもあらずです。それを見越して `fms_nginx.conf` の中身は include のみにしてしまって、全て外部ファイルへ逃がしてしまう……というやり方もとれるとは思うのですが、もし本当に今後 ver.up で上書きされるような事態に陥ったときに、対応して記事更新しようと思います

## 参考
* nginx の各項目についてさらに深く知りたい方はこちらの記事がたいへん参考になります
  * [Qiita - nginxの基本設定を改めてちゃんと調べてみた](https://qiita.com/hclo/items/35f00b266506a707447e)

https://qiita.com/hclo/items/35f00b266506a707447e

* 言うまでもなく nginx 公式ドキュメントもたいへん重要です
  * [nginx documentation](http://nginx.org/en/docs/)

http://nginx.org/en/docs/