PR feedback
This commit is contained in:
parent
b40cb5562a
commit
589df0e230
|
@ -262,22 +262,101 @@ and are used when Lemur creates the CSR for your certificates.
|
||||||
LEMUR_DEFAULT_AUTHORITY = "verisign"
|
LEMUR_DEFAULT_AUTHORITY = "verisign"
|
||||||
|
|
||||||
|
|
||||||
|
.. _NotificationOptions:
|
||||||
|
|
||||||
Notification Options
|
Notification Options
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
Lemur currently has very basic support for notifications. Currently only expiration notifications are supported. Actual notification
|
Lemur supports a small variety of notification types through a set of notification plugins.
|
||||||
is handled by the notification plugins that you have configured. Lemur ships with the 'Email' notification that allows expiration emails
|
By default, Lemur configures a standard set of email notifications for all certificates.
|
||||||
to be sent to subscribers.
|
|
||||||
|
|
||||||
Templates for expiration emails are located under `lemur/plugins/lemur_email/templates` and can be modified for your needs.
|
**Plugin-capable notifications**
|
||||||
Notifications are sent to the certificate creator, owner and security team as specified by the `LEMUR_SECURITY_TEAM_EMAIL` configuration parameter.
|
|
||||||
|
|
||||||
Certificates marked as inactive will **not** be notified of upcoming expiration. This enables a user to essentially
|
These notifications can be configured to use all available notification plugins.
|
||||||
silence the expiration. If a certificate is active and is expiring the above will be notified according to the `LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS` or
|
|
||||||
30, 15, 2 days before expiration if no intervals are set.
|
|
||||||
|
|
||||||
Lemur supports sending certificate expiration notifications through SES and SMTP.
|
Supported types:
|
||||||
|
|
||||||
|
* Certificate expiration
|
||||||
|
|
||||||
|
**Email-only notifications**
|
||||||
|
|
||||||
|
These notifications can only be sent via email and cannot use other notification plugins.
|
||||||
|
|
||||||
|
Supported types:
|
||||||
|
|
||||||
|
* CA certificate expiration
|
||||||
|
* Pending ACME certificate failure
|
||||||
|
* Certificate rotation (currently disabled in code)
|
||||||
|
|
||||||
|
**Default notifications**
|
||||||
|
|
||||||
|
When a certificate is created, the following email notifications are created for it if they do not exist.
|
||||||
|
If these notifications already exist, they will be associated with the new certificate.
|
||||||
|
|
||||||
|
* ``DEFAULT_<OWNER>_X_DAY``, where X is the set of values specified in ``LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS`` and defaults to 30, 15, and 2 if not specified. The owner's username will replace ``<OWNER>``.
|
||||||
|
* ``DEFAULT_SECURITY_X_DAY``, where X is the set of values specified in ``LEMUR_SECURITY_TEAM_EMAIL_INTERVALS`` and defaults to ``LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS`` if not specified (which also defaults to 30, 15, and 2 if not specified).
|
||||||
|
|
||||||
|
These notifications can be disabled if desired. They can also be unassociated with a specific certificate.
|
||||||
|
|
||||||
|
**Disabling notifications**
|
||||||
|
|
||||||
|
Notifications can be disabled either for an individual certificate (which disables all notifications for that certificate)
|
||||||
|
or for an individual notification object (which disables that notification for all associated certificates).
|
||||||
|
At present, disabling a notification object will only disable certificate expiration notifications, and not other types,
|
||||||
|
since other notification types don't use notification objects.
|
||||||
|
|
||||||
|
**Certificate expiration**
|
||||||
|
|
||||||
|
Certificate expiration notifications are sent when the scheduled task to send certificate expiration notifications runs
|
||||||
|
(see :ref:`PeriodicTasks`). Specific patterns of certificate names may be excluded using ``--exclude`` (when using
|
||||||
|
cron; you may specify this multiple times for multiple patterns) or via the config option ``EXCLUDE_CN_FROM_NOTIFICATION``
|
||||||
|
(when using celery; this is a list configuration option, meaning you specify multiple values, such as
|
||||||
|
``['exclude', 'also exclude']``). The specified exclude pattern will match if found anywhere in the certificate name.
|
||||||
|
|
||||||
|
When the periodic task runs, Lemur checks for certificates meeting the following conditions:
|
||||||
|
|
||||||
|
* Certificate has notifications enabled
|
||||||
|
* Certificate is not expired
|
||||||
|
* Certificate is not revoked
|
||||||
|
* Certificate name does not match the `exclude` parameter
|
||||||
|
* Certificate has at least one associated notification object
|
||||||
|
* That notification is active
|
||||||
|
* That notification's configured interval and unit match the certificate's remaining lifespan
|
||||||
|
|
||||||
|
All eligible certificates are then grouped by owner and applicable notification. For each notification and certificate group,
|
||||||
|
Lemur will send the expiration notification using whichever plugin was configured for that notification object.
|
||||||
|
In addition, Lemur will send an email to the certificate owner and security team (as specified by the
|
||||||
|
``LEMUR_SECURITY_TEAM_EMAIL`` configuration parameter).
|
||||||
|
|
||||||
|
**CA certificate expiration**
|
||||||
|
|
||||||
|
Certificate authority certificate expiration notifications are sent when the scheduled task to send authority certificate
|
||||||
|
expiration notifications runs (see :ref:`PeriodicTasks`). Notifications are sent via the intervals configured in the
|
||||||
|
configuration parameter ``LEMUR_AUTHORITY_CERT_EXPIRATION_EMAIL_INTERVALS``, with a default of 365 and 180 days.
|
||||||
|
|
||||||
|
When the periodic task runs, Lemur checks for certificates meeting the following conditions:
|
||||||
|
|
||||||
|
* Certificate has notifications enabled
|
||||||
|
* Certificate is not expired
|
||||||
|
* Certificate is not revoked
|
||||||
|
* Certificate is associated with a CA
|
||||||
|
* Certificate's remaining lifespan matches one of the configured intervals
|
||||||
|
|
||||||
|
All eligible certificates are then grouped by owner and expiration interval. For each interval and certificate group,
|
||||||
|
Lemur will send the CA certificate expiration notification via email to the certificate owner and security team
|
||||||
|
(as specified by the ``LEMUR_SECURITY_TEAM_EMAIL`` configuration parameter).
|
||||||
|
|
||||||
|
**Pending ACME certificate failure**
|
||||||
|
|
||||||
|
Whenever a pending ACME certificate fails to be issued, Lemur will send a notification via email to the certificate owner
|
||||||
|
and security team (as specified by the ``LEMUR_SECURITY_TEAM_EMAIL`` configuration parameter). This email is not sent if
|
||||||
|
the pending certificate had notifications disabled.
|
||||||
|
|
||||||
|
**Email notifications**
|
||||||
|
|
||||||
|
Templates for emails are located under `lemur/plugins/lemur_email/templates` and can be modified for your needs.
|
||||||
|
|
||||||
|
The following configuration options are supported:
|
||||||
|
|
||||||
.. data:: LEMUR_EMAIL_SENDER
|
.. data:: LEMUR_EMAIL_SENDER
|
||||||
:noindex:
|
:noindex:
|
||||||
|
@ -318,7 +397,7 @@ Lemur supports sending certificate expiration notifications through SES and SMTP
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
LEMUR_EMAIL = 'lemur.example.com'
|
LEMUR_EMAIL = 'lemur@example.com'
|
||||||
|
|
||||||
|
|
||||||
.. data:: LEMUR_SECURITY_TEAM_EMAIL
|
.. data:: LEMUR_SECURITY_TEAM_EMAIL
|
||||||
|
@ -333,7 +412,7 @@ Lemur supports sending certificate expiration notifications through SES and SMTP
|
||||||
.. data:: LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS
|
.. data:: LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS
|
||||||
:noindex:
|
:noindex:
|
||||||
|
|
||||||
Lemur notification intervals
|
Lemur notification intervals. If unspecified, the value [30, 15, 2] is used.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|
|
@ -325,7 +325,7 @@ celery tasks or cron jobs that run these commands.
|
||||||
|
|
||||||
There are currently three commands that could/should be run on a periodic basis:
|
There are currently three commands that could/should be run on a periodic basis:
|
||||||
|
|
||||||
- `notify expirations` and `notify authority_expirations`
|
- `notify expirations` and `notify authority_expirations` (see :ref:`NotificationOptions` for configuration info)
|
||||||
- `check_revoked`
|
- `check_revoked`
|
||||||
- `sync`
|
- `sync`
|
||||||
|
|
||||||
|
|
|
@ -40,9 +40,7 @@ def expirations(exclude):
|
||||||
print("Starting to notify subscribers about expiring certificates!")
|
print("Starting to notify subscribers about expiring certificates!")
|
||||||
success, failed = send_expiration_notifications(exclude)
|
success, failed = send_expiration_notifications(exclude)
|
||||||
print(
|
print(
|
||||||
"Finished notifying subscribers about expiring certificates! Sent: {success} Failed: {failed}".format(
|
f"Finished notifying subscribers about expiring certificates! Sent: {success} Failed: {failed}"
|
||||||
success=success, failed=failed
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
status = SUCCESS_METRIC_STATUS
|
status = SUCCESS_METRIC_STATUS
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -66,9 +64,7 @@ def authority_expirations():
|
||||||
success, failed = send_authority_expiration_notifications()
|
success, failed = send_authority_expiration_notifications()
|
||||||
print(
|
print(
|
||||||
"Finished notifying subscribers about expiring certificate authority certificates! "
|
"Finished notifying subscribers about expiring certificate authority certificates! "
|
||||||
"Sent: {success} Failed: {failed}".format(
|
f"Sent: {success} Failed: {failed}"
|
||||||
success=success, failed=failed
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
status = SUCCESS_METRIC_STATUS
|
status = SUCCESS_METRIC_STATUS
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
@ -132,7 +132,7 @@ def get_eligible_authority_certificates():
|
||||||
for owner, owner_certs in groupby(all_certs, lambda x: x.owner):
|
for owner, owner_certs in groupby(all_certs, lambda x: x.owner):
|
||||||
# group by expiration interval
|
# group by expiration interval
|
||||||
for interval, interval_certs in groupby(owner_certs, lambda x: (x.not_after - now).days):
|
for interval, interval_certs in groupby(owner_certs, lambda x: (x.not_after - now).days):
|
||||||
certificates[owner][interval] = list(interval_certs) # list(c for c in interval_certs)
|
certificates[owner][interval] = list(interval_certs)
|
||||||
|
|
||||||
return certificates
|
return certificates
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,9 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#202020;line-height:1.5">
|
<td style="font-family:Roboto-Regular,Helvetica,Arial,sans-serif;font-size:13px;color:#202020;line-height:1.5">
|
||||||
<br>This is a Lemur CA certificate expiration notice. The following CA certificates are expiring soon;
|
<br>This is a Lemur CA certificate expiration notice. The following CA certificates are expiring soon;
|
||||||
please take manual action to renew them if necessary. You may also disable notifications via the
|
please take manual action to renew them if necessary. Note that rotating a root CA requires
|
||||||
|
advanced planing and the respective trustStores need to be updated. A sub-CA, on the other hand,
|
||||||
|
does not require any changes to the trustStore. You may also disable notifications via the
|
||||||
Notify toggle in Lemur if they are no longer in use.
|
Notify toggle in Lemur if they are no longer in use.
|
||||||
<table border="0" cellspacing="0" cellpadding="0"
|
<table border="0" cellspacing="0" cellpadding="0"
|
||||||
style="margin-top:48px;margin-bottom:48px">
|
style="margin-top:48px;margin-bottom:48px">
|
||||||
|
|
|
@ -131,13 +131,13 @@ def test_send_pending_failure_notification(notification_plugin, async_issuer_plu
|
||||||
def test_get_authority_certificates():
|
def test_get_authority_certificates():
|
||||||
from lemur.notifications.messaging import get_expiring_authority_certificates
|
from lemur.notifications.messaging import get_expiring_authority_certificates
|
||||||
|
|
||||||
certificate_1 = create_cert_that_expires_in_days(180)
|
certificate_1 = create_ca_cert_that_expires_in_days(180)
|
||||||
certificate_2 = create_cert_that_expires_in_days(365)
|
certificate_2 = create_ca_cert_that_expires_in_days(365)
|
||||||
create_cert_that_expires_in_days(364)
|
create_ca_cert_that_expires_in_days(364)
|
||||||
create_cert_that_expires_in_days(366)
|
create_ca_cert_that_expires_in_days(366)
|
||||||
create_cert_that_expires_in_days(179)
|
create_ca_cert_that_expires_in_days(179)
|
||||||
create_cert_that_expires_in_days(181)
|
create_ca_cert_that_expires_in_days(181)
|
||||||
create_cert_that_expires_in_days(1)
|
create_ca_cert_that_expires_in_days(1)
|
||||||
|
|
||||||
assert set(get_expiring_authority_certificates()) == {certificate_1, certificate_2}
|
assert set(get_expiring_authority_certificates()) == {certificate_1, certificate_2}
|
||||||
|
|
||||||
|
@ -147,19 +147,19 @@ def test_send_authority_expiration_notifications():
|
||||||
from lemur.notifications.messaging import send_authority_expiration_notifications
|
from lemur.notifications.messaging import send_authority_expiration_notifications
|
||||||
verify_sender_email()
|
verify_sender_email()
|
||||||
|
|
||||||
create_cert_that_expires_in_days(180)
|
create_ca_cert_that_expires_in_days(180)
|
||||||
create_cert_that_expires_in_days(180) # two on the same day results in a single email
|
create_ca_cert_that_expires_in_days(180) # two on the same day results in a single email
|
||||||
create_cert_that_expires_in_days(365)
|
create_ca_cert_that_expires_in_days(365)
|
||||||
create_cert_that_expires_in_days(364)
|
create_ca_cert_that_expires_in_days(364)
|
||||||
create_cert_that_expires_in_days(366)
|
create_ca_cert_that_expires_in_days(366)
|
||||||
create_cert_that_expires_in_days(179)
|
create_ca_cert_that_expires_in_days(179)
|
||||||
create_cert_that_expires_in_days(181)
|
create_ca_cert_that_expires_in_days(181)
|
||||||
create_cert_that_expires_in_days(1)
|
create_ca_cert_that_expires_in_days(1)
|
||||||
|
|
||||||
assert send_authority_expiration_notifications() == (2, 0)
|
assert send_authority_expiration_notifications() == (2, 0)
|
||||||
|
|
||||||
|
|
||||||
def create_cert_that_expires_in_days(days):
|
def create_ca_cert_that_expires_in_days(days):
|
||||||
now = arrow.utcnow()
|
now = arrow.utcnow()
|
||||||
not_after = now + timedelta(days=days, hours=1) # a bit more than specified since we'll check in the future
|
not_after = now + timedelta(days=days, hours=1) # a bit more than specified since we'll check in the future
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue