This readme defines the Command and control configuration options that work with Apache NiFi. All options defined are located in minifi.properties.
Apache NiFi MiNiFi C++ can communicates with a C2 Server via a number of protocols. These protocols deliver a C2 response the server, expecting requests in a heartbeat response. The protocol transforms the C2 messages into a protocol specific representation. The internal representation is an AST therefore you must define the root classes, which configure the classes that branch from the root. You can define arbitrary nodes and sub-trees, but this isn't necessary and only advantageous for custom C2 servers. That will be explained in greater detail in the metrics section.
For more more insight into the API used within the C2 agent, please visit: https://cwiki.apache.org/confluence/display/MINIFI/C2+Design+Proposal
Release 0.6.0: Please note that all c2 properties now exist as nifi.c2.* . If your configuration properties files contain the former naming convention of c2.*, we will continue to support that as an alternate key, but you are encouraged to switch your configuration options as soon as possible.
in minifi.properties # Disable/Enable C2 nifi.c2.enable=true # specify classes for the AST response nifi.c2.root.classes=DeviceInfoNode,AgentInformation,FlowInformation # specify C2 protocol -- default is CoapProtocol if not specified nifi.c2.agent.protocol.class=CoapProtocol # may also use MQTT or REST # nifi.c2.agent.protocol.class=MQTTC2Protocol # nifi.c2.agent.protocol.class=RESTSender # control c2 heartbeat interval in millisecocnds nifi.c2.agent.heartbeat.period=250 # enable reporter classes nifi.c2.agent.heartbeat.reporter.class=RESTReciver # specify the rest URIs if using RESTSender nifi.c2.rest.url=http://localhost:10080/minifi-c2-api/c2-protocol/heartbeat nifi.c2.rest.url.ack=http://localhost:10080/minifi-c2-api/c2-protocol/acknowledge nifi.c2.flow.base.url=http://localhost:10080/minifi-c2-api/c2-protocol/ # c2 agent identifier nifi.c2.agent.identifier=<your identifier> # c2 agent class -- must be defined to run agent nifi.c2.agent.class=<your agent class> # configure SSL Context service for REST Protocol nifi.c2.rest.ssl.context.service
Command and Control metrics can be used to send metrics through the heartbeat or via the DESCRIBE operation. Since responses are formed in an AST, metrics can be formed as a sub tree. Metrics classes are defined apriori and may reference a metrics class specific to a processor. The following example describes a configuration of an agent
# in minifi.properties nifi.c2.root.class.definitions=metrics nifi.c2.root.class.definitions.metrics.name=metrics nifi.c2.root.class.definitions.metrics.metrics=typedmetrics,processorMetrics nifi.c2.root.class.definitions.metrics.metrics.typedmetrics.name=RuntimeMetrics nifi.c2.root.class.definitions.metrics.metrics.typedmetrics.classes=ProcessMetrics,SystemInformation nifi.c2.root.class.definitions.metrics.metrics.processorMetrics.name=ProcessorMetrics nifi.c2.root.class.definitions.metrics.metrics.processorMetrics.classes=GetFileMetrics
This example shows a metrics sub tree defined by the option ‘nifi.c2.root.class.definitions’.
This is a comma separated list of all sub trees. In the example, above, only one sub tree exists: metrics.
The options below metrics define the sub-trees within metrics: typedmetrics and processorMetrics. Each of these has a name. The classes sub option will define the metrics classes that are placed within this sub-tree. For the RESTProtocol, the above configuration produces the following JSON:
"metrics": { "ProcessorMetrics": { "GetFileMetrics": { "AcceptedFiles": 22, "InputBytes": 61755, "OnTriggerInvocations": 1 } }, "RuntimeMetrics": { "ProcessMetrics": { "CpuMetrics": { "involcs": 1 }, "MemoryMetrics": { "maxrss": 145804 } }, "systeminfo": { "systemInfo": { "machinearch": "x86_64", "physicalMem": 67361411072, "vCores": 12 }, "identifier": "identifier" } } }
The default protocol is a RESTFul service; however, there is an MQTT protocol with a translation to use the RESTFul C2 server and a CoAP Protocol implementation. The CoAP protocol requires that COAP be enabled either through the bootstrap or the cmake flag -DENABLE_COAP=ON .
Once configured, COAP uses a controller service within the flow OR minifi properties entries: nifi.c2.agent.coap.host and nifi.c2.agent.coap.port. Note that with CoAP, the payload will be significantly smaller, paring down metrics that are sent in each heartbeat. This will be useful for constrained environments.
nifi.c2.agent.coap.host=hostname nifi.c2.agent.coap.port=<port number>
If you wish to use the Controller service you made add a controller service named CoapConnectorService with the properties in the example config below. Note that Max Queue Size is the only non-required property:
Controller Services: - id: 94491a38-015a-1000-0000-000000000001 name: coapservice class: CoapConnectorService Properties: Remote Server: server Remote Port: port Max Queue Size: 1000
As defined, above, MQTTC2Protocol can be used for the agent protocol class. If you wish to communicate with a RESTFul C2 server, you may use the ConvertBase, ConvertHeartBeat, ConvertJSONAack, and ConvertUpdate classes on an agent to perform the translation. State is not kept with an intermediate agent other than the broker. The broker is not embedded with the agent to simplify the agent.
An example configuration, below, defines an agent that receives and forward MQTT C2 requests to a C2 server. Additionally, this agent will forward responses and updates to the heartbeating agents.
MiNiFi Config Version: 3 Flow Controller: name: GetFile Core Properties: flow controller graceful shutdown period: 10 sec flow service write delay interval: 500 ms administrative yield duration: 30 sec bored yield duration: 10 millis max concurrent threads: 1 variable registry properties: '' FlowFile Repository: partitions: 256 checkpoint interval: 2 mins always sync: false Swap: threshold: 20000 in period: 5 sec in threads: 1 out period: 5 sec out threads: 4 Content Repository: content claim max appendable size: 10 MB content claim max flow files: 100 always sync: false Provenance Repository: provenance rollover time: 1 min Component Status Repository: buffer size: 1440 snapshot frequency: 1 min Security Properties: keystore: '' keystore type: '' keystore password: '' key password: '' truststore: '' truststore type: '' truststore password: '' ssl protocol: '' Sensitive Props: key: algorithm: PBEWITHMD5AND256BITAES-CBC-OPENSSL provider: BC Processors: - id: 24493a28-015a-1000-0000-000000000000 name: convert class: org.apache.nifi.processors.standard.ConvertHeartBeat max concurrent tasks: 1 scheduling strategy: TIMER_DRIVEN scheduling period: 10 msec penalization period: 30 sec yield period: 2 sec run duration nanos: 10 msec auto-terminated relationships list: Properties: MQTT Controller Service: mqttservice Listening Topic: heartbeats - id: 24493a28-015a-1000-0000-000000000006 name: convertJSON class: org.apache.nifi.processors.standard.ConvertJSONAck max concurrent tasks: 1 scheduling strategy: TIMER_DRIVEN scheduling period: 10 msec penalization period: 30 sec yield period: 1 sec run duration nanos: 10 msec auto-terminated relationships list: - success Properties: MQTT Controller Service: mqttservice - id: 24493a28-015a-1000-0000-000000000007 name: convertupdate class: org.apache.nifi.processors.standard.ConvertUpdate max concurrent tasks: 1 scheduling strategy: TIMER_DRIVEN scheduling period: 10 msec penalization period: 30 sec yield period: 1 sec run duration nanos: 10 msec auto-terminated relationships list: - success Properties: MQTT Controller Service: mqttservice Listening Topic: updates - id: 24493a28-015a-1000-0000-000000000021 name: httpheartbeat class: org.apache.nifi.processors.standard.InvokeHTTP max concurrent tasks: 1 scheduling strategy: TIMER_DRIVEN scheduling period: 10 msec penalization period: 30 sec yield period: 1 sec run duration nanos: 10 msec auto-terminated relationships list: Properties: HTTP Method: POST Remote URL: http://localhost:10080/minifi-c2-api/c2-protocol/heartbeat Content-type: application/json - id: 24493a28-015a-1000-0000-000000000022 name: log class: org.apache.nifi.processors.standard.LogAttribute max concurrent tasks: 1 scheduling strategy: TIMER_DRIVEN scheduling period: 100 msec penalization period: 30 sec yield period: 1 sec run duration nanos: 1 msec auto-terminated relationships list: - success Properties: Controller Services: - id: 94491a38-015a-1000-0000-000000000001 name: mqttservice class: MQTTContextService Properties: Broker URI: localhost:1883 Client ID: hiblajl Quality of Service: 2 Process Groups: [] Input Ports: [] Output Ports: [] Funnels: [] Connections: - id: 1d09c015-015d-1000-0000-000000000000 name: convert/success/httpheartbeat source id: 24493a28-015a-1000-0000-000000000000 source relationship name: success destination id: 24493a28-015a-1000-0000-000000000021 max work queue size: 10000 max work queue data size: 1 GB flowfile expiration: 0 sec queue prioritizer class: org.apache.nifi.prioritizer.FirstInFirstOutPrioritizer - id: 1d09c015-015d-1000-0000-000000000002 name: httpheartbeat/success/convertJSON source id: 24493a28-015a-1000-0000-000000000021 source relationship name: success destination id: 24493a28-015a-1000-0000-000000000006 max work queue size: 10000 max work queue data size: 1 GB flowfile expiration: 0 sec queue prioritizer class: org.apache.nifi.prioritizer.FirstInFirstOutPrioritizer Remote Process Groups: [] NiFi Properties Overrides: {}
Updates to MiNiFi C++ properties can be controlled through an UpdatePolicyControllerService named C2UpdatePolicy. The service supports several configuration options. They are defined in the following example:
Controller Services: - id: 94491a38-015a-1000-0000-000000000001 name: C2UpdatePolicy class: UpdatePolicyControllerService Properties: # true enables all properties to be updated. Allow All Properties: true # allowed properties are those which can be updated Allowed Properties: Property_1:true Property_2:true Disallowed Properties: Property_3:true Property_4:true
C2 Triggers can be activated to perform some C2 activity via a local event. Currently only FileUpdateTrigger exists, which monitors for C2 File triggers to update the flow configuration. Classes can be defined as a comma separated list of classes to load via the option nifi.c2.agent.trigger.classes
C2 updates can be triggered with updates to a flow configuration file. It doesn't have to be the same base configuration file. It will be copied into place. A new property, nifi.c2.file.watch, can be placed into minifi.properties to monitor. If the update time changes while the agent is running, it will be copied into place of the file defined by nifi.flow.configuration.file. The agent will then be restarted with the new flow configuration. If a failure occurs in reading that file or it is an invalid YAML file, the update process will be halted.
in minifi.properties to activate the file update trigger specify # specifying a trigger nifi.c2.agent.trigger.classes=FileUpdateTrigger nifi.c2.file.watch=<full path of file to monitor>
Type descriptions ( class descriptions entered in PROCESSORS.md ) can be automatically placed within C2 by building cmake with the following flag:
cmake -DBOOTSTRAP=ON .. You can then run ./extensions/bootstrap/bstrp --inputc2docs <PROCESSORS.md> --outputc2docs ../libminifi/include/agent/agent_docs.h
When cmake is instantiated with this, a build will re-generate the type descriptions from PROCESSORS.md. Once this is finished you may re-build the project with the following command from the build directory, running the build as you normally would:
cmake -DBOOTSTRAP= ..