Настройка и запуск Apache NiFi и Zookeeper, настройка авторизации по LDAP и работа NiFi по HTTPS, настройка и запуск Apache NiFi Registry, пример запуска NiFi c Kerberos — вот темы, которые будут в этой статье.



Не вижу смысла полностью рассказывать, как настраивать NiFi и NiFi Registry — есть официальная документация и мануалы в сети. Я сосредоточился на ошибках, информации по которым нет, в том числе и на английском. При самостоятельном поиске решения, это реально масса времени. Я провел месяцы в режиме DEBUG и TRACE, чтобы понять, как всё сделать правильно. Готов поделится.

На всякий случай, NiFi (Niagara Files) – система для обработки потоковых данных. У нас она читает сообщения из Кафки и кладет в базу данных без написания кода.

В ходе работы мне пришлось настраивать и разворачивать кластер NiFi несколько раз, на разные виртуальные машины. Для этого у нас в компании уже было создано множество автоматизаций на Ansible, которые помогают в данный момент разворачивать и настраивать кластеры NiFi намного быстрее.

Настройка и запуск Apache NiFi


В Группе НЛМК настройка и запуск NiFi происходит с помощью Ansible Playbooks, которые на «голые» ВМ ставят софт, размечают диски, настраивают экспортеры, генерируют сертификаты, устанавливают zookepeer, а далее и сам NiFi.

Я расскажу, как аутентификация пользователей будет происходить с помощью LDAP, поэтому по умолчанию у вас должен быть сервер каталогов AD (не буду объяснять, как АD настраивать, у многих это уже есть).

Так же для запуска NiFi по HTTPS необходимо создать сертификаты. Для этого простого шага можете воспользоваться документацией здесь Securing NiFi with Provided Certificates. В нашей компании сертификатами занимаются отдельные люди, поэтому на этапе установки сертификаты у меня уже были. Тут не буду объяснять, как их сгенерить, лишь расскажу, как настроить identity mapping и установить связь между NiFi и NiFi Registry.

Разворачивать все сервисы мы будем с помощью docker. Для работы NiFi в режиме кластера необходимо подготовить и запустить zookeeper.

Настройка и запуск Zookeeper


NiFi в режиме кластера не запустится без zookeeper. Вот пример, как настроить и запустить zookeeper быстро.

<b>docker-compose.yaml</b> 
---
version: '3.5'

services:
  zookeeper:
    image: 'bitnami/zookeeper:3.7.0'
    hostname: nifi-test-node-1.mycompany
    restart: unless-stopped
    ports:
      - '2181:2181'
      - '2888:2888'
      - '3888:3888'
    env_file:
      - zookeeper.env
    volumes:
      - zookeeper_data:/bitnami

volumes:
  zookeeper_data:
    driver: local
...

Для образа bitnami/ zookeeper необходимо настроить параметры, список которых можно взять тут.

Для безопасности включим авторизацию, настроив список параметров. Ниже в комментариях я подписал значение каждой переменной.

<b>zookeeper.env</b>
# ID сервера зоокипера
ZOO_SERVER_ID=1

# Запрещаем присоединяться анонимно
ALLOW_ANONYMOUS_LOGIN=NO
# Включаем авторизацию
ZOO_ENABLE_AUTH=yes
# Указываем пользователей сервера
ZOO_SERVER_USERS=user1,user1
# Указываем пароли для пользователей сервера
ZOO_SERVER_PASSWORDS=password1,password2
# Пользователь который будет использоваться при авторизации других нод Zookeeper
ZOO_CLIENT_USER=user1
# Пароль от клиентского пользователя
ZOO_CLIENT_PASSWORD=password1
# Необходимо правильно указать другие ноды Zookeeper и ZOO_SERVER_ID для корректного коннекта между нодами
ZOO_SERVERS=nifi-test-node-1.mycompany:2888:3888::1,nifi-test-node-2.mycompany:2888:3888::2,nifi-test-node-3.mycompany:2888:3888::3
ZOO_ENABLE_PROMETHEUS_METRICS=YES

После того, как zookeeper запустится и все ноды войдут в режим кластера, в логах появятся сообщения об успешном коннекте каждой ноды. Если этого не произойдет, то NiFi будет выдавать ошибку о том, что он не может подключиться к Zookeeper.

Разберем ошибки, которые могут быть при запуске Zookeeper:

  • Ошибка Zookeeper "Cannot open channel to 2 at election address nifi-test-node-2.mycompany/ip:3888 java.net.ConnectException: Connection refused (Connection refused)" ошибка говорит о том, что либо нода zookeeper nifi-test-node-2.mycompany еще не поднята. Либо вторая нода считает себя другой 1 или 3, поэтому zookeeper не может войти в режим кластера. Для решения этой проблемы необходимо обратить внимание на параметры ZOO_SERVER_ID и ZOO_SERVERS, в ZOO_SERVERS необходимо чтобы был указан ID у ноды.
  • Если же вы используете другой zookeeper то необходимо обратить внимание на zoo.cfg а именно на server.1=nifi-test-node-1.mycompany:2888:3888 server.2=nifi-test-node-2.mycompany:2888:3888 и так далее. А также на значение файла /data/myid значение в файле должно соответствовать номеру ноды zookeeper.
  • Ошибка NiFi (возникает, если неправильно настроить Zookeeper) "WARN [main] o.a.nifi.controller.StandardFlowService There is currently no Cluster Coordinator. This often happens upon restart of NiFi when running an embedded ZooKeeper. Will register this node to become the active Cluster Coordinator and will attempt to connect to cluster again." Данная ошибка возникает в NiFi, когда он не может подключиться к указанному zookeeper, и пытается подключится к внутреннему, но у nifi отключен внутренний zookeeper (описание ошибки в системе на английском немного некорректное). Можно проверить внутри этого файла conf/nifi.properties nifi.state.management.embedded.zookeeper.start=false.

    Т. е. эта ошибка говорит о двух ситуациях: 1) когда nifi не может подключится к внутреннему zookeeper – это то, что и написано в описании ошибки на английском 2) но может быть и второй случай, о котором описание умалчивает: когда nifi не может подключится к внешнему zookeeper.

    Для решения второго случая необходимо проверить параметры в NiFi conf/nifi.properties: nifi.zookeeper.connect.string=nifi-test-node-1.mycompany:2181,nifi-test-node-1.mycompany:2181,nifi-test-node-1.mycompany:2181

Настройка и запуск Apache NiFi


После успешного запуска Zookeeper, перейдем к настройкам параметров самого кластера NiFi. В данном разделе я разберу ошибки, которые получим, если неправильно настроим кластер.
Разберем файлы конфигурации NiFi для работы по LDAP:

1) conf/nifi.properties

Вот блоки, которые необходимо настроить, чтобы NiFi запустился без ошибок.

<b>nifi.properties</b>
# ... - Можно оставлять стандартные настройки без изменений

# Site to Site properties
# ...
# Значение данного параметра ставим на True
nifi.remote.input.secure=True

# web properties #
# При запуске по https необходимо пропустить параметры nifi.web.http.host и nifi.web.http.port и оставить их пустыми
nifi.web.http.host=
nifi.web.http.port=
nifi.web.http.network.interface.default=
# При запуске по https необходимо заполнить параметры nifi.web.https.host и nifi.web.https.port
nifi.web.https.host=nifi-test-node-1.mycompany
nifi.web.https.port=9091
nifi.web.https.network.interface.default=

#...
# Если у вас есть балансировщик на ноды NiFi необходимо здесь указать web proxy host
nifi.web.proxy.host=my-test-nifi-proxy.com
#...

# security properties #
# До NiFi 1.14 значение этого параметра можно было оставлять пустым и ваш flow файл конфигурации бы не шифровался, и NiFi работал бы в нормальном режиме
# C версией NiFi выше 1.14 необходимо указать данный ключ иначе NiFi выдаст ошибку.
nifi.sensitive.props.key=<ваше_значение_ключа>
#...

# Так же необходимо настроить пути до сертификатов и их пароли для запуска NiFi в secure режиме
nifi.security.keystore=/etc/ssl/keystore.jks
nifi.security.keystoreType=JKS
nifi.security.keystorePasswd=<пароль>
nifi.security.keyPasswd=<пароль>
nifi.security.truststore=/etc/ssl/truststore.jks
nifi.security.truststoreType=JKS
nifi.security.truststorePasswd=<пароль>
nifi.security.user.authorizer=managed-authorizer
nifi.security.allow.anonymous.authentication=false
# Обратите значение на этот параметр
nifi.security.user.login.identity.provider=ldap-provider

#...
# Identity Mapping Properties #
# Данные параметры необходимы для более быстрой нормализации идентификаторов пользователей
# Данная настройка зависит только от вашей организации. Подробная докуемнтация тут https://docs.cloudera.com/HDPDocuments/HDF3/HDF-3.2.0/nifi-system-properties/content/identity-mapping-properties.html
nifi.security.identity.mapping.pattern.dn=^L=(.*?), ST=(.*?), C=(.*?), OU=(.*?), O=(.*?),.*?$
nifi.security.identity.mapping.value.dn=$4@$5
nifi.security.identity.mapping.transform.dn=LOWER

# cluster node properties (only configure for cluster nodes) #
# Для запуска NiFi в режиме кластера необходимо указать значение True в nifi.cluster.is.node и настроить дополнительные параметры по вашим приоритетам
# иначе нода NiFi не будет прицепляться к кластеру
nifi.cluster.is.node=True
nifi.cluster.node.address=nifi-test-node-1.mycompany
nifi.cluster.node.protocol.port=9088
nifi.cluster.node.protocol.threads=10
nifi.cluster.node.protocol.max.threads=50
nifi.cluster.node.event.history.size=25
nifi.cluster.node.connection.timeout=5 sec
nifi.cluster.node.read.timeout=5 sec
nifi.cluster.node.max.concurrent.requests=100
nifi.cluster.firewall.file=
nifi.cluster.flow.election.max.wait.time=5 mins
nifi.cluster.flow.election.max.candidates=

# zookeeper properties, used for cluster management #
# При запуске на внешнем zookeeper,настройку которого мы обсуждали ранее необходимо заполнить параметры nifi.zookeeper.*
nifi.zookeeper.connect.string=nifi-test-node-1.mycompany:2181,nifi-test-node-2.mycompany:2181,nifi-test-node-3.mycompany:2181
nifi.zookeeper.connect.timeout=10 secs
nifi.zookeeper.session.timeout=10 secs
nifi.zookeeper.root.node=/nifi

  1. При запуске по https необходимо пропустить параметры nifi.web.http.host и nifi.web.http.port и оставить их пустыми.
  2. При запуске по https необходимо заполнить параметры nifi.web.https.host и nifi.web.https.port.
  3. Если параметры, указанные выше, останутся заполненными, то NiFi выдаст ошибку "IllegalStateException: Only one of the HTTP and HTTPS connectors can be configured at one time".
  4. До NiFi 1.14 значение этого nifi.sensitive.props.key=<ваше_значение_ключа> параметра можно было оставлять пустым и ваш flow файл конфигурации бы не шифровался, и NiFi работал бы в нормальном режиме.

    C версией NiFi выше 1.14 необходимо указать данный ключ иначе NiFi выдаст ошибку "IllegalArgumentException: There was an issue decrypting protected properties"
  5. Параметры nifi.security.identity.mapping.* зависят от вашей компании, но их необходимо заполнить для корректной аутентификации пользователей и самих нод найфая друг с другом. Документация.
  6. Для запуска NiFi в режиме кластера необходимо указать значение True в nifi.cluster.is.node и настроить дополнительные параметры nifi.cluster.node.* по вашим приоритетам иначе нода NiFi не будет прицепляться к кластеру.
  7. При запуске на внешнем zookeeper, настройку которого мы обсуждали ранее, необходимо заполнить параметры nifi.zookeeper.*

2) conf/authorizers.xml

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

Документация

<b>authorizers.xml</b>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<authorizers>
    <userGroupProvider>
        <identifier>file-user-group-provider</identifier>
        <class>org.apache.nifi.authorization.FileUserGroupProvider</class>
        <property name="Users File">./conf/users.xml</property>
        <property name="Legacy Authorized Users File"></property>
        <property name="Initial User Identity 1">nifi_habr@test</property>
        <property name="Initial User Identity 2">nifiadmin</property>
    </userGroupProvider>

    <userGroupProvider>
        <identifier>ldap-user-group-provider</identifier>
        <class>org.apache.nifi.ldap.tenants.LdapUserGroupProvider</class>
        <property name="Authentication Strategy">SIMPLE</property>

        <property name="Manager DN">cn=nifiadmin,ou=nifi-habr,ou=nifi,ou=test,ou=example,dc=com,dc=mycompany</property>
        <property name="Manager Password">pass</property>

         <!--
        TLS параметры если необходимо
        -->

        <property name="Referral Strategy">FOLLOW</property>
        <property name="Connect Timeout">10 secs</property>
        <property name="Read Timeout">10 secs</property>

        <property name="Url">ldaps://mycompany.com:10109</property>
        <property name="Page Size"></property>
        <property name="Sync Interval">5 mins</property>
        <property name="Group Membership - Enforce Case Sensitivity">false</property>

        <property name="User Search Base">DC=com,DC=mycompany</property>
        <property name="User Object Class">user</property>
        <property name="User Search Scope">SUBTREE</property>
        <property name="User Search Filter">filter_users</property>
        <property name="User Identity Attribute">SamAccountName</property>
        <property name="User Group Name Attribute"></property>
        <property name="User Group Name Attribute - Referenced Group Attribute"></property>

        <property name="Group Search Base">OU=nifi-habr,OU=nifi,OU=test,OU=example,DC=com,DC=mycompany</property>
        <property name="Group Object Class">group</property>
        <property name="Group Search Scope">SUBTREE</property>
        <property name="Group Search Filter">filter_groups</property>
        <property name="Group Name Attribute">cn</property>
        <property name="Group Member Attribute">member</property>
        <property name="Group Member Attribute - Referenced User Attribute"></property>
    </userGroupProvider>


    <userGroupProvider>
        <identifier>composite-configurable-user-group-provider</identifier>
        <class>org.apache.nifi.authorization.CompositeConfigurableUserGroupProvider</class>
        <property name="Configurable User Group Provider">file-user-group-provider</property>
        <property name="User Group Provider 1">ldap-user-group-provider</property>
    </userGroupProvider>

    <accessPolicyProvider>
        <identifier>file-access-policy-provider</identifier>
        <class>org.apache.nifi.authorization.FileAccessPolicyProvider</class>
        <property name="User Group Provider">composite-configurable-user-group-provider</property>
        <property name="Authorizations File">./conf/authorizations.xml</property>
        <property name="Initial Admin Identity">nifiadmin</property>
        <property name="Legacy Authorized Users File"></property>
        <property name="Node Identity 1">nifi_habr@test</property>
        <property name="Node Group"></property>
        <property name="Legacy Authorized Users File"></property>
    </accessPolicyProvider>

    <authorizer>
        <identifier>managed-authorizer</identifier>
        <class>org.apache.nifi.authorization.StandardManagedAuthorizer</class>
        <property name="Access Policy Provider">file-access-policy-provider</property>
        <property name="Initial Admin Identity">nifiadmin</property>
        <property name="Legacy Authorized Users File"></property>
        <property name="Node Identity 1">nifi_habr@test</property>
    </authorizer>
</authorizers>

3) conf/login-identity-providers.xml

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

<b>login-identity-providers.xml</b>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<loginIdentityProviders>
    <provider>
        <identifier>ldap-provider</identifier>
        <class>org.apache.nifi.ldap.LdapProvider</class>
        <property name="Authentication Strategy">SIMPLE</property>

        <property name="Manager DN">cn=nifiadmin,ou=nifi-habr,ou=nifi,ou=test,ou=example,dc=com,dc=mycompany</property>
        <property name="Manager Password">pass</property>

        <!--
        TLS параметры если необходимо
        -->

        <property name="Referral Strategy">FOLLOW</property>
        <property name="Connect Timeout">10 secs</property>
        <property name="Read Timeout">10 secs</property>

        <property name="Url">ldaps://mycompany.com:10109</property>
        <property name="User Search Base">DC=com,DC=mycompany</property>
        <property name="User Search Filter">(sAMAccountName={0})</property>

        <property name="Identity Strategy">USE_USERNAME</property>
        <property name="Authentication Expiration">12 hours</property>
    </provider>
</loginIdentityProviders>

При авторизации пользователя, NiFi будет обращаться к DC=com,DC=mycompany идентифицировать пользователя по его имени USE_USERNAME и хранить авторизацию данное время 12 hours. Но если данного пользователя не будет в authorizers.xml filter_users, то, скорее всего, у него не будет доступа даже к UI.

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

Настройка и запуск Apache NiFi Registry


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

Особое внимание следует обратить на параметры в nifi-registry.properties при связи NiFi и NiFi Registry. Именно в эти параметры влияют на их связь.

<b>nifi-registry.properties</b>
#...
# Identity Mapping Properties #
# Данные параметры необходимы для более быстрой нормализации идентификаторов пользователей
# Данная настройка зависит только от вашей организации. Подробная документация тут https://docs.cloudera.com/HDPDocuments/HDF3/HDF-3.2.0/nifi-system-properties/content/identity-mapping-properties.html
nifi.registry.security.identity.mapping.pattern.dn=^L=(.*?), ST=(.*?), C=(.*?), OU=(.*?), O=(.*?),.*?$
nifi.registry.security.identity.mapping.value.dn=$4@$5
nifi.registry.security.identity.mapping.transform.dn=LOWER
L=NLMK-IT, ST=Moscow, C=RU, OU=nifi, O=prod, EMAILADDRESS=sre-team@nlmk.com, CN=000_0

Запустим NiFi и NiFi registry.

Добавляем наш NiFi Registry в список доступных Settings → Controller Settings → Registry Clients.

Если при попытке сохранить изменения в NiFi Registry мы получаем ошибку: 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. При этом в пользовательском интерфейсе из доступных бакетов у вас будет «No Available Buckets». Чтобы убрать ошибку, здесь необходимо добавить truststore NiFi Registry в truststore NiFi и truststore NiFi в truststore NiFi Registry для запросов между кластерами (добавить доверительные сертификаты друг в друга).

Можете воспользоваться документацией. После этого данная ошибка у вас пропадет.

«No Available Buckets» самая распространенная ошибка, на которую нет нормального объяснения.
Попробую объяснить на пальцах, почему так происходит.

В официальной документации указано, что необходимо создать пользователя с правами Proxy User Request, но нет примера как этого пользователя создавать.

Рассмотрим сертификат NiFi, после его создания, владелец выглядит так:

L=mycompany, ST=Moscow, C=RU, OU=nifi_habr, O=test, EMAILADDRESS=nifihabr@mycompany.com, CN=nifi-test-node-1.mycompany
Подгоним данное значение под паттерн маппинга из файла nifi-registry.properties: 
^L=(.*?), ST=(.*?), C=(.*?), OU=(.*?), O=(.*?),.*?$
$4@$5

В итоге, когда наш кластер NiFi будет ходить в NiFi Registry, NiFi Registry, будет его аутентифицировать по значению nifi_habr@test, поэтому нам необходимо создать этого пользователя в NiFi Registry, выдать ему права Proxy User Request. Так же данный маппинг вы можете настроить по своему усмотрению, ведь теперь вы знаете, что это значит.

Настройка и запуск NiFi c протоколом взаимодействия Kerberos


Перед тем как настроить запуск NiFi c Kerberos необходимо запустить кластер zookeeper с Kerberos.

Допустим мы уже имеем созданные кейтабы для zookeeper и nifi такого вида.

<b>zookeeper_server.keytab</b>
Keytab name: FILE:/etc/security/keytabs/zookeeper_server.keytab
KVNO Timestamp           Principal
---- ------------------- ------------------------------------------------------
   1 11.11.2021 15:45:18 zookeeper/nifi-test-node-1.mycompany@mycompany.com (aes256-cts-hmac-sha1-96)
   1 11.11.2021 16:13:04 zookeeper/nifi-test-node-1.mycompany@mycompany.com (aes128-cts-hmac-sha1-96)
<b>nifi_server.keytab</b>
Keytab name: FILE:/etc/security/keytabs/nifi_server.keytab
KVNO Timestamp           Principal
---- ------------------- ------------------------------------------------------
   1 11.11.2021 16:52:43 nifi/nifi-test-node-1.mycompany@mycompany.com (aes256-cts-hmac-sha1-96)
   1 11.11.2021 16:52:43 nifi/nifi-test-node-1.mycompany@mycompany.com (aes128-cts-hmac-sha1-96)

Здесь я хочу заметить что тип шифрования должен совпадать с параметрами указанными в файле krb5.conf (у нас настроено так):

default_tgs_enctypes = aes256-cts aes128-cts rc4-hmac
default_tkt_enctypes = aes256-cts aes128-cts rc4-hmac
permitted_enctypes = aes256-cts aes128-cts rc4-hmac

Иначе соединения по протоколу Kerberos не произойдет.

В этом тоже есть некоторые сложности, выложу пример docker-compose файлов.

Разберем настройку Zookeeper.

<b>docker-compose.yaml</b>
---
version: '3.7'

services:
  zookeeper:
    image: zookeeper
    restart: always
    hostname: nifi-test-node-1.mycompany
    ports:
      - 2181:2181
      - 2888:2888
      - 3888:3888
    networks:
      - zk
    environment:
      JVMFLAGS: "-Djava.net.preferIPv4Stack=true -Djava.security.auth.login.config=/conf/jaas.conf -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.rmi.port=9010 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djute.maxbuffer=4194304 -Dsun.security.krb5.disableReferrals=true -Djdk.tls.ephemeralDHKeySize=2048 -Dzookeeper.multiAddress.enabled=true"
    volumes:
      - zk_data:/data
      - zk_datalog:/datalog
      - zk_logs:/logs
      - /etc/security/keytabs/zookeeper_server.keytab:/zookeeper.keytab:ro
      - /etc/krb5.conf:/etc/krb5.conf:ro
      - ./jaas.conf:/conf/jaas.conf:ro
      - ./zoo.cfg:/conf/zoo.cfg:ro

volumes:
  zk_data: {}
  zk_datalog: {}
  zk_logs: {}
networks:
  zk:
    name: zk
...

В данной настройке необходимо установить флаги JVM и прокинуть дополнительные конфигурационные файлы, связанные с Kerberos.

Можете взять файлы настройки в качестве примера, значения их можете посмотреть в документации.

<b>jaas.conf</b>
Server {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  keyTab="/zookeeper.keytab"
  storeKey=true
  useTicketCache=false
  principal="zookeeper/nifi-test-node-1.mycompany@mycompany.com";
};

 QuorumServer {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  keyTab="/zookeeper.keytab"
  storeKey=true
  useTicketCache=false
  principal="zookeeper/nifi-test-node-1.mycompany@mycompany.com";
};

 QuorumLearner {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  keyTab="/zookeeper.keytab"
  storeKey=true
  useTicketCache=false
  principal="zookeeper/nifi-test-node-1.mycompany@mycompany.com";
};
<b>zoo.cfg</b>
jaasLoginRenew=3600000
requireClientAuthScheme=sasl
tickTime=2000
initLimit=300
syncLimit=10
4lw.commands.whitelist=conf,cons,crst,dirs,dump,envi,gtmk,ruok,stmk,srst,srvr,stat,wchs,mntr,isro
dataDir=/data/
dataLogDir=/datalog/
clientPort=2181
maxClientCnxns=2000
minSessionTimeout=4000
maxSessionTimeout=60000000
autopurge.purgeInterval=1
autopurge.snapRetainCount=10
quorum.auth.enableSasl=true
quorum.cnxn.threads.size=20
admin.enableServer=false
admin.serverPort=5181
leaderServes=yes
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
kerberos.removeHostFromPrincipal=true
kerberos.removeRealmFromPrincipal=true
quorum.auth.kerberos.servicePrincipal=zookeeper/_HOST
quorum.auth.learnerRequireSasl=true
quorum.auth.serverRequireSasl=true
preAllocSize=131072
snapCount=3000000
server.1=nifi-test-node-1.mycompany:2888:3888
server.2=nifi-test-node-2.mycompany:2888:3888
server.3=nifi-test-node-3.mycompany:2888:3888

Так же для вашей компании необходимо сконфигурировать krb5.conf файл, можно воспользоваться документацией. После этого можно запустить кластер Zookeeper дождаться соединения всех нод и идти настраивать NiFi.

Настройка и запуск Apache NiFi c Kerberos


Здесь я хочу сделать акцент на изменения, которые вам необходимо сделать. Авторизацию пользователя мы оставим через LDAP, но если вы хотите сделать через Kerberos  можете воспользоваться документацией

Пример конфигурации можете взять из настройки NiFi выше.

В настройке появляется файл клиента zookeeper-jaas.conf

<b>zookeeper-jaas.conf</b>
Client {
	com.sun.security.auth.module.Krb5LoginModule required debug=true
	useKeyTab=true
	storeKey=true
	doNotPrompt=true
	useTicketCache=false
	keyTab="/etc/security/keytabs/nifi.keytab"
	principal="nifi/nifi-test-node-1.mycompany@mycompany.com";
};

Данный файл прокидывается в аргументы запуска Java в файле bootstrap.conf

<b>bootstrap.conf</b>
# ...
java.arg.18=-Djava.security.auth.login.config=./conf/zookeeper-jaas.conf
# ...
В настройках nifi.properties необходимо указать параметры 
<b>nifi.properties</b>
# ...
nifi.zookeeper.auth.type=sasl
nifi.zookeeper.kerberos.removeHostFromPrincipal=true
nifi.zookeeper.kerberos.removeRealmFromPrincipal=true

# kerberos #
nifi.kerberos.krb5.file=/etc/krb5.conf

# kerberos service principal #
nifi.kerberos.service.principal=nifi/nifi-test-node-1.mycompany@AO.NLMK
nifi.kerberos.service.keytab.location=/etc/security/keytabs/nifi.keytab

# ...

Если не указать параметр nifi.kerberos.service.principal или указать его не корректно, NiFi не будет запускаться и будет выдавать данную ошибку java.lang.IllegalArgumentException: No Kerberos Principal configured for use with SASL Authentication Scheme.

Надеюсь, когда люди будут гуглить Exception в NiFi, они будут сразу попадать на эту статью, и это реально облегчит им жизнь.

Комментарии (8)


  1. borisdenis
    07.06.2022 10:19

    Почему решить? Ошибки исправляют, решают задачи.


    1. Istra_ok
      07.06.2022 11:15
      +2

      Как уст румяных без улыбки,

      Без грамматической ошибки

      Я русской речи не люблю..., писал Пушкин)


    1. nickmatyukov Автор
      07.06.2022 11:18
      +5

      Коллега, а к статье (кроме заголовка) у вас есть какие-то комментарии? Да, в Apache NiFi, я действительно сильней, чем в русском.

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

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


      1. borisdenis
        07.06.2022 12:43
        +1

        По тексту вообще мне всё нравится. Поясню почему придрался к слову "Решить", если не прав - минусы никто не отменял)))

        Сейчас наблюдаю тотальную безграмотность. Если заглянуть на тостер - везде "как решить ошибку" и в последнее время это очень режет глаз (про ться/тся вообще молчу), но решают проблемы или вопросы, ошибки исправляют. В вашем случае возможно более корректно было сформулировать "Как найти ошибку...", но это только моё мнение, ничем не хотел кого либо обидеть/унизить или оскорбить.


        1. nickmatyukov Автор
          07.06.2022 15:05
          +1

          Cпасибо за подробное объяснение, буду следить и решать только задачи))


  1. strangeman
    07.06.2022 13:45
    +1

    Пару недель назад аналогичные шишки собирали, и с LDAP, и с Registry. Где ж вы раньше с вашей статьёй были... :)

    С HTTPS еще огребли историю с куками, у нас везде по умолчанию стоит `proxy_cookie_flags ~ httponly secure samesite=lax;` на Nginx, а NiFi такие параметры не подошли, в итоге вместо внятной ошибки NiFi просто 403 отдавал с довольно невнятной руганью


    1. nickmatyukov Автор
      07.06.2022 15:12
      +1

      Да, жаль самому, что долго "выкладывался". Но, поверьте, там еще есть, что "поковырять" и я еще пару статей готовлю: "Автоматическая доставка и управление сертификатами, драйверами, процессорами NiFi", "NiFi Cluster Coordinator в рамках Nifi as a Service для проектов". Можем обмениваться опытом, раз вы тоже по этим граблям прошлись)


  1. KlimenkoIv
    10.06.2022 00:48

    Отличная статья, коллега.

    Небольшое замечание (м.б. вы специально так сделали).

    В настройках провайдера указано

      <property name="Manager DN">cn=nifiadmin,ou=nifi-habr,ou=nifi,ou=test,ou=example,dc=com,dc=mycompany</property>
      <property name="Manager Password">pass</property>

    Насколько я понимаю, Manager DN - учетная запись, под которой NIFI идет в LDAP, запрашивает данные о пользователях. У вас эта же учётка является админом, выполняющим начальную настройку.
    У себя сделал так - создал учётку для NIFI, админы запретили все все что можно, кроме авторизации и запроса даных из каталога LDAP. А initial admin указал себя)