AWS Transfer Family - S3 + サービスマネージド

# 構成

AWS Transfer Familyの記事は今回が初めてということもありまずは、理解も含めて簡単な構成から試してみたいと思います。

今回はサービスマネージドでユーザーを２つ準備し、以下の検証を行います。

- user1
  - アクセス可能　s3://XXX-transferfamily/home/user1/
  - アクセス可能　s3://XXX-transferfamily/home/
- user2
  - アクセス可能　s3://XXX-transferfamily/home/user2/
  - アクセス不可　s3://XXX-transferfamily/home/

![transfer1.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/70f632ec-7ef6-bc45-2f25-4b44bb3d60aa.png)


# 設定

## Amazon S3

保存先にはS3を利用するので、S3バケットとディレクトリを準備しておきます。

```
aws s3 ls s3://XXX-transferfamily/    
                           PRE home/
aws s3 ls s3://XXX-transferfamily/home/
                           PRE user1/
                           PRE user2/
```

## IAMポリシーとIAMロール

ドキュメントを参考にIAMポリシーとIAMロールを作成します。

https://docs.aws.amazon.com/ja_jp/transfer/latest/userguide/requirements-roles.html

### 読み書きアクセスポリシー

```json:信頼関係
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "transfer.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

```json:読み書きアクセスポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowListingOfUserFolder",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::DOC-EXAMPLE-BUCKET"
            ]
        },
        {
            "Sid": "HomeDirObjectAccess",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:DeleteObjectVersion", 
                "s3:GetObjectVersion",
                "s3:GetObjectACL",
                "s3:PutObjectACL"
            ],
            "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
        }
    ]
}
```

なお、ドキュメントにも記載がありますが、S3バケットをAWS KMSのカスタムキーで暗号化している場合は、ポリシーで追加のアクセス許可を指定する必要がある点に留意が必要です。

### セッションポリシー

```json:セッションポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowListingOfUserFolder",
            "Action": [
                "s3:ListBucket"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::${transfer:HomeBucket}"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "${transfer:HomeFolder}/*",
                        "${transfer:HomeFolder}"
                    ]
                }
            }
        },
        {
            "Sid": "HomeDirObjectAccess",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:DeleteObjectVersion",
                "s3:GetObjectVersion",
                "s3:GetObjectACL",
                "s3:PutObjectACL"
            ],
            "Resource": "arn:aws:s3:::${transfer:HomeDirectory}*"
        }
    ]
}     
```

`transfer:HomeBucket、transfer:HomeFolder、transfer:HomeDirectory`は各ユーザーごとに適切な値に設定されるため、ユーザによらずポリシーを使いまわせます。
後で、Transfer Family ユーザーを作成しますがその時に、HomeDirectory を設定します。 

## 公開鍵と秘密鍵の作成

```
ssh-keygen -t rsa -b 4096 -N "" -f sftp

-rw-------  1 naata  staff  3401 10 25 16:54 sftp
-rw-r--r--  1 naata  staff   756 10 25 16:54 sftp.pub
```

## AWS Transfer Family

基本的に設計として重要なのは、

- プロトコル
- IDプロバイダー
- エンドポイント
- 保存先
- ユーザーの追加

といったところがメインでしょうか。
一応理解のため他の設定箇所についても記述していきます。

### プロトコル

- SFTP
- AS2
- FTPS
- FTP

セキュリティ上暗号化されたファイル転送がよいので、ここでは「**SFTP**」を選択します。
![スクリーンショット 2023-10-25 16.45.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/49adf6fe-a6cd-3675-479f-416616dbe1a7.png)

なお、IDプロバイダーやエンドポイントタイプごとによっては利用できるプロトコルに制限があるので注意が必要です。

### IDプロバイダー

- サービスマネージド
  - AWS Transfer Family 内にユーザー情報を保存
  - SSHキー認証
- AWS Directory Service
  - AWS Mnaged Microsoft AD、AD Connector、（SimpleADは非対応）
  - パスワード認証
- カスタムIDプロバイダー（IdP）

ここでは**サービスマネージド**を利用します。
![スクリーンショット 2023-10-25 16.45.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/baa6acb3-5403-1cda-ce40-0ca17d5ec566.png)

### エンドポイント

- パブリックアクセス可能
- VPCでホスト
  - 内部のみ（VPC内またはDirect ConnectやVPN経由でアクセス）
  - インターネット向け（VPC内またインターネットでアクセス）

セキュアに通信するのであれば、VPCでホストするのが良いのでしょうが、必要最低限のリソースのみで検証したいためここでは「**パブリックアクセス可能**」を選択します。

- なし
- Amazon Route53
- 外部DNSサービス

ここでは、AWS Transfer Familyのデフォルトのエンドポイントを使って直接アクセスしてしまうので、「**なし**」としました。
![スクリーンショット 2023-10-25 16.46.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/4b78ad83-785c-bd07-4852-f02d023f3b7c.png)

### 保存先

- Amazon S3
- Amazon EFS

ここではシンプルに「S3」を選択します。
![スクリーンショット 2023-10-25 16.46.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/5a3120b8-5284-c988-e04d-db988ac68e43.png)

### ログ

CloudWatchログにイベントを配信できます。
![スクリーンショット 2023-10-25 16.47.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/d29f1f0d-c566-e291-35e0-44882fabe306.png)

### マネージドワークフロー

簡単にいうと転送されたファイルに対してコピー、タグ付け、削除、複合、またはLambdaを使ってカスタムに処理をフローの中に導入できます。

今回はシンプルに行きたいので特になにも設定せずに、またに機会に試したいと思います。
![スクリーンショット 2023-10-25 16.48.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/88ef0028-5ca3-e300-32a3-10283afb47cc.png)

### 暗号化アルゴリズム

暗号化アルゴリズムのセキュリティポリシーを指定できます。ここの設定はクライアントの動作にも依存すると思いますがデフォルトのままにしておきました。
![スクリーンショット 2023-10-25 16.48.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/c02a266b-851e-625a-16f1-524290093639.png)

https://docs.aws.amazon.com/ja_jp/transfer/latest/userguide/security-policies.html

### サーバーホストキー

デフォルトでは、AWS Transfer for SFTP は AWS SFTP サーバーのホストキーを提供します。
デフォルトのホストキーは、別のサーバーのホストキーに置き換えることが可能なようですが、特に今回は新規に作成するだけですので、追加で設定せずそのまま進みます。
![スクリーンショット 2023-10-25 16.49.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/567918b0-bcb8-bb12-858a-91835a02d1c0.png)

### 表示バナー

クライアントがサーバーに接続する前にメッセージを表示できるみたいです。
今回は「**Transfer family connection test**」と入力しておきます。
![スクリーンショット 2023-10-26 9.31.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/763fda58-e74d-e012-8b13-17d3c4d01c9a.png)

### ユーザーの追加

「user1」と「user２」を作成します。

- ユーザー名
  - サーバーに接続するときのユーザー名

ここでは、「user1」と「user２」です。

- ロール
  - S3バケットへの操作権限

先に作成済みの読み書きアクセスポリシーをアタッチしたIAMロールを指定します。

- ポリシー
  - なし
  - IAM からポリシーを選択
  - ホームフォルダに基づくポリシーの自動生成

「user1」は「なし」。
「user2」は「IAM からポリシーを選択」で先程作成したセッションポリシーを選択します。

それでわかりにくいのが先に指定したロールとポリシーどう違うのって話。
ロールってポリシーに紐づけるからポリシーっていらないんじゃないって思ってしまうところですが、全体的なS3へのアクセスに関してはロールに、個別のユーザーに関する制限についてはポリシーに指定しましょうというところでしょうか。

- ホームディレクトリ

「user1」は、
　S3バケット「XXX-transferfamily」
　ディレクトリ「/home/user1」

「user2」は、
　S3バケット「XXX-transferfamily」
　ディレクトリ「/home/user2」

- 制限付き
  - 要するに、chroot　です。

　今回は特に設定しません。
![スクリーンショット 2023-10-26 10.54.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/d0909b2c-6a8a-338d-c3a8-0887f16ea697.png)
![スクリーンショット 2023-10-26 10.53.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/6e31b65f-9365-3b5a-4392-fc74fd252119.png)

- SSH パブリックキー

先程作成した公開鍵をペーストします。
（本当は「user1」も「user2」も異なる公開鍵を設定すべきなのでしょうが、面倒だったので同じものにしています。）
![スクリーンショット 2023-10-26 9.55.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/28667e0c-9e87-f53f-fe5d-8cbfbbf8531a.png)


# 動作確認 

## user1

```
$ sftp -i sftp user1@XXX.server.transfer.ap-northeast-1.amazonaws.com
Transfer family connection test
Connected to s-XXX.server.transfer.ap-northeast-1.amazonaws.com.

sftp> pwd
Remote working directory: /XXX-transferfamily/home/user1

## /XXX-transferfamily/home/user1/に put できたことを確認。
sftp> put test1.txt       
Uploading test1.txt to /XXX-transferfamily/home/user1/test1.txt
test1.txt                                                                                         100%    0     0.0KB/s   00:00    
sftp> ls
test1.txt  

sftp> cd ..
sftp> pwd
Remote working directory: /XXX-transferfamily/home

# /XXX-transferfamily/home/　にも put できたことを確認。
sftp> put test1.txt
Uploading test1.txt to /XXX-transferfamily/home/test1.txt
test1.txt                                                                                  100%    0     0.0KB/s   00:00    

sftp> ls
test1.txt  user1
```

## user2

```
% sftp -i sftp user2@s-XXX.server.transfer.ap-northeast-1.amazonaws.com

Transfer family connection test
Connected to s-XXX.server.transfer.ap-northeast-1.amazonaws.com.

sftp> pwd
Remote working directory: /XXX-transferfamily/home/user2

## /XXX-transferfamily/home/user2/に put できたことを確認。
sftp> put test2.txt
Uploading test2.txt to /naata-transferfamily/home/user2/test2.txt
test2.txt                                                                                         100%    0     0.0KB/s   00:00    

sftp> ls
test2.txt 

## /XXX-transferfamily/home/ には移動できないことを確認。
sftp> cd ..
stat remote: Permission denied
```

# 参考

https://dev.classmethod.jp/articles/summary-point-aws-transfer-family-202307/

https://dev.classmethod.jp/articles/reinvent2018-sftp-iam/

また、少々古かったですが、AWSトレーニングにもいくつかあったのでそちらも参考にするとよいでしょう。

https://aws.amazon.com/jp/training/

# その他

サーバーあたりのサービス管理ユーザーの数は、10,000で上限緩和可能なようなのでそれ程困ることはないと思いますが、ユーザー分作成しないといけないのでAD連携で管理することも良いかと思ました。

https://docs.aws.amazon.com/ja_jp/general/latest/gr/transfer-service.html

次回余裕があったら検証してみようかなというところです。