OCIにOracle Linux Storage Appliance環境を構築し、SMBでファイル共有してみた

## はじめに
少し前に、OCIにOracle Linux Storage Appliance環境を構築し、Windows端末からインターネット経由でファイル共有(SMB)してみたので、その備忘として。

## 構成
リバースプロキシとしてロードバランサーをパブリックサブネットに配置し、Windows端末とStorage Appliance(Virtual Machine)との間は、SMBv3の暗号化通信をします。
また、ロードバランサーでは、ネットワークセキュリティグループにより、特定のIPアドレスからのHTTPS、SMB、SSHでの通信のみを許可するようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/5ce084e8-3829-a324-bef1-bacdc39b590f.png)
- SMBでの通信は、Windowsファイル共有用(通信は暗号化)。
- HTTPSでの通信は、Storage Applianceの管理画面にアクセスするために必要。SSHでの通信は、Storage Applianceが構成されているComputeインスタンスへのアクセス用。カーネルアップデートなどサーバー運用で、SMBの通信とは別拠点からアクセスする想定。
- ブロック・ボリュームに保管されるデータは、必要に応じてオブジェクトストレージにバックアップ。
- 本記事では、コンパートメント構成、グループ、ポリシー設定、ブロック・ボリュームのバックアップなどについては割愛します。

## OCI環境の設定
上記構成図に従い、各種リソースの作成および設定をします。

なお、OCIにはコンパートメントという概念があります。
コンパートメントは、管理者によって権限が付与された特定のグループのみがアクセスできる関連リソース(インスタンス、仮想クラウド・ネットワーク、ブロック・ボリュームなど)を集めた論理グループです。

ポリシー設定にもよりますが、各種リソースを異なるコンパートメントに配置すると、リソース間でアクセスができなくなる場合があるため、注意が必要です。
本記事では、全てのOCIリソースを同一コンパートメントに作成する前提で記載します。

## ネットワークリソースの設定(ロードバランサー以外)

#### パブリックIPアドレスの予約
以下3つのパブリックIPアドレスを払い出します。
- Windows端末からOCI環境にアクセスする為のパブリックIPアドレス(SMB通信)
- Storage Applianceの設定、サーバー運用用にアクセスするパブリックIPアドレス(HTTPS、SSH通信)
- NAT Gateway用のパブリックIPアドレス

管理コンソールで、`ネットワーキング >> IP管理 >> 予約済パブリックIP`と画面遷移し、コンパートメントがパブリック・サブネットを作成するコンパートメントになっていることを確認して、パブリックIPアドレスの払い出しを行います。
| 名前 | 用途 |
|:-|:-|
| Public IP for SMB Access from Client | Windows端末からのSMBアクセス用 |
| Public IP for SSH HTTPS Setting | Storage Appliance管理画面へのHTTPSアクセス、Storage ApplianceのComputeインスタンスへのSSH接続用 |
| Public IP for NAT Gateway | NAT Gatewayに割り当てるパブリックIPアドレス |

#### VCNの設定
管理コンソールで、`ネットワーキング >> 仮想クラウドネットワーク`と画面遷移し、コンパートメントがOCIリソースを作成するコンパートメントになっていることを確認し、以下のような設定でVCNを作成します。
| 項目 | 設定値 |
|:-|:-|
| 名前 | vcn_storage_appliance |
| CIDRブロック | 10.0.0.0/16 |
| DNSリゾルバ | vcn_storage_appliance |
| デフォルト・ルート表 | Default Route Table for vcn_storage_appliance |

なお、本記事では、全てのOCIリソースを同一コンパートメントに作成する前提なので、各種リソースのコンパートメント設定についての記載は省略します。

#### Internet Gatewayの設定
作成したVCNに、Internet Gatewayを作成します。
| 項目 | 設定値 |
|:-|:-|
| 名前 | internet_gateway_vcn_storage_appliance |

#### NAT Gatewayの設定
作成したVCNに、NAT Gatewayを作成します。
| 項目 | 設定値 |
|:-|:-|
| 名前 | nat_gateway_vcn_storage_appliance |
| パブリックIPアドレス | 「Public IP for NAT Gateway」で払い出した、パブリックIPアドレスを指定 |

#### Service Gatewayの設定
作成したVCNに、Service Gatewayを作成します。
| 項目 | 設定値 |
|:-|:-|
| 名前 | service_gateway_vcn_storage_appliance |
| サービス | All NRT Services In Oracle Services Network |

#### ルート表の設定
作成したVCNに、パブリック・サブネット用、プライベート・サブネットの2つのルート表を作成します。
###### パブリック・サブネット用
名前：Route Table for Public Subnet
| 宛先 | ターゲット・タイプ | ターゲット |
|:-|:-|:-|
| 0.0.0.0/0 | インターネット・ゲートウェイ | internet_gateway_vcn_storage_appliance |

###### プライベート・サブネット用
名前：Route Table for Private Subnet

| 宛先 | ターゲット・タイプ | ターゲット |
|:-|:-|:-|
| 0.0.0.0/0 | NATゲートウェイ | nat_gateway_vcn_storage_appliance |
| All NRT Services In Oracle Services Network | サービス・ゲートウェイ | service_gateway_vcn_storage_appliance |

#### パブリック・サブネットの設定
作成したVCNに、パブリック・サブネットを作成します。
| 項目 | 設定値 |
|:-|:-|
| 名前 | public_subnet-vcn_storage_appliance |
| CIDRブロック | 10.0.0.0/24 |
| サブネット・タイプ | リージョナル |
| サブネット・アクセス | パブリック・サブネット |
| ルート表 | Route Table for Public Subnet |

#### プライベート・サブネットの設定
作成したVCNに、プライベート・サブネットを作成します。
| 項目 | 設定値 |
|:-|:-|
| 名前 | private_subnet-vcn_storage_appliance |
| CIDRブロック | 10.0.1.0/24 |
| サブネット・タイプ | リージョナル |
| サブネット・アクセス | プライベート・サブネット |
| ルート表 | Route Table for Private Subnet |

#### ネットワーク・セキュリティ・グループの設定
ネットワーク・セキュリティ・グループ(NSG)を作成し、Windows端末およびStorage Applianceの管理拠点からのアクセス制御、ロードバランサーからプライベート・サブネットに構築するStorage Appliance用のComputeインスタンスへのアクセス制御設定を行います。

なお、この構成では、SSH接続はデフォルトのTCP/22ではなく、TCP/10022を使う事にします。

:::note warn
Oracle LinuxのComputeインスタンスは、デフォルトでTCP/22の通信を受け付ける設定になっているため、SSHにTCP/10022を使うようにするには、最初はTCP/22とTCP/10022の通信を許可しておき、後述するOS設定でSSH用の通信ポートをTCP/10022に変更した後、ネットワーク・セキュリティ・グループ設定からTCP/22の通信許可を削除する必要があります。
:::

| 名前 | ICMP(Public) | SMB(TCP/445) -> Public Subnet | SSH(TCP/10022),HTTPS(TCP/443) -> Public Subnet | nsg for storage appliance public subnet -> private subnet |
|:-|:-|:-|:-|:-|
| 方向 | 方向：イングレス、ステートレス：いいえ | 方向：イングレス、ステートレス：いいえ | 方向：イングレス、ステートレス：いいえ | 方向：イングレス、ステートレス：いいえ |
| ソースまたは宛先タイプ | ソース・タイプ：CIDR | ソース・タイプ：CIDR | ソース・タイプ：CIDR | ソース・タイプ：CIDR |
| ソースまたは宛先 | Windows端末がある拠点のグローバルIP | Windows端末がある拠点のグローバルIP | Storage Applianceの設定、運用を行う拠点のグローバルIP | 10.0.0.0/24 (パブリック・サブネットのCIDR) |
| プロトコル | ICMP | TCP | TCP | TCP |
| 詳細 | タイプ：All、コード：All | ソース・ポート：All<br>宛先ポート：445 | ソース・ポート：All<br>宛先ポート：443、10022 | ソース・ポート：All<br>宛先ポート：443、445、10022 |
| 用途 | ping | Windows端末からのWindowsファイル共有 | Storage Applianceの設定、運用用 | ロードバランサーからStorage ApplianceのComputeインスタンスへの通信用 |

#### セキュリティ・リストの設定
イングレスのアクセス制御はNSGで行っているので、セキュリティ・リストではエグレスの設定のみ行います。
パブリック・サブネット用、プライベート・サブネット用ともに、以下の設定にします。
| ルールの方向 | ステートレス | ソースまたは宛先 | IPプロトコル、ソース・ポート範囲 | 宛先ポート範囲 |
|:-|:-|:-|:-|:-|
| イングレス・ルール | - | - | - | - |
| エグレス・ルール | いいえ | 0.0.0.0/0 | すべてのプロトコル | 1-65535 |

## Storage Applianceの構築
構築の流れは、以下が参考になると思います。

https://k-kane.hatenablog.jp/entry/2019/03/02/131620

Oracle Linuxのインスタンスを構築し、そこにStorage Applianceを入れてもよいと思いますが、Oracle社がOCI上で提供しているイメージがあるので、そのイメージからインスタンスを作成します。
以前は、E3、E4といった最新のシェイプを選択できませんでしたが、2022年8月時点ではE4シェイプも選択できるようになっています。

また、Storage Appliance用にブロック・ボリュームを別途アタッチする必要があります(ブロック・ボリュームが無いと、Storage Applianceの設定ができません)。

なお、Oracleイメージを使うデメリットとして、カスタムイメージを利用できないという点があるため、Storage Appliance環境を複数利用したいなど場合、サーバー運用上の考慮が必要になります。
![temp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/0af9e172-9b81-e35b-e515-8b16e62884f3.png)
本記事では、実際に設定した内容を記載しておきます。

#### Storage Appliance用Computeインスタンスの構築
Oracleイメージから、Storage Applianceのインスタンスを構築します。
###### インスタンス情報
| 項目 | 設定値 |
|:-|:-|
| インスタンス名 | storage_appliance |
| ブート・ボリューム | storage_appliance_boot_volume |
| VCN | vcn_storage_appliance |
| サブネット | private_subnet-vcn_storage_appliance |
| ネットワーク・セキュリティ・グループ  | nsg for storage appliance public subnet -> private subnet |
| SSH接続用秘密鍵(ユーザー:opc) | SSH接続時に必要なので、秘密鍵を保管しておきます |

#### ブロック・ボリュームの作成とインスタンスへのアタッチ
次に、管理コンソールで空のブロック・ボリュームを作成(サイズは、ファイル共有領域で必要なサイズを指定)し、Storage Appliance用インスタンスにアタッチします。
| 項目 | 設定値 |
|:-|:-|
| ブロック・ボリューム | storage_appliance_block_volume |
| ボリューム・サイズ | 1024GB |
| ボリューム・パフォーマンス | バランス |
| アタッチするComputeインスタンス(iSCSI) | storage_appliance |

:::note warn
ブロック・ボリュームをアタッチしておかないと、Storage Applianceの設定画面で怒られるので注意です。
:::
この後、インスタンスにSSH接続し、OSやSMBの設定などを行う必要がありますが、今回の構成では、ロードバランサー経由でSSH接続するため、先にロードバランサーの設定を行います。

## ロードバランサーの設定
管理コンソールで、`ネットワーキング >> ロード・バランサ`と画面遷移し、コンパートメントがOCIリソースを作成するコンパートメントになっていることを確認し、以下のような設定でロード・バランサを作成します。

なお、本構成では、SMBアクセスする拠点とSSH、HTTPSアクセスする環境が別の想定なので、ロード・バランサを2つ作成します。
#### SMBアクセス用ロード・バランサ
| 項目 | 設定値1 | 設定値2 |
|:-|:-|:-|
| ロード・バランサ・タイプ | ロード・バランサ | - |
| ロード・バランサ名 | lb_smb | - |
| 可視性タイプの選択 | パブリック | - |
| パブリックIPアドレスの割当て | 「Public IP for SMB Access from Client」で払い出したパブリックIPアドレス | - |
| シェイプ | フレキシブル・シェイプ | 最小帯域幅：100Mbps<br>最大帯域幅：100Mbps |
| ネットワーキングの選択：VCN | vcn_storage_appliance | - |
| ネットワーキングの選択：サブネット | public_subnet-vcn_storage_appliance | - |
| ネットワーク・セキュリティ・グループを使用してトラフィックを制御 | チェックボックスをチェック | ICMP(Public)<br>SMB(TCP/445) -> Public Subnet |
| ロード・バランシング・ポリシーの指定 | 重み付けラウンド・ロビン | - |
| バックエンド・サーバーの選択 | storage_appliance | 選択したバックエンドのポートを445に |
| ヘルス・チェック・ポリシーの指定 | プロトコル：TCP、ポート：445 | 間隔(ミリ秒)：30000<br>タイムアウト(ミリ秒)：10000<br>再試行回数：3 |
| バックエンド・セット名 | bs_lb_storage_appliance | - |
| セキュリティ・リスト | ロード・バランサの作成後にセキュリティ・リスト・ルールを手動で構成します | - |
| セッション永続性 | セッション永続性を無効化 | - |
| リスナー名 | listener_lb_smb | - |
| リスナーで処理するトラフィックのタイプ | TCP | 445 |

#### SSH、HTTPSアクセス用ロード・バランサ
| 項目 | 設定値1 | 設定値2 |
|:-|:-|:-|
| ロード・バランサ・タイプ | ロード・バランサ | - |
| ロード・バランサ名 | lb_ssh_https | - |
| 可視性タイプの選択 | パブリック | - |
| パブリックIPアドレスの割当て | 「Public IP for SSH HTTPS Setting」で払い出したパブリックIPアドレス | - |
| シェイプ | フレキシブル・シェイプ | 最小帯域幅：10Mbps<br>最大帯域幅：10Mbps |
| ネットワーキングの選択：VCN | vcn_storage_appliance | - |
| ネットワーキングの選択：サブネット | public_subnet-vcn_storage_appliance | - |
| ネットワーク・セキュリティ・グループを使用してトラフィックを制御 | チェックボックスをチェック | ICMP(Public)<br>SSH(TCP/10022),HTTPS(TCP/443) -> Public Subnet |
| ロード・バランシング・ポリシーの指定 | 重み付けラウンド・ロビン | - |
| バックエンド・サーバーの選択 | storage_appliance | 選択したバックエンドのポートを445に |
| バックエンド・サーバーの選択<br>※ロードバランサー作成後に追加 | storage_appliance | 選択したバックエンドのポートを10022に |
| ヘルス・チェック・ポリシーの指定 | プロトコル：TCP、ポート：443 | 間隔(ミリ秒)：30000<br>タイムアウト(ミリ秒)：10000<br>再試行回数：3 |
| バックエンド・セット名 | bs_lb_storage_appliance | - |
| セキュリティ・リスト | ロード・バランサの作成後にセキュリティ・リスト・ルールを手動で構成します | - |
| セッション永続性 | セッション永続性を無効化 | - |
| リスナー名 | listener_lb_https | - |
| リスナーで処理するトラフィックのタイプ | TCP | 443 |
| リスナー名<br>※ロードバランサー作成後に追加 | listener_lb_ssh | - |
| リスナーで処理するトラフィックのタイプ<br>※ロードバランサー作成後に追加 | TCP | 10022 |

## Storage Applianceの設定
ロード・バランサの作成、設定完了後、Storage Appliance用のインスタンスにSSH接続します。
本構成の場合の接続情報は以下の通りです。
| 項目 | 設定値 |
|:-|:-|
| 接続先IPアドレス | 「Public IP for SSH HTTPS Setting」で払い出したパブリックIPアドレス |
| ポート | 10022 |
| 秘密鍵| Computeインスタンス「storage_appliance」作成時にダウンロードした秘密鍵 |
| OSアカウント | opc |

本来は、OCI環境でよく知られた初期OSアカウントであるopcユーザーではなく、違うOSアカウントを作成し、そのアカウントでサーバー運用する事が推奨ではありますが、本記事では、説明を簡略にするためopcユーザーでログイン後、rootユーザーにスイッチ(`$ sudo su -`)するか、sudoしてOS設定を行います。

opcユーザー以外のOSアカウントを作成し、SSH接続できるようにする手順については、以下が参考になると思います。

https://www.ashisuto.co.jp/db_blog/article/howto-allow-ssh-connections-other-than-opc-users.html

#### OS設定
rootユーザーの権限でOS設定を行います。

:::note warn
この設定を行う場合、実際にはネットワーク・セキュリティ・グループで一時的にTCP/22のイングレス通信を許可しておき、SSHの接続設定を10022に変更後、ネットワーク・セキュリティ・グループからTCP/22の通信許可を削除する必要があります。
:::
| 項目 | 設定内容 | 備考 |
|:-|:-|:-|
| NTP設定 | \\$ sudo vi /etc/chrony.conf<br><br>-- 最終行に以下追加<br>leapsecmode slew<br><br>\\$ sudo systemctl restart chronyd | Slewモードに変更 |
| journald | \\$ sudo vi /etc/systemd/journald.conf<br><br>-- 最終行に以下追加<br>Storage=persistent<br>SystemMaxUse=100M<br><br>\\$ sudo systemctl restart rsyslog | syslogを永続化 |
| Locale, KeyMap | \\$ sudo localectl set-locale LANG=ja_JP.utf8<br>\\$ sudo localectl set-keymap jp106<br>\\$ sudo localectl status<br><br>-- 以下が出力される<br>   System Locale: LANG=ja_JP.utf8<br>       VC Keymap: jp106<br>      X11 Layout: jp<br>       X11 Model: jp106<br>     X11 Options: terminate:ctrl_alt_bksp |  |
| TimeZone | \\$ sudo timedatectl set-timezone Asia/Tokyo |  |
| パッケージ更新 | \\$ sudo yum update<br><br>-- kernel更新等あった場合はreboot<br>$ sudo reboot now |  |
| Firewall設定 | -- 許可されているポートの確認<br>\\$ sudo firewall-cmd --list-ports --zone=public --permanent<br><br>-- 許可されているサービスの確認<br>\\$ sudo firewall-cmd --list-services --zone=public --permanent<br><br>-- 許可するポートの追加<br>\\$ sudo firewall-cmd --add-port=10022/tcp --zone=public --permanent<br><br>-- SSHサービスの許可設定を削除<br>\\$ sudo firewall-cmd --remove-service=ssh --zone=public --permanent<br>\\$ sudo firewall-cmd --reload | OSのファイアウォール設定で、TCP/10022を許可し、TCP/22を不許可に変更 |
| SSH | \\$ sudo vi /etc/ssh/sshd_config<br><br>-- 以下のように変更<br>Port 22<br>↓<br>Port 10022<br><br>\\$ sudo semanage port -a -t ssh_port_t -p tcp 10022<br><br>\\$ sudo systemctl restart sshd.service | SSH接続用のポートを22から10022に変更 |
| SMB設定 | \\$ sudo vi /etc/samba/smb.conf<br><br>-- 以下を末尾に追記<br>server max protocol = SMB3<br>smb encrypt = required<br><br>\\$ sudo systemctl restart smb.service | SMBの暗号化設定 |
| SMB用ユーザー作成 | --SMB用OSアカウントの作成<br>\\$ sudo useradd -u 2001 -g users smbuser<br>\\$ sudo passwd smbuser<br><br>-- SMB用ユーザーの作成(パスワードはsmbuserと同じにする)<br>\\$ sudo pdbedit -a smbuser<br>$ sudo pdbedit -L | Windows端末からStorage Applianceの共有ストレージにアクセスする際の、WindowsのOSアカウント、パスワードとなる |

#### iSCSIコマンドの実行(インスタンスからブロックボリュームにiSCSI接続)
rootユーザーの権限で、iSCSIコマンドを実行し、アタッチしたブロック・ボリュームに、Storage Appliance用のインスタンスからiSCSI接続します。

ブロック・ボリュームに接続するためにコマンド、接続解除するためのコマンドは、作成したブロック・ボリュームを選択後、「アタッチされたインスタンス」で「iSCSIコマンドおよび情報」を選択して確認します。
![temp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/68fa5087-231d-b41e-07f5-8dc5f7b22ce4.png)
「iSCSIコマンドおよび情報」を選択すると、インスタンスからブロック・ボリュームに接続または接続解除するためのコマンドが表示されるので、接続用のコマンドをコピーし、SSH接続したターミナルで、rootユーザー権限で実行します。
![temp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/4c5f59d5-a29e-c28d-e59a-367106dee47f.png)

#### Storage Appliance管理コンソール設定
Storage Applianceの管理コンソールには、「Public IP for SSH HTTPS Setting」で払い出したパブリックIPアドレス(`https://「Public IP for SSH HTTPS Setting」で払い出したパブリックIPアドレス`)で接続します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/415d936a-36b4-1f8e-1af6-08f8f922e562.png)
まず、管理コンソールにアクセスする「admin」ユーザーのパスワードを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/042c53ac-9b8c-9085-2519-9a75c248c9db.png)
「admin」ユーザーのパスワード設定後、設定したパスワードでログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/f8a69f9b-84b0-eea8-c433-9a658f26c70d.png)
空のブロック・ボリュームをアタッチした状態でStorage Applianceの管理コンソールにログインすると、ブロック・ボリュームが自動的に認識されるので、Storageタブで「Add」ボタンをクリックし、Storage Poolを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/ea28a456-a421-0c03-e394-699818ef06e3.png)
共有設定では、以下のように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/b43db9ca-b643-9d2d-dca7-a0490f9b0ba4.png)
| 項目 | 設定値 |
|:-|:-|
| Share name | test |
| Share size | アタッチしたブロック・ボリューム全て |
| Use 32 bits inodes only | No |
| Export Protocols | SMB export |
| SMB share name | test |
| Read only | No |
| Guest ok | No |
| 他全ての項目 | No |

Storage Poolが作成されると、以下のような表示になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/acf4f96e-2896-f9cb-fb43-1a2215e0e022.png)

#### 共有領域のパーミッション設定
Storage Poolを作成すると、/shares以下にSMB共有名のディレクトリ(この例では、`/shares/test`)が指定の共有サイズで作成されます(共有ディレクトリの所有者は`nfsnobody:nfsnobody`)。

パーミッションはフルアクセス可(777)になっていますが、今回は、ゲストアクセスをNGにしているので、`/shares/test`ディレクトリ以下の所有者を、SMBアクセス用に作成した「smbuser」に変更しておきます。
````
$ sudo chown -R smbuser:users /shares/test
````

長くなりましたが、以上でOCI環境の設定は完了です。

## Windows端末での設定と疎通確認
Windows端末にOSアカウント「smbuser」を作成し、パスワードもStorage ApplianceのSMB用OSアカウント「smbuser」と同じものに設定します。

その後、Windows端末にOSアカウント「smbuser」でログオンし、エクスプローラーで`\\「Public IP for SMB Access from Client」で払い出したパブリックIPアドレス\test`(例)\\13.X.XX.XX\test)と入力し、共有フォルダへのアクセスおよびファイル、ディレクトリの編集ができれば、疎通確認も完了です。
![temp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/441b0a21-4082-b53c-6bfe-6bb867d30a5e.png)

## おわりに
OCIにOracle Linux Storage Appliance環境を構築し、Windows端末からインターネット経由でファイル共有(SMB)してみました。

NFSでのファイル共有であれば、ファイルストレージサービス(FSS)を利用してファイル共有する方が簡単そうですが(WindowsでもNFS接続できますし)、この仕組みを利用して、WindowsサーバーのWindows Serverバックアップのバックアップ先に指定し、オンプレミス環境にあるデータの簡易的なBCP対策などに利用してもよいかもしれません。

https://oracle-japan.github.io/ocitutorials/beginners/using-file-storage/