データベースに必要とされるセキュリティ（Couchbase Serverの機能を通じた考察）② IPアドレス設定

# はじめに

[以前の記事](https://qiita.com/yoshiyuki_kono/items/a541522ccbea28f2747e)では、データベースに必要とされるセキュリティについて、概観を見ていきました。また、その最後に、MongoDBのバインドIP設定について触れました。この記事では、MongoDBのバインドIPに対応する設定が、Couchbaseでどのよう対処されているかを見ていきます。

また、クラスターにおいては、モノリシックなアーキテクチャであれば考慮する必要がない面も考慮する必要があります。

## クラスターマップ
本題に入る前に、Couchbaseに特徴的なアーキテクチャの説明をしておく必要があるでしょう。

Couchbaseにおいて、アプリケーションが、SDKを介して、Couchbase Serverに接続する際には、「クラスターマップ」という要素が介在します。初期接続は、アプリケーションに設定されている（ノード（複数指定可能）に対して行われますが、接続確立（ブートストラップ）時に、接続したノードから、クラスターマップを受け取り、以降の接続は、ノードに対して直接行われます。つまり、一方方向のリクエストだけを考えて、IPやドメイン名の解決について、外部で整合性が取れていれば良い、という訳にはいかない、ということになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/3e86bf2a-af29-d399-9d14-ac9960127f66.png)



## 代替(Alternate)アドレス
Couchbase Serverでは、クラスターを構成するノードに対して、「プリンシパルアドレス」に加えて、「代替(Alternate)アドレス」を割り当てることができます（また、代替ポート番号をそのノードで実行されているサービスに割り当てることができます）。プリンシパルアドレスは、クラスタの初期構成時に、設定されるアドレスです。代替アドレスの設定は必要に応じて行います。

2つの考えられるユースケースを以下に示します。

### NAT（ネットワークアドレス変換）

#### 注意事項
まず、注意しておくと、この図では、アプリケーションサーバは、外部ネットワークにあり、内部ネットワークにある、データベースを利用していますが、これは、必ずしも典型的なケースとして示されているわけではなく、代替アドレスを利用する可能なケースとして示されていることにご留意ください（典型的なケースとしては、アプリケーションは内部ネットワークにあり、NATの利用はアプリケーションへの接続に利用されることが考えられます。）。どちらかと言えば、管理コンソールへのアクセスと考えた方が、イメージがしやすく思われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/0555b7f5-9f40-ec6d-edbc-10e313ac1902.png)



このケースでは、内部ネットワーク環境内で、2つのノードにそれぞれのIPアドレス（10.0.0.1および10.0.0.2）が割り当てられています。

ノードのオペレーティングシステムは、外部アドレスを認識していません。外部アプリケーションから参照できるようにするため、通常、ルーターによるネットワークアドレス変換（NAT）機能で代替アドレスを使用できるようにします。

外部アプリケーションは、代替アドレスを使用して接続します。NATは代替アドレスを内部アドレスに変換し、ノードと外部アプリケーション間の通信はそれに基づいて続行されます。

クラスター内のノード間の接続は、プリンシパルアドレスを利用すれば十分です。一方で、外部からのアクセスに使われる外部アドレスが代替アドレスとして、クラスターに登録されることによって、（クラスターマップに反映される）クラスター全体として、適切な挙動が実現されることになります（ここでは、Couchbase Serverへのアクセスの目的や方法を特に特定していませんが、例えば、単純なWEBコンソールへのアクセスのように、外部でアドレスが解決されていれば十分なケースも存在します）。

### デュアルネットワーク
次の図で示すように、セキュリティを最適化するために、デュアルネットワークを使用してアプリケーションのノードへのアクセスを分離できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/a10b2a42-f314-2a34-891a-8747910289f5.png)



クラスターには、そのプリンシパルアドレス10.0.0.100またはその代替アドレス10.1.0.100でアクセスできます。クラスタ内には2つのノードがあり、それぞれにプライマリまたはセカンダリIPアドレスを使用して内部的にアクセスできます。


プリンシパルアドレスと代替アドレスの両方を所有している場合、アプリケーションは通常、デフォルトでプリンシパルを使用します。ただし、デフォルトをオーバーライドして、代替アドレスが使用される場合があります。このケースでは、アプリケーション2は代替アドレスを使用します。

クラスター内では、外部アプリケーションによるノードアクセスは、クラスターのプリンシパルアドレスと代替アドレスのマッピングに従って管理されます。ここで、プリンシパルアドレスはノードのプライマリアドレスにマップされ、代替アドレスはノードのセカンダリアドレスにマップされます。

## 代替アドレスの割り当て
Couchbase Serverでは、次の二つの方法で代替アドレスを割り当てることができます。

### CLI


```
couchbase-cli setting-alternate-address [--cluster <url>] [--username <user>]
    [--password <password>] [--list] [--set] [--remove] [--hostname <host>]
    [--ports <ports>]
```

https://docs.couchbase.com/server/current/cli/cbcli/couchbase-cli-setting-alternate-address.html


`--list`パラメータを用いて、現在の代替アドレスと現在のすべてのポート番号設定を表示することができます。

```
$ couchbase-cli setting-alternate-address -c 192.168.1.5:8091 --username Administrator \
   --password password --list
```


### REST API

```
curl -v -X PUT -u [admin]:[password]
  http://[ip-address]:8091/node/controller/setupAlternateAddresses/external
  [-d hostname=<alternate-address> ]
  [-d <service-name>=<alternate-port-number> ]

curl -v -X DELETE -u [admin]:[password]
  http://[ip-address]:8091/node/controller/setupAlternateAddresses/external
```
https://docs.couchbase.com/server/current/rest-api/rest-set-up-alternate-address.html

# 最後に

バインドされる（リスニングしている）IPアドレスの設定といった時、二つの異なる見方があるように思われます。

- それ以外の接続を退ける。
- その接続を受け入れる。つまり（分散環境において整合性を持って）処理可能にする。

例えば、（PostgreSQL等）デフォルトでは、localhost接続のみをリスニングしており、リモートTCP/IP接続は許可されないというケースが考えられます。このような場合、localhost接続については、ユーザー/クライアント認証の概念が適用されないということもあり得ます。Couchbaseでは、そのような区別はなく、全ての接続にユーザ認証が必要です。そして、Couchbaseの代替アドレス設定は、上記の後者の見方に対応します。

このように、データベースのセキュリティについて（比較）検討する場合には、個々の要素を個別に見るのではなく、全体の関連から理解することが重要と思われます。



# 関連情報

[データベースに必要とされるセキュリティ（Couchbase Serverの機能を通じた考察）① 概観：何が必要かつ実現されているか？](https://qiita.com/yoshiyuki_kono/items/a541522ccbea28f2747e)