2-June-2022 DC CAW
A publicly available MQTT broker is setup to test OpenC2 Messages over MQTT. This is a sandbox for testing OpenC2, so please connect, subscribe, and start publishing!
It’s a RabbitMQ server configured for MQTT, and will be up 24/7 except for any maintenance.
No MQTT topics-names or topic-filters are defined on the server itself; they are ephemeral, defined on-the-fly by clients that publish and subscribe. Please see the notes below about sandboxing your tests.
Remember to look in Slack/Discord for a pinned message with the connection details, not shown here.
With the IP, Port, User, and Password, you can use any MQTT client to connect to the broker over an unencrypted TCP connection. Look at the Hello World section below for an example.
There are two ways to connect with TLS. These options assume you are using the Hello World example below.
If you aren’t concerned with the broker’s identity, just add a basic ssl context:
import ssl
# ... client already created
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
client.tls_set_context(context)
# ... now connect client
To verify the broker’s identity, you’ll need its CA certificate, referenced here as ca-broker.crt:
import ssl
# ... client already created
CA_CERTS = 'path/to/ca-broker.crt'
context = ssl.create_default_context()
context.load_verify_locations(cafile=CA_CERTS)
client.tls_set_context(context)
# ... now connect client
The plugfest will use the OASIS OpenC2 Transfer Specification as the working standard for use of MQTT. This version of the document can be found at:
https://docs.oasis-open.org/openc2/transf-mqtt/v1.0/transf-mqtt-v1.0.html
This specification incorporates, in Section 2.4, a new OpenC2 message format with more complete contents, originally presented in issue #353 for the OpenC2 Language Specification. This message format has not yet been published as an OASIS committee specifciation, but is in the working version of the OpenC2 Language Specification.
The plugfest will use the default topic structure described in
Section
2.2
of the draft MQTT specification. However, in order to permit
groups within the plugfest a controlled space for testing, the
plugfest will add a top-layer “namespacing” topic to the
structure to create ad hoc partitioning of the topic structure.
Producers and Consumers connected to the broker who wish to be
available to any interested communications peer should prefix
their topic subsubscriptions and message publising with
vpf/
(virtual plug fest). Groups of participants who wish
to focus their communications to the gruop members should select
a namespace related to their group or organization and adjust
their subscriptions and publications accordingly. For example a
group focused on firewalls might use fw/
, leading to topics
like:
fw/oc2/cmd/all
fw/oc2/cmd/slpf
Topic subscriptions and publications with out a namespace prefix should be avoided.
To get started, here is a simple Python3 example with a publisher sending a message to a subscriber.
Bash shell
mkdir test_mqtt
cd test_mqtt
python3 -m venv venv
source venv/bin/activate
pip install paho-mqtt
mkdir test1
cd test1
touch mqtt_subscriber.py
touch mqtt_publish.py
touch mqtt_config.py
mqtt_config.py
If your code might be stored on GitHub or other public location, please ensure that it does not contain access credentials (CWE). Your mqtt_config.py should obtain credentials from a local configuration file, environment variable, etc.
YOUR_NAME_PREFIX = # Your name, Eg "johnd/"
broker_ip = "*.*.*.*"
broker_port = ****
user_name = '****'
user_pw = '****'
mqtt_subscriber.py
#!/usr/bin/env python3
import paho.mqtt.client as mqtt
import mqtt_config as config
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
client.subscribe(config.YOUR_NAME_PREFIX + "oc2/cmd")
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
client = mqtt.Client()
client.username_pw_set(config.user_name, password=config.user_pw)
client.on_connect = on_connect
client.on_message = on_message
# Using TLS? Insert context code here
client.connect(config.broker_ip, config.broker_port, 60)
client.loop_forever()
mqtt_publish.py
#!/usr/bin/env python3
import paho.mqtt.publish as publish
import mqtt_config as config
login = {'username':config.user_name, 'password':config.user_pw}
query_features = {
"action": "query",
"target": {
"features": []
},
"args": {
"response_requested": "complete"
}
}
# Using TLS? Create an ssl context here and supply it as the 'tls' argument below.
publish.single(config.YOUR_NAME_PREFIX + "oc2/cmd", payload=str(query_features), qos=0,
retain=False, hostname=config.broker_ip, port=config.broker_port, client_id="",
keepalive=60, will=None, auth=login, tls=None)
Now start the subscriber in one shell, then run the publisher in another, eg:
Original Shell
python mqtt_subscriber.py
New Shell
source ../venv/bin/activate
python mqtt_publish.py
To verify the broker’s identity over a TLS connection, use the following CA certificate:
TBSL
Please reach out on the plugfest Discord and Slack channels, we want this to be as easy as possible.