GCSToSFTPOperatorでハマった

こんにちは!WEBアプリケーションエンジニアの小松です!

今まで主に EC サイトの WEB エンジニアとして仕事をしてきて、Airflow を触るようになったのはエニグモに入社してからでした。

BUYMA では、広告媒体向けのフィード生成や外部パートナーとのデータ連携、在庫データの収集など、毎日大量に発生するバッチ処理を Airflow に任せています。

人手では絶対に回せない規模なので、Airflow は影の立役者のような存在です。

そんな Airflow を動かしている基盤が Google Cloud Composer なのですが、会社全体でオンプレサーバーからクラウドへ移行していく流れの中で、Composer も新しいバージョンへ移し替えることになりました。

「まあ普通に移行できるだろう」と思っていたら、まさかの沼にハマってしまい……
同じ罠に落ちる人が一人でも減りますように、という気持ちでこの記事を書いています。

この記事は[Enigmo Advent Calendar 2025]の13日目の記事です。  


結論(先に言います)

Airflow の GCSToSFTPOperator が突然 SFTP 認証できなくなった原因は…

Composer が入れている Paramiko のバージョンが古く、RSA 署名アルゴリズムがサーバーに拒否されたから。

つまり、

  • コマンドからは接続できる

  • Python の Paramiko スクリプトでも接続できる

  • でも Airflow からだけ認証エラーになる

という、最悪に分かりづらい症状が発生していました。


何が起きていたのか(時系列で紹介)

① Composer 移行後、SFTP アップロードだけエラー

Airflow 2 → Composer の新環境に移行した際、GCSToSFTPOperator だけが謎の認証失敗。

ログにはこれだけ:

 
Bad authentication type; allowed types: ['publickey']

鍵は設定済みのはずなのに、Airflow だけ失敗。謎が深まる。


② コマンド実行では成功する

Docker コンテナに入り、

 
sftp -i pri.key sftp.host.com

→ 成功。

設定ミスではないと確信。


Python(paramiko)でも成功する

「Airflow がダメなら paramiko 生で試すか」と思いテストコードを書くと…

→ 普通に成功。

つまり、Airflow 経由でのみ認証が弾かれている。


④ 「Airflow からだけ接続できない」という地獄に突入

Airflow → SFTPHook → SSHHook → Paramiko

このどこかが悪いのは確実だが、Extra の書式を変えても、パラメータを変えても改善しない。

Airflow のログは詳細な理由を出してくれない。

完全に暗闇の中を歩く状態。


⑤ 試行錯誤の果てに見えてきた「署名アルゴリズム問題」

Docker の sftp でのみ発生していたエラー:

 
sign_and_send_pubkey: no mutual signature supported

ここでようやく糸口が見えた。

  • サーバー:rsa-sha2-256/512 を要求

  • 古い Paramiko:ssh-rsaSHA1)署名を使ってしまう

サーバーが拒否

という構図。


⑥ Airflow(Paramiko)は署名アルゴリズムを指定できない

OpenSSH のように

 
-PubkeyAcceptedAlgorithms=ssh-rsa

といった強制は Paramiko では不可能。

つまり:

  • Airflow から署名アルゴリズムを変更するすべがない

  • 古い Paramiko を使っている限り絶対に成功しない

という仕様の問題。


⑦ Composer の paramiko を確認すると…古い!

Composer 内で

 
pip freeze | grep paramiko

すると……

2.7 系(古い)
rsa-sha2 に未対応

原因が完全に確定。


⑧ Composer をアップグレード → 一発成功

Composer の Airflow イメージをアップデートし、

  • Paramiko が 2.9+(rsa-sha2 デフォルト対応) に更新

その瞬間、

→ GCSToSFTPOperator が何事もなく成功。

設定は一文字も変えていません。

完全にバージョン差の問題でした。


技術的まとめ:今回の本質

問題の本質はこれ:

GCSToSFTPOperator → SFTPHook → Paramiko が SHA1 署名(ssh-rsa)しか使えず、外部サーバーが RSA-SHA2 を要求していたため認証が失敗した。


回避策(原理上)

方法 可能? 説明
Paramiko を 2.9+ にアップグレード 今回の完全解決策
key_file 形式で渡す Composer では鍵配置がやや面倒
RSA 鍵を SHA2 対応形式へ変換 問題は鍵ではなくクライアント側
SFTP サーバーに設定変更を依頼 外部企業のため不可能

最後に:今回の教訓

  • 「Airflow だけ接続できない」→ Paramiko のバージョンをまず疑うべし

  • Airflow のログは認証まわりが不親切で根本原因が見えづらい

  • Composer は内部ライブラリが固定なので、移行時に“バージョン差事故”が起きやすい

  • 結局のところ、問題の 9 割は Airflow が使っているライブラリのバージョン差

数日単位で調査し、無数のテストを書き、ようやく原因に辿り着いたので、この記事が誰かの時間を 30 分でも節約できたら嬉しいです。

 

明日12/14の記事はインフラエンジニア森田さんです。お楽しみに。