Skip to content

Commit bb176c9

Browse files
Sync docs from Discourse (#610)
Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 5cd10e4 commit bb176c9

File tree

5 files changed

+216
-68
lines changed

5 files changed

+216
-68
lines changed

docs/explanation/e-audit-logs.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Audit Logs
22

3-
The Audit Log plugin allows all login/logout records to be stored in a log file. It is enabled in Charmed MySQL by default.
3+
The Audit Log plugin allows fine grained configuration for all login/logout, queries or both records to be stored in a log file. It is enabled in Charmed MySQL by default.
44

55
## Overview
6-
The following is a sample of the audit logs, with format json with login/logout records:
6+
The following is a sample of the audit logs, with format json with only logins records (default configuration):
77

88
```json
99
{"audit_record":{"name":"Quit","record":"6_2024-09-03T01:53:14","timestamp":"2024-09-03T01:53:33Z","connection_id":"992","status":0,"user":"clusteradmin","priv_user":"clusteradmin","os_login":"","proxy_user":"","host":"localhost","ip":"","db":""}}
@@ -24,6 +24,13 @@ It's recommended to integrate the charm with [COS](/t/9900), from where the logs
2424
```
2525
Valid value are `false` and `true`. By setting it to false, existing logs are still kept in the `archive_audit` directory.
2626

27+
1. `logs_audit_policy` - Audit log policy:
28+
29+
```bash
30+
juju config mysql logs_audit_policy=queries
31+
```
32+
Valid values are: "all", "logins" (default), "queries"
33+
2734
1. `plugin-audit-strategy` - By default the audit plugin writes logs in asynchronous mode for better performance.
2835
To ensure logs are written to disk on more timely fashion, this configuration can be set to semi-synchronous mode:
2936

docs/explanation/e-cryptography.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Cryptography
2+
3+
This document describes the cryptography used by Charmed MySQL.
4+
5+
## Resource checksums
6+
7+
Charmed MySQL and Charmed MySQL Router operators use pinned revisions of the [Charmed MySQL snap](https://github.com/canonical/charmed-mysql-snap) to provide reproducible and secure environments.
8+
9+
The Charmed MySQL snap packages the MySQL workload along with the necessary dependencies and utilities required for the operators’ lifecycle. For more details, see the snap contents in the [snapcraft.yaml file](https://github.com/canonical/charmed-mysql-snap/blob/8.0/edge/snap/snapcraft.yaml).
10+
11+
Every artifact bundled into the Charmed MySQL snap is verified against its MD5, SHA256, or SHA512 checksum after download. The installation of certified snap into the rock is ensured by snap primitives that verify their squashfs filesystems images GPG signature. For more information on the snap verification process, refer to the [snapcraft.io documentation](https://snapcraft.io/docs/assertions).
12+
13+
## Sources verification
14+
15+
MySQL and its extra components (mysql-shell, xtrabackup, mysqld-exporter, mysqlrouter-exporter, percona-server-plugins, mysql-pitr-helper, etc.) are built by Canonical from upstream source codes into PPAs and stored on [Launchpad](https://launchpad.net/mysql).
16+
17+
Charmed MySQL snap is published using a GitHub repository workflow.
18+
19+
All repositories in GitHub are set up with branch protection rules, requiring:
20+
21+
* new commits to be merged to main branches via pull request with at least 2 approvals from repository maintainers
22+
* new commits to be signed (e.g. using GPG keys)
23+
* developers to sign the [Canonical Contributor License Agreement (CLA)](https://ubuntu.com/legal/contributors)
24+
25+
## Encryption
26+
27+
Charmed MySQL can be used to deploy a secure MySQL cluster that provides encryption-in-transit capabilities out of the box for:
28+
29+
* Cluster communications
30+
* MySQL Router connection
31+
* External client connection
32+
33+
To set up a secure connection Charmed MySQL and Charmed MySQL Router need to be integrated with TLS Certificate Provider charms, e.g. `self-signed-certificates` operator. Certificate Singing Requests (CSRs) are generated for every unit using the `tls_certificates_interface` library that uses the `cryptography` Python library to create X.509 compatible certificates. The CSR is signed by the TLS Certificate Provider, returned to the units, and stored in Juju secret. The relation also provides the CA certificate, which is loaded into Juju secret.
34+
35+
Encryption at rest is currently not supported, although it can be provided by the substrate (cloud or on-premises).
36+
37+
## Authentication
38+
39+
In Charmed MySQL, authentication layers can be enabled for:
40+
41+
1. MySQL Router connections
42+
2. MySQL cluster communication
43+
3. MySQL clients connections
44+
45+
### MySQL Router authentication to MySQL
46+
47+
Authentication to MySQL Router is based on the [caching_sha2_password auth plugin](https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html).
48+
49+
Credentials are exchanged via [Juju secrets](https://canonical-juju.readthedocs-hosted.com/en/latest/user/howto/manage-secrets/).
50+
51+
### MySQL cluster authentication
52+
53+
Authentication among members of a MySQL cluster is based on the [caching_sha2_password auth plugin](https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html).
54+
55+
An internal user is used for this authentication with its hashed password stored in a system metadata database.
56+
57+
### Client authentication to MySQL
58+
59+
Authentication to MySQL Router is based on the [caching_sha2_password auth plugin](https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html).
60+
61+
Credentials are exchanged via [Juju secrets](https://canonical-juju.readthedocs-hosted.com/en/latest/user/howto/manage-secrets/).

docs/explanation/e-logs.md

Lines changed: 55 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,59 @@
11
# Logs
22

3-
This explanation goes over the types of logging in MySQL and the configuration parameters for log rotation.
4-
5-
The charm currently has audit, error and general logs enabled by default, while slow query logs are disabled by default. All of these files are rotated if present into a separate dedicated archive folder under the logs directory.
3+
This explanation goes over the types of logging in MySQL and the configuration parameters for log
4+
rotation.
65

6+
The charm currently has audit and error logs enabled by default. All of these files are rotated if
7+
present into a separate dedicated archive folder under the logs directory.
78
We do not yet support the rotation of binary logs (binlog, relay log, undo log, redo log, etc).
89

910
## Summary
11+
1012
* [Log types](#log-types)
11-
* [Audit logs](#audit-logs)
12-
* [Error logs](#error-logs)
13-
* [General logs](#general-logs)
14-
* [Slowquery logs](#slowquery-logs)
13+
* [Audit logs](#audit-logs)
14+
* [Error logs](#error-logs)
1515
* [Log rotation configuration](#log-rotation-configuration)
1616
* [High Level Design](#high-level-design)
1717

1818
---
1919

2020
## Log types
2121

22-
The charm stores its logs in `/var/snap/charmed-mysql/common/var/log/mysql`.
22+
The charm stores its logs in `/var/snap/charmed-mysql/common/var/log/mysql`.
2323

2424
```shell
25+
2526
$ ls -lahR /var/snap/charmed-mysql/common/var/log/mysql
2627

2728
/var/log/mysql:
2829
drwxrwx--- 2 mysql mysql 4.0K Oct 23 20:46 archive_audit
2930
drwxrwx--- 2 mysql mysql 4.0K Oct 23 20:46 archive_error
30-
drwxrwx--- 2 mysql mysql 4.0K Oct 23 20:46 archive_general
31-
drwxrwx--- 2 mysql mysql 4.0K Oct 23 20:45 archive_slowquery
3231
-rw-r----- 1 mysql mysql 1.1K Oct 23 20:46 audit.log
3332
-rw-r----- 1 mysql mysql 1.1K Oct 23 20:46 error.log
34-
-rw-r----- 1 mysql mysql 1.7K Oct 23 20:46 general.log
3533

3634
/var/snap/charmed-mysql/common/var/log/mysql/archive_audit:
37-
-rw-r----- 1 snap_daemon root 43K Sep 3 01:24 audit.log-20240903_0124
38-
-rw-r----- 1 snap_daemon root 109K Sep 3 01:25 audit.log-20240903_0125
35+
-rw-r----- 1 snap_daemon root 43K Sep 3 01:24 audit.log-20240903_0124.gz
36+
-rw-r----- 1 snap_daemon root 109K Sep 3 01:25 audit.log-20240903_0125.gz
3937

4038
/var/snap/charmed-mysql/common/var/log/mysql/archive_error:
41-
-rw-r----- 1 mysql mysql 8.7K Oct 23 20:44 error.log-43_2045
42-
-rw-r----- 1 mysql mysql 2.3K Oct 23 20:45 error.log-43_2046
4339

44-
/var/snap/charmed-mysql/common/var/log/mysql/archive_general:
45-
-rw-r----- 1 mysql mysql 8.0M Oct 23 20:45 general.log-43_2045
46-
-rw-r----- 1 mysql mysql 4.6K Oct 23 20:46 general.log-43_2046
47-
48-
/var/snap/charmed-mysql/common/var/log/mysql/archive_slowquery:
40+
-rw-r----- 1 mysql mysql 8.7K Oct 23 20:44 error.log-43_2045.gz
41+
-rw-r----- 1 mysql mysql 2.3K Oct 23 20:45 error.log-43_2046.gz
4942
```
5043

51-
It is recommended to set up a [COS integration] so that these log files can be streamed to Loki. This leads to better persistence and security of the logs.
44+
It is recommended to set up a [COS integration] so that these log files can be streamed to Loki.
45+
This leads to better persistence and security of the logs.
5246

5347
### Audit logs
48+
5449
The Audit Log plugin allows all login/logout records to be stored in a log file.
5550

5651
<details>
52+
5753
<summary>Example of audit logs in JSON format with login/logout records</summary>
5854

5955
```json
56+
6057
{"audit_record":{"name":"Connect","record":"17_2024-09-03T01:52:14","timestamp":"2024-09-03T01:53:14Z","connection_id":"988","status":1156,"user":"","priv_user":"","os_login":"","proxy_user":"","host":"juju-da2225-8","ip":"10.207.85.214","db":""}}
6158
{"audit_record":{"name":"Connect","record":"18_2024-09-03T01:52:14","timestamp":"2024-09-03T01:53:14Z","connection_id":"989","status":0,"user":"serverconfig","priv_user":"serverconfig","os_login":"","proxy_user":"","host":"juju-da2225-8","ip":"10.207.85.214","db":""}}
6259
{"audit_record":{"name":"Quit","record":"1_2024-09-03T01:53:14","timestamp":"2024-09-03T01:53:14Z","connection_id":"989","status":0,"user":"serverconfig","priv_user":"serverconfig","os_login":"","proxy_user":"","host":"juju-da2225-8","ip":"10.207.85.214","db":""}}
@@ -68,14 +65,17 @@ The Audit Log plugin allows all login/logout records to be stored in a log file.
6865
{"audit_record":{"name":"Connect","record":"7_2024-09-03T01:53:14","timestamp":"2024-09-03T01:53:33Z","connection_id":"993","status":1156,"user":"","priv_user":"","os_login":"","proxy_user":"","host":"juju-da2225-8","ip":"10.207.85.214","db":""}}
6966
{"audit_record":{"name":"Connect","record":"8_2024-09-03T01:53:14","timestamp":"2024-09-03T01:53:33Z","connection_id":"994","status":0,"user":"serverconfig","priv_user":"serverconfig","os_login":"","proxy_user":"","host":"juju-da2225-8","ip":"10.207.85.214","db":""}}
7067
```
68+
7169
</details>
7270

73-
For more details, see the [Audit Logs explanation].
71+
The audit log allows for more configuration. For details, see the [Audit Logs explanation].
7472

7573
### Error logs
7674

7775
<details>
76+
7877
<summary>Example of error logs with format <code>time thread [label] [err_code] [subsystem] msg</code></summary>
78+
7979
```shell
8080
2023-10-24T23:28:07.048728Z mysqld_safe Number of processes running now: 0
8181
2023-10-24T23:28:07.063027Z mysqld_safe mysqld restarted
@@ -86,7 +86,7 @@ For more details, see the [Audit Logs explanation].
8686
2023-10-24T23:28:11.486308Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
8787
2023-10-24T23:28:11.487473Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
8888
2023-10-24T23:28:11.538807Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '0.0.0.0' port: 33060, socket: /var/snap/charmed-mysql/common/var/run/mysqld/mysqlx.sock
89-
2023-10-24T23:28:11.538957Z 0 [System] [MY-010931] [Server] /snap/charmed-mysql/69/usr/sbin/mysqld: ready for connections. Version: '8.0.34-0ubuntu0.22.04.1' socket: '/var/snap/charmed-mysql/common/var/run/mysqld/mysqld.sock' port: 3306 (Ubuntu).
89+
2023-10-24T23:28:11.538957Z 0 [System] [MY-010931] [Server] /snap/charmed-mysql/69/usr/sbin/mysqld: ready for connections. Version: '8.0.34-0ubuntu0.22.04.1' socket: '/var/snap/charmed-mysql/common/var/run/mysqld/mysqld.sock' port: 3306 (Ubuntu).
9090
2023-10-24T23:28:17.983851Z 12 [Warning] [MY-010604] [Repl] Neither --relay-log nor --relay-log-index were used; so replication may break when this MySQL server acts as a replica and has his hostname changed!! Please use '--relay-log=juju-9860bb-0-relay-bin' to avoid this problem.
9191
2023-10-24T23:28:17.999093Z 12 [System] [MY-010597] [Repl] 'CHANGE REPLICATION SOURCE TO FOR CHANNEL 'mysqlsh.test' executed'. Previous state source_host='', source_port= 3306, source_log_file='', source_log_pos= 4, source_bind=''. New state source_host='juju-9860bb-0.lxd', source_port= 3306, source_log_file='', source_log_pos= 4, source_bind=''.
9292
2023-10-24T23:28:18.025941Z 15 [Warning] [MY-010897] [Repl] Storing MySQL user name or password information in the connection metadata repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START REPLICA; see the 'START REPLICA Syntax' in the MySQL Manual for more information.
@@ -108,55 +108,36 @@ For more details, see the [Audit Logs explanation].
108108
2023-10-24T23:28:19.179289Z 28 [System] [MY-011566] [Repl] Plugin group_replication reported: 'Setting super_read_only=OFF.'
109109
2023-10-24T23:28:19.179408Z 28 [System] [MY-013731] [Repl] Plugin group_replication reported: 'The member action "mysql_start_failover_channels_if_primary" for event "AFTER_PRIMARY_ELECTION" with priority "10" will be run.'
110110
2023-10-24T23:28:19.179600Z 31 [System] [MY-011510] [Repl] Plugin group_replication reported: 'This server is working as primary member.'
111-
2023-10-24T23:28:19.875216Z 12 [System] [MY-014010] [Repl] Plugin group_replication reported: 'Plugin 'group_replication' has been started.'
111+
2023-10-24T23:28:19.875216Z 12 [System] [MY-014010] [Repl] Plugin group_replication reported: 'Plugin 'group_replication' has been started.'
112112
```
113-
</details>
114-
115-
### General logs
116113
117-
<details>
118-
<summary>Example of general logs, with format <code>time thread_id command_type query_body</code></summary>
119-
```shell
120-
Time Id Command Argument
121-
2023-10-23T20:50:02.023329Z 94 Quit
122-
2023-10-23T20:50:02.667063Z 95 Connect
123-
2023-10-23T20:50:02.667436Z 95 Query /* xplugin authentication */ SELECT /*+ SET_VAR(SQL_MODE = 'TRADITIONAL') */ @@require_secure_transport, `authentication_string`, `plugin`, (`account_locked
124-
`='Y') as is_account_locked, (`password_expired`!='N') as `is_password_expired`, @@disconnect_on_expired_password as `disconnect_on_expired_password`, @@offline_mode and (`Super_priv`='N') as `is_offline_
125-
mode_and_not_super_user`, `ssl_type`, `ssl_cipher`, `x509_issuer`, `x509_subject` FROM mysql.user WHERE 'serverconfig' = `user` AND '%' = `host`
126-
2023-10-23T20:50:02.668277Z 95 Query /* xplugin authentication */ SELECT /*+ SET_VAR(SQL_MODE = 'TRADITIONAL') */ @@require_secure_transport, `authentication_string`, `plugin`, (`account_locked
127-
`='Y') as is_account_locked, (`password_expired`!='N') as `is_password_expired`, @@disconnect_on_expired_password as `disconnect_on_expired_password`, @@offline_mode and (`Super_priv`='N') as `is_offline_
128-
mode_and_not_super_user`, `ssl_type`, `ssl_cipher`, `x509_issuer`, `x509_subject` FROM mysql.user WHERE 'serverconfig' = `user` AND '%' = `host`
129-
2023-10-23T20:50:02.668778Z 95 Query select @@lower_case_table_names, @@version, connection_id(), variable_value from performance_schema.session_status where variable_name = 'mysqlx_ssl_cipher'
130-
2023-10-23T20:50:02.669991Z 95 Query SET sql_log_bin = 0
131-
2023-10-23T20:50:02.670389Z 95 Query FLUSH SLOW LOGS
132-
2023-10-23T20:50:02.670924Z 95 Quit
133-
```
134114
</details>
135115
136-
### Slowquery logs
116+
### Other logs
137117
138-
<details>
139-
<summary>Example of a slowquery log</summary>
140-
```shell
141-
Time Id Command Argument
142-
# Time: 2023-10-23T22:22:47.564327Z
143-
# User@Host: serverconfig[serverconfig] @ localhost [127.0.0.1] Id: 21
144-
# Query_time: 15.000332 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 1
145-
SET timestamp=1698099752;
146-
do sleep(15);
147-
```
148-
</details>
118+
Other logs (slow queries, general query) are currently disabled.
149119
150120
## Log rotation configuration
151121
152-
For each log (audit, error, general and slow query):
122+
Following the configuration options exposed by the charm:
123+
124+
| Configuration option | Description | Default value |
125+
| --- | --- | --- |
126+
| `plugin-audit-enabled` | Enable or disable the audit log | `true` |
127+
| `logs_audit_policy` | The audit log policy ("all", "logins", "queries") | `logins` |
128+
| `logs_retention_period` | The number of days to keep the rotated logs | `auto` |
129+
130+
The `logs_retention_period` option accepts an integer value of 3 or greater, or the special value
131+
`auto`. When set to "auto" (default), the retention period is 3 days, except when COS-related,
132+
where it is 1 day
133+
134+
For each log (audit, error):
153135
154136
- The log file is rotated every minute (even if the log files are empty)
155137
- The rotated log file is formatted with a date suffix of `-%V-%H%M` (-weeknumber-hourminute)
156-
- The rotated log files are not compressed or mailed
138+
- The rotated log files are compressed but not mailed
157139
- The rotated log files are owned by the `snap_daemon` user and group
158-
- The rotated log files are retained for a maximum of 7 days before being deleted
159-
- The most recent 10080 rotated log files are retained before older rotated log files are deleted
140+
- By default the rotated log files are retained for 3 days before being deleted, but this can be configured.
160141
161142
The following are logrotate config values used for log rotation:
162143
@@ -171,18 +152,26 @@ The following are logrotate config values used for log rotation:
171152
| `dateformat` | -%V-%H%M |
172153
| `ifempty` | true |
173154
| `missingok` | true |
174-
| `nocompress` | true |
155+
| `compress` | true |
175156
| `nomail` | true |
176157
| `nosharedscripts` | true |
177158
| `nocopytruncate` | true |
178-
| `olddir` | archive_error / archive_general / archive_slowquery |
159+
| `olddir` | archive_<log_name> |
179160
180161
## High Level Design
181162
182-
There is a cron job on the machine where the charm exists that is triggered every minute and runs `logrotate`. The logrotate utility does *not* use `copytruncate`. Instead, the existing log file is moved into the archive directory by logrotate, and then the logrotate's postrotate script invokes `juju-run` (or `juju-exec` depending on the juju version) to dispatch a custom event. This custom event's handler flushes the MySQL log with the [FLUSH](https://dev.mysql.com/doc/refman/8.0/en/flush.html) statement that will result in a new and empty log file being created under `/var/snap/charmed-mysql/common/var/log/mysql` and the rotated file's descriptor being closed.
183-
184-
We use a custom event in juju to execute the FLUSH statement in order to avoid storing any credentials on the disk. The charm code has a mechanism that will retrieve credentials from the peer relation databag or juju secrets backend, if available, and keep these credentials in memory for the duration of the event handler.
185-
163+
There is a cron job on the machine where the charm exists that is triggered every minute and runs
164+
`logrotate`. The logrotate utility does *not* use `copytruncate`. Instead, the existing log file is
165+
moved into the archive directory by logrotate, and then the logrotate's postrotate script invokes
166+
`juju-run` (or `juju-exec` depending on the juju version) to dispatch a custom event. This custom
167+
event's handler flushes the MySQL log with the
168+
[FLUSH](https://dev.mysql.com/doc/refman/8.0/en/flush.html) statement that will result in a new and
169+
empty log file being created under `/var/snap/charmed-mysql/common/var/log/mysql` and the rotated
170+
file's descriptor being closed.
171+
We use a custom event in juju to execute the FLUSH statement in order to avoid storing any
172+
credentials on the disk. The charm code has a mechanism that will retrieve credentials from the
173+
peer relation databag or juju secrets backend, if available, and keep these credentials in memory
174+
for the duration of the event handler.
186175
187176
<!-- LINKS -->
188177

0 commit comments

Comments
 (0)