別アカウントからS3にアップロードされたファイルの所有者を変更する(S3マウントツール使用)

# はじめに
先日以下のような記事を書きました。
・[別アカウントからS3にアップロードされたファイルの所有者を変更する](https://qiita.com/handy-dd18/items/61150784c3cf608288b3)

記事の中では、コマンドを使用して別アカウントからアップロードされたファイルの所有者をS3バケットの所有者に変更する方法について試しました。

ただ、S3を使用する場合はコマンド以外にも方法はあります。
今回はS3マウントツールのCloudBerryDrive(MSP360)とJPCyberを使用して、別アカウントのEC2からファイルをアップロードした際の所有者変更方法について試してみます。

マウントツールについて知らない方は以下をご覧ください。
・[有名なS3マウントツール2つを比較してみた](https://qiita.com/handy-dd18/items/c962fa9ac8201429720c)

# 準備
S3バケットのオブジェクト所有者は希望するバケット所有者にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/d0e46243-b19e-31bb-6de6-cf89da289788.png)


前回作成したEC2にCloudBerryDriveとJPCyberをインストールします。
アカウントの設定も同時に行っておきます。権限はEC2にアタッチされている別アカウントのIAMロールのものを使用します。

インストール方法は過去の記事に書いています。
・[JPCYBER S3 Driveを使ってWindowsにS3をマウントしてみた](https://www.capybara-engineer.com/entry/2019/12/25/151707)
・[CloudBerry Driveを使用してEC2にS3をマウントしてみた](https://www.capybara-engineer.com/entry/2019/10/18/152936)

S3バケットは前回のものを流用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/bdda575e-4f6c-7002-7b4b-21ea42aa67a8.png)


# JPCyberで実施
## 事前確認
JPCyberで対象のS3バケットがマウントされていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/74169b14-0aa6-940c-301b-80ad22069cce.png)

エクスプローラーからファイルを配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/8c0ce0b6-1239-51d5-8cfa-914427926866.png)

コンソールで確認するとファイルがアップロードされていることが確認できます。
ただ、このままでは別アカウントが所有者のままで設定されてしまっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/652c23b3-b302-7dfd-243f-fa1d7e1f889d.png)

## ACL設定
JPCyberのツールからオプションの設定を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/f31e7e10-3632-c551-1f9f-040a8142c566.png)

オプションの設定に「親バケットのアクセス権をアップロードするファイルに適用する」というチェックボックスがあるので、チェックをつけて保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/45f57604-af70-2117-4646-7ed4885fd656.png)

自動でJPCyberが再起動されるため、再度エクスプローラーからファイルをアップロードしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/37fa8339-e011-f419-1005-f4ed2d5df64e.png)

これで所有者が変更されるはず...と思ったのですが、何故か変わっていません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/4c79d482-54b6-245e-a059-0120402b24ab.png)

JPCyberのログを見てみるとAccess Deniedが出ていることがわかりました。
アップロード自体は成功しているところを見るとACLを操作しようとして権限の問題で失敗しているように見えます。

```
2021/06/07 10:49:08.241 [W] Access Denied
2021/06/07 10:49:09.824 [I] Uploading: s3://test-tmp-20210603/test/test2.txt
2021/06/07 10:49:10.888 [I] Upload completed: s3://test-tmp-20210603/test/test2.txt
2021/06/07 10:49:10.935 [W] Access Denied
```

試しにとACLのチェックを外してアップロードしたらAccess Deniedは出なかったのでACLが関係していることは確定です。

```
2021/06/07 10:51:06.121 [I] Uploading: s3://test-tmp-20210603/test/test3.txt
2021/06/07 10:51:06.278 [I] Upload completed: s3://test-tmp-20210603/test/test3.txt
```

念のため同じIAMロールの権限使ってCLIでアップロードしてみます。

```
PS C:\Users\Administrator\Desktop> aws s3 cp .\test4.txt s3://test-tmp-20210603/test/ --acl bucket-owner-full-control
upload: .\test4.txt to s3://test-tmp-20210603/test/test4.txt
```

CLIでは問題なくアップロードされて所有者もS3バケットと一緒になっていることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/e23ccbf1-fe98-8060-86b4-0298d55e2dad.png)

ちょっと色々と調べてみましたが、答えが見つかりそうにないので一旦置いておきます。
もしエラー原因に心当たりある方がいればコメントください。

## 2021/6/11追記
以下の記事に記載していますが、JPCYBERのオプションを設定した場合、①ファイルをアップロード→②マウント時に取得したS3バケットACLをPutObjectACLリクエストで設定、という2段階に分けて処理がされているようです。
このうち②のPutObjectACLリクエストで403エラーが発生しているようでした。
・[JPCYBERのPUT通信をWiresharkで確認する(ACL設定あり)](https://qiita.com/handy-dd18/items/c234ce964f749a200fc4)

以下の記事でS3バケットACLをPutObjectACLリクエストで設定する手順を検証してみました。
結果、S3バケットACLのOwnerに設定されているAWSアカウントとPutObjectACLリクエストを送る認証AWSアカウントが一致している必要があるということがわかりました。
・[別アカウントからS3にアップロードされたファイルのACLを変更する](https://qiita.com/handy-dd18/items/dc16c86d4ca180475ded)

上記2つの検証を元に考えると
①マウント時に取得したS3バケットACLを取得
　※Ownerはアップロード先S3バケットのAWSアカウント
②JPCYBERでファイルをアップロード
③アップロードしたファイルに対してPutObjectACLリクエストを送信
　※その際の認証AWSアカウントは①のACLのOwnerに設定されたものとは異なる
④Access Deniedでエラー発生
ということのようです。

解消方法として、アップロード元のAWSアカウントのIAMロールで認証しているのがよろしくないので、アップロード先のAWSアカウントのIAMユーザを作成し、そのアクセスキーを使用することで対応は可能そうです。
※あまりアクセスキーは使用したくないですが。

# CloudBerry Driveで実施
## 事前確認
CloudBerry Driveでマウントされていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/e6d56be8-9cd7-d60f-3ad8-d686e0136479.png)

エクスプローラーからファイルをアップロードしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/b4a8d96e-9590-8df3-68f0-66a4e3621574.png)

所有者はアップロード元のAWSアカウントのままです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/39e6989b-a61a-289f-8b0e-b12ce99ae5dd.png)

## ACL設定
CloudBerry DriveでACL設定をしていくのですが、実はCloudBerry DriveにはACLの設定をする項目は存在しません。
その代わりCloudBerry Driveから送られるHTTPSリクエストに指定したヘッダーを追加することができます。

CLIのデバッグモードで「--acl bucket-owner-full-control」を実行するとわかりますが、そのオプションを指定した場合はリクエストのヘッダーに「'x-amz-acl': b'bucket-owner-full-control'」が追加されるため、これをCloudBerry Driveのリクエストヘッダーに追加します。

オプションを開いて、Addボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/fb35813d-e0c2-ce7e-9d28-b9ed4767c8d4.png)

Add Rule設定画面が表示されるので、上部の「Specify HTTP Headers」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/bbf4ea12-8e0b-eef7-80f6-d3f15081cdb2.png)

表示された画面でさらにAddボタンを押下して、先ほど記載した設定を追加しOKボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/94678b18-c8d6-0f77-d2fe-77590d5db8e8.png)

以下の真ん中を選択してOKボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/07b7c020-43b0-4dc7-63b6-95a2e4e5dc50.png)

これで設定が完了しました。
さらにOKを押下するとマウントしなおすポップアップが出てくるので、OKを押しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/a2d950e0-c438-1ba7-0057-19eb0369e308.png)

別のファイルをアップロードしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/45502261-e473-af5a-c5eb-1c7833ba861f.png)

S3コンソールから見ると所有者が変更されていました。
これでエクスプローラーからファイルをアップロードする際は、自動でACLの権限を追加することが可能になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/3acaccab-522c-4d5e-5271-63e3124ce6b6.png)

# おわりに
JPCyberの設定が上手くできていないので不完全燃焼感はありますが、CloudBerryDriveでは無事できたので良かったです。

どちらのツールにも言えることですが、アップロードする際にオブジェクトに対してアップロード以外の操作が実行されることになるため、大量のデータや大規模なサイズのデータを扱う場合には注意が必要です。