ONTAPのFabricPool用のNginx Proxyを5分で構築する方法 (サンプルnginx.confあり)

#雑談
ONTAPから透過型ProxyとしてNginxを使う際のNginxのインストールと設定方法です。
ONTAPにvserver http-proxy createでProxyサーバを明示的に指定する非透過型で使いたい場合はこの手順は使えません。(非透過型はONTAPがProxyサーバにhttp層で`CONNECT`要求を行いますが、以下の手順で作成したNginxは`CONNECT`を処理するモジュールがインストールされないので、モジュールを別途追加するか、あるいはSquidなどを立てる必要があります。)

#目次

1. FabricPoolの機能とメリット
2. Proxyが必要になる状況とは？
3. Proxyインストール先のOS設定
4. Nginxのインストールと設定
5. 関連情報

#1. FabricPoolの機能とメリット

NetApp社のONTAP OSにはデータを階層化する機能があります(ONTAP 9.2以降)。ローカルのディスク上にあるデータを4KBのブロック単位でコールドかどうかを判定した後に、エンドユーザには透過的にデータをオブジェクトストレージに移動し、オンプレミスのストレージの容量を削減する機能です。

この機能の詳細は「6. 関連情報」の記事に譲りますが、オンプレ環境にあるストレージはオブジェクトストレージに直接送信できないネットワークに存在することもあるので、この記事では途中経路に立てるProxyの構築方法について記載します。

**補足) NetApp CBS(Cloud Backup Service)用のProxy設定については別記事で記載予定です。**

#2. Proxyが必要になる状況とは？
Proxyが必要な状況を書く前に、オブジェクトストレージへの3つの通信方法について整理します。

1. インターネット直  
　(ONTAPとオブジェクトストレージ間のSSL/TLSによる暗号化)
2. インターネットVPN  
　(オンプレルータとクラウド間のVPNによる暗号化)
3. 閉域接続回線  
　(AWS Direct ConnectやAzure Express Route, GCP Partner Interconnect等。非暗号化)

<font color="Red">補足)
上記の2.のパターンも3.のパターンも、経路の暗号化の有無にかかわらずデフォルトでONTAPはSSL/TLSをONにしてオブジェクトストレージと通信を行います。</font>

一般的な企業ではデータの漏洩を防ぐために、ストレージからインターネットに直接通信をさせない、あるいはできないネットワーク構成になっているかと思います。この場合はクラウド接続回線の種類に関係なく、Proxyを立てて中継させる必要があります。
クラウド接続回線が2.や3.の場合は、仮に直接通信できたとしても意図した経路にデータを流すにはやはりProxyが必要となります。(オブジェクトストレージのエンドポイントを名前解決するとインターネット側のグローバルIPが返ってくるため、それをVPN網 or 閉域網にまげて通信させるためです。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001215/7da9c611-099c-d03d-de4e-3a8caab6c7a8.png)
**Azureの場合は、vnet内にBLOBのプライベートエンドポイントを引き込めるようなので、この場合はストレージから直接通信させることも可能です。**

#3. Proxyインストール先のCentOSの設定
CentOSを前提に、ポイントをまとめます。(必要に応じて追記します。)

- /etc/resolv.confが正しく設定され、yumコマンドが使えること(インターネット側の名前解決)
- データ階層化先のオブジェクトストレージの名前解決が意図したIPに解決できること
クラウド上のインスタンスは、オブジェクトストレージのプライベートエンドポイントを内部IPに名前解決できることが多いのですが、うまういかない場合には必要に応じてhostsを使って宛先IPを曲げることも検討。

- SELinuxが正しく設定されていること。
  ~~(検証用途であればOFFにしてしまいましょう。)~~
  ~~# vi /etc/selinux/config~~
  ~~SELINUX=disabledに変更して、shutdown -r now~~
  ~~# getenforceで確認~~
  https://qiita.com/mattsun/items/470581ff34f87c7eb21d

#4. Nginxのインストールと設定
(1) OpenSSLインストール
root権限で実行することを前提に記載します。

新規： ```yum install openssl openssl-libs```
更新： ```yum clean all```
　　　 ```yum update openssl openssl-libs```  
(2) 暗号化鍵と自己証明書作成 

```
mkdir /etc/nginx
mkdir /etc/nging/ssl
openssl req -new -x509 -sha256 -newkey rsa:2048 -days 2190 -nodes -out /etc/nginx/ssl/nginx.pem -keyout /etc/nginx/ssl/nginx.key
(-daysは365日 x 6年=2190日で指定)
chown root:root -R /etc/nginx/ssl/ sudo chmod 600 /etc/nginx/ssl/* 
chmod 700 /etc/nginx/ssl
```  

(3) yum-utilsインストール
```yum install yum-utils```  

(4) Repoファイル作成
```vi /etc/yum.repos.d/nginx.repo```

```
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
```

(5) Nginxインストールと自動起動設定

```
yum install nginx
systemctl enable nginx
systemctl start nginx
```

(6) 構成ファイル
access/error ログ　```/var/log/nginx/*```
NGINXバイナリ　```/usr/sbin/nginx```
設定ファイル
　　```/etc/nginx/nginx.conf```
　　```/etc/nginx/conf.d/default.conf```

(7) nginx.confの修正
``` vi /etc/nginx/nginx.conf```

```
server {
    listen       443 ssl;
    server_name  nginx;
    ssl_certificate /etc/nginx/ssl/nginx.pem;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;

    keepalive_timeout    70;
    sendfile             on;
    client_max_body_size 30720M;
    client_body_buffer_size 5m;

    location / {
      proxy_pass  https://s3.endpoint.domain.com:443/;
      proxy_pass_header Server;
    }
}
```

- `listen 443 ssl;` でNginxがTCPポート443でSSL/TLSをListen。

- `client_max_body_size` でこのNginxが受け付けるデータの最大サイズを指定。
  (FabricPoolの場合、4KBのブロックを1000個まとめて約4MBのオブジェクトにしてデータを階層化するため、少なくとも5M程度を指定する必要あり。これを行わないと、データがNginxで捨てられる。)
　Nginxマニュアル→ http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size

- `client_body_buffer_size` でNginxが扱うデータのメモリバッファを調整する。この値が少ないと急激なデータ送受信が発生した際にNginxサーバ内のディスクに一時的にデータを書き出すため、性能が遅くなる場合がある。メモリを多めに積んでいる場合は大きくすることを検討。
　Nginxマニュアル→ http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size

- `proxy_pass`でFabricPoolの階層化先のオブジェクトストレージのFQDNとポート番号を指定。

- `proxy_pass_header`に`Server;`を指定することで、オブジェクトストレージがHTTPヘッダー内に付与する`Server;`ヘッダーをNginxはそのままONTAP OSにパスするようになる。これを付けないと`Server;`ヘッダーにNginxのバージョンなどが付与されることがあり、対向のオブジェクトストレージが何かONTAPが判断できなくなることがあるので、特にオブジェクトストレージにNetApp StorageGRIDなどを使っている場合には必須。
　Nginxマニュアル→ http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass_header



この設定以外にも、Nginxがマルチコアをきちんと使うように`worker_processes auto;`などを入れるのも良いかもしれません。

ここまで設定したらサービス再起動します。
```systemctl start nginx```

/var/log/nginx/の下にアクセスログが生成されるので、ONTAPのFabricPool設定をする際にはログをモニタします。
```tail -f /var/log/nginx/access.log```
```tail -f /var/log/nginx/error.log```


### 参考情報
　　http://nginx.org/en/linux_packages.html
　　http://vdeep.net/nginx-oreore-ssl


#5. 関連情報

- 関連情報  

＜追記中＞
Proxyの立て方だけを説明しましたが、FabricPoolにProxyを経由させる設定は別途記載予定です。

- FabricPoolの関連技術情報

https://www.storage-channel.jp/blog/fabricpool-networld-01.html

https://www.storage-channel.jp/blog/fabricpool-networld-02.html

https://www.storage-channel.jp/blog/fabricpool-networld-03.html

https://www.storage-channel.jp/blog/fabricpool-networld-04.html

https://www.storage-channel.jp/blog/fabricpool-networld-05.html