Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

### Added

- Support specifying the SecretClass that is used to obtain TLS certificates ([#662]).

### Changed

- Make it easy to test custom Nifi images ([#616])

[#616]: https://github.com/stackabletech/nifi-operator/pull/616
[#662]: https://github.com/stackabletech/nifi-operator/pull/662

## [24.3.0] - 2024-03-20

Expand Down
10 changes: 10 additions & 0 deletions deploy/helm/nifi-operator/crds/crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,16 @@ spec:
required:
- keySecret
type: object
tls:
default:
serverSecretClass: tls
description: TLS configuration options for the server.
properties:
serverSecretClass:
default: tls
description: This only affects client connections and is used to control which certificate the servers should use to authenticate themselves against the client.
type: string
type: object
vectorAggregatorConfigMapName:
description: Name of the Vector aggregator [discovery ConfigMap](https://docs.stackable.tech/home/nightly/concepts/service_discovery). It must contain the key `ADDRESS` with the address of the Vector aggregator. Follow the [logging tutorial](https://docs.stackable.tech/home/nightly/tutorials/logging-vector-aggregator) to learn how to configure log aggregation with Vector.
nullable: true
Expand Down
20 changes: 20 additions & 0 deletions docs/modules/nifi/pages/usage_guide/security.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
= Security

== TLS

NiFi sets up TLS encryption for the http endpoints that serve the UI.
By default, this interface is secured using certificates generated to work with the default SecretClass `tls`.

Nifi can be configured to use a different SecretClass as shown below:

[source, yaml]
----
apiVersion: nifi.stackable.tech/v1alpha1
kind: NifiCluster
spec:
# ...
clusterConfig:
tls:
serverSecretClass: non-default-secret-class # <1>
----

<1> The name of the `SecretClass` that will be used for certificates for the NiFi UI.

== Authentication

Every user has to authenticate themselves before using NiFI.
Expand Down
11 changes: 11 additions & 0 deletions rust/crd/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod affinity;
pub mod authentication;
pub mod tls;

use crate::authentication::NifiAuthenticationClassRef;

Expand Down Expand Up @@ -33,6 +34,7 @@ use stackable_operator::{
};
use std::collections::BTreeMap;
use strum::Display;
use tls::NifiTls;

pub const APP_NAME: &str = "nifi";

Expand Down Expand Up @@ -114,6 +116,10 @@ pub struct NifiClusterConfig {
// We don't add `#[serde(default)]` here, as we require authentication
pub authentication: Vec<NifiAuthenticationClassRef>,

/// TLS configuration options for the server.
#[serde(default)]
pub tls: NifiTls,

// no doc - docs in NifiSensitivePropertiesConfig struct.
pub sensitive_properties: NifiSensitivePropertiesConfig,

Expand Down Expand Up @@ -481,6 +487,11 @@ impl NifiCluster {
}
}

/// Return user provided server TLS settings
pub fn server_tls_secret_class(&self) -> &str {
&self.spec.cluster_config.tls.server_secret_class
}

/// List all pods expected to form the cluster
///
/// We try to predict the pods here rather than looking at the current cluster state in order to
Expand Down
26 changes: 26 additions & 0 deletions rust/crd/src/tls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use serde::{Deserialize, Serialize};
use stackable_operator::schemars::{self, JsonSchema};

#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct NifiTls {
/// This only affects client connections and is used to
/// control which certificate the servers should use to
/// authenticate themselves against the client.
#[serde(default = "NifiTls::default_server_secret_class")]
pub server_secret_class: String,
}

impl Default for NifiTls {
fn default() -> Self {
Self {
server_secret_class: Self::default_server_secret_class(),
}
}
}

impl NifiTls {
fn default_server_secret_class() -> String {
"tls".to_owned()
}
}
1 change: 1 addition & 0 deletions rust/operator-binary/src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,7 @@ async fn build_node_rolegroup_statefulset(
// One volume for the keystore and truststore data configmap
.add_volume(
build_tls_volume(
nifi,
KEYSTORE_VOLUME_NAME,
vec![
&nifi_cluster_name,
Expand Down
1 change: 1 addition & 0 deletions rust/operator-binary/src/reporting_task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ fn build_reporting_task_job(
.add_container(cb.build())
.add_volume(
build_tls_volume(
nifi,
REPORTING_TASK_CERT_VOLUME_NAME,
vec![],
SecretFormat::TlsPem,
Expand Down
3 changes: 2 additions & 1 deletion rust/operator-binary/src/security/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ pub async fn check_or_generate_sensitive_key(client: &Client, nifi: &NifiCluster
}

pub fn build_tls_volume(
nifi: &NifiCluster,
volume_name: &str,
service_scopes: Vec<&str>,
secret_format: SecretFormat,
) -> Result<Volume> {
tls::build_tls_volume(volume_name, service_scopes, secret_format).context(TlsSnafu)
tls::build_tls_volume(nifi, volume_name, service_scopes, secret_format).context(TlsSnafu)
}
6 changes: 4 additions & 2 deletions rust/operator-binary/src/security/tls.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use snafu::{ResultExt, Snafu};
use stackable_nifi_crd::NifiCluster;
use stackable_operator::{
builder::pod::volume::{SecretFormat, SecretOperatorVolumeSourceBuilder, VolumeBuilder},
k8s_openapi::api::core::v1::Volume,
Expand All @@ -21,12 +22,13 @@ pub enum Error {
}

pub(crate) fn build_tls_volume(
nifi: &NifiCluster,
volume_name: &str,
service_scopes: Vec<&str>,
secret_format: SecretFormat,
) -> Result<Volume> {
// TODO: Make adaptable (https://github.com/stackabletech/nifi-operator/issues/499)
let mut secret_volume_source_builder = SecretOperatorVolumeSourceBuilder::new("tls");
let mut secret_volume_source_builder =
SecretOperatorVolumeSourceBuilder::new(nifi.server_tls_secret_class());

if secret_format == SecretFormat::TlsPkcs12 {
secret_volume_source_builder.with_tls_pkcs12_password(STACKABLE_TLS_STORE_PASSWORD);
Expand Down