summaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-14 13:31:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-14 13:31:28 +0000
commit067008c5f094ba9606daacbe540f6b929dc124ea (patch)
tree3092ce2cd8bf1ac6db6c97f4c98c7f71a51c6ac8 /doc
parentInitial commit. (diff)
downloadicingaweb2-module-x509-upstream.tar.xz
icingaweb2-module-x509-upstream.zip
Adding upstream version 1:1.3.2.upstream/1%1.3.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc')
-rw-r--r--doc/01-About.md22
-rw-r--r--doc/02-Installation.md73
-rw-r--r--doc/02-Installation.md.d/From-Source.md16
-rw-r--r--doc/03-Configuration.md77
-rw-r--r--doc/04-Scanning.md85
-rw-r--r--doc/10-Monitoring.md212
-rw-r--r--doc/11-Housekeeping.md38
-rw-r--r--doc/80-Upgrading.md91
-rw-r--r--doc/res/check-host-perf-data.pngbin0 -> 7466 bytes
-rw-r--r--doc/res/host-check-multiple-services.pngbin0 -> 49022 bytes
-rw-r--r--doc/res/host-check-single-service.pngbin0 -> 32771 bytes
-rw-r--r--doc/res/host-template-fields.pngbin0 -> 15012 bytes
-rw-r--r--doc/res/hosts-import-result.pngbin0 -> 7182 bytes
-rw-r--r--doc/res/hosts-import-source.pngbin0 -> 8344 bytes
-rw-r--r--doc/res/multiple-services-result.pngbin0 -> 13992 bytes
-rw-r--r--doc/res/new-host-template.pngbin0 -> 11630 bytes
-rw-r--r--doc/res/new-service-template.pngbin0 -> 14294 bytes
-rw-r--r--doc/res/ports-property-modifier.pngbin0 -> 12071 bytes
-rw-r--r--doc/res/service-template-fields.pngbin0 -> 27772 bytes
-rw-r--r--doc/res/single-service-result.pngbin0 -> 82322 bytes
-rw-r--r--doc/res/sync-rule-properties.pngbin0 -> 19091 bytes
-rw-r--r--doc/res/weekly-schedules.pngbin0 -> 140091 bytes
-rw-r--r--doc/res/x509-certificates.pngbin0 -> 475307 bytes
-rw-r--r--doc/res/x509-dashboard.pngbin0 -> 208525 bytes
-rw-r--r--doc/res/x509-usage.pngbin0 -> 286297 bytes
25 files changed, 614 insertions, 0 deletions
diff --git a/doc/01-About.md b/doc/01-About.md
new file mode 100644
index 0000000..38fa06a
--- /dev/null
+++ b/doc/01-About.md
@@ -0,0 +1,22 @@
+# Icinga Certificate Monitoring
+
+The certificate monitoring module for Icinga keeps track of certificates as they are deployed in a network environment.
+It does this by scanning networks for TLS services and collects whatever certificates it finds along the way.
+The certificates are verified using its own trust store.
+
+The module’s web frontend can be used to view scan results, allowing you to drill down into detailed information
+about any discovered certificate of your landscape:
+
+![X.509 Usage](res/x509-usage.png "X.509 Usage")
+
+![X.509 Certificates](res/x509-certificates.png "X.509 Certificates")
+
+At a glance you see which CAs have issued your certificates and key counters of your environment:
+
+![X.509 Dashboard](res/x509-dashboard.png "X.509 Dashboard")
+
+## Documentation
+
+* [Installation](02-Installation.md)
+* [Configuration](03-Configuration.md)
+* [Monitoring](10-Monitoring.md)
diff --git a/doc/02-Installation.md b/doc/02-Installation.md
new file mode 100644
index 0000000..af2eaf3
--- /dev/null
+++ b/doc/02-Installation.md
@@ -0,0 +1,73 @@
+<!-- {% if index %} -->
+# Installing Icinga Certificate Monitoring
+
+The recommended way to install Icinga Certificate Monitoring
+and its dependencies is to use prebuilt packages for
+all supported platforms from our official release repository.
+Please note that [Icinga Web](https://icinga.com/docs/icinga-web) is required
+and if it is not already set up, it is best to do this first.
+
+The following steps will guide you through installing and setting up Icinga Certificate Monitoring.
+<!-- {% else %} -->
+<!-- {% if not icingaDocs %} -->
+
+## Installing the Package
+
+If the [repository](https://packages.icinga.com) is not configured yet, please add it first.
+Then use your distribution's package manager to install the `icinga-x509` package
+or install [from source](02-Installation.md.d/From-Source.md).
+<!-- {% endif %} -->
+
+## Setting up the Database
+
+### Setting up a MySQL or MariaDB Database
+
+The module needs a MySQL/MariaDB database with the schema that's provided in the `/usr/share/icingaweb2/modules/x509/schema/mysql.schema.sql` file.
+<!-- {% if not icingaDocs %} -->
+
+**Note:** If you haven't installed this module from packages, then please adapt the schema path to the correct installation path.
+
+<!-- {% endif %} -->
+
+You can use the following sample command for creating the MySQL/MariaDB database. Please change the password:
+
+```
+CREATE DATABASE x509;
+GRANT CREATE, SELECT, INSERT, UPDATE, DELETE, DROP, ALTER, CREATE VIEW, INDEX, EXECUTE ON x509.* TO x509@localhost IDENTIFIED BY 'secret';
+```
+
+After, you can import the schema using the following command:
+
+```
+mysql -p -u root x509 < /usr/share/icingaweb2/modules/x509/schema/mysql.schema.sql
+```
+
+### Setting up a PostgreSQL Database
+
+The module needs a PostgreSQL database with the schema that's provided in the `/usr/share/icingaweb2/modules/x509/schema/pgsql.schema.sql` file.
+<!-- {% if not icingaDocs %} -->
+
+**Note:** If you haven't installed this module from packages, then please adapt the schema path to the correct installation path.
+
+<!-- {% endif %} -->
+
+You can use the following sample command for creating the PostgreSQL database. Please change the password:
+
+```sql
+CREATE USER x509 WITH PASSWORD 'secret';
+CREATE DATABASE x509
+ WITH OWNER x509
+ ENCODING 'UTF8'
+ LC_COLLATE = 'en_US.UTF-8'
+ LC_CTYPE = 'en_US.UTF-8';
+```
+
+After, you can import the schema using the following command:
+
+```
+psql -U x509 x509 -a -f /usr/share/icingaweb2/modules/x509/schema/pgsql.schema.sql
+```
+
+This concludes the installation. You should now be able to import CA certificates and set up scan jobs.
+Please read the [Configuration](03-Configuration.md) section for details.
+<!-- {% endif %} --><!-- {# end else if index #} -->
diff --git a/doc/02-Installation.md.d/From-Source.md b/doc/02-Installation.md.d/From-Source.md
new file mode 100644
index 0000000..31f3d2b
--- /dev/null
+++ b/doc/02-Installation.md.d/From-Source.md
@@ -0,0 +1,16 @@
+# Installing Icinga Certificate Monitoring from Source
+
+Please see the Icinga Web documentation on
+[how to install modules](https://icinga.com/docs/icinga-web-2/latest/doc/08-Modules/#installation) from source.
+Make sure you use `x509` as the module name. The following requirements must also be met.
+
+## Requirements
+
+* PHP (≥7.2)
+* MySQL or PostgreSQL PDO PHP libraries
+* The following PHP modules must be installed: `gmp`, `pcntl`, `openssl`
+* [Icinga Web](https://github.com/Icinga/icingaweb2) (≥2.9)
+* [Icinga PHP Library (ipl)](https://github.com/Icinga/icinga-php-library) (≥0.13.0)
+* [Icinga PHP Thirdparty](https://github.com/Icinga/icinga-php-thirdparty) (≥0.12.0)
+
+<!-- {% include "02-Installation.md" %} -->
diff --git a/doc/03-Configuration.md b/doc/03-Configuration.md
new file mode 100644
index 0000000..4ecde77
--- /dev/null
+++ b/doc/03-Configuration.md
@@ -0,0 +1,77 @@
+# <a id="Configuration"></a>Configuration
+
+## Importing CA certificates
+
+The module tries to verify certificates using its own trust store. By default, this trust store is empty, and it
+is up to the Icinga Web 2 admin to import CA certificates into it.
+
+Using the `icingacli x509 import` command CA certificates can be imported. The certificate chain file that is specified
+with the `--file` option should contain a PEM-encoded list of X.509 certificates which should be added to the trust
+store:
+
+```
+icingacli x509 import --file /etc/ssl/certs/ca-certificates.crt
+```
+
+## Configure Jobs
+
+Scan jobs have a name which uniquely identifies them, e.g. `lan`. These names are used by the CLI command to start
+scanning for specific jobs.
+
+Each scan job can have one or more IP address ranges and one or more port ranges. The module scans each port in
+a job's port ranges for all the individual IP addresses in the IP ranges. IP address ranges have to be specified using
+the CIDR format. Multiple IP address ranges can be separated with commas, e.g.:
+
+`192.0.2.0/24,10.0.10.0/24`
+
+Port ranges are separated with dashes (`-`). If you only want to scan a single port you don't need to specify the second
+port:
+
+`443,5665-5669`
+
+Additionally, each job may also exclude specific **hosts** and **IP** addresses from scan. These hosts won't be scanned
+when you run the [scan](04-Scanning.md#scan-command) or [jobs](04-Scanning.md#scheduling-jobs) command. Excluding an entire network and specifying IP addresses in CIDR
+format will not work. You must specify concrete **IP**s and **host CN**s separated with commas, e.g:
+
+`192.0.2.2,192.0.2.5,icinga.com`
+
+### Job Schedules
+
+Schedules are [`cron`](https://crontab.guru) and rule based configs used to run jobs periodically at the given interval.
+Every job is allowed to have multiple schedules that can be run independently of each other. Each job schedule provides
+different options that you can use to control the scheduling behavior of the [jobs command](04-Scanning.md#scheduling-jobs).
+
+#### Examples
+
+A schedule that runs weekly on **Friday** and scans all targets that have not yet been scanned, or
+whose last scan is older than `1 week`.
+
+![Weekly Schedules](res/weekly-schedules.png "Weekly Schedules")
+
+## Server Name Indication
+
+In case you are serving multiple virtual hosts under a single IP you can configure those in
+`Configuration -> Modules -> x509 -> SNI`.
+
+Each entry defines an IP with multiple hostnames associated with it. These are then utilized when jobs run.
+
+Modules may also provide sources for SNI. At this time the module monitoring is the only one with known support.
+
+## Icinga Certificate Monitoring Daemon
+
+The default `systemd` service of this module, shipped with package installations, uses the [jobs command](04-Scanning.md#scheduling-jobs)
+and runs all your configured jobs and schedules.
+
+<!-- {% if not icingaDocs %} -->
+
+> **Note**
+>
+> If you haven't installed this module from packages, you have to configure this as a `systemd` service yourself by just
+> copying the example service definition from `/usr/share/icingaweb2/modules/x509/config/systemd/icinga-x509.service`
+> to `/etc/systemd/system/icinga-x509.service`.
+<!-- {% endif %} -->
+
+You can run the following command to enable and start the daemon.
+```
+systemctl enable --now icinga-x509.service
+```
diff --git a/doc/04-Scanning.md b/doc/04-Scanning.md
new file mode 100644
index 0000000..608d18a
--- /dev/null
+++ b/doc/04-Scanning.md
@@ -0,0 +1,85 @@
+# <a id="Scanning"></a>Scanning
+
+The Icinga Certificate Monitoring provides CLI commands to scan **hosts** and **IPs** in various ways.
+These commands are listed below and can be used individually. It is necessary for all commands to know which IP address
+ranges and ports to scan. These can be configured as described [here](03-Configuration.md#configure-jobs).
+
+## Scan Command
+
+The scan command, scans targets to find their X.509 certificates and track changes to them.
+A **target** is an **IP-port** combination that is generated from the job configuration, taking into account configured
+[**SNI**](03-Configuration.md#server-name-indication) maps, so that targets with multiple certificates are also properly
+scanned.
+
+By default, successive calls to the scan command perform partial scans, checking both targets not yet scanned and
+targets whose scan is older than 24 hours, to ensure that all targets are rescanned over time and new certificates
+are collected. This behavior can be customized through the command [options](#usage-1).
+
+> **Note**
+>
+> When rescanning due targets, they will be rescanned regardless of whether the target previously provided a certificate
+> or not, to collect new certificates, track changed certificates, and remove decommissioned certificates.
+
+### Usage
+
+This scan command can be used like any other Icinga Web cli operations like this: `icingacli x509 scan [OPTIONS]`
+
+**Options:**
+
+```
+--job=<name> Scan targets that belong to the specified job. (Required)
+--since-last-scan=<time> Scan targets whose last scan is older than the spcified date/time, which can also be an
+ English textual datetime description like "2 days". Defaults to "-24 hours".
+--rescan Rescn only targets that have been scanned before.
+--full (Re)scan all known and unknown targets. This will override the "rescan" and "since-last-scan" options.
+--parallel=<number> Allow parallel scanning of targets up to the specified number. Defaults to 256.
+ May cause **too many open files** error if set to a number higher than the configured one (ulimit).
+```
+
+#### Example
+
+Scan all targets that have not yet been scanned, or whose last scan is older than a certain date/time:
+```
+# icingacli x509 scan --job <name> --since-last-scan '3 days'
+```
+
+Scan only **unknown** targets:
+```
+# icingacli x509 scan --job <name> --since-last-scan=null
+```
+
+Scan only known targets:
+```
+# icingacli x509 scan --job <name> --rescan
+```
+
+Scan only known targets whose last scan is older than certain a given date/time:
+```
+# icingacli x509 scan --job <name> --rescan --since-last-scan '5 days'
+```
+
+Scan all known and unknown targets:
+```
+# icingacli x509 scan --job <name> --full
+```
+
+## Scheduling Jobs
+
+The jobs command is similar to the [scan command](#scan-command), but it additionally allows you to schedule your jobs
+in a more convenient way. This is used by the default `systemd` service of this module as well. By default, this command
+will run all your configured jobs based on their frequency. This behaviour can be customized through the command options
+too. Since you can have multiple schedules for a single job, all job schedules can also be scheduled individually.
+
+### Usage
+
+This scan command can be used like any other Icinga Web cli operations like this: `icingacli x509 jobs run [OPTIONS`
+
+**Options:**
+
+```
+--job=<name> Run all configured schedules only of the specified job.
+--schedule=<name> Run only the given schedule of the specified job.
+ Providing a schedule name without a job will fail immediately.
+--parallel=<number> Allow parallel scanning of targets up to the specified number. Defaults to 256.
+ May cause **too many open files** error if set to a number higher than the configured one (ulimit).
+```
diff --git a/doc/10-Monitoring.md b/doc/10-Monitoring.md
new file mode 100644
index 0000000..d729bb9
--- /dev/null
+++ b/doc/10-Monitoring.md
@@ -0,0 +1,212 @@
+# <a id="Monitoring"></a>Monitoring
+
+## Host Check Command
+
+The module provides a CLI command to check a host's certificate. It does so by
+fetching all the necessary information from this module's own database.
+
+### Usage
+
+General: `icingacli x509 check host [options]`
+
+Options:
+
+```
+--ip A hosts IP address
+--host A hosts name
+--port The port to check in particular
+--warning Less remaining time results in state WARNING [25%]
+--critical Less remaining time results in state CRITICAL [10%]
+--allow-self-signed Ignore if a certificate or its issuer has been self-signed
+```
+
+### Threshold Definition
+
+Thresholds can either be defined relative (in percent) or absolute (time interval).
+Time intervals consist of a digit and an accompanying unit (e.g. "3M" are three
+months). Supported units are:
+
+ Identifier | Description
+------------|------------
+y, Y | Year
+M | Month
+d, D | Day
+h, H | Hour
+m | Minute
+s, S | Second
+
+**Example:**
+
+```
+$ icingacli x509 check host --host example.org --warning 1y
+WARNING - *.example.org expires in 219 days|'*.example.org'=18985010s;25574400;10281600;0;102470399
+```
+
+### Performance Data
+
+The command outputs a performance data value for each certificate that is
+served by the host. The value measured is the amount of seconds remaining
+until the certificate expires.
+
+![check host perf data](res/check-host-perf-data.png)
+
+The value of `max` is the total amount of seconds the certificate is valid.
+`warning` and `critical` are the seconds remaining after which the respective
+state is reported.
+
+## Icinga 2 Integration
+
+First off, this chapter relies on the fact that you're using the Director
+already and that you're familiar with some of the terms and functionalities
+used there.
+
+If you don't want to use the Director, know that Icinga 2 already provides
+an appropriate template for the host check command in its template library:
+https://icinga.com/docs/icinga2/latest/doc/10-icinga-template-library/#x509
+
+### Director Import Sources
+
+The module provides two different import sources:
+
+#### Hosts (X509)
+
+Focuses on the hosts the module found when scanning the networks. Use this
+for the most straightforward way of integrating the results into your
+environment. It's also the utilized source in the example further below.
+
+Columns provided by this source:
+
+Name | Description
+----------------|--------------------------------------------------------------
+host_name_or_ip | Default key column. This is primarily `host_name`, though if this is not unique it falls back to `host_ip` for individual results
+host_ip | A host's IP address by which it is known to this module. May be IPv4 or IPv6
+host_name | A host's name as detected by SNI or a reverse DNS lookup during the scan process
+host_ports | Separated by comma. All ports where certificates were found
+host_address | Set to `host_ip` if it is IPv4 else `null`
+host_address6 | Set to `host_ip` if it is IPv6 else `null`
+
+#### Services (X509)
+
+While the hosts import source does not provide any details about the found
+certificates this one does. This also means that this source may generate
+multiple results for a single host since it focuses on the found certificates.
+
+Use this source if you want to import service objects directly and relate them
+to already existing hosts by their utilized certificates. The Director's many
+utilities provided in this regard will again come in handy here.
+
+Columns provided by this source:
+
+Name | Description
+----------------------|--------------------------------------------------------
+host_name_ip_and_port | Default key column. This is a combination of `host_name`, `host_ip` and `host_port` in the format `name/ip:port`
+host_ip | A host's IP address by which it is known to this module. May be IPv4 or IPv6
+host_name | A host's name as detected by SNI or a reverse DNS lookup during the scan process
+host_port | A host's port where a certificate has been found
+host_address | Set to `host_ip` if it is IPv4 else `null`
+host_address6 | Set to `host_ip` if it is IPv6 else `null`
+cert_subject | A certificate's common name
+cert_issuer | The issuer's common name
+cert_self_signed | Whether the certificate is self-signed (`y` or `n`)
+cert_trusted | Whether the certificate is trusted (`y` or `n`)
+cert_valid_from | The certificate's start time of validity (UNIX timestamp)
+cert_valid_to | The certificate's end time of validity (UNIX timestamp)
+cert_fingerprint | The certificate's fingerprint (hex-encoded)
+cert_dn | The certificate's distinguished name
+cert_subject_alt_name | The certificate's alternative subject names (Comma separated pairs of `type:name`)
+
+### Service Checks With the Hosts Import Source
+
+This example covers the setup of service checks by using a particular host
+template and suggests then two options utilizing service apply rules.
+
+#### Preparations
+
+Assuming the check command definition `icingacli-x509` has already been imported
+you need to define a few data fields now:
+
+Field name | Data type
+---------------------------------|----------
+certified_ports | Array
+icingacli_x509_ip | String
+icingacli_x509_host | String
+icingacli_x509_port | String
+icingacli_x509_warning | String
+icingacli_x509_critical | String
+icingacli_x509_allow_self_signed | Boolean
+
+Then please create a new host template with a name of your choosing. We've chosen
+`x509-host`. We're also importing our base template `base-host` here which defines
+all the default properties of our hosts.
+
+![new host template](res/new-host-template.png)
+
+This host template also requires three data fields which are shown below.
+
+![host template fields](res/host-template-fields.png)
+
+A service template is also needed. We chose the name `x509-host-check` and
+`icingacli-x509` as check command.
+
+![new service template](res/new-service-template.png)
+
+The service template now requires all data fields which correspond to the
+check command's parameters.
+
+![service template fields](res/service-template-fields.png)
+
+#### Import Source Setup
+
+Create a new import source of type `Hosts (X509)`.
+![hosts import source](res/hosts-import-source.png)
+
+Configure a property modifier for column `host_ports` of type `Split` and use
+the comma `,` as delimiter.
+![ports property modifier](res/ports-property-modifier.png)
+
+The preview should now produce a similar result to this:
+![hosts import result](res/hosts-import-result.png)
+
+#### Sync Rule Setup
+
+Create a new sync rule for objects of type `Host`. Depending on your environment
+you may choose either `Merge` or `Replace` as update policy. Choose `Merge` to
+continue with this example.
+
+Which properties this rule defines is also very dependent on what you want to
+achieve. We now assume that you already have host objects whose object names
+match exactly those the import source provides. (Hence you should choose
+`Merge` as update policy)
+
+![sync rule properties](res/sync-rule-properties.png)
+
+#### Service Check Setup
+
+There are two choices now. The first checks a host's certificates as a single
+service. The second creates for each individual certificate (port) a service.
+
+##### Single Service
+
+This is done by defining a new service as part of the host template created
+earlier. There add a service and choose the service template also created
+previously.
+
+![host check single service](res/host-check-single-service.png)
+
+Once you've triggered the import and synchronisation as well as deployed
+the resulting changes you should see this in Icinga Web 2:
+
+![single service result](res/single-service-result.png)
+
+##### Multiple Services
+
+This utilizes a service apply rule. Trigger the import and synchronisation
+first, otherwise you can't choose a custom variable for the *apply for* rule.
+
+Once the synchronisation is finished, set up the service apply rule like this:
+
+![host check multiple services](res/host-check-multiple-services.png)
+
+After deploying the resulting changes you should see this in Icinga Web 2:
+
+![multiple services result](res/multiple-services-result.png)
diff --git a/doc/11-Housekeeping.md b/doc/11-Housekeeping.md
new file mode 100644
index 0000000..174a9ef
--- /dev/null
+++ b/doc/11-Housekeeping.md
@@ -0,0 +1,38 @@
+# <a id="Datbase Housekeeping"></a>Database Housekeeping
+
+Your database may grow over time and contain some outdated information. Icinga Certificate Monitoring provides you
+the ability to clean up these outdated info in an easy way.
+
+## Certificates and Targets
+
+The default `cleanup` action removes targets whose last scan is older than a certain date/time and certificates that
+are no longer used.
+
+By default, any targets whose last scan is older than `1 month` are removed. The last scan information is always updated
+when scanning a target, regardless of whether a successful connection is made or not. Therefore, targets that have been
+decommissioned or are no longer part of a job configuration are removed after the specified period. Any certificates
+that are no longer used are also removed. This can either be because the associated target has been removed or because
+it is presenting a new certificate chain.
+
+The `cleanup` command will also remove additionally all jobs activities created before the given date/time.
+Jobs activities are usually just some stats about the job runs performed by the scheduler or/and manually
+executed using the [scan](04-Scanning.md#scan-command) and/or [jobs](04-Scanning.md#scheduling-jobs) command.
+
+### Usage
+
+This command can be used like any other Icinga Web cli operations like this: `icingacli x509 cleanup [OPTIONS]`
+
+**Options:**
+
+```
+--since-last-scan=<datetime> Clean up targets whose last scan is older than the specified date/time,
+ which can also be an English textual datetime description like "2 days".
+ Defaults to "1 month".
+```
+
+#### Example
+
+Remove any targets that have not been scanned for at least two months and any certificates that are no longer used.
+```
+icingacli x509 cleanup --since-last-scan="2 months"
+```
diff --git a/doc/80-Upgrading.md b/doc/80-Upgrading.md
new file mode 100644
index 0000000..a66ddc4
--- /dev/null
+++ b/doc/80-Upgrading.md
@@ -0,0 +1,91 @@
+# Upgrading Icinga Certificate Monitoring
+
+Upgrading Icinga Certificate Monitoring is straightforward.
+Usually the only manual steps involved are schema updates for the database.
+
+## Upgrading to version 1.3.0
+
+Icinga Certificate Monitoring version `1.3.0` requires a schema update for the database. We have dropped the use of **INI**
+files to store jobs and are using the database instead. So you need to migrate your job configs to the database.
+
+If you're already using Icinga Web 2 version `>= 2.12`, then you don't need to import the sql upgrade scripts manually.
+Icinga Web provides you the ability to perform such migrations in a simple way. You may be familiar with such an automation
+if you're an Icinga Director user.
+
+> **Note**
+>
+> Please note that it doesn't matter if you import the database upgrade script manually or via the new automation,
+> you will have to migrate your [Jobs config](#migrate-jobs) from INI to the database manually afterwards.
+
+Before migrating your jobs from **INI** to the database, you need to first apply the migration script. This will create
+the tables needed to store the jobs and schedules in the database.
+
+You may use the following command to apply the database schema upgrade file:
+<!-- {% if not icingaDocs %} -->
+
+**Note:** If you haven't installed this module from packages, then please adapt the schema path to the correct installation path.
+
+<!-- {% endif %} -->
+```sql
+# mysql -u root -p x509 < /usr/share/icingaweb2/modules/x509/schema/mysql-upgrades/1.3.0.sql
+```
+
+### Migrate Jobs
+
+Afterwards, you can safely migrate your jobs with the following command. Keep in mind that you need to specify an
+Icinga Web username that will be used as the author of these jobs in the database.
+
+```
+# icingacli x509 migrate jobs --author "icingaadmin"
+```
+
+## Upgrading to version 1.2.0
+
+Icinga Certificate Monitoring version 1.2.0 requires a schema update for the database. We have changed all `timestamp`
+columns in the database to biguint to store all timestamps in milliseconds. The sort column `expires` has been dropped
+as well, but you can sort the certificates by `valid_to` instead.
+
+You may use the following command to apply the database schema upgrade file:
+<!-- {% if not icingaDocs %} -->
+
+**Note:** If you haven't installed this module from packages, then please adapt the schema path to the correct installation path.
+
+<!-- {% endif %} -->
+```sql
+# mysql -u root -p x509 < /usr/share/icingaweb2/modules/x509/schema/mysql-upgrades/1.2.0.sql
+```
+
+## Upgrading to version 1.1.0
+
+Icinga Certificate Monitoring version 1.1.0 fixes issues that affect the database schema.
+To have these issues really fixed in your environment, the schema must be upgraded.
+Please find the upgrade script in **/usr/share/icingaweb2/modules/x509/schema/mysql-upgrades**.
+
+You may use the following command to apply the database schema upgrade file:
+<!-- {% if not icingaDocs %} -->
+
+**Note:** If you haven't installed this module from packages, then please adapt the schema path to the correct installation path.
+
+<!-- {% endif %} -->
+
+```
+# mysql -u root -p x509 < /usr/share/icingaweb2/modules/x509/schema/mysql-upgrades/1.1.0.sql
+```
+
+## Upgrading to version 1.0.0
+
+Icinga Certificate Monitoring version 1.0.0 requires a schema update for the database.
+The schema has been adjusted so that it is no longer necessary to adjust server settings
+if you're using a version of MySQL < 5.7 or MariaDB < 10.2.
+Please find the upgrade script in **/user/share/icingaweb2/modules/x509/schema/mysql-upgrades**.
+
+You may use the following command to apply the database schema upgrade file:
+<!-- {% if not icingaDocs %} -->
+
+**Note:** If you haven't installed this module from packages, then please adapt the schema path to the correct installation path.
+
+<!-- {% endif %} -->
+
+```
+# mysql -u root -p x509 < /usr/share/icingaweb2/modules/x509/schema/mysql-upgrades/1.0.0.sql
+```
diff --git a/doc/res/check-host-perf-data.png b/doc/res/check-host-perf-data.png
new file mode 100644
index 0000000..958a226
--- /dev/null
+++ b/doc/res/check-host-perf-data.png
Binary files differ
diff --git a/doc/res/host-check-multiple-services.png b/doc/res/host-check-multiple-services.png
new file mode 100644
index 0000000..a153e2e
--- /dev/null
+++ b/doc/res/host-check-multiple-services.png
Binary files differ
diff --git a/doc/res/host-check-single-service.png b/doc/res/host-check-single-service.png
new file mode 100644
index 0000000..1f4bdec
--- /dev/null
+++ b/doc/res/host-check-single-service.png
Binary files differ
diff --git a/doc/res/host-template-fields.png b/doc/res/host-template-fields.png
new file mode 100644
index 0000000..a6aa438
--- /dev/null
+++ b/doc/res/host-template-fields.png
Binary files differ
diff --git a/doc/res/hosts-import-result.png b/doc/res/hosts-import-result.png
new file mode 100644
index 0000000..c19b1f2
--- /dev/null
+++ b/doc/res/hosts-import-result.png
Binary files differ
diff --git a/doc/res/hosts-import-source.png b/doc/res/hosts-import-source.png
new file mode 100644
index 0000000..fe525c7
--- /dev/null
+++ b/doc/res/hosts-import-source.png
Binary files differ
diff --git a/doc/res/multiple-services-result.png b/doc/res/multiple-services-result.png
new file mode 100644
index 0000000..8bec4b9
--- /dev/null
+++ b/doc/res/multiple-services-result.png
Binary files differ
diff --git a/doc/res/new-host-template.png b/doc/res/new-host-template.png
new file mode 100644
index 0000000..2ff9074
--- /dev/null
+++ b/doc/res/new-host-template.png
Binary files differ
diff --git a/doc/res/new-service-template.png b/doc/res/new-service-template.png
new file mode 100644
index 0000000..fec3d22
--- /dev/null
+++ b/doc/res/new-service-template.png
Binary files differ
diff --git a/doc/res/ports-property-modifier.png b/doc/res/ports-property-modifier.png
new file mode 100644
index 0000000..7bb3ecc
--- /dev/null
+++ b/doc/res/ports-property-modifier.png
Binary files differ
diff --git a/doc/res/service-template-fields.png b/doc/res/service-template-fields.png
new file mode 100644
index 0000000..17c1cbd
--- /dev/null
+++ b/doc/res/service-template-fields.png
Binary files differ
diff --git a/doc/res/single-service-result.png b/doc/res/single-service-result.png
new file mode 100644
index 0000000..418f495
--- /dev/null
+++ b/doc/res/single-service-result.png
Binary files differ
diff --git a/doc/res/sync-rule-properties.png b/doc/res/sync-rule-properties.png
new file mode 100644
index 0000000..1b54553
--- /dev/null
+++ b/doc/res/sync-rule-properties.png
Binary files differ
diff --git a/doc/res/weekly-schedules.png b/doc/res/weekly-schedules.png
new file mode 100644
index 0000000..a7b9508
--- /dev/null
+++ b/doc/res/weekly-schedules.png
Binary files differ
diff --git a/doc/res/x509-certificates.png b/doc/res/x509-certificates.png
new file mode 100644
index 0000000..2a67029
--- /dev/null
+++ b/doc/res/x509-certificates.png
Binary files differ
diff --git a/doc/res/x509-dashboard.png b/doc/res/x509-dashboard.png
new file mode 100644
index 0000000..4d5eaf1
--- /dev/null
+++ b/doc/res/x509-dashboard.png
Binary files differ
diff --git a/doc/res/x509-usage.png b/doc/res/x509-usage.png
new file mode 100644
index 0000000..cb80267
--- /dev/null
+++ b/doc/res/x509-usage.png
Binary files differ