Сломанный DAG: [/airflow/dags/a.py] Не удается расшифровать «дополнительные» параметры для входа в систему = нет, отсутствует конфигурация FERNET_KEY

Я запустил Airflow без FERNET_KEY. Как только я это понял, я сделал следующее: https://airflow.apache.org/configuration.html#connections

pip install apache-airflow[crypto]

from cryptography.fernet import Fernet
fernet_key= Fernet.generate_key()
print(fernet_key)

взял ключ и вставил в airflow.cfg а потом позвонил airflow initdb но ошибка все равно появляется.

Что я делаю не так?

Когда я делаю:

airflow webserver -D

Я получил:

  File "/usr/local/lib/python2.7/dist-packages/airflow/models.py", line 713, in extra_dejson
    if self.extra:
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/attributes.py", line 293, in __get__
    return self.descriptor.__get__(instance, owner)
  File "/usr/local/lib/python2.7/dist-packages/airflow/models.py", line 632, in get_extra
    return fernet.decrypt(bytes(self._extra, 'utf-8')).decode()
  File "/usr/lib/python2.7/dist-packages/cryptography/fernet.py", line 101, in decrypt
    raise InvalidToken

Журнал показывает, что есть проблема с этим кодом:

def get_conn(conn_id, session=None):
    conn = (session.query(Connection)
                   .filter(Connection.conn_id == conn_id)
                   .first())
    return conn


def my_python_function():
   conn = get_conn('s3connection')
   key_id = conn.extra_dejson.get('aws_access_key_id')
   secret_key = conn.extra_dejson.get('aws_secret_access_key')
   default_region = conn.extra_dejson.get('region_name')
   return key_id,secret_key,default_region

person jack    schedule 13.06.2018    source источник
comment
Вносили ли вы какие-либо изменения в ключ fernet после того, как впервые добавили его в airflow.cfg?   -  person cwurtz    schedule 13.06.2018
comment
@CJWurtz Это первый DAG, который я обедаю. После того, как я установил airflow и загрузил DAG, я получил похожее сообщение. Затем я сделал модификацию, указанную в вопросе.   -  person jack    schedule 13.06.2018
comment
@ tobi6, в документе говорится, что если криптопакет не был установлен изначально, вы все равно можете включить шифрование для соединений, выполнив следующие шаги, поэтому есть способ решить эту проблему. После того, как я установил его, я удалил соединения и воссоздал их. Все еще не работает. Что еще я могу сделать?   -  person jack    schedule 13.06.2018
comment
@tobi6 без кавычек.. На самом деле там был предыдущий ключ (не знаю откуда) я его просто заменил. Без кавычек и без одинарных кавычек.   -  person jack    schedule 13.06.2018
comment
@tobi6 Проблема в том, что в разделе 6 говорится о перезапуске веб-сервера AirFlow. Но я не могу перезапустить сервер из-за ошибки python   -  person jack    schedule 13.06.2018
comment
@tobi6 не менял кодировку. Опять же, я создал ключ только один раз.. после того, как появилась ошибка... Но файл cfg имел значение там раньше.   -  person jack    schedule 13.06.2018


Ответы (5)


Airflow обычно генерирует один для вас.

Вот пример:

$ python
>>> from cryptography.fernet import Fernet
>>> k=Fernet.generate_key()
>>> print(k)
Z6BkzaWcF7r5cC-VMAumjpBpudSyjGskQ0ObquGJhG0=
>>> ^D
$ $EDITOR $AIRFLOW_HOME/airflow.cfg

Там меняют:

# Secret key to save connection passwords in the db
fernet_key = cryptography_not_found_storing_passwords_in_plain_text

to:

# Secret key to save connection passwords in the db
fernet_key = Z6BkzaWcF7r5cC-VMAumjpBpudSyjGskQ0ObquGJhG0=

Проверьте, установлен ли он, как ожидалось (или он будет генерировать случайный каждый раз)

$ python
Python 2.7.13 (default, Jul 18 2017, 09:17:00)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from airflow import configuration as conf
[2018-06-14 17:53:36,200] {__init__.py:57} INFO - Using executor SequentialExecutor
>>> conf.get('core','fernet_key')
'Z6BkzaWcF7r5cC-VMAumjpBpudSyjGskQ0ObquGJhG0='
>>>

Вышеупомянутый должен быть синтаксис v1.9.0 и v1.8.2 [исправлено], я дважды проверил это с последним.

Всякий раз, когда вы меняете свой ключ fernet, вам нужно удалить все соединения и переменные, которые используют шифрование, так как они больше не будут расшифровываться.

Вы можете сбросить свой db, но это, вероятно, переусердствовать.

person dlamblin    schedule 14.06.2018
comment
Когда я делаю c=AirflowConfigParser(default_config=AIRFLOW_CONFIG), я получаю: TypeError: __init__() got an unexpected keyword argument 'default_config' - person jack; 14.06.2018
comment
Также у меня не работает $EDITOR $AIRFLOW_HOME/airflow.cfg. Пришлось делать cd airflow а потом nano airflow.cfg - person jack; 14.06.2018
comment
@jack Да, вы можете выбрать своего редактора. Если вы прочтете man man и man crontab, вы увидите, что posix рекомендует установить EDITOR равным пути к вашему любимому редактору. Моя ошибка в default_config, это пост v1.9.0. Итак, на самом деле вам нужны обновления, которые я сделал выше. - person dlamblin; 14.06.2018
comment
Работает и с 1.10. Благодарю вас! - person Leo; 22.10.2018

Используя Fernet, Airflow шифрует все пароли для своих соединений в серверной базе данных.

В вашем случае серверная часть Airflow использует предыдущий ключ fernet, и вы сгенерировали ключ, с помощью которого вы создали новое соединение.

Я рекомендую сделать следующее. Во-первых,

airflow resetdb

это поможет удалить все существующие записи в вашей серверной базе данных.

Затем,

airflow initdb

это инициализирует бэкэнд как свежий.

Затем запустите веб-сервер и планировщик воздушного потока.

airflow web server -p {port}
airflow scheduler

Затем создайте новое подключение s3 в пользовательском интерфейсе (дополнительно — {"aws_access_key_id":"_your_aws_access_key_id_", "aws_secret_access_key": "_your_aws_secret_access_key_"})

Теперь вы сможете протестировать средство наблюдения за файлами s3, выполнив следующее решение: соединение Airflow s3 с использованием пользовательского интерфейса

person shyam    schedule 11.09.2018

Это также может произойти, если у вас есть scheduler и webserver, работающие в отдельных контейнерах Docker без общей конфигурации. Каждый контейнер будет генерировать свой собственный ключ fernet, что означает, что они не могут расшифровать секреты друг друга.

В этом случае вы можете:

  • используйте AIRFLOW__CORE__FERNET_KEY env var, чтобы явно установить ключ для обоих контейнеров
  • настроить том для совместного использования файла конфигурации между контейнерами
  • запустить оба процесса в одном контейнере
person Tamlyn    schedule 11.11.2020
comment
python3 -c из cryptography.fernet import Fernet; печать (Fernet.generate_key()) - person Kernelv5; 14.11.2020
comment
Я использовал эту команду для генерации ключа. Раньше я случайно набирал что-то в качестве ключа, но это не сработало. - person Kernelv5; 14.11.2020
comment
python3 -c из cryptography.fernet import Fernet; печать (Fernet.generate_key().decode()) - person Kernelv5; 14.11.2020
comment
Эта команда для проверки правильности работы или установки Fernet - person Kernelv5; 14.11.2020

Если вы запустите воздушный поток без ключа fernet, это не позволит зашифровать какое-либо соединение.

Если у вас был ключ fernet, добавляли/редактировали какие-либо соединения, они будут зашифрованы этим ключом. Если вы каким-либо образом измените ключ, эти соединения нельзя будет расшифровать. Если в настоящее время у вас есть соединения, зашифрованные с помощью разных ключей fernet, единственным решением является перенос ключей, созданных с помощью одного, на другой. Или просто удалите их и создайте заново, если у вас все еще есть под рукой значения.

person cwurtz    schedule 13.06.2018
comment
У меня только 1 соединение. Я удалил его и начал заново... Но все равно - не работает. Есть проверка Is Extra Encrypted, но не Is Encrypted - person jack; 13.06.2018
comment
CJ, если то, что вы говорите, было бы решением, то удаление всех соединений, а затем определение их снова должно было решить эту проблему. Но это не так. Также я не понимаю, что именно зашифровано... Я думаю, что само шифрование не работает, поэтому не работает и расшифровка. - person jack; 13.06.2018
comment
Поле пароля и дополнительное поле шифруются отдельно. Если Is Encrypted не отмечено, а Extra Ecnrypted есть, это означает, что пароль не зашифрован, но зашифрованы дополнительные данные. Шифрование в airflow определенно работает. - person cwurtz; 13.06.2018
comment
Возможно, попробуйте очень простой ключ fernet, например, test, добавьте с его помощью соединение и посмотрите, появляется ли у вас та же ошибка. Возможно, это проблема с каким-то символом самого ключа fernet, который вы используете. - person cwurtz; 13.06.2018
comment
Я не сделал EXPORT AIRFLOW__CORE__FERNET_KEY = your_fernet_key, потому что в документе сказано, что это может быть альтернатива? - person jack; 13.06.2018
comment
В airflow, когда он пытается получить переменную конфигурации, он сначала проверяет переменную ENV, затем airflow.cnf, затем аргументы команды и, наконец, значения по умолчанию. Вам не нужно устанавливать его, экспортируя переменную ENV, если она есть в вашем airflow.cfg. - person cwurtz; 13.06.2018
comment
честно не понимаю этой проблемы. Я создал новый ключ. удалил все подключения. спас их снова. Почему это продолжается?! Я вижу, что модуль возвращает: return Fernet(configuration.get('core', 'FERNET_KEY').encode('utf-8')) airflow.apache.org/_modules/airflow/models.html как проверить, почему эта строка не работает? - person jack; 13.06.2018
comment
Самый простой способ проверить - получить значение соединения из базы данных, открыть окно консоли Python, скопировать и вставить метод get_fernet() без AirflowException (или также импортировать его) и попытаться запустить декодирование fernet со значением из базы данных. . Просто выполните каждую команду шаг за шагом и посмотрите, где происходит что-то неожиданное. - person cwurtz; 13.06.2018
comment
NameError: имя «get_fernet» не определено - person jack; 13.06.2018
comment
Вы захотите скопировать и вставить его из models.py воздушного потока, взяв ту часть, которая вам нужна для создания объекта Fernet. - person cwurtz; 13.06.2018
comment
У меня есть объект FERNET. что теперь? - person jack; 13.06.2018
comment
Я сказал скопировать и вставить, чтобы вы могли изменить функцию, если это необходимо для отладки. Однако, если вы пойдете по этому пути, вам нужно сделать from airflow.models import get_fernet. По сути, просто отследите маршрут, по которому проходит воздушный поток, когда он запускает get_extra(), передавая то, что вам нужно расшифровать, из необработанного значения из базы данных. - person cwurtz; 13.06.2018
comment
Когда я это делаю: печатаю Fernet(configuration.get('core', 'FERNET_KEY').encode('utf-8')).__encryption_key я вижу: ▒▒0▒8▒▒[Ƞ/I▒9 - person jack; 13.06.2018
comment
Может дело в самом шифровании? Когда я проверяю соединения пользовательского интерфейса, я не вижу там ничего зашифрованного. - person jack; 13.06.2018
comment
Если configuration.get('core', 'FERNET_KEY').encode('utf-8') соответствует тому, что вы настроили, тогда оно должно быть правильным. Не уверен, что stackoverflow форматирует символы или нет, я сделал то же самое локально и получил b'\xad\x9e9l\x97\xe9\xd4\x1fF4Y"\t\xfcLj'. Я бы продолжил попытку использовать ваш объект Fernet для декодирования значения из базы данных - person cwurtz; 13.06.2018

Обязательно сначала поместите ключ fernet, а затем выполните следующую команду:

airflow initdb

Если проблема не устранена, удалите все таблицы из базы данных и повторите команду:

airflow initdb
person Ankit Adlakha    schedule 05.07.2019