AWS Transfer Family の SFTP 接続失敗がログに記録されない事象の原因と対処方法
はじめに
AWS Transfer Family で SFTP 接続が断続的に失敗し、Transfer Family 側のログに痕跡が残らない事象に遭遇しました。原因は CloudWatch Logs の CreateLogStream API スロットリングでした。原因の一例として調査の経緯と対処方法を共有します。
結論
Transfer Family のログ記録ロール(LoggingRole)によるログ記録を使用している場合、SFTP セッション確立のたびに CreateLogStream API が呼ばれます。CreateLogStream のデフォルトクォータは 50 回/秒(アカウント・リージョン単位)です。多数のクライアントが同時接続するとクォータを超過し、スロットリングで接続が切断されます。
推奨の対処方法は JSON 構造化ログ記録(JSON structured logging)への切り替えです。vended logs 方式でログを配信するため、CreateLogStream の呼び出し自体が不要になり、ここの問題は解決されます。
| 項目 | 内容 |
|---|---|
| 原因 | CloudWatch Logs CreateLogStream API のスロットリング(50 回/秒の上限超過) |
| 発生条件 | ログ記録ロールによるログ記録を使用 + 同時接続数がクォータを超過 |
| 厄介な点 | ログストリーム作成自体が失敗するため、Transfer Family のログにエラーのが残らない |
| 暫定対応 | Service Quotas で CreateLogStream クォータを引き上げ |
| 恒久対応 | JSON 構造化ログ記録への切り替えを推奨 |
症状
以下のような症状が見られました。
- 多数のクライアントが同時刻に一斉接続するタイミングで SFTP 接続が断続的に失敗する
- SFTP クライアント側からみると接続成功と失敗が混在し、リトライすると成功することがある
- VPC フローログでは SSH Key Exchange Init の時点でサーバーから FIN,ACK が返されていることを確認できる
- Transfer Family のログには接続エラーの記録が一切残らない
原因特定が難しかった
まず、Transfer Family のログにエラーの記録が残りません。後述するとおり、ログストリームの作成自体が失敗しているためエラーを書き込む先がないのです。ログがない以上、調査の手がかりが限られます。
ログがないため、切り分けには SFTP クライアント側のネットワークでパケットキャプチャなど低レイヤーの情報に頼るしかありません。パケットキャプチャの内容からは、SSH Key Exchange Init の時点で SFTP サーバーから FIN,ACK が返されていることを確認できました。そのため、最初期の調査ではネットワーク設定やポート変更で切り分けしましたが解消しませんでした。
最終的に CloudWatch Logs API のスロットリングが原因であると判明しました。SFTP 接続のトラブルシューティングで「ログ出力先の CloudWatch Logs の API のクォータ上限」を疑うのは直感的でなく、なかなか手強い話でした。
原因の整理
Transfer Family でログ記録ロール(LoggingRole)によるログ記録を使用している場合、SFTP セッション確立の過程で CreateLogStream API を呼び出します。この方式ではログストリームがセッションごとに作成されるため、接続のたびに API が呼ばれます。CreateLogStream のデフォルトクォータはアカウント・リージョン単位で 50 回/秒 です。
同時接続数が増加してクォータを超過すると、以下の流れで接続が切断されることがわかりました。
今回のケースでは、CloudWatch Usage メトリクスでピーク時の 1 分間に 3,000 回以上の CreateLogStream 呼び出しを確認しました。秒間換算で 50 回以上となり、クォータ上限に達していたと考えられます。

API 呼び出し数の確認方法
CloudWatch メトリクスで CreateLogStream の呼び出し数を確認します。AWS/Usage 名前空間の CallCount メトリクスを使用します。
- CloudWatch コンソールを開く
- 左メニューから「メトリクス」>「すべてのメトリクス」を選択
- 名前空間
AWS/Usageを選択し、Resource:CreateLogStreamでフィルターする

- メトリクス
CallCountを SUM 統計、1 分間隔で表示する

- ピーク値を 60 で割り、秒間換算値を算出する。クォータ上限(50 回/秒)を超えていればスロットリングが疑われる

閾値の線を追加する場合はグラフのオプションから設定できます。

対処方法
暫定対応: CreateLogStream クォータの引き上げ
Service Quotas から CreateLogStream のクォータ引き上げを申請し、スロットリングを解消します。
- Service Quotas コンソールを開く
- 「Amazon CloudWatch Logs」を選択
- 「CreateLogStream throttle limit in transactions per second」を検索(クォータコード:
L-76507CEF) - 必要な値を指定して引き上げをリクエスト

接続数の増加に応じて再度の引き上げが必要になるため、あくまで暫定策です。
恒久対応: JSON 構造化ログ記録への切り替えを推奨
JSON 構造化ログ記録は AWS が現時点で推奨するログ方式であり、vended logs 方式でログを配信します。セッションごとの CreateLogStream 呼び出しが不要になるため、スロットリングの問題を根本的に解決できます。
切り替え手順は以下の記事を参考にしてください。
切り替えにあたっての注意事項は以下のとおりです。
you should be careful transferring files during the first hour after changing your logging method, as logs could be dropped.
— Creating, updating, and viewing logging for servers - AWS Transfer Family
- マネージドワークフローやコネクタを使用している場合、ログ記録ロールとの併用が必要(JSON 構造化ログ記録は未対応)
- ログのフォーマットが変わるため、ログ解析スクリプトや監視設定の改修を計画した上で移行すること
- 設定操作を行う IAM ユーザーまたはロールに
logs:CreateLogDelivery等の権限が必要(詳細は上記記事を参照)
まとめ
Transfer Family で SFTP 接続が断続的に失敗し、ログにエラーが残らない場合は CreateLogStream のスロットリングを疑ってください。CloudWatch メトリクスで呼び出し回数を確認し、クォータを超過していれば JSON 構造化ログ記録への切り替えで根本解決できます。
おわりに
原因がわかってしまえばそんなことかという感じなのですが、マネージドサービスに切り分けがなかなか手強かったです。Transfer Family が SFTP クライアント側にわかりやすくエラーを返してくれると良かったのですけどね。
参考
- Amazon CloudWatch logging for AWS Transfer Family servers
- Creating, updating, and viewing logging for servers - AWS Transfer Family
- Configure CloudWatch logging role - AWS Transfer Family
- CloudWatch Logs quotas - Amazon CloudWatch Logs
- CloudWatch usage metrics - Amazon CloudWatch
- Monitoring with CloudWatch metrics - Amazon CloudWatch Logs






