Skip to content

Instantly share code, notes, and snippets.

@LTGIV
Last active July 5, 2021 05:42
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save LTGIV/d5abd000e7e7422b8b08 to your computer and use it in GitHub Desktop.
Save LTGIV/d5abd000e7e7422b8b08 to your computer and use it in GitHub Desktop.
Ansible playbook: install Mosquitto on Ubuntu (14.04 LTS) from PPA (alpha)
---
#
# Ansible playbook: install Mosquitto from PPA on Ubuntu v201502131346
# Louis T. Getterman IV (@LTGIV)
# www.GotGetLLC.com / www.opensour.cc
#
# Thanks to @jpmens for insight on cert locations ( https://twitter.com/jpmens/status/565513595644313600 )
#
# Example Usage:
# [user@host ~$] ansible-playbook /etc/ansible/playbooks/ubuntu-mosquitto.yml --extra-vars 'target=nameFromHostsFile'
#
# Manual Service Test (make sure you first stop mosquitto service)
# /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf
#
# [TO-DO]
#
# * AUTOMATE AUTH-PLUG DEPLOYMENT (https://github.com/jpmens/mosquitto-auth-plug)
#
# * FUTURE VERSIONS (and switching from a playbook into this being a role) WILL COVER MULTIPLE OPERATING SYSTEM VERSIONS (starting with Ubuntu, Raspbian, Debian, RHEL, and CentOS)
#
# * ALT NAMES SHOULD INCLUDE IP ADDRESSES (what to do if they're dynamic/ephemeral?) - [Writing to certificate extensions file]
#
# * [Stop Mosquitto service] ONLY WHEN FRESH INSTALL, OTHERWISE IGNORE
#
# * FIX REPETITIVE PERMISSION ISSUES ( [Permisions for certificates], [Permissions for /etc/mosquitto/certs/] )
#
- hosts: '{{ target }}'
sudo: yes
tasks:
- name: Add Mosquitto repositories
apt_repository: >
repo='{{ item }}'
state=present
with_items:
- 'ppa:mosquitto-dev/mosquitto-ppa'
- name: Add Mosquitto key
apt_key: >
url='http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key'
state=present
- name: Install Mosquitto Broker, Clients, and API
apt: >
update_cache=yes
pkg={{ item }}
state=installed
with_items:
- mosquitto
- mosquitto-clients
- python-mosquitto
- name: Stop Mosquitto service
service: >
name=mosquitto
state=stopped
- name: Create mosquitto group
group: >
name=mosquitto
state=present
- name: Set primary group to mosquitto
user: >
name=mosquitto
group=mosquitto
- name: Create certificate authority directory
file: >
path=/etc/mosquitto/ca/
state=directory
owner=mosquitto
group=mosquitto
mode="u=rwx,g=rx,o-rwx"
- name: Generate a certificate request
command: >
/usr/bin/openssl \
req \
-nodes \
-new \
-newkey rsa:4096 \
-x509 \
-days 365 \
-extensions v3_ca \
-keyout /etc/mosquitto/ca/ca.key \
-out /etc/mosquitto/ca/ca.crt \
-subj "/CN=An MQTT broker/O=MQTTitude.org/emailAddress=nobody@example.net"
args:
creates: /etc/mosquitto/ca/ca.crt
- name: Create symbolic link for ca.crt
file: >
src=/etc/mosquitto/ca/ca.crt
dest=/etc/mosquitto/ca_certificates/ca.crt
state=link
- name: Generate a self-signed key
command: >
/usr/bin/openssl \
x509 \
-in /etc/mosquitto/ca/ca.crt \
-nameopt multiline \
-subject \
-noout
args:
creates: /etc/mosquitto/certs/{{ ansible_hostname }}.key
- name: Generate RSA private key for host
command: >
/usr/bin/openssl \
genrsa \
-out /etc/mosquitto/certs/{{ ansible_hostname }}.key \
4096
args:
creates: /etc/mosquitto/certs/{{ ansible_hostname }}.key
- name: Generating a CSR from existing RSA private key for host
command: >
/usr/bin/openssl \
req \
-new \
-key /etc/mosquitto/certs/{{ ansible_hostname }}.key \
-out /etc/mosquitto/certs/{{ ansible_hostname }}.csr \
-subj /CN={{ ansible_hostname }}/O={{ ansible_fqdn }}/emailAddress=root@{{ ansible_fqdn }}
args:
removes: /etc/mosquitto/certs/{{ ansible_hostname }}.key
creates: /etc/mosquitto/certs/{{ ansible_hostname }}.crt
- name: Check existence of host crt file
stat: path=/etc/mosquitto/certs/{{ ansible_hostname }}.crt
register: hostcrt
- name: Creating certificate extensions file
command: mktemp /tmp/ansible.XXXXXXXXX
register: tmp_file
when: hostcrt.stat.exists == False
- name: Writing to certificate extensions file
lineinfile: >
dest='{{ tmp_file.stdout }}'
line='{{ item }}'
create=no
state=present
with_items:
- '[ JPMextensions ]'
- 'basicConstraints = critical,CA:false'
- 'nsCertType = server'
- 'keyUsage = nonRepudiation, digitalSignature, keyEncipherment'
- 'nsComment = "Broker Certificate"'
- 'subjectKeyIdentifier = hash'
- 'authorityKeyIdentifier = keyid,issuer:always'
- '# subjectAltName = $ENV::SUBJALTNAME'
- '# issuerAltName = issuer:copy'
- '#nsCaRevocationUrl = http://mqttitude.org/carev/'
- '#nsRevocationUrl = http://mqttitude.org/carev/'
- 'certificatePolicies = ia5org,@polsection'
- '# '
- '[polsection]'
- 'policyIdentifier = 1.3.5.8'
- 'CPS.1 = "http://localhost"'
- 'userNotice.1 = @notice'
- '# '
- '[notice]'
- 'explicitText = "This CA is for a local MQTT broker installation only"'
- 'organization = "MQTTitude"'
- 'noticeNumbers = 1'
when: hostcrt.stat.exists == False
- name: Sign certificate request with certificate extensions file
command: >
/usr/bin/openssl \
x509 \
-req \
-in /etc/mosquitto/certs/{{ ansible_hostname }}.csr \
-CA /etc/mosquitto/ca/ca.crt \
-CAkey /etc/mosquitto/ca/ca.key \
-CAcreateserial \
-CAserial /etc/mosquitto/ca/ca.srl \
-out /etc/mosquitto/certs/{{ ansible_hostname }}.crt \
-days 365 \
-extfile {{ tmp_file.stdout }} \
-extensions JPMextensions
args:
creates: /etc/mosquitto/certs/{{ ansible_hostname }}.crt
when: hostcrt.stat.exists == False
- name: 'Clean-up: host csr'
file: >
path=/etc/mosquitto/certs/{{ ansible_hostname }}.csr
state=absent
- name: 'Clean-up: certificate extensions file'
file: >
path={{ tmp_file.stdout }}
state=absent
when: hostcrt.stat.exists == False
- name: Writing to configuration file
lineinfile: >
dest='/etc/mosquitto/conf.d/{{ ansible_hostname }}.conf'
line='{{ item }}'
create=yes
state=present
with_items:
- '# Ansible playbook: Mosquitto Broker ( http://thad.getterman.org/post/110821419248/ansible-playbook-install-mosquitto-with-ssl )'
- '#'
- 'allow_anonymous false'
- 'autosave_interval 1800'
- 'connection_messages true'
- 'log_dest stderr'
- 'log_dest topic'
- 'log_type error'
- 'log_type warning'
- 'log_type notice'
- 'log_type information'
- 'log_type all'
- 'log_type debug'
- 'log_timestamp true'
- '#message_size_limit 10240'
- '#password_file jp.pw'
- '#acl_file jp.acl'
- 'persistence true'
- '#persistence_location /tmp/'
- 'persistence_file mosquitto.db'
- 'persistent_client_expiration 1m'
- '#pid_file xxxx'
- 'retained_persistence true'
- '#listener 1883'
- 'listener 1883 127.0.0.1'
- 'listener 8883'
- 'tls_version tlsv1'
- 'cafile /etc/mosquitto/ca/ca.crt'
- 'certfile /etc/mosquitto/certs/{{ ansible_hostname }}.crt'
- 'keyfile /etc/mosquitto/certs/{{ ansible_hostname }}.key'
- 'require_certificate true'
when: hostcrt.stat.exists == False
- name: Permissions for /etc/mosquitto/
file: >
path=/etc/mosquitto/
owner=mosquitto
group=mosquitto
mode="o-rwx"
state=directory
recurse=yes
- name: Permisions for certificates
file: >
path=/etc/mosquitto/{{ item }}
owner=mosquitto
group=mosquitto
mode=0440
state=file
with_items:
- 'ca/ca.crt'
- 'ca/ca.srl'
- 'certs/{{ ansible_hostname }}.crt'
- name: Permisions for keys
file: >
path=/etc/mosquitto/{{ item }}
owner=mosquitto
group=mosquitto
mode=0400
state=file
with_items:
- 'ca/ca.key'
- 'certs/{{ ansible_hostname }}.key'
- name: Permissions for /etc/mosquitto/certs/
file: >
path=/etc/mosquitto/certs/
owner=mosquitto
group=mosquitto
mode="g-rwx"
state=directory
recurse=yes
- name: Mosquitto verison and service restart
shell: 'mosquitto --help | head -n1 | egrep -o "([0-9]{1,}\.)+[0-9]{1,}"'
notify: restart mosquitto service
register: mosquittoVersion
- debug: msg='Installed Mosquitto version {{ mosquittoVersion.stdout }}'
handlers:
- name: restart mosquitto service
service: >
name=mosquitto
enabled=yes
state=restarted
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment