Changeset - 91e4754320e6
[Not reviewed]
0 6 2
Branko Majic (branko) - 3 years ago 2020-11-22 22:15:51
branko@majic.rs
MAR-164: Fix Prosody TLS configuration in xmpp_server role:

- Added warning to role reference documentation about what DNS names
need to be included in the subject alternative name of issued
certificate used for Prosody.
- Added crontab with script that validates the certificate on daily
basis.
- Updated tests to include the proxy.DOMAIN and conference.DOMAIN DNS
names in subject alternative name for generated test certificates.
- Added and updated tests that cover new functionality.
- Fixed the Prosody TLS configuration to have common parameters
specified in general section, and any kind of overrides (mainly the
ciphers) in more specific sections.
- Updated release notes.
8 files changed with 102 insertions and 9 deletions:
0 comments (0 inline, 0 general)
docs/releasenotes.rst
Show inline comments
 
@@ -159,6 +159,11 @@ upgrade to Python 3.x, dropping support for Python 2.7.
 

	
 
  * Server now supports blocking users via `XEP-0191: Blocking Command
 
    <https://xmpp.org/extensions/xep-0191.html>`_.
 
  * XMPP server certificate is checked on daily basis using the
 
    ``prosodyctl check certs`` command. This helps catch issues where
 
    issued certificate does not include all the necessary subject
 
    alternative names (this has also been documented in the role
 
    reference documentation).
 

	
 
**Deprecations:**
 

	
docs/rolereference.rst
Show inline comments
 
@@ -834,6 +834,18 @@ The role implements the following:
 
* Sets-up the Debian backports repository and pins the ``lua-ldap``
 
  package to it (needed for Lua 5.2 support with Prosody 0.11).
 
* Deploys XMPP TLS private key and certificate.
 

	
 
  .. warning::
 
     The issued certificate must have multiple FQDNs listed as subject
 
     alternative names (DNS names) for each configured domain:
 

	
 
     - domain itself
 
     - ``conference.DOMAIN``
 
     - ``proxy.DOMAIN``
 

	
 
     A daily cron job is run to validate that all certificates have
 
     been configured and issued correctly.
 

	
 
* Installs Prosody.
 
* Configures Prosody.
 
* Configures firewall to allow incoming connections to the XMPP server.
roles/xmpp_server/files/check_prosody_certificate.sh
Show inline comments
 
new file 100644
 
#!/bin/bash
 

	
 
if ! output=$(prosodyctl check certs); then
 
    echo "$output" >&2
 
    echo
 
    echo "[ERROR] Prosody certificate check has failed. See above for details." >&2
 
    echo "[INFO] To manually perform the check, run the command: prosodyctl check certs"
 
    exit 1
 
else
 
    exit 0
 
fi
roles/xmpp_server/files/cron_check_prosody_certificate
Show inline comments
 
new file 100644
 
MAILTO=root
 
0 0 * * * prosody /usr/local/bin/check_prosody_certificate.sh
roles/xmpp_server/molecule/default/prepare.yml
Show inline comments
 
@@ -26,11 +26,17 @@
 
          fqdn:
 
            - parameters-mandatory
 
            - domain1
 
            - proxy.domain1
 
            - conference.domain1
 
        - name: parameters-optional-stretch64_xmpp
 
          fqdn:
 
            - parameters-optional
 
            - domain2
 
            - proxy.domain2
 
            - conference.domain2
 
            - domain3
 
            - proxy.domain3
 
            - conference.domain3
 

	
 
    - name: Set-up link to generated X.509 material
 
      file:
roles/xmpp_server/molecule/default/tests/test_default.py
Show inline comments
 
@@ -318,6 +318,50 @@ def test_enabled_modules(host):
 
    assert enabled_modules == expected_modules
 

	
 

	
 
def test_certificate_configuration(host):
 
    """
 
    Tests if certificates have been issued and configured correctly
 
    for use with Prosody. Relies on Prosody's own internal check
 
    command.
 
    """
 

	
 
    with host.sudo():
 
        check_certs = host.run("prosodyctl check certs")
 

	
 
    assert check_certs.rc == 0, check_certs.stdout
 

	
 

	
 
def test_prosody_certificate_checker_script(host):
 
    """
 
    Tests if Prosody certificate checker script has been correctly
 
    deployed.
 
    """
 

	
 
    with host.sudo():
 
        script = host.file("/usr/local/bin/check_prosody_certificate.sh")
 

	
 
        assert script.is_file
 
        assert script.user == 'root'
 
        assert script.group == 'root'
 
        assert script.mode == 0o755
 

	
 

	
 
def test_prosody_certificate_checker_crontab(host):
 
    """
 
    Tests if crontab entry has been deployed for running the Prosody
 
    certificate checker script.
 
    """
 

	
 
    crontab = host.file('/etc/cron.d/check_prosody_certificate')
 

	
 
    assert crontab.is_file
 
    assert crontab.user == 'root'
 
    assert crontab.group == 'root'
 
    assert crontab.mode == 0o644
 
    assert "MAILTO=root" in crontab.content_string
 
    assert "/usr/local/bin/check_prosody_certificate.sh" in crontab.content_string
 

	
 

	
 
# @TODO: Tests which were not implemented due to lack of out-of-box tools:
 
#
 
# - Proxy capability.
roles/xmpp_server/tasks/main.yml
Show inline comments
 
@@ -95,6 +95,22 @@
 
    group: root
 
    mode: 0644
 

	
 
- name: Deploy script for validating Prosody certificate
 
  copy:
 
    src: "check_prosody_certificate.sh"
 
    dest: "/usr/local/bin/check_prosody_certificate.sh"
 
    owner: root
 
    group: root
 
    mode: 0755
 

	
 
- name: Set-up crontab task that runs the Prosody certificate checker script once a day
 
  copy:
 
    src: "cron_check_prosody_certificate"
 
    dest: "/etc/cron.d/check_prosody_certificate"
 
    owner: root
 
    group: root
 
    mode: 0644
 

	
 
- name: Set-up directory for storing additional Prosody modules
 
  file:
 
    path: "/usr/local/lib/prosody/modules/"
roles/xmpp_server/templates/prosody.cfg.lua.j2
Show inline comments
 
@@ -40,26 +40,23 @@ modules_enabled = {
 
-- For more information see http://prosody.im/doc/creating_accounts
 
allow_registration = false;
 

	
 
-- These are the SSL/TLS-related settings. If you don't want
 
-- to use SSL/TLS, you may comment or remove this
 
s2s_ssl = {
 
-- Set global settings for SSL/TLS.
 
ssl = {
 
  key = "/etc/ssl/private/{{ ansible_fqdn }}_xmpp.key";
 
  certificate = "/etc/ssl/certs/{{ ansible_fqdn }}_xmpp.pem";
 
  dhparam = "/etc/ssl/private/{{ ansible_fqdn }}_xmpp.dh.pem";
 
}
 

	
 
-- Configure TLS protocol and ciphers for client-to-server
 
-- connections (STARTTLS).
 
c2s_ssl = {
 
  key = "/etc/ssl/private/{{ ansible_fqdn }}_xmpp.key";
 
  certificate = "/etc/ssl/certs/{{ ansible_fqdn }}_xmpp.pem";
 
  dhparam = "/etc/ssl/private/{{ ansible_fqdn }}_xmpp.dh.pem";
 
  protocol = "{{ xmpp_server_tls_protocol }}";
 
  ciphers = "{{ xmpp_server_tls_ciphers }}";
 
}
 

	
 
-- Configure TLS protocol and ciphers for client-to-server
 
-- connections (direct TLS).
 
legacy_ssl_ssl = {
 
  key = "/etc/ssl/private/{{ ansible_fqdn }}_xmpp.key";
 
  certificate = "/etc/ssl/certs/{{ ansible_fqdn }}_xmpp.pem";
 
  dhparam = "/etc/ssl/private/{{ ansible_fqdn }}_xmpp.dh.pem";
 
  protocol = "{{ xmpp_server_tls_protocol }}";
 
  ciphers = "{{ xmpp_server_tls_ciphers }}";
 
}
0 comments (0 inline, 0 general)