Kafka Streams - 内部主题的ACL

时间:2018-02-05 19:09:38

标签: apache-kafka apache-kafka-streams

我试图建立一个安全的Kafka群集,并且对ACL有点困难。

Kafka Streams的汇合安全指南(https://docs.confluent.io/current/streams/developer-guide/security.html)只是说明了必须为主体提供群集创建ACL ......但它没有说明如何实际处理内部主题。

通过研究和实验,我已经确定(对于Kafka版本1.0.0):

  1. 通配符不能与ACL中的主题名称的文本一起使用。例如,由于所有内部主题都以应用程序ID为前缀,我首先想到的是将acl应用于匹配&#;;< application.id> - *'的主题。这不起作用。
  2. Streams API创建的主题不会自动获得创建者的读/写访问权限。
  3. 内部主题的确切名称是否可预测且一致?换句话说,如果我在开发服务器上运行我的应用程序,运行时是否会在生产服务器上创建完全相同的主题?如果是这样,那么我可以在部署之前添加从dev派生的ACL。如果没有,应该如何添加ACL?

1 个答案:

答案 0 :(得分:4)

  

内部主题的确切名称是否可预测且一致?换句话说,如果我在开发服务器上运行我的应用程序,运行时是否会在生产服务器上创建完全相同的主题?

是的,您将从运行到运行中获得相同的主题名称。 DSL生成处理器名称with a function,如下所示:

public String newProcessorName(final String prefix) {
    return prefix + String.format("%010d", index.getAndIncrement());
}

(其中index只是一个递增的整数)。然后将这些处理器名称用于create repartition topics,其函数看起来像这样(参数name是如上生成的处理器名称):

static <K1, V1> String createReparitionedSource(final InternalStreamsBuilder builder,
                                                final Serde<K1> keySerde,
                                                final Serde<V1> valSerde,
                                                final String topicNamePrefix,
                                                final String name) {
    Serializer<K1> keySerializer = keySerde != null ? keySerde.serializer() : null;
    Serializer<V1> valSerializer = valSerde != null ? valSerde.serializer() : null;
    Deserializer<K1> keyDeserializer = keySerde != null ? keySerde.deserializer() : null;
    Deserializer<V1> valDeserializer = valSerde != null ? valSerde.deserializer() : null;
    String baseName = topicNamePrefix != null ? topicNamePrefix : name;

    String repartitionTopic = baseName + REPARTITION_TOPIC_SUFFIX;
    String sinkName = builder.newProcessorName(SINK_NAME);
    String filterName = builder.newProcessorName(FILTER_NAME);
    String sourceName = builder.newProcessorName(SOURCE_NAME);

    builder.internalTopologyBuilder.addInternalTopic(repartitionTopic);
    builder.internalTopologyBuilder.addProcessor(filterName, new KStreamFilter<>(new Predicate<K1, V1>() {
        @Override
        public boolean test(final K1 key, final V1 value) {
            return key != null;
        }
    }, false), name);

    builder.internalTopologyBuilder.addSink(sinkName, repartitionTopic, keySerializer, valSerializer,
        null, filterName);
    builder.internalTopologyBuilder.addSource(null, sourceName, new FailOnInvalidTimestamp(),
        keyDeserializer, valDeserializer, repartitionTopic);

    return sourceName;
}

如果你没有改变你的拓扑结构,如果不改变它的构建顺序等等 - 无论拓扑结构如何,你都会得到相同的结果构建(假设您使用的是相同版本的Kafka Streams)。

  

如果是这样,那么我可以在部署之前添加从dev派生的ACL。如果没有,应该如何添加ACL?

我没有使用过ACL,但我想因为这些只是常规主题,所以是的,你可以对它们应用ACL。 security guide确实提到了:

  

当应用程序针对安全的Kafka群集运行时,运行应用程序的主体必须具有ACL --cluster --operation Create set,以便应用程序具有创建内部主题的权限。

我自己一直在想这个问题,所以如果我错了,我猜猜来自Confluent的人会纠正我。