Initial commit
This commit is contained in:
commit
eac272444f
|
|
@ -0,0 +1 @@
|
|||
hcloud/
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
# mailserver - Mail Server mail.nbit.ch
|
||||
|
||||
Als Grundlage soll https://thomas-leister.de/mailserver-debian-buster/ dienen,
|
||||
jedoch verwenden wir CentOS 8.
|
||||
|
||||
Code zum Erstellen des Servers
|
||||
|
||||
Spezifikaktion:
|
||||
- CentOS 8
|
||||
- Hetzner Cloud Server
|
||||
- mailcow (Docker-basiert)
|
||||
|
||||
## Erstellen des Servers
|
||||
|
||||
Mit dem Binary hcloud von:
|
||||
https://github.com/hetznercloud/cli
|
||||
|
||||
Temporaer einen API Key erstellen (nachher wieder loeschen)
|
||||
|
||||
$ hcloud context create nbit.ch
|
||||
$ hcloud image list # zeigt moegliche Images
|
||||
$ hcloud server-type list # zeigt moegliche Typen
|
||||
|
||||
$ hcloud server create --name mail --image centos-8 --type cx21 --ssh-key joerg@cinnamon.nbit.ch
|
||||
$ hcloud server set-rdns mail --hostname mail.nbit.ch
|
||||
$ IPV6="$(hcloud server ip mail -6)"
|
||||
$ hcloud server set-rdns mail --ip $IPV6 --hostname mail.nbit.ch
|
||||
|
||||
DNS Eintraege erstellen:
|
||||
$ hcloud server ip mail
|
||||
$ hcloud server ip mail -6
|
||||
|
||||
Root-Passwort setzen (das machen wir von Hand)
|
||||
|
||||
## Ansible Playbook laufen lassen
|
||||
|
||||
$ cd ansible
|
||||
$ ansible-playbook -i production mailserver.yml
|
||||
|
||||
|
||||
## Zertifikate erzeugen
|
||||
|
||||
# systemctl stop nginx
|
||||
# certbot certonly --noninteractive --standalone --agree-tos -m postmaster@nbit.ch -d mail2.nbit.ch -d smtp.nbit.ch -d imap.nbit.ch
|
||||
# systemctl start nginx
|
||||
|
||||
|
||||
## DB erstellen
|
||||
|
||||
# mysql
|
||||
MariaDB [(none)]> create database vmail CHARACTER SET 'utf8';
|
||||
MariaDB [(none)]> grant select on vmail.* to 'vmail'@'localhost' identified by 'vmaildbpass';
|
||||
# anderes Passwort waehlen!
|
||||
MariaDB [(none)]> use vmail;
|
||||
|
||||
Folgende Statements durchfuehren:
|
||||
|
||||
CREATE TABLE `domains` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`domain` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY (`domain`)
|
||||
);
|
||||
|
||||
CREATE TABLE `accounts` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(64) NOT NULL,
|
||||
`domain` varchar(255) NOT NULL,
|
||||
`password` varchar(255) NOT NULL,
|
||||
`quota` int unsigned DEFAULT '0',
|
||||
`enabled` boolean DEFAULT '0',
|
||||
`sendonly` boolean DEFAULT '0',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (`username`, `domain`),
|
||||
FOREIGN KEY (`domain`) REFERENCES `domains` (`domain`)
|
||||
);
|
||||
|
||||
CREATE TABLE `aliases` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`source_username` varchar(64),
|
||||
`source_domain` varchar(255) NOT NULL,
|
||||
`destination_username` varchar(64) NOT NULL,
|
||||
`destination_domain` varchar(255) NOT NULL,
|
||||
`enabled` boolean DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY (`source_username`, `source_domain`, `destination_username`, `destination_domain`),
|
||||
FOREIGN KEY (`source_domain`) REFERENCES `domains` (`domain`)
|
||||
);
|
||||
|
||||
CREATE TABLE `tlspolicies` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`domain` varchar(255) NOT NULL,
|
||||
`policy` enum('none', 'may', 'encrypt', 'dane', 'dane-only', 'fingerprint', 'verify', 'secure') NOT NULL,
|
||||
`params` varchar(255),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY (`domain`)
|
||||
);
|
||||
|
||||
|
||||
## DKIM Signing (manuell einrichten)
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
# file: mailserver.yml
|
||||
- hosts: mailserver
|
||||
vars:
|
||||
ansible_ssh_pipelining: yes
|
||||
roles:
|
||||
- common
|
||||
- zabbix-agent
|
||||
- aide
|
||||
- mailserver
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
[all:vars]
|
||||
ansible_user=root
|
||||
my_domain=nbit.ch
|
||||
zabbix_server_ip=195.201.222.24
|
||||
|
||||
[mailserver]
|
||||
mail.nbit.ch ansible_host=135.181.95.247
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
/usr/sbin/aide -c /etc/aide.conf --init
|
||||
/bin/cp /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
!/root/.ansible/tmp
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
- name: update aide database
|
||||
action: command /usr/local/bin/aide-update
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
- name: Install aide
|
||||
yum:
|
||||
name: aide
|
||||
|
||||
- name: Remove all the current ignore list in aide.conf
|
||||
lineinfile:
|
||||
dest: /etc/aide.conf
|
||||
backup: yes
|
||||
regexp: "^#!|!/"
|
||||
state: absent
|
||||
|
||||
- name: change up aide.conf to standards set in aide_ignore_list var
|
||||
lineinfile:
|
||||
dest: /etc/aide.conf
|
||||
line: "@@include /etc/aide.conf.local"
|
||||
insertafter: EOF
|
||||
state: present
|
||||
|
||||
- name: copy aide.conf.local
|
||||
copy:
|
||||
src: aide.conf.local
|
||||
dest: /etc/aide.conf.local
|
||||
mode: '0600'
|
||||
|
||||
- name: copy aide-update script
|
||||
copy:
|
||||
src: aide-update
|
||||
dest: /usr/local/bin/aide-update
|
||||
mode: '0755'
|
||||
|
||||
- name: Add crontab to check aide nightly
|
||||
cron:
|
||||
cron_file: aide_check
|
||||
user: root
|
||||
name: "Check Aide DB nightly"
|
||||
hour: "23"
|
||||
minute: "45"
|
||||
job: "/usr/sbin/aide --check"
|
||||
|
||||
notify:
|
||||
- update aide database
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[sshd]
|
||||
enabled = true
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
- name: Restart ssh
|
||||
service:
|
||||
name=sshd
|
||||
state=restarted
|
||||
|
||||
- name: Restart fail2ban
|
||||
service:
|
||||
name=fail2ban
|
||||
state=restarted
|
||||
|
||||
- name: reload firewalld
|
||||
systemd:
|
||||
name=firewalld
|
||||
state=reloaded
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
---
|
||||
- name: install basic packages
|
||||
yum:
|
||||
name: "{{ packages }}"
|
||||
vars:
|
||||
packages:
|
||||
- langpacks-en
|
||||
- langpacks-de
|
||||
- glibc-all-langpacks
|
||||
- sysstat
|
||||
- mailx
|
||||
- bind-utils
|
||||
- epel-release
|
||||
- setroubleshoot-server
|
||||
- telnet
|
||||
- git
|
||||
- yum-utils
|
||||
|
||||
- name: Enable SELinux
|
||||
selinux:
|
||||
policy: targeted
|
||||
state: enforcing
|
||||
|
||||
- name: disable kdump
|
||||
systemd:
|
||||
name: kdump
|
||||
enabled: no
|
||||
|
||||
- name: allow root SSH with key only
|
||||
lineinfile: dest=/etc/ssh/sshd_config
|
||||
regexp="^PermitRootLogin"
|
||||
line="PermitRootLogin without-password"
|
||||
state=present
|
||||
notify: Restart ssh
|
||||
|
||||
- name: create /etc/hosts from template
|
||||
template:
|
||||
src: hosts.j2
|
||||
dest: /etc/hosts
|
||||
owner: root
|
||||
group: root
|
||||
backup: yes
|
||||
mode: '0644'
|
||||
|
||||
- name: install fail2ban
|
||||
yum:
|
||||
name: fail2ban
|
||||
|
||||
- name: enable fail2ban
|
||||
systemd:
|
||||
name: fail2ban
|
||||
enabled: yes
|
||||
|
||||
- name: copy fail2ban config
|
||||
copy:
|
||||
src: jail.local
|
||||
dest: /etc/fail2ban/jail.local
|
||||
mode: '0644'
|
||||
notify: Restart fail2ban
|
||||
|
||||
- name: setup firewalld rules - services
|
||||
firewalld:
|
||||
service: "{{ item }}"
|
||||
permanent: yes
|
||||
state: enabled
|
||||
immediate: yes
|
||||
loop:
|
||||
- ssh
|
||||
- http
|
||||
- https
|
||||
- smtp
|
||||
- smtps
|
||||
- imap
|
||||
- imaps
|
||||
- pop3
|
||||
- pop3s
|
||||
- managesieve
|
||||
notify: reload firewalld
|
||||
|
||||
- name: setup firewalld rules - remove services
|
||||
firewalld:
|
||||
service: "{{ item }}"
|
||||
permanent: yes
|
||||
state: disabled
|
||||
loop:
|
||||
- cockpit
|
||||
notify: reload firewalld
|
||||
|
||||
- name: setup firewalld rules - ports
|
||||
firewalld:
|
||||
port: "{{ item }}"
|
||||
permanent: yes
|
||||
state: enabled
|
||||
loop:
|
||||
- 10050/tcp
|
||||
notify: reload firewalld
|
||||
|
||||
- name: Create ~/.forward
|
||||
copy:
|
||||
content: 'joerg.lehmann@nbit.ch'
|
||||
dest: "/root/.forward"
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# Your system has configured 'manage_etc_hosts' as True.
|
||||
# As a result, if you wish for changes to this file to persist
|
||||
# then you will need to either
|
||||
# a.) make changes to the master file in /etc/cloud/templates/hosts.redhat.tmpl
|
||||
# b.) change or remove the value of 'manage_etc_hosts' in
|
||||
# /etc/cloud/cloud.cfg or cloud-config from user-data
|
||||
#
|
||||
# The following lines are desirable for IPv4 capable hosts
|
||||
{{ ansible_default_ipv4.address }} {{ ansible_hostname }}.{{ my_domain }} {{ ansible_hostname }}
|
||||
127.0.0.1 localhost.localdomain localhost
|
||||
127.0.0.1 localhost4.localdomain4 localhost4
|
||||
|
||||
# The following lines are desirable for IPv6 capable hosts
|
||||
{{ ansible_default_ipv6.address }} {{ ansible_hostname }}.{{ my_domain }} {{ ansible_hostname }}
|
||||
::1 localhost.localdomain localhost
|
||||
::1 localhost6.localdomain6 localhost6
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
$ANSIBLE_VAULT;1.1;AES256
|
||||
62656635343535363437303935663462656438363731363763373039303830656261623531646362
|
||||
3036653865663464643836626233383238643931613236340a343566623134323565333766326165
|
||||
64646533643836323734303739383761396463633464373732383230656461396131626334303735
|
||||
3166323135393565390a303538353031346632653336366363353739653639613661346539383535
|
||||
37393330356262363233336439336566623064386261306433613962306531366339373930363838
|
||||
38376161633933643633393665386432353734373866333437656335343764663933393366623931
|
||||
37343639353730333834373466336439653836313135386162343963653430306238386665383362
|
||||
36343364626132333430333261373237333136313337333638366136303931663930613737633163
|
||||
66336364646262656666643361626133343637383566626163343366616566306462326566353161
|
||||
30663438366232646332363937636639306130313130386137363138626635333364393630303063
|
||||
656161633037633830353064666236356632
|
||||
|
|
@ -0,0 +1 @@
|
|||
backend = "redis";
|
||||
|
|
@ -0,0 +1 @@
|
|||
<h1>mail2.nbit.ch</h1>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[main]
|
||||
dns=none
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
##
|
||||
## Aktivierte Protokolle
|
||||
##
|
||||
|
||||
protocols = imap lmtp sieve
|
||||
|
||||
|
||||
##
|
||||
## TLS Config
|
||||
## Quelle: https://ssl-config.mozilla.org/#server=dovecot&version=2.3.9&config=intermediate&openssl=1.1.1d&guideline=5.4
|
||||
##
|
||||
|
||||
ssl = required
|
||||
ssl_cert = </etc/letsencrypt/live/mail2.nbit.ch/fullchain.pem
|
||||
ssl_key = </etc/letsencrypt/live/mail2.nbit.ch/privkey.pem
|
||||
ssl_dh = </etc/dovecot/dh4096.pem
|
||||
ssl_min_protocol = TLSv1.2
|
||||
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
|
||||
ssl_prefer_server_ciphers = no
|
||||
|
||||
|
||||
##
|
||||
## Dovecot services
|
||||
##
|
||||
|
||||
service imap-login {
|
||||
inet_listener imap {
|
||||
port = 143
|
||||
}
|
||||
}
|
||||
|
||||
service managesieve-login {
|
||||
inet_listener sieve {
|
||||
port = 4190
|
||||
}
|
||||
}
|
||||
|
||||
service lmtp {
|
||||
unix_listener /var/spool/postfix/private/dovecot-lmtp {
|
||||
mode = 0660
|
||||
group = postfix
|
||||
user = postfix
|
||||
}
|
||||
|
||||
user = vmail
|
||||
}
|
||||
|
||||
service auth {
|
||||
### Auth socket für Postfix
|
||||
unix_listener /var/spool/postfix/private/auth {
|
||||
mode = 0660
|
||||
user = postfix
|
||||
group = postfix
|
||||
}
|
||||
|
||||
### Auth socket für LMTP-Dienst
|
||||
unix_listener auth-userdb {
|
||||
mode = 0660
|
||||
user = vmail
|
||||
group = vmail
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
## Protocol settings
|
||||
##
|
||||
|
||||
protocol imap {
|
||||
mail_plugins = $mail_plugins quota imap_quota imap_sieve
|
||||
mail_max_userip_connections = 20
|
||||
imap_idle_notify_interval = 29 mins
|
||||
}
|
||||
|
||||
protocol lmtp {
|
||||
postmaster_address = postmaster@nbit.ch
|
||||
mail_plugins = $mail_plugins sieve notify push_notification
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
## Client authentication
|
||||
##
|
||||
|
||||
disable_plaintext_auth = yes
|
||||
auth_mechanisms = plain login
|
||||
|
||||
passdb {
|
||||
driver = sql
|
||||
args = /etc/dovecot/dovecot-sql.conf
|
||||
}
|
||||
|
||||
userdb {
|
||||
driver = sql
|
||||
args = /etc/dovecot/dovecot-sql.conf
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
## Address tagging
|
||||
##
|
||||
recipient_delimiter = +
|
||||
|
||||
|
||||
##
|
||||
## Mail location
|
||||
##
|
||||
|
||||
mail_uid = vmail
|
||||
mail_gid = vmail
|
||||
mail_privileged_group = vmail
|
||||
|
||||
mail_home = /var/vmail/mailboxes/%d/%n
|
||||
mail_location = maildir:~/mail:LAYOUT=fs
|
||||
|
||||
|
||||
##
|
||||
## Mailbox configuration
|
||||
##
|
||||
|
||||
namespace inbox {
|
||||
inbox = yes
|
||||
|
||||
mailbox Spam {
|
||||
auto = subscribe
|
||||
special_use = \Junk
|
||||
}
|
||||
|
||||
mailbox Trash {
|
||||
auto = subscribe
|
||||
special_use = \Trash
|
||||
}
|
||||
|
||||
mailbox Drafts {
|
||||
auto = subscribe
|
||||
special_use = \Drafts
|
||||
}
|
||||
|
||||
mailbox Sent {
|
||||
auto = subscribe
|
||||
special_use = \Sent
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
## Mail plugins
|
||||
##
|
||||
|
||||
plugin {
|
||||
sieve_plugins = sieve_imapsieve sieve_extprograms
|
||||
sieve_before = /var/vmail/sieve/global/spam-global.sieve
|
||||
sieve = file:/var/vmail/sieve/%d/%n/scripts;active=/var/vmail/sieve/%d/%n/active-script.sieve
|
||||
|
||||
###
|
||||
### Spam learning
|
||||
###
|
||||
# From elsewhere to Spam folder
|
||||
imapsieve_mailbox1_name = Spam
|
||||
imapsieve_mailbox1_causes = COPY
|
||||
imapsieve_mailbox1_before = file:/var/vmail/sieve/global/learn-spam.sieve
|
||||
|
||||
# From Spam folder to elsewhere
|
||||
imapsieve_mailbox2_name = *
|
||||
imapsieve_mailbox2_from = Spam
|
||||
imapsieve_mailbox2_causes = COPY
|
||||
imapsieve_mailbox2_before = file:/var/vmail/sieve/global/learn-ham.sieve
|
||||
|
||||
sieve_pipe_bin_dir = /usr/bin
|
||||
sieve_global_extensions = +vnd.dovecot.pipe
|
||||
|
||||
quota = maildir:User quota
|
||||
quota_exceeded_message = Benutzer %u hat das Speichervolumen überschritten. / User %u has exhausted allowed storage space.
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
type = "syslog";
|
||||
level = "warning";
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name mail2.nbit.ch;
|
||||
|
||||
root /var/www/default_webroot;
|
||||
ssl_certificate /etc/letsencrypt/live/mail2.nbit.ch/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/mail2.nbit.ch/privkey.pem;
|
||||
|
||||
add_header Strict-Transport-Security max-age=15768000;
|
||||
|
||||
location /rspamd/ {
|
||||
proxy_pass http://localhost:11334/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
if ($ssl_protocol = "") {
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
use = ["x-spamd-bar", "x-spam-level", "authentication-results"];
|
||||
authenticated_headers = ["authentication-results"];
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
WHITELIST_IP {
|
||||
type = "ip";
|
||||
map = "$CONFDIR/local.d/whitelist_ip.map";
|
||||
description = "Local ip whitelist";
|
||||
action = "accept";
|
||||
}
|
||||
|
||||
WHITELIST_FROM {
|
||||
type = "from";
|
||||
map = "$CONFDIR/local.d/whitelist_from.map";
|
||||
description = "Local from whitelist";
|
||||
action = "accept";
|
||||
}
|
||||
|
||||
BLACKLIST_IP {
|
||||
type = "ip";
|
||||
map = "$CONFDIR/local.d/blacklist_ip.map";
|
||||
description = "Local ip blacklist";
|
||||
action = "reject";
|
||||
}
|
||||
|
||||
BLACKLIST_FROM {
|
||||
type = "from";
|
||||
map = "$CONFDIR/local.d/blacklist_from.map";
|
||||
description = "Local from blacklist";
|
||||
action = "reject";
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
servers = "127.0.0.1";
|
||||
|
|
@ -0,0 +1 @@
|
|||
0 20 * * * root python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# Managed by Ansible
|
||||
nameserver ::1
|
||||
nameserver 127.0.0.1
|
||||
nameserver 213.133.99.99
|
||||
#nameserver 213.133.98.98
|
||||
#nameserver 213.133.100.100
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
---
|
||||
- name: Restart ssh
|
||||
service:
|
||||
name=sshd
|
||||
state=restarted
|
||||
|
||||
- name: Restart fail2ban
|
||||
service:
|
||||
name=fail2ban
|
||||
state=restarted
|
||||
|
||||
- name: Restart NetworkManager
|
||||
service:
|
||||
name=NetworkManager
|
||||
state=restarted
|
||||
|
||||
- name: Restart nginx
|
||||
service:
|
||||
name=nginx
|
||||
state=restarted
|
||||
|
||||
- name: Restart dovecot
|
||||
service:
|
||||
name=dovecot
|
||||
state=restarted
|
||||
|
||||
- name: Restart postfix
|
||||
service:
|
||||
name=postfix
|
||||
state=restarted
|
||||
|
||||
- name: Restart rspamd
|
||||
service:
|
||||
name=rspamd
|
||||
state=restarted
|
||||
|
||||
- name: Restart nginx
|
||||
service:
|
||||
name=nginx
|
||||
state=restarted
|
||||
|
|
@ -0,0 +1,275 @@
|
|||
---
|
||||
- name: Add Rspamd repository
|
||||
shell: yum-config-manager --add-repo=https://rspamd.com/rpm-stable/centos-8/rspamd.repo
|
||||
args:
|
||||
creates: /etc/yum.repos.d/rspamd.repo
|
||||
|
||||
- name: install needed packages
|
||||
yum:
|
||||
name: "{{ packages }}"
|
||||
vars:
|
||||
packages:
|
||||
- postfix
|
||||
- postfix-mysql
|
||||
- dovecot
|
||||
- dovecot-mysql
|
||||
- dovecot-pigeonhole
|
||||
- rspamd
|
||||
- redis
|
||||
- mariadb
|
||||
- mariadb-server
|
||||
- nginx
|
||||
- unbound
|
||||
- certbot
|
||||
- haveged
|
||||
|
||||
- name: enable services
|
||||
systemd:
|
||||
name: "{{ item }}"
|
||||
enabled: yes
|
||||
state: started
|
||||
loop:
|
||||
- unbound
|
||||
- nginx
|
||||
- mariadb
|
||||
- dovecot
|
||||
- haveged
|
||||
- postfix
|
||||
- redis
|
||||
- rspamd
|
||||
|
||||
- name: Copy disable_dns.conf
|
||||
copy:
|
||||
src: disable_dns.conf
|
||||
dest: /etc/NetworkManager/conf.d/disable_dns.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
notify: Restart NetworkManager
|
||||
|
||||
- name: Copy /etc/resolv.conf
|
||||
copy:
|
||||
src: resolv.conf
|
||||
dest: /etc/resolv.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
notify: Restart NetworkManager
|
||||
|
||||
- name: enable nginx
|
||||
systemd:
|
||||
name: nginx
|
||||
enabled: yes
|
||||
state: started
|
||||
|
||||
- name: Copy webserver config
|
||||
copy:
|
||||
src: mail.nbit.ch.conf
|
||||
dest: /etc/nginx/conf.d/mail.nbit.ch.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
notify: Restart nginx
|
||||
|
||||
- name: Add Group vmail
|
||||
group:
|
||||
name: vmail
|
||||
gid: 1000
|
||||
state: present
|
||||
|
||||
- name: Add User vmail
|
||||
user:
|
||||
name: vmail
|
||||
shell: /sbin/nologin
|
||||
home: /var/vmail
|
||||
uid: 1000
|
||||
group: vmail
|
||||
|
||||
- name: Change Permission
|
||||
file:
|
||||
path: "/var/vmail"
|
||||
state: directory
|
||||
owner: vmail
|
||||
group: vmail
|
||||
mode: '0770'
|
||||
|
||||
- name: Create /var/vmail Directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: vmail
|
||||
group: vmail
|
||||
mode: '0755'
|
||||
loop:
|
||||
- /var/vmail/mailboxes
|
||||
- /var/vmail/sieve
|
||||
- /var/vmail/sieve/global
|
||||
|
||||
- name: Copy dovecot config
|
||||
copy:
|
||||
src: dovecot.conf
|
||||
dest: /etc/dovecot/dovecot.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
notify: Restart dovecot
|
||||
|
||||
- name: Copy dovecot-sql config
|
||||
template:
|
||||
src: dovecot-sql.conf.j2
|
||||
dest: /etc/dovecot/dovecot-sql.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0440'
|
||||
notify: Restart dovecot
|
||||
|
||||
- name: Create Dovecot DH File
|
||||
# this can take quite some time...
|
||||
shell: openssl dhparam -out /etc/dovecot/dh4096.pem 4096
|
||||
args:
|
||||
creates: /etc/dovecot/dh4096.pem
|
||||
|
||||
- name: Create Postfix DH File
|
||||
# this can take quite some time...
|
||||
shell: openssl dhparam -out /etc/postfix/dh2048.pem 2048
|
||||
args:
|
||||
creates: /etc/postfix/dh2048.pem
|
||||
|
||||
- name: Create /etc/postfix/sql
|
||||
file:
|
||||
path: "/etc/postfix/sql"
|
||||
state: directory
|
||||
owner: root
|
||||
group: postfix
|
||||
mode: '0755'
|
||||
|
||||
- name: Create postfix conf
|
||||
template:
|
||||
src: main.cf.j2
|
||||
dest: "/etc/postfix/main.cf"
|
||||
owner: root
|
||||
group: root
|
||||
backup: no
|
||||
mode: '0644'
|
||||
notify: Restart postfix
|
||||
|
||||
- name: create postfix sql files
|
||||
template:
|
||||
src: "{{ item }}.j2"
|
||||
dest: "/etc/postfix/sql/{{ item }}"
|
||||
owner: root
|
||||
group: postfix
|
||||
backup: no
|
||||
mode: '0644'
|
||||
loop:
|
||||
- accounts.cf
|
||||
- aliases.cf
|
||||
- domains.cf
|
||||
- recipient-access.cf
|
||||
- sender-login-maps.cf
|
||||
- tls-policy.cf
|
||||
notify: Restart postfix
|
||||
|
||||
- name: Create /etc/postfix/without_ptr
|
||||
copy:
|
||||
content: ''
|
||||
dest: /etc/postfix/without_ptr
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
|
||||
- name: Create Postfix Maps
|
||||
shell: postmap /etc/postfix/without_ptr
|
||||
args:
|
||||
creates: /etc/postfix/without_ptr.db
|
||||
|
||||
- name: Create rspamd password file
|
||||
template:
|
||||
src: worker-controller.inc.j2
|
||||
dest: "/etc/rspamd/local.d/worker-controller.inc"
|
||||
owner: root
|
||||
group: root
|
||||
backup: no
|
||||
mode: '0644'
|
||||
notify: Restart rspamd
|
||||
|
||||
- name: create rspamd config files
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: "/etc/rspamd/local.d/{{ item }}"
|
||||
owner: root
|
||||
group: root
|
||||
backup: no
|
||||
mode: '0644'
|
||||
loop:
|
||||
- logging.inc
|
||||
- milter_headers.conf
|
||||
- classifier-bayes.conf
|
||||
- redis.conf
|
||||
- multimap.conf
|
||||
notify: Restart rspamd
|
||||
|
||||
- name: create /etc/rspamd/override.d/classifier-bayes.conf
|
||||
copy:
|
||||
content: 'autolearn = true;'
|
||||
dest: "/etc/rspamd/override.d/classifier-bayes.conf"
|
||||
owner: root
|
||||
group: root
|
||||
backup: no
|
||||
mode: '0644'
|
||||
notify: Restart rspamd
|
||||
|
||||
- name: Create rspamd black-/whitelists
|
||||
copy:
|
||||
content: ''
|
||||
dest: "/etc/rspamd/local.d/{{ item }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
loop:
|
||||
- whitelist_ip.map
|
||||
- whitelist_from.map
|
||||
- blacklist_ip.map
|
||||
- blacklist_from.map
|
||||
|
||||
- name: Set httpd_can_network_connect flag on and keep it persistent across reboots
|
||||
seboolean:
|
||||
name: httpd_can_network_connect
|
||||
state: yes
|
||||
persistent: yes
|
||||
|
||||
- name: create Cronjob for certbot
|
||||
copy:
|
||||
src: renew-certificates
|
||||
dest: "/etc/cron.d/renew-certificates"
|
||||
owner: root
|
||||
group: root
|
||||
backup: no
|
||||
mode: '0644'
|
||||
|
||||
- name: Replace nginx root
|
||||
lineinfile:
|
||||
path: /etc/nginx/nginx.conf
|
||||
regexp: '^ root.*/usr/share/nginx/html;'
|
||||
line: ' root /var/www/default_webroot;'
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
notify: Restart nginx
|
||||
|
||||
- name: Create /var/www/default_webroot
|
||||
file:
|
||||
path: "/var/www/default_webroot"
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0755'
|
||||
|
||||
- name: create Default Website
|
||||
copy:
|
||||
src: default_website.html
|
||||
dest: "/var/www/default_webroot/index.html"
|
||||
owner: root
|
||||
group: root
|
||||
backup: no
|
||||
mode: '0644'
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
user = vmail
|
||||
password = {{ vmaildbpass }}
|
||||
hosts = unix:/run/mysqld/mysqld.sock
|
||||
dbname = vmail
|
||||
query = select 1 as found from accounts where username = '%u' and domain = '%d' and enabled = true LIMIT 1;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
user = vmail
|
||||
password = {{ vmaildbpass }}
|
||||
hosts = unix:/run/mysqld/mysqld.sock
|
||||
dbname = vmail
|
||||
query = SELECT DISTINCT concat(destination_username, '@', destination_domain) AS destinations FROM aliases
|
||||
WHERE (source_username = '%u' OR source_username IS NULL) AND source_domain = '%d'
|
||||
AND enabled = true
|
||||
AND NOT EXISTS (SELECT id FROM accounts WHERE username = '%u' and domain = '%d');
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
user = vmail
|
||||
password = {{ vmaildbpass }}
|
||||
hosts = unix:/run/mysqld/mysqld.sock
|
||||
dbname = vmail
|
||||
query = SELECT domain FROM domains WHERE domain='%s';
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
driver=mysql
|
||||
connect = "host=localhost dbname=vmail user=vmail password={{ vmaildbpass }}"
|
||||
default_pass_scheme = SHA512-CRYPT
|
||||
|
||||
password_query = SELECT username AS user, domain, password FROM accounts WHERE username = '%n' AND domain = '%d' and enabled = true;
|
||||
user_query = SELECT concat('*:storage=', quota, 'M') AS quota_rule FROM accounts WHERE username = '%n' AND domain = '%d' AND sendonly = false;
|
||||
iterate_query = SELECT username, domain FROM accounts where sendonly = false;
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
##
|
||||
## Netzwerkeinstellungen
|
||||
##
|
||||
|
||||
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
|
||||
inet_interfaces = 127.0.0.1, ::1, {{ ansible_default_ipv4.address }}, {{ ansible_default_ipv6.address }}
|
||||
myhostname = mail2.nbit.ch
|
||||
|
||||
|
||||
##
|
||||
## Mail-Queue Einstellungen
|
||||
##
|
||||
|
||||
maximal_queue_lifetime = 1h
|
||||
bounce_queue_lifetime = 1h
|
||||
maximal_backoff_time = 15m
|
||||
minimal_backoff_time = 5m
|
||||
queue_run_delay = 5m
|
||||
|
||||
|
||||
##
|
||||
## TLS Einstellungen
|
||||
## Quelle: https://ssl-config.mozilla.org/#server=postfix&version=3.4.8&config=intermediate&openssl=1.1.1d&guideline=5.4
|
||||
##
|
||||
|
||||
### Allgemein
|
||||
tls_preempt_cipherlist = no
|
||||
tls_ssl_options = NO_COMPRESSION
|
||||
tls_medium_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
|
||||
|
||||
### Ausgehende SMTP-Verbindungen (Postfix als Sender)
|
||||
smtp_tls_security_level = dane
|
||||
smtp_dns_support_level = dnssec
|
||||
smtp_tls_policy_maps = proxy:mysql:/etc/postfix/sql/tls-policy.cf
|
||||
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
|
||||
smtp_tls_ciphers = medium
|
||||
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
|
||||
|
||||
### Eingehende SMTP-Verbindungen
|
||||
smtpd_tls_security_level = may
|
||||
smtpd_tls_auth_only = yes
|
||||
smtpd_tls_ciphers = medium
|
||||
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
|
||||
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
|
||||
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
|
||||
smtpd_tls_cert_file=/etc/letsencrypt/live/mail2.nbit.ch/fullchain.pem
|
||||
smtpd_tls_key_file=/etc/letsencrypt/live/mail2.nbit.ch/privkey.pem
|
||||
smtpd_tls_dh1024_param_file = /etc/postfix/dh2048.pem
|
||||
|
||||
|
||||
##
|
||||
## Lokale Mailzustellung an Dovecot
|
||||
##
|
||||
|
||||
virtual_transport = lmtp:unix:private/dovecot-lmtp
|
||||
|
||||
|
||||
##
|
||||
## Spamfilter und DKIM-Signaturen via Rspamd
|
||||
##
|
||||
|
||||
smtpd_milters = inet:localhost:11332
|
||||
non_smtpd_milters = inet:localhost:11332
|
||||
milter_protocol = 6
|
||||
milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}
|
||||
milter_default_action = accept
|
||||
|
||||
|
||||
|
||||
##
|
||||
## Server Restrictions für Clients, Empfänger und Relaying
|
||||
## (im Bezug auf S2S-Verbindungen. Mailclient-Verbindungen werden in master.cf im Submission-Bereich konfiguriert)
|
||||
##
|
||||
|
||||
### Bedingungen, damit Postfix als Relay arbeitet (für Clients)
|
||||
smtpd_relay_restrictions = reject_non_fqdn_recipient
|
||||
reject_unknown_recipient_domain
|
||||
permit_mynetworks
|
||||
reject_unauth_destination
|
||||
|
||||
|
||||
### Bedingungen, damit Postfix ankommende E-Mails als Empfängerserver entgegennimmt (zusätzlich zu relay-Bedingungen)
|
||||
### check_recipient_access prüft, ob ein account sendonly ist
|
||||
smtpd_recipient_restrictions = check_recipient_access proxy:mysql:/etc/postfix/sql/recipient-access.cf
|
||||
|
||||
|
||||
### Bedingungen, die SMTP-Clients erfüllen müssen (sendende Server)
|
||||
smtpd_client_restrictions = permit_mynetworks
|
||||
check_client_access hash:/etc/postfix/without_ptr
|
||||
reject_unknown_client_hostname
|
||||
|
||||
|
||||
### Wenn fremde Server eine Verbindung herstellen, müssen sie einen gültigen Hostnamen im HELO haben.
|
||||
smtpd_helo_required = yes
|
||||
smtpd_helo_restrictions = permit_mynetworks
|
||||
reject_invalid_helo_hostname
|
||||
reject_non_fqdn_helo_hostname
|
||||
reject_unknown_helo_hostname
|
||||
|
||||
# Clients blockieren, wenn sie versuchen zu früh zu senden
|
||||
smtpd_data_restrictions = reject_unauth_pipelining
|
||||
|
||||
|
||||
##
|
||||
## Restrictions für MUAs (Mail user agents)
|
||||
##
|
||||
|
||||
mua_relay_restrictions = reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,permit_sasl_authenticated,reject
|
||||
mua_sender_restrictions = permit_mynetworks,reject_non_fqdn_sender,reject_sender_login_mismatch,permit_sasl_authenticated,reject
|
||||
mua_client_restrictions = permit_mynetworks,permit_sasl_authenticated,reject
|
||||
|
||||
|
||||
##
|
||||
## MySQL Abfragen
|
||||
##
|
||||
|
||||
proxy_read_maps = proxy:mysql:/etc/postfix/sql/aliases.cf
|
||||
proxy:mysql:/etc/postfix/sql/accounts.cf
|
||||
proxy:mysql:/etc/postfix/sql/domains.cf
|
||||
proxy:mysql:/etc/postfix/sql/recipient-access.cf
|
||||
proxy:mysql:/etc/postfix/sql/sender-login-maps.cf
|
||||
proxy:mysql:/etc/postfix/sql/tls-policy.cf
|
||||
|
||||
virtual_alias_maps = proxy:mysql:/etc/postfix/sql/aliases.cf
|
||||
virtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/accounts.cf
|
||||
virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/domains.cf
|
||||
local_recipient_maps = $virtual_mailbox_maps
|
||||
|
||||
|
||||
##
|
||||
## Sonstiges
|
||||
##
|
||||
|
||||
### Maximale Größe der gesamten Mailbox (soll von Dovecot festgelegt werden, 0 = unbegrenzt)
|
||||
mailbox_size_limit = 0
|
||||
|
||||
### Maximale Größe eingehender E-Mails in Bytes (50 MB)
|
||||
message_size_limit = 52428800
|
||||
|
||||
### Keine System-Benachrichtigung für Benutzer bei neuer E-Mail
|
||||
biff = no
|
||||
|
||||
### Nutzer müssen immer volle E-Mail Adresse angeben - nicht nur Hostname
|
||||
append_dot_mydomain = no
|
||||
|
||||
### Trenn-Zeichen für "Address Tagging"
|
||||
recipient_delimiter = +
|
||||
|
||||
### Keine Rückschlüsse auf benutzte Mailadressen zulassen
|
||||
disable_vrfy_command = yes
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
user = vmail
|
||||
password = {{ vmaildbpass }}
|
||||
hosts = unix:/run/mysqld/mysqld.sock
|
||||
dbname = vmail
|
||||
query = select if(sendonly = true, 'REJECT', 'OK') AS access from accounts where username = '%u' and domain = '%d' and enabled = true LIMIT 1;
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
user = vmail
|
||||
password = {{ vmaildbpass }}
|
||||
hosts = unix:/run/mysqld/mysqld.sock
|
||||
dbname = vmail
|
||||
query = select concat(username, '@', domain) as 'owns' from accounts where username = '%u' AND domain = '%d' and enabled = true union select
|
||||
concat(destination_username, '@', destination_domain) AS 'owns' from aliases
|
||||
where source_username = '%u' and source_domain = '%d' and enabled = true;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
user = vmail
|
||||
password = {{ vmaildbpass }}
|
||||
hosts = unix:/run/mysqld/mysqld.sock
|
||||
dbname = vmail
|
||||
query = SELECT policy, params FROM tlspolicies WHERE domain = '%s';
|
||||
|
|
@ -0,0 +1 @@
|
|||
password = "{{ passwd_rspamd_web_hashed }}";
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
- name: Restart zabbix-agent
|
||||
service:
|
||||
name=zabbix-agent
|
||||
state=restarted
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
- name: install zabbix agent
|
||||
yum:
|
||||
name: zabbix40-agent
|
||||
|
||||
- name: enable zabbix agent
|
||||
systemd:
|
||||
name: zabbix-agent
|
||||
enabled: yes
|
||||
|
||||
- name: zabbix config
|
||||
lineinfile: dest=/etc/zabbix/zabbix_agentd.conf
|
||||
regexp="^Server="
|
||||
line="Server={{ zabbix_server_ip }}"
|
||||
state=present
|
||||
notify: Restart zabbix-agent
|
||||
Loading…
Reference in New Issue