Apache NiFi. Как быстро подружиться с LDAP и Registry

Казалось бы, про Apache NiFi уже писали не раз. Но если ты только знакомишься с инструментом, разобраться в таких статьях бывает нелегко. Обычно с тобой говорят так, будто ты уже давно в теме, да и задачи чаще решают явно не твои. С официальной документацией тоже все сложно: она есть, но для быстрого погружения явно не подходит.

5209cc4d9e5bb4efe81cc4aaa5f974e7.jpg

Вот почему я решил подготовить свой гайд для новичка. Попробуем максимально быстро:

Обычно пользователи читают разные мануалы. Так можно найти что-то новое и полезное, чего нет в других источниках. Надеюсь, эта статья тоже пригодится. А если вы хотите что-то добавить по теме, пишите в комментариях. Буду рад пообщаться :)

Первичная настройка  

На всякий случай напомню, что Apache NiFi — это инструмент для обработки и передачи данных в режиме реального времени. С его помощью можно управлять потоками информации из различных источников. Самый простой пример использования: взять данные из Kafka, обработать и перенести в БД.

Мы в компании НУБЕС (Nubes) начали использовать NiFi с задачи по обработке больших объемов данных, которые поступают в формате Json. Преобразовываем их и переносим в PostgreSQL, а далее — используем для генерации аналитических отчетов.

Итак, первичная установка выглядит так:

  1. Для установки инструмента потребуется Java — без нее ничего не запустится.

sudo dnf install java-21-openjdk-devel
  1. Далее добавляем пользователя NiFi.

useradd -d /opt/NiFi/ NiFi -s /sbin/nologin
  1. Теперь устанавливаем NiFi с официального сайта, подбираем нужную версию. Мы будем работать с 1.25.0.

wget https://dlcdn.apache.org/nifi/1.25.0/nifi-1.25.0-bin.zip
unzip https://dlcdn.apache.org/nifi/1.25.0/nifi-1.25.0-bin.zip
ln -s nifi-1.25.0-bin nifi
  1. Описываем потребление памяти (меняем значение NN на свое) и то, кто будет управлять NiFi.

/opt/nifi/conf/bootstrap.conf

run.as=nifi
java.arg.2=-XmsNNg
java.arg.3=-XmxNNg
  1. Настраиваем systemd.

/etc/systemd/system/nifi.service

[Unit]
Description=Apache Nifi
After=network.target
 
[Service]
Type=forking
ExecStart=/opt/nifi/bin/nifi.sh start
ExecStop=/opt/nifi/bin/nifi.sh stop
ExecReload=/opt/nifi/bin/nifi.sh restart
User=nifi
Restart=always
Environment="JAVA_HOME=/usr/lib/jvm/jre-openjdk"
Environment="LD_LIBRARY_PATH=/usr/lib/jvm/jre-openjdk/lib"
 
[Install]
WantedBy=multi-user.target

/etc/systemd/system/nifi-registry.service

[Unit]
Description=Apache Nifi
After=network.target

[Service]
Type=forking
ExecStart=/opt/nifi/bin/nifi-registry.sh start
ExecStop=/opt/nifi/bin/nifi-registry.sh stop
ExecReload=/opt/nifi/bin/nifi-registry.sh restart
User=nifi
Restart=always
Environment=«JAVA_HOME=/usr/lib/jvm/jre-openjdk»
Environment=«LD_LIBRARY_PATH=/usr/lib/jvm/jre-openjdk/lib»

[Install]
WantedBy=multi-user.target

Первичная настройка завершена. На этом моменте можно запускать NiFi и Registry…  

Но не все так просто. Дружить друг с другом они не захотят, авторизация будет работать абы как. Что делать? Ответ — далее.

Добавляем сертификаты

Как вы уже поняли, это очень важный момент. В нашей инструкции за центр сертификации отвечает модуль CA (certificate authority) в FreeIPA. В целом, нет конкретной привязки к FreeIPA: достаточно иметь любой СА, который сможет подписать все, что ему сконфигурируешь.

Все следующие настройки будут создаваться в /opt/NiFi/ssl (директорию также необходимо создать).

Создаем запрос на сертификат.

/opt/nifi/ssl/$(hostname).conf

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
 
[req_distinguished_name]
C = RU
ST = Russia
L = Moscow
O = nubes
OU = nubes
CN = $(hostname)
 
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth

Затем генерируем приватный ключ и сертификат по запросу.

openssl req -newkey rsa:2048 -keyout  $(hostname).key -out  $(hostname).csr -config  $(hostname).conf -nodes

В итоге получаем CSR (зашифрованный запрос на выпуск сертификата, содержащий подробную информацию о домене и организации). Теперь берем его и бежим подписывать сертификат. Складываем его рядом на сервер. Заодно получаем root/intermediate сертификаты. В нашем случае это сертификаты FreeIPA СА.

a18f3f66b0cf01343a7efa898f2041e6.png

Все сертификаты NiFi хранятся либо в p12, либо в jks — вариант выбирайте на свое усмотрение. Мы рассмотрим оба случая. 

Для теста достаточно иметь одинаковый ks и ts, однако на деле рекомендуется их разделять.

KeyStore хранит ключи и сертификаты, тогда как TrustStore содержит сертификаты, которым доверяет ПО.

Для начала создаем p12. Заранее придумываем пароль, который мы будем задавать для KeyStore.

openssl pkcs12 -export -in $(hostname).crt -inkey $(hostname).key -out $(hostname).p12

И из p12 создаем jks. Пароль необходимо ввести тот же, что и в действии выше.

keytool -importkeystore -destkeystore $(hostname).jks -srckeystore $(hostname).p12 -srcstoretype PKCS12

Далее помещаем все остальные сертификаты в jks.

keytool -importcert -file idm-intermediate.crt -keystore $(hostname).jks -alias "idm-intermediate"
keytool -importcert -file idm-root.crt -keystore $(hostname).jks -alias "idm-root"
keytool -importcert -file registry.crt -keystore $(hostname).jks -alias "nifi-registry"

Настраиваем конфигурационные файлы NiFi

О всех настройках NiFi можно почитать здесь. Ниже приведено только то, что необходимо для запуска и интеграции компонент между собой. 

В целом NiFi использует три основных файла для настройки:

  • NiFi-properties (основные параметры) — на каком порту, на каких адресах и какие политики авторизации будут использоваться;

  • Login-identity — указывается основная политика авторизации, которая будет применяться (noauth, ldap, salm, kerb);

  • Authorizers — описываются права доступов, пользовательские окружения.

/opt/nifi/conf/nifi.properties

Настраиваем конфигурационные файлы NiFi
О всех настройках NiFi можно почитать здесь. Ниже приведено только то, что необходимо для запуска и интеграции компонент между собой. 
В целом NiFi использует три основных файла для настройки:
NiFi-properties (основные параметры) — на каком порту, на каких адресах и какие политики авторизации будут использоваться;
Login-identity — указывается основная политика авторизации, которая будет применяться (noauth, ldap, salm, kerb);
Authorizers — описываются права доступов, пользовательские окружения.
# Базовая настройка сервера
nifi.web.https.host=$(hostname)
nifi.web.https.port=8443
# Необходимо придумать еще один секретный ключ и записать его сюда
nifi.sensitive.props.key=123qwesecretkey
 
nifi.security.keystore=./ssl/$(hostname).jks
nifi.security.keystoreType=jks
# Пароль от jks
nifi.security.keystorePasswd=jksSecretKey
# Пароль от jks
nifi.security.keyPasswd=jksSecretKey
nifi.security.truststore=./ssl/$(hostname).jks
nifi.security.truststoreType=jks
# Пароль от jks
nifi.security.truststorePasswd=jksSecretKey
# Включаем авторизацию по LDAP
nifi.security.user.authorizer=managed-authorizer
nifi.security.allow.anonymous.authentication=false
nifi.security.user.login.identity.provider=ldap-provider

Далее описываем блок авторизации. На данном этапе обычно происходит авторизация всех пользователей. Если необходимость работать с LDAP вызывает истерический припадок, достаточно скачать Apache DS и подключиться под сервисным пользователем. Затем можно дойти до нужных групп/пользователей, которым необходимо будет предоставлять доступ.

/opt/nifi/conf/login-identity-providers.xml


	
    	single-user-provider
    	org.apache.nifi.authentication.single.user.SingleUserLoginIdentityProvider
    	
   	 
	
 
	
    	ldap-provider
    	org.apache.nifi.ldap.LdapProvider
    	SIMPLE
 
    	cn=svc_nifi,ou=Service Users,dc=XXX,dc=nubes,dc=ru
    	secretpass
 
    	
    	
    	
    	
    	
    	
    	
    	
    	
 
    	FOLLOW
    	10 secs
    	10 secs
 
    	ldaps://ADSERVER:636
    	ou=nubes-XXX,dc=XXX,dc=nubes,dc=ru
    	sAMAccountName={0}
 
    	USE_USERNAME
    	12 hours
	
 

После авторизации NiFi регистрирует пользователей как sAMAccountName (в нашем случае был почтовый префикс, которым удобнее пользоваться — об этом расскажу чуть ниже) и передает в следующий конфигурационный файл, где настраивается ролевая область.

Важный момент 1. После включения LDAP пользователи будут вообще без каких-либо доступов. Чтобы можно было хоть как-то подключиться к NiFi, лучше сразу создать пользователя-администратора.

В качестве админа указана учетная запись ldap, которая регистрируется как sAMAccountName. Бывают также случаи настройки LDAP, когда пользователи регистрируются как «cn=myuser, ou=NiFi», uid=13567 или как полный bind_dn, содержащий все группы. Здесь поможет только включение TRACE всех настроек в logback.xml и мониторинг /opt/NiFi/logs/NiFi-app.log.

Важный момент 2. Registry принимает запросы от NiFi по сертификатам, и Owner для него является пользователем. Здесь мы сталкиваемся с двумя нюансами: либо генерировать удобный сертификат, чтобы cn=myuser, либо создавать user с неудобным именем. Мы идем по второму пути, так как хотим иметь валидный сертификат при работе с NiFi без красных замков в вебе.

Чтобы узнать, какого пользователя создавать, смотрим содержимое jks.

keytool --list -v -keystore $(hostname).jks

Получается, что нужен пользователь «CN=$(hostname), O=XXX.NUBES.RU». Он и будет из NiFi подключаться к NiFi Registry.

Важный момент 3. В NiFi-properties мы передаем параметр managed-authorizer. Он вызывает класс file-access-policy-provider, в котором обязательно описывается админ. Можно указать своего пользователя AD (Active Directory), чтобы потом легче было настраивать NiFi. 

Далее идет ссылка на composite-configurable-user-group-provider, который содержит локальных пользователей и пользователей ldap. Очень важно оставить локальных пользователей, чтобы NiFi мог общаться с Registry. При указании локального пользователя он будет создан автоматически (но без прав).

И пара слов о ролевой системе. Зачастую достаточно создать минимум две группы в AD (админские, обычные). В нашем случае обозначим их как _security и nubes-XXX. Во вторую группу входят все пользователи, которым можно подключаться. Для _security будем выдавать полные права. Разграничивать права между пользователями можно, и это исключительно ваше дело. 

/opt/nifi/conf/authorizers.xml



 
	
    	file-user-group-provider
    	org.apache.nifi.authorization.FileUserGroupProvider
    	./conf/users.xml
    	CN=$(hostname), O=XXX.NUBES.RU
	
 
	
    	ldap-user-group-provider
    	org.apache.nifi.ldap.tenants.LdapUserGroupProvider
    	SIMPLE
 
    	cn=svc_nifi,ou=Service Users,dc=XXX,dc=nubes,dc=ru
    	secretpass
 
    	
    	
    	
    	
    	
    	
    	
    	
    	
 
    	FOLLOW
    	10 secs
    	10 secs
 
    	ldaps://ADSERVER:636
    	
    	30 mins
 
    	false
    	ou=nubes-XXX,dc=XXX,dc=nubes,dc=ru
    	person
    	SUBTREE
    	
    	sAMAccountName
    	
    	
 
    	OU=nifi,OU=_security,OU=nubes-XXX,DC=XXX,DC=nubes,DC=ru
    	group
    	SUBTREE
    	
    	cn
    	member
    	
	
 
	
    	composite-configurable-user-group-provider
    	org.apache.nifi.authorization.CompositeConfigurableUserGroupProvider
    	file-user-group-provider
    	ldap-user-group-provider
	
 
	
    	file-access-policy-provider
    	org.apache.nifi.authorization.FileAccessPolicyProvider
    	composite-configurable-user-group-provider
    	./conf/authorizations.xml
    	myAdminUser
    	
    	CN=$(hostname), O=XXX.NUBES.RU
	
 
	
    	managed-authorizer
    	org.apache.nifi.authorization.StandardManagedAuthorizer
    	file-access-policy-provider
    	CN=$(hostname), O=XXX.NUBES.RU
	
 
	
    	single-user-authorizer
    	org.apache.nifi.authorization.single.user.SingleUserAuthorizer
	

Далее можно перекреститься и запустить NiFi.

systemctl daemon-reload
systemctl enable --now nifi

Переключаемся на конфигурационные файлы NiFi Registry

Процесс во многом похож на то, что мы делали на предыдущем этапе с NiFi. Но бездумно копировать все настройки не получится, так как файлы binary source и классы java отличаются.

/opt/nifi/conf/nifi-registry.properties

# Базовая настройка сервера
nifi.registry.web.https.host=$(hostname)
nifi.registry.web.https.port=8443
 
nifi.registry.security.keystore=./ssl/$(hostname).jks
nifi.registry.security.keystoreType=jks
nifi.registry.security.keystorePasswd=jksSecretKey
nifi.registry.security.keyPasswd=jksSecretKey
nifi.registry.security.truststore=./ssl/$(hostname).jks
nifi.registry.security.truststoreType=jks
nifi.registry.security.truststorePasswd=jksSecretKey
 
nifi.registry.security.needClientAuth=false
nifi.registry.security.authorizers.configuration.file=./conf/authorizers.xml
nifi.registry.security.authorizer=managed-authorizer
nifi.registry.security.identity.providers.configuration.file=./conf/identity-providers.xml
nifi.registry.security.identity.provider=ldap-identity-provider

Настройка блока авторизации тоже ничем особо не отличается.

/opt/nifi/conf/identity-providers.xml


 

	
    	ldap-identity-provider
    	org.apache.nifi.registry.security.ldap.LdapIdentityProvider
    	SIMPLE
 
    	cn=svc_nifi,ou=Service Users,dc=XXX,dc=nubes,dc=ru
    	secretpass
 
    	FOLLOW
    	10 secs
    	10 secs
 
    	ldaps://ADSERVER:636
    	ou=nubes-XXX,dc=XXX,dc=nubes,dc=ru
    	sAMAccountName={0}
 
    	USE_USERNAME
    	12 hours
	

Пользователь NiFi должен также быть зарегистрирован в NiFi Registry. Если серверов будет несколько (кластер), то их следует указывать через «Initial User Identity 2», «Initial User Identity 3» и т.д.

/opt/nifi/conf/authorizers.xml



 
	
    	file-user-group-provider
    	org.apache.nifi.registry.security.authorization.file.FileUserGroupProvider
    	./conf/users.xml
    	CN=$(hostname), O=XXX.NUBES.RU
	
 
	
    	ldap-user-group-provider
    	org.apache.nifi.registry.security.ldap.tenants.LdapUserGroupProvider
    	SIMPLE
 
    	cn=svc_nifi,ou=Service Users,dc=XXX,dc=nubes,dc=ru
    	secretpass
 
    	
    	
    	
    	
    	
    	
       
    	
    	
 
    	FOLLOW
    	10 secs
    	10 secs
 
    	ldaps://ADSERVER:636
    	
    	30 mins
 
    	false
    	ou=nubes-XXX,dc=XXX,dc=nubes,dc=ru
    	person
    	SUBTREE
    	
    	sAMAccountName
    	
    	
 
    	OU=nifi,OU=_security,OU=nubes-XXX,DC=XXX,DC=nubes,DC=ru
    	group
    	SUBTREE
    	
    	cn
    	member
    	
	
 
	
    	composite-user-group-provider
    	org.apache.nifi.registry.security.authorization.CompositeUserGroupProvider
    	file-user-group-provider
    	ldap-user-group-provider
	
 
 
	
    	file-access-policy-provider
    	org.apache.nifi.registry.security.authorization.file.FileAccessPolicyProvider
    	composite-user-group-provider
    	./conf/authorizations.xml
        myAdminUser
    	CN=$(hostname), O=XXX.NUBES.RU
	
 
	
    	managed-authorizer
    	org.apache.nifi.registry.security.authorization.StandardManagedAuthorizer
    	file-access-policy-provider
    	CN=$(hostname), O=XXX.NUBES.RU
	

На данном этапе ставим свечку и запускаем NiFi Registry.

systemctl daemon-reload
systemctl enable --now nifi

Связываем NiFi с NiFi Registry

Синхронизации между ними сразу не будет. Чтобы исправить проблему, для начала необходимо выдать локальному пользователю права на чтение workflow.

Такой политики среди готовых вариантов может не быть. Но ее всегда можно создать, причем довольно быстро. На оформление всех основных политик у нас ушло минут 10—15, в том числе с указанием нужных групп/пользователей. Для read/write есть отдельные вкладки в политиках. По умолчанию доступ дается исключительно пользователю-администратору.

eef0932af340bcf8452be97b8c5e3a5a.png90be5890a469c52d34dee7fa63e5dd34.png90be5890a469c52d34dee7fa63e5dd34.png

Далее настраиваем подключение в Registry. Для этого идем в меню настроек — Controller Settings — Registry clients — Add. Вводим любое имя. После добавления заходим в редактирование Properties и вводим URL.

e8b9965dc3fa6dc3f105f7199d8efc3d.png

Теперь переходим к Registry. Авторизовываемся, после чего проваливаемся в Settings — Users. В поиске набираем данные локального пользователя и выдаем ему следующие права (см. скрин ниже).

e3253367411d7d5082256db640705e46.png

Тестируем работоспособность 

В NiFi Registry создаeм простой бакет.

16b7522b998a3dc785792518121d740f.png

Затем идем в NiFi и создаем Process Group. Если меню будет заблокировано, добавляем новую политику и выдаем доступ для нужной группы пользователей.

c50194a691137c0c725723e0fa0612e8.png87844482a0c68faf4fbb78afaeec2685.png

Если бакет загрузился, открываем шампанское — настройка NiFi завершена! С инструментом можно работать. Остается только прочитать 100500 инструкций о том, как это делать.

1c8cd0cde54f6e4cfed9dbc07d616246.png

Ошибки, проблемы и их решения

Unable to obtain listing of buckets

Unable to obtain listing of buckets: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Ошибка возникает, когда вы добавляете NiFi Registry в Registry Clients или заходите в Start Version ControlВ jks, который используется в NiFi-Properties. Суть проблемы: у NiFi и NiFi Registry отсутствуют доверительные сертификаты друг друга. Добавлять их можно через команду:

keytool -importcert -file cert.crt -keystore $(hostname).jks -alias "cert"

Unable to view the user interface

Ошибку можно получить с логином ldap. Она указывает на то, что некорректно настроен LDAP или неверно указан пользователь-администратор.

При первичной настройке получилось так, что настройка LDAP была проведена корректно и пользователь-администратор указан верно, но ничего не работало. Причем изначально NiFi запускался без LDAP, хотя и недолго. Помогла полная переустановка.

No available buckets

Когда подключаемся к Start Version Control, не отображается созданный bucket.

Ошибка говорит о том, что мы некорректно настроили пользователя, который одновременно присутствует в NiFi и NiFi Registry. Отдебажить проблему получилось только после включения TRACE во всех параметрах в logback.xml и изучения множества логов при нажатии на Start Version Control. В конечном счете можно будет увидеть ошибку No user found for identity. Эту фразу можно вбить в поиск по всем записям, чтобы не читать тонны логов разом.

Локальный пользователь не удаляется в NiFi

С проблемой можно столнуться при изменении в конфигурационных файлах authorized.xml значений Initial User Identity. Чтобы устранить проблему, достаточно удалить пользователя из users.xml и перезапустить NiFi.

Надеюсь, гайд поможет вам быстро подружиться с NiFi и не споткнуться на исправлении ошибок. Расскажите, с какими проблемами при первичной настройке инструмента столкнулись вы? Как их решали? :)

© Habrahabr.ru