Byte Ebi's Logo

Byte Ebi 🍤

每天一小口,蝦米變鯨魚

MWAA Connections 加密機制調查

追查 Amazon MWAA 上 Connections 是否能以明碼儲存

Ray

Airflow 文件裡其實記載著,加密金鑰設成空字串就會讓 Connections 直接以明碼儲存
但同樣的做法放到 AWS 代管的 MWAA 上,是否也一樣行得通?
這篇文章記錄我從 Airflow 原生的 Fernet 機制查到 MWAA 保留變數,一路找出答案的過程

調查起因

Airflow 官方文件提到,只要加密金鑰是空字串
Connections 的 passwordextra 欄位就會以明碼儲存,並且 is_encrypted 會是 0
這是 Airflow 原生就支援的行為,並非設定錯誤

這讓我好奇:在 AWS 代管的 MWAA 環境中,是否也能透過同樣的方式停用加密?

調查經過

官方預設值

Airflow 3 的官方文件 指出,預設應該都有透過 Fernet 加密:

For connections stored in the Airflow metadata database, Airflow uses Fernet to encrypt password and other potentially sensitive data. It guarantees that without the encryption password, Connection Passwords cannot be manipulated or read without the key. For information on configuring Fernet, look at Fernet .

原生 Airflow Connections 加解密機制

AWS MWAA 並不開放直接連進 metadata DB 查詢,所以這段是透過容器啟動 Airflow 來驗證原生的加解密邏輯

環境資訊

  • Metadata DB 使用 SQLite:路徑 /usr/local/airflow/airflow.db
  • 加解密金鑰:AIRFLOW__CORE__FERNET_KEY
  • 加密演算法:Fernet

確認欄位是否加密

查詢 SQLite 的 connection 表:

sqlite3 /usr/local/airflow/airflow.db \
  "SELECT conn_id, conn_type, is_encrypted, is_extra_encrypted, password, extra FROM connection;"

也可以用 GUI 工具檢視,例如 VS Code 擴充套件 qwtel.sqlite-viewer

觀察重點:

欄位 說明
is_encrypted 1 代表 password 欄位有加密
is_extra_encrypted 1 代表 extra 欄位有加密
password / extra 加密後為 gAAAAAB... 開頭的 Fernet token,非明文

預設只有 passwordextra 兩欄會加密
conn_idconn_typehostloginportschema 一律明文儲存

確認金鑰存在

airflow config get-value core fernet_key

有值代表加解密金鑰已設定,當金鑰被明確改成空字串時才會用明文儲存
並且先前查詢的 is_encrypted 會是 0

這是因為 airflow.cfg 不存在時,Airflow 會自動隨機生成一組 Fernet key 並寫入設定檔

解密驗證

方法一:Airflow CLI(自動解密)

airflow connections get <conn_id> -o json

Airflow 會用當前環境的 AIRFLOW__CORE__FERNET_KEY 自動解密,直接輸出明文的 password

⚠️ 這個指令會把明文密碼印到終端機,注意輸出不要外流。

方法二:手動用 Fernet key 對照原始加密值解密

from cryptography.fernet import Fernet

fernet_key = "<airflow config get-value core fernet_key 取得的值>"
encrypted = b"<connection.password 欄位裡的 gAAAAAB... 字串>"

f = Fernet(fernet_key.encode())
print(f.decrypt(encrypted).decode())

這個方法能完整展示「原始加密字串 + 金鑰 → 解密還原明文」的過程

小結

  • Airflow 對 Connections 的 password / extra 欄位使用 Fernet 對稱加密
    金鑰由 AIRFLOW__CORE__FERNET_KEY 控制
  • 只要拿得到金鑰,任何人都能解密
  • 金鑰被明確清空時,Airflow 才會直接明文儲存,is_encrypted 會是 0

檢查 MWAA 設定

原先假設 MWAA 的 Airflow Configuration Options 裡 core.fernet_key 可能被設成空值
所以先到 AWS 頁面上查看實際的設定內容

⇒ 檢查 MWAA 上的 Airflow Configuration Options

⇒ 結果:並未被覆寫成空值

但這樣無法排除是否還有其他管道可以覆寫這個值,進一步查文件才發現
Using a startup script with Amazon MWAA 提到 AIRFLOW__CORE__FERNET_KEY 屬於保留字元
就算透過其他方式複寫,也一定會被改回預設值:

Amazon MWAA 會保留一組重要的環境變數。如果您覆寫預留變數,Amazon MWAA 會將其還原為其預設值。下列列出預留變數:

  • AIRFLOW__CORE__FERNET_KEY - 用於加密和解密存放在中繼資料資料庫中之敏感資料的金鑰,例如連線密碼。

所以在 Fernet InvalidToken #18127 中提到,透過將 FERNET_KEY 設為空字串來停用加密的方法不適用。

結論

因為 core.fernet_key 屬於 MWAA 的保留變數,即使嘗試覆寫也會被還原成預設值
所以可以研判在 MWAA 環境中,任何存放在 Metadata 的連線敏感資訊,在底層都必定會強制處於加密儲存狀態
因此不用擔心 MWAA 上的 Connections 密碼會被以明碼形式儲存

最新文章

Category

Tag