summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chaos-at-home/ch-testvm-prometheus.yml6
-rw-r--r--filter_plugins/crypto.py14
-rw-r--r--inventory/host_vars/ch-testvm-prometheus.yml50
-rw-r--r--roles/mosquitto/defaults/main.yml31
-rw-r--r--roles/mosquitto/handlers/main.yml10
-rw-r--r--roles/mosquitto/tasks/main.yml71
-rw-r--r--roles/mosquitto/templates/config.j229
7 files changed, 211 insertions, 0 deletions
diff --git a/chaos-at-home/ch-testvm-prometheus.yml b/chaos-at-home/ch-testvm-prometheus.yml
index 9a1191ad..bd71a3a4 100644
--- a/chaos-at-home/ch-testvm-prometheus.yml
+++ b/chaos-at-home/ch-testvm-prometheus.yml
@@ -7,3 +7,9 @@
- role: core/sshd/base
- role: core/zsh
- role: core/ntp
+
+- name: Payload Setup
+ hosts: ch-testvm-prometheus
+ roles:
+ - role: x509/selfsigned/base
+ - role: mosquitto
diff --git a/filter_plugins/crypto.py b/filter_plugins/crypto.py
index 54547a34..995776d3 100644
--- a/filter_plugins/crypto.py
+++ b/filter_plugins/crypto.py
@@ -2,6 +2,7 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import hashlib
+import passlib
from binascii import hexlify
from passlib.utils.binary import Base64Engine, HASH64_CHARS, BCRYPT_CHARS
from ansible.module_utils._text import to_bytes, to_text
@@ -53,6 +54,18 @@ def wifi_80211r_key(seed):
raise errors.AnsibleFilterError("wifi_80211r_key(): %s" % str(e))
+def mosquitto_passwd_hash(password, seed):
+ ''' generate password hash for use by mosquitto mqtt server '''
+ try:
+ h = hashlib.new('sha512')
+ h.update(to_bytes(seed, errors='surrogate_or_strict'))
+ salt = h.digest()[0:12]
+ digest = passlib.hash.pbkdf2_sha512.using(salt=salt).hash(password).replace('pbkdf2-sha512', '7').replace('.', '+')
+ return digest + '=='
+ except Exception as e:
+ raise errors.AnsibleFilterError("mosquitto_passwd_hash(): %s" % str(e))
+
+
class FilterModule(object):
''' crypto helpers '''
@@ -62,6 +75,7 @@ class FilterModule(object):
'sha512_salt': sha2_crypt_salt,
'bcrypt_salt': bcrypt_salt,
'wifi_80211r_key': wifi_80211r_key,
+ 'mosquitto_passwd_hash': mosquitto_passwd_hash,
}
def filters(self):
diff --git a/inventory/host_vars/ch-testvm-prometheus.yml b/inventory/host_vars/ch-testvm-prometheus.yml
index 415e6774..50e625fa 100644
--- a/inventory/host_vars/ch-testvm-prometheus.yml
+++ b/inventory/host_vars/ch-testvm-prometheus.yml
@@ -35,3 +35,53 @@ network:
- *_network_primary_
ntp_variant: systemd-timesyncd
+
+
+###
+mosquitto_global_config_options:
+ per_listener_settings: "true"
+
+mosquitto_listeners:
+ example:
+ bind: 1884 192.168.32.42
+ hostnames:
+ - mqtt.example.com
+ tls:
+ certificate_provider: selfsigned
+ certificate_config:
+ cert:
+ organization_name: "spreadspace"
+ organizational_unit_name: "ansible"
+ san_extra:
+ - "IP:192.168.32.42"
+ create_subject_key_identifier: yes
+ not_after: +100w
+ options:
+ allow_anonymous: "true"
+ require_certificate: "true"
+ acl_file: /etc/mosquitto/foo.acl
+ foo:
+ bind: 1883
+ options:
+ allow_anonymous: "false"
+ acl_file: /etc/mosquitto/example.acl
+ password_file: /etc/mosquitto/example.passwd
+
+mosquitto_prometheus_listener: true
+
+mosquitto_acl_files:
+ example: |
+ user admin
+ topic read test/+
+ user equinox
+ topic write test/+
+ foo: |
+ user consumer
+ topic read foo/+
+ user producer
+ topic write foo/+
+
+mosquitto_password_files:
+ example: |
+ admin:{{ 'admin' | mosquitto_passwd_hash('admin@mqtt.example.com') }}
+ equinox:{{ 'secret' | mosquitto_passwd_hash('equinox@mqtt.example.com') }}
diff --git a/roles/mosquitto/defaults/main.yml b/roles/mosquitto/defaults/main.yml
new file mode 100644
index 00000000..32199a50
--- /dev/null
+++ b/roles/mosquitto/defaults/main.yml
@@ -0,0 +1,31 @@
+---
+# mosquitto_global_config_options:
+# per_listener_settings: "true"
+
+mosquitto_listeners: {}
+# example:
+# bind: 1883 192.0.2.1
+# hostnames:
+# - mqtt.example.com
+# tls:
+# certificate_provider: ...
+# options:
+# require_certificate: "true"
+# use_identity_as_username: "true"
+# foo:
+# bind: 1884
+# options:
+# allow_anonymous: "false"
+# acl_file: /etc/mosquitto/example.acl
+# password_file: /etc/mosquitto/example.passwd
+
+mosquitto_prometheus_listener: false
+
+mosquitto_acl_files: {}
+# example: |
+# user somebody
+# topic read example/+/foo
+
+mosquitto_password_files: {}
+# example: |
+# somebody:{{ 'secret' | mosquitto_passwd_hash('somebody@mqtt.example.com') }}
diff --git a/roles/mosquitto/handlers/main.yml b/roles/mosquitto/handlers/main.yml
new file mode 100644
index 00000000..c188764d
--- /dev/null
+++ b/roles/mosquitto/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+- name: restart mosquitto
+ service:
+ name: mosquitto
+ state: restarted
+
+- name: reload mosquitto
+ service:
+ name: mosquitto
+ state: reloaded
diff --git a/roles/mosquitto/tasks/main.yml b/roles/mosquitto/tasks/main.yml
new file mode 100644
index 00000000..ed872789
--- /dev/null
+++ b/roles/mosquitto/tasks/main.yml
@@ -0,0 +1,71 @@
+---
+- name: install mosquitto
+ apt:
+ name:
+ - mosquitto
+ - mosquitto-clients
+ state: present
+
+- name: install mosquitto acl files
+ loop: "{{ mosquitto_acl_files | dict2items }}"
+ loop_control:
+ label: "{{ item.key }}"
+ copy:
+ content: |
+ # Ansible managed
+ {{ item.value }}
+ dest: "/etc/mosquitto/{{ item.key }}.acl"
+ notify: reload mosquitto
+
+- name: install mosquitto password files
+ loop: "{{ mosquitto_password_files | dict2items }}"
+ loop_control:
+ label: "{{ item.key }}"
+ copy:
+ content: |
+ {{ item.value }}
+ dest: "/etc/mosquitto/{{ item.key }}.passwd"
+ owner: root
+ group: mosquitto
+ mode: "0640"
+ notify: reload mosquitto
+
+- name: generate Diffie-Hellman parameters
+ when: (mosquitto_listeners | dict2items | selectattr('value.tls', 'defined') | length) > 0
+ openssl_dhparam:
+ path: /etc/mosquitto/certs/dhparams.pem
+ size: 2048
+ notify: reload mosquitto
+
+- name: generate/install/fetch TLS certificate
+ loop: "{{ mosquitto_listeners | dict2items | selectattr('value.tls', 'defined') }}"
+ loop_control:
+ label: "{{ item.key }}"
+ vars:
+ x509_certificate_name: "mosquitto-{{ item.key }}"
+ x509_certificate_hostnames: "{{ item.value.hostnames }}"
+ x509_certificate_config: "{{ item.value.tls.certificate_config | default({}) }}"
+ x509_certificate_renewal:
+ install:
+ - dest: "/etc/mosquitto/certs/{{ item.key }}-crt.pem"
+ src:
+ - fullchain
+ owner: root
+ group: mosquitto
+ mode: "0644"
+ - dest: "/etc/mosquitto/certs/{{ item.key }}-key.pem"
+ src:
+ - key
+ owner: root
+ group: mosquitto
+ mode: "0640"
+ x509_certificate_reload_services:
+ - mosquitto
+ include_role:
+ name: "x509/{{ item.value.tls.certificate_provider }}/cert"
+
+- name: install mosquitto config
+ template:
+ src: config.j2
+ dest: /etc/mosquitto/conf.d/main.conf
+ notify: restart mosquitto
diff --git a/roles/mosquitto/templates/config.j2 b/roles/mosquitto/templates/config.j2
new file mode 100644
index 00000000..e6fa4b52
--- /dev/null
+++ b/roles/mosquitto/templates/config.j2
@@ -0,0 +1,29 @@
+# {{ ansible_managed }}
+
+## Global
+{% if mosquitto_global_config_options is defined %}
+{% for option, value in mosquitto_global_config_options.items() %}
+{{ option }} {{ value }}
+{% endfor %}
+{% endif %}
+{% for name, listener in mosquitto_listeners.items() %}
+
+## Listener: {{ name }}
+listener {{ listener.bind }}
+{% if 'tls' in listener %}
+certfile /etc/mosquitto/certs/{{ name }}-crt.pem
+keyfile /etc/mosquitto/certs/{{ name }}-key.pem
+dhparamfile /etc/mosquitto/certs/dhparams.pem
+{% endif %}
+{% if 'options' in listener %}
+{% for option, value in listener.options.items() %}
+{{ option }} {{ value }}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% if mosquitto_prometheus_listener %}
+
+## Prometheus monitoring
+listener 0 /var/run/mosquitto/prometheus.sock
+allow_anonymous true
+{% endif %}