Remove MySQL and use dynamic file based accounts instead.

This commit is contained in:
Jason Rothstein 2022-04-07 22:41:04 -05:00
parent 351cffc637
commit c7cb38303f
5 changed files with 59 additions and 88 deletions

View File

@ -6,83 +6,16 @@ A brief description of the role goes here.
Requirements
------------
Create database for MySQL/MariaDB with :
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
```
CREATE DATABASE IF NOT EXISTS `mailserver` DEFAULT CHARACTER SET utf8mb4;
USE `mailserver`;
CREATE TABLE IF NOT EXISTS `virtual_domains` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8mb4 CHECKSUM=1;
CREATE TABLE IF NOT EXISTS `virtual_aliases` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`domain_id` int(11) NOT NULL,
`source` varchar(255) NOT NULL,
`destination` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `domain_id` (`domain_id`),
CONSTRAINT `virtual_aliases_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `virtual_domains` (`id`) ON DELETE CASCADE
) DEFAULT CHARSET=utf8mb4 CHECKSUM=1;
CREATE TABLE IF NOT EXISTS `virtual_users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`domain_id` int(11) NOT NULL,
`password` varchar(106) NOT NULL,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
KEY `domain_id` (`domain_id`),
CONSTRAINT `virtual_users_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `virtual_domains` (`id`) ON DELETE CASCADE
) DEFAULT CHARSET=utf8mb4 CHECKSUM=1;
```
Create an account to access MySQL/MariaDB with :
```
GRANT SELECT ON mailserver.* TO 'mailserver'@'%' IDENTIFIED BY 'changeme';
FLUSH PRIVLEGES;
```
New users created via the following SQL :
```
INSERT INTO `virtual_domains`
(`name`)
VALUES
('example.com');
SELECT *
FROM `virtual_domains`
WHERE `name`='example.com';
INSERT INTO `virtual_users`
(`domain_id`, `password`, `email`)
VALUES
('1', ENCRYPT('changeme', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'webmaster@example.com');
```
In the above example, the MySQL/MariaDB ENCRYPT() function calls the OS crypt(3) function. The above uses a random 16 character SALT to encrypt, and selects the SHA-512 crypt method. Other available crypt methods are as follows :
| ID | Method |
| - | - |
| 1 | MD5 |
| 5 | SHA-256 (glibc >= 2.7) |
| 6 | SHA-512 (glibc >= 2.7) |
Role Variables
--------------
| Variable | Default | Description |
| - | - | - |
| dovecot_mysql_server | undefined | Server to connect to |
| dovecot_mysql_database | undefined | Database with MySQL to use |
| dovecot_mysql_username | undefined | Username with read only rights |
| dovecot_mysql_password | undefined | Password for read only user |
| dovecot_vhost | inventory_hostname | What mod_md certificate should be used for Dovecot |
| dovecot_quota | 1G | Default mail quota for users of the system |
Dependencies
------------

View File

@ -1,3 +1,4 @@
---
# defaults file for ensure_dovecot
dovecot_vhost: '{{ inventory_hostname }}'
dovecot_quota: '1G'

View File

@ -1,8 +0,0 @@
{% if dovecot_mysql_server is defined and dovecot_mysql_database is defined and dovecot_mysql_username is defined and dovecot_mysql_password is defined %}
driver = mysql
connect = host={{ dovecot_mysql_server }} dbname={{ dovecot_mysql_database }} user={{ dovecot_mysql_username }} password={{ dovecot_mysql_password }}
default_pass_scheme = SHA512-CRYPT
password_query = SELECT email AS user, password FROM virtual_users WHERE email='%u';
user_query = SELECT email AS user FROM virtual_users WHERE email='%u';
iterate_query = SELECT email AS user FROM users;
{% endif %}

View File

@ -1,10 +1,62 @@
!include conf.d/auth-sql.conf.ext
ssl_min_protocol = TLSv1.2
ssl_cipher_list = PROFILE=SYSTEM
ssl_cert = </etc/dovecot/certificates/pubcert.pem
ssl_key = </etc/dovecot/certificates/privkey.pem
mail_location = maildir:/var/spool/mail/%d/%n
mail_privileged_group = mail
first_valid_uid = 0
mail_uid = mail
mail_gid = mail
ssl_min_protocol = TLSv1.2
ssl_cipher_list = PROFILE=SYSTEM
ssl_cert = </etc/dovecot/certificates/pubcert.pem
ssl_key = </etc/dovecot/certificates/privkey.pem
passdb {
driver = passwd-file
args = username_format=%n /etc/dovecot/accounts/%d/etc/passwd
}
userdb {
driver = passwd-file
args = username_format=%n scheme=SHA512-CRYPT /etc/dovecot/accounts/%d/etc/passwd
default_fields = uid=mail gid=mail home=/var/spool/mail/%d/%u
}
mail_plugins = $mail_plugins quota
protocols = imap lmtp
service lmtp {
inet_listener lmtp {
address = 0.0.0.0 ::
port = 24
}
}
lmtp_add_received_header = yes
protocol lmtp {
mail_plugins = $mail_plugins sieve
}
protocol imap {
mail_plugins = $mail_plugins imap_quota
}
service quota-status {
client_limit = 1
executable = quota-status -p postfix
inet_listener {
# port = 12340
}
}
mailbox_list_index = yes
protocol !indexer-worker {
mail_vsize_bg_after_count = 100
}
plugin {
quota = count:User quota
quota_rule = *:storage={{ dovecot_quota }}
quota_rule2 = Trash:storage=+100M
quota_rule3 = SPAM:ignore
quota_vsizes = yes
}

View File

@ -3,10 +3,6 @@
package_list:
- name: 'dovecot'
state: 'present'
- name: 'dovecot-fts-xapian'
state: 'present'
- name: 'dovecot-mysql'
state: 'present'
- name: 'dovecot-pigeonhole'
state: 'present'
firewall_list:
@ -85,9 +81,6 @@ template_list:
src: '{{ ansible_distribution }}/{{ ansible_distribution_major_version }}/etc/dovecot/conf.d/90-sieve.conf'
- dest: '/etc/dovecot/dovecot.conf'
src: '{{ ansible_distribution }}/{{ ansible_distribution_major_version }}/etc/dovecot/dovecot.conf'
- dest: '/etc/dovecot/dovecot-sql.conf.ext'
mode: '0600'
src: '{{ ansible_distribution }}/{{ ansible_distribution_major_version }}/etc/dovecot/dovecot-sql.conf.ext'
- dest: '/etc/dovecot/local.conf'
src: '{{ ansible_distribution }}/{{ ansible_distribution_major_version }}/etc/dovecot/local.conf'
- dest: '/usr/lib/systemd/system/dovecot-copytls.service'