Joseph Nuthalapati a918f9a885
matrix-synapse: Use Let's Encrypt certificates
Matrix requires valid certificates for federation with other servers from
version 1.0 onward. If the FreedomBox server already has LE cert and private
key, copy them into /etc/matrix-synapse

- Add certificate renewal hooks for Matrix Synapse. Reusing the certificate
  renewal mechanism built for ejabberd with matrix-synapse as well. One notable
  difference is that Matrix Synapse doesn't support switching the domain name or
  dropping the Let's Encrypt certificate.

- Use self-signed certificate if there is no LE certificate. Matrix Synapse
  server startup fails if the files homeserver.tls.crt and homeserver.tls.key
  are missing.

- Copy Apache's snakeoil certificates to /etc/matrix-synapse when LE
  certificates are not available. Prefer LE certificates if available.

- Display warning if no valid LE certificate is found.

Signed-off-by: Joseph Nuthalapati <njoseph@thoughtworks.com>
2019-02-13 11:29:36 -08:00

330 lines
14 KiB
HTML

{% extends "simple_service.html" %}
{% comment %}
#
# This file is part of FreedomBox.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
{% endcomment %}
{% load bootstrap %}
{% load i18n %}
{% block page_head %}
<style type="text/css">
.table .form .btn {
width: 7em;
}
.form-inline {
display: inline;
}
</style>
{% endblock %}
{% block configuration %}
<h3>{% trans "Configuration" %}</h3>
{% if status.domains %}
<table class="table table-bordered table-condensed table-striped">
<thead>
<tr>
<th>{% trans "Domain" %}</th>
<th>{% trans "Certificate Status" %}</th>
<th>{% trans "Website Security" %}</th>
<th>{% trans "Actions" %}</th>
</tr>
</thead>
<tbody>
{% for domain, domain_status in status.domains.items %}
<tr>
<td>
{% if domain == status.current_domain.name %}
<b>{{ domain }}</b>
{% else %}
{{ domain }}
{% endif %}
</td>
<td>
{% if domain_status.certificate_available and domain_status.validity == "valid" %}
<span class="label label-success">
{% blocktrans trimmed with expiry_date=domain_status.expiry_date %}
Valid, expires on {{ expiry_date }}
{% endblocktrans %}
</span>
{% elif domain_status.certificate_available and not domain_status.validity == "valid" %}
<span class="label label-warning">
{% if "revoked" in domain_status.validity %}
{% blocktrans trimmed %}
Revoked
{% endblocktrans %}
{% elif "expired" in domain_status.validity %}
{% blocktrans trimmed with expiry_date=domain_status.expiry_date %}
Expired on {{ expiry_date }}
{% endblocktrans %}
{% elif "test" in domain_status.validity %}
{% blocktrans trimmed %}
Invalid test certificate
{% endblocktrans %}
{% else %}
{% blocktrans trimmed with reason=domain_status.validity %}
Invalid ({{ reason }})
{% endblocktrans %}
{% endif %}
</span>
{% else %}
<span class="label label-warning">
{% trans "No certificate" %}
</span>
{% endif %}
</td>
<td>
{% if domain_status.web_enabled %}
<span class="label label-success">{% trans "Enabled" %}</span>
{% else %}
<span class="label label-warning">{% trans "Disabled" %}</span>
{% endif %}
</td>
<td>
{% if domain_status.certificate_available %}
<form class="form form-inline" method="post"
action="{% url 'letsencrypt:obtain' domain %}">
{% csrf_token %}
<button class="btn btn-sm btn-default" type="submit">
{% trans "Re-obtain" %}</button>
</form>
<form class="form form-inline" method="post"
action="{% url 'letsencrypt:delete' domain %}">
{% csrf_token %}
<button class="btn btn-sm btn-default" type="submit">
{% trans "Delete" %}</button>
</form>
{% if "revoked" not in domain_status.validity %}
<form class="form form-inline" method="post"
action="{% url 'letsencrypt:revoke' domain %}">
{% csrf_token %}
<button class="btn btn-sm btn-default" type="submit">
{% trans "Revoke" %}</button>
</form>
{% endif %}
{% else %}
<form class="form form-inline" method="post"
action="{% url 'letsencrypt:obtain' domain %}">
{% csrf_token %}
<button class="btn btn-sm btn-primary" type="submit">
{% trans "Obtain" %}</button>
</form>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include "diagnostics_button.html" with module="letsencrypt" enabled=True %}
<h4>{% trans "Certificate renewal management and use by other modules" %}</h4>
<p class="help-block">
{% blocktrans trimmed %}
If you have a Let's Encrypt certificate for your current domain, you may
let {{ box_name }} manage its renewal process. This also enables other apps
to use that certificate, so that users would not prompted with security
warnings when using them.
{% endblocktrans %}
</p>
{% if status.current_domain.name %}
<form class="form" method="post"
action="{% url 'letsencrypt:toggle_hooks' status.current_domain.name %}">
{% csrf_token %}
<div class="checkbox">
<label>
{% if status.current_domain.has_cert %}
<input type="checkbox" name="toggle_hooks" id="id_toggle_hooks"
{% if 'enabled' in status.current_domain.manage_hooks_status %}
checked
{% endif %}
onchange="this.form.submit();">
</input>
<noscript>
<button class="btn btn-sm btn-default" type="submit">
{% trans "Update config" %}</button>
</noscript>
{% else %}
<input type="checkbox" name="toggle_hooks" id="id_toggle_hooks" disabled></input>
<noscript>
<button class="btn btn-sm btn-default disabled" type="submit">
{% trans "Update config" %}</button>
</noscript>
{% endif %}
<span>
{% blocktrans trimmed with current_domain=status.current_domain.name %}
Let {{ box_name }} manage certificate renewal of
<b>{{ current_domain }}</b>
{% endblocktrans %}
</span>
</label>
</div>
<p class="help-block">
{% if status.current_domain.has_cert %}
{% blocktrans trimmed %}
If enabled, {{ box_name }} can make sure that all apps can use the
certificate as soon as it is renewed.
{% endblocktrans %}
{% else %}
{% blocktrans trimmed %}
<b>No certificate available for the current domain.</b>
First obtain a certificate to enable its management.
{% endblocktrans %}
{% endif %}
</p>
</form>
<form class="form" method="post"
action="{% url 'letsencrypt:toggle_module' domain=status.current_domain.name module='ejabberd' %}">
{% csrf_token %}
<div class="checkbox">
<label>
{% if 'ejabberd' in installed_modules and 'enabled' in status.current_domain.manage_hooks_status %}
<input type="checkbox" name="ejabberd" id="ejabberd"
{% if 'ejabberd' in status.current_domain.manage_hooks_status %}
checked
{% endif %}
onchange="this.form.submit();">
</input>
<noscript>
<button class="btn btn-sm btn-default" type="submit">
{% trans "Update config" %}</button>
</noscript>
{% else %}
<input type="checkbox" name="ejabberd" id="ejabberd" disabled></input>
<noscript>
<button class="btn btn-sm btn-default disabled" type="submit">
{% trans "Update config" %}</button>
</noscript>
{% endif %}
<span>
{% if 'ejabberd' in installed_modules and 'enabled' in status.current_domain.manage_hooks_status %}
{% blocktrans trimmed with current_domain=status.current_domain.name %}
Use certificate of {{ current_domain }} for <b>ejabberd</b>
{% endblocktrans %}
{% else %}
{% blocktrans trimmed %}
Use certificate of the current domain for <b>ejabberd</b>
{% endblocktrans %}
{% endif %}
</span>
</label>
</div>
<p class="help-block">
{% url 'ejabberd:index' as ejabberd_url %}
{% if 'ejabberd' in installed_modules and 'enabled' in status.current_domain.manage_hooks_status %}
{% blocktrans trimmed %}
If enabled, the app <a href="{{ ejabberd_url }}">ejabberd</a>
will also use the Let's Encrypt certificate.
This will reduce warnings about self-signed certificates in
client applications, and enable more wide-spread federation with
other XMPP servers in the Internet.
{% endblocktrans %}
{% elif 'ejabberd' not in installed_modules %}
{% blocktrans trimmed %}
This feature only makes sense if you are using the
<a href="{{ ejabberd_url }}">ejabberd</a> chat server app.
{% endblocktrans %}
{% else %}
{% blocktrans trimmed %}
To use a Let's Encrypt certificate for
<a href="{{ ejabberd_url }}">ejabberd</a> chat server app, you
must first enable certificate renewal of the current domain.
{% endblocktrans %}
{% endif %}
</p>
</form>
<form class="form" method="post"
action="{% url 'letsencrypt:toggle_module' domain=status.current_domain.name module='matrixsynapse' %}">
{% csrf_token %}
<div class="checkbox">
<label>
{% if 'matrixsynapse' in installed_modules and 'enabled' in status.current_domain.manage_hooks_status %}
<input type="checkbox" name="matrixsynapse" id="matrixsynapse"
{% if 'matrixsynapse' in status.current_domain.manage_hooks_status %}
checked
{% endif %}
onchange="this.form.submit();">
</input>
<noscript>
<button class="btn btn-sm btn-default" type="submit">
{% trans "Update config" %}</button>
</noscript>
{% else %}
<input type="checkbox" name="matrixsynapse" id="matrixsynapse"
class="disabled"></input>
<noscript>
<button class="btn btn-sm btn-default disabled" type="submit">
{% trans "Update config" %}</button>
</noscript>
{% endif %}
<span>
{% if 'matrixsynapse' in installed_modules and 'enabled' in status.current_domain.manage_hooks_status %}
{% blocktrans trimmed with current_domain=status.current_domain.name %}
Use certificate of {{ current_domain }} for <b>matrixsynapse</b>
{% endblocktrans %}
{% else %}
{% blocktrans trimmed %}
Use certificate of the current domain for <b>matrixsynapse</b>
{% endblocktrans %}
{% endif %}
</span>
</label>
</div>
<p class="help-block">
{% url 'matrixsynapse:index' as matrixsynapse_url %}
{% if 'matrixsynapse' in installed_modules and 'enabled' in status.current_domain.manage_hooks_status %}
{% blocktrans trimmed %}
If enabled, the app <a href="{{ matrixsynapse_url }}">Matrix Synapse</a>
will also use the same Let's Encrypt certificate.
Other Matrix Synapse instances running version 1.0 or greater expect
your server to produce a valid TLS certificate. Federation with other
instances will not work without this.
{% endblocktrans %}
{% elif 'matrixsynapse' not in installed_modules %}
{% blocktrans trimmed %}
This feature only makes sense if you are using the
<a href="{{ matrixsynapse_url }}">Matrix Synapse</a> chat server app.
{% endblocktrans %}
{% else %}
{% blocktrans trimmed %}
To use a Let's Encrypt certificate for
<a href="{{ matrixsynapse_url }}">Matrix Synapse</a> chat server app, you
must first enable certificate renewal of the current domain.
{% endblocktrans %}
{% endif %}
</p>
</form>
{% else %}
{% blocktrans trimmed %}
<b>No current domain is configured.</b>
First configure a domain to enable management of its certificates.
{% endblocktrans %}
{% endif %}
{% else %}
{% blocktrans trimmed %}
No domains have been configured. Configure domains to be able to
obtain certificates for them.
{% endblocktrans %}
{% endif %}
{% endblock %}