From eac272444f0c1cc9fd2cb9970be75f4f10fbcf71 Mon Sep 17 00:00:00 2001 From: Joerg Lehmann Date: Fri, 4 Dec 2020 20:07:39 +0100 Subject: [PATCH] Initial commit --- .gitignore | 1 + README.md | 100 +++++++ ansible/mailserver.yml | 10 + ansible/production | 7 + ansible/roles/aide/files/aide-update | 4 + ansible/roles/aide/files/aide.conf.local | 1 + ansible/roles/aide/handlers/main.yml | 3 + ansible/roles/aide/tasks/main.yml | 42 +++ ansible/roles/common/files/jail.local | 2 + ansible/roles/common/handlers/main.yml | 15 + ansible/roles/common/tasks/main.yml | 104 +++++++ ansible/roles/common/templates/hosts.j2 | 16 + ansible/roles/mailserver/defaults/main.yml | 12 + .../mailserver/files/classifier-bayes.conf | 1 + .../mailserver/files/default_website.html | 1 + .../roles/mailserver/files/disable_dns.conf | 2 + ansible/roles/mailserver/files/dovecot.conf | 174 +++++++++++ ansible/roles/mailserver/files/logging.inc | 2 + .../roles/mailserver/files/mail.nbit.ch.conf | 24 ++ .../mailserver/files/milter_headers.conf | 2 + ansible/roles/mailserver/files/multimap.conf | 27 ++ ansible/roles/mailserver/files/redis.conf | 1 + .../roles/mailserver/files/renew-certificates | 1 + ansible/roles/mailserver/files/resolv.conf | 6 + ansible/roles/mailserver/handlers/main.yml | 40 +++ ansible/roles/mailserver/tasks/main.yml | 275 ++++++++++++++++++ .../roles/mailserver/templates/accounts.cf.j2 | 5 + .../roles/mailserver/templates/aliases.cf.j2 | 8 + .../roles/mailserver/templates/domains.cf.j2 | 5 + .../mailserver/templates/dovecot-sql.conf.j2 | 7 + ansible/roles/mailserver/templates/main.cf.j2 | 150 ++++++++++ .../templates/recipient-access.cf.j2 | 5 + .../templates/sender-login-maps.cf.j2 | 7 + .../mailserver/templates/tls-policy.cf.j2 | 5 + .../templates/worker-controller.inc.j2 | 1 + ansible/roles/zabbix-agent/handlers/main.yml | 5 + ansible/roles/zabbix-agent/tasks/main.yml | 16 + 37 files changed, 1087 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 ansible/mailserver.yml create mode 100644 ansible/production create mode 100644 ansible/roles/aide/files/aide-update create mode 100644 ansible/roles/aide/files/aide.conf.local create mode 100644 ansible/roles/aide/handlers/main.yml create mode 100644 ansible/roles/aide/tasks/main.yml create mode 100644 ansible/roles/common/files/jail.local create mode 100644 ansible/roles/common/handlers/main.yml create mode 100644 ansible/roles/common/tasks/main.yml create mode 100644 ansible/roles/common/templates/hosts.j2 create mode 100644 ansible/roles/mailserver/defaults/main.yml create mode 100644 ansible/roles/mailserver/files/classifier-bayes.conf create mode 100644 ansible/roles/mailserver/files/default_website.html create mode 100644 ansible/roles/mailserver/files/disable_dns.conf create mode 100644 ansible/roles/mailserver/files/dovecot.conf create mode 100644 ansible/roles/mailserver/files/logging.inc create mode 100644 ansible/roles/mailserver/files/mail.nbit.ch.conf create mode 100644 ansible/roles/mailserver/files/milter_headers.conf create mode 100644 ansible/roles/mailserver/files/multimap.conf create mode 100644 ansible/roles/mailserver/files/redis.conf create mode 100644 ansible/roles/mailserver/files/renew-certificates create mode 100644 ansible/roles/mailserver/files/resolv.conf create mode 100644 ansible/roles/mailserver/handlers/main.yml create mode 100644 ansible/roles/mailserver/tasks/main.yml create mode 100644 ansible/roles/mailserver/templates/accounts.cf.j2 create mode 100644 ansible/roles/mailserver/templates/aliases.cf.j2 create mode 100644 ansible/roles/mailserver/templates/domains.cf.j2 create mode 100644 ansible/roles/mailserver/templates/dovecot-sql.conf.j2 create mode 100644 ansible/roles/mailserver/templates/main.cf.j2 create mode 100644 ansible/roles/mailserver/templates/recipient-access.cf.j2 create mode 100644 ansible/roles/mailserver/templates/sender-login-maps.cf.j2 create mode 100644 ansible/roles/mailserver/templates/tls-policy.cf.j2 create mode 100644 ansible/roles/mailserver/templates/worker-controller.inc.j2 create mode 100644 ansible/roles/zabbix-agent/handlers/main.yml create mode 100644 ansible/roles/zabbix-agent/tasks/main.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..61962e6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +hcloud/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..8249682 --- /dev/null +++ b/README.md @@ -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) diff --git a/ansible/mailserver.yml b/ansible/mailserver.yml new file mode 100644 index 0000000..d8c63f8 --- /dev/null +++ b/ansible/mailserver.yml @@ -0,0 +1,10 @@ +--- +# file: mailserver.yml +- hosts: mailserver + vars: + ansible_ssh_pipelining: yes + roles: + - common + - zabbix-agent + - aide + - mailserver diff --git a/ansible/production b/ansible/production new file mode 100644 index 0000000..10fabc8 --- /dev/null +++ b/ansible/production @@ -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 diff --git a/ansible/roles/aide/files/aide-update b/ansible/roles/aide/files/aide-update new file mode 100644 index 0000000..ddb8c66 --- /dev/null +++ b/ansible/roles/aide/files/aide-update @@ -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 + diff --git a/ansible/roles/aide/files/aide.conf.local b/ansible/roles/aide/files/aide.conf.local new file mode 100644 index 0000000..1aa3856 --- /dev/null +++ b/ansible/roles/aide/files/aide.conf.local @@ -0,0 +1 @@ +!/root/.ansible/tmp diff --git a/ansible/roles/aide/handlers/main.yml b/ansible/roles/aide/handlers/main.yml new file mode 100644 index 0000000..7825d8e --- /dev/null +++ b/ansible/roles/aide/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: update aide database + action: command /usr/local/bin/aide-update diff --git a/ansible/roles/aide/tasks/main.yml b/ansible/roles/aide/tasks/main.yml new file mode 100644 index 0000000..6a5c3cc --- /dev/null +++ b/ansible/roles/aide/tasks/main.yml @@ -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 diff --git a/ansible/roles/common/files/jail.local b/ansible/roles/common/files/jail.local new file mode 100644 index 0000000..9eb356c --- /dev/null +++ b/ansible/roles/common/files/jail.local @@ -0,0 +1,2 @@ +[sshd] +enabled = true diff --git a/ansible/roles/common/handlers/main.yml b/ansible/roles/common/handlers/main.yml new file mode 100644 index 0000000..acf60a7 --- /dev/null +++ b/ansible/roles/common/handlers/main.yml @@ -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 diff --git a/ansible/roles/common/tasks/main.yml b/ansible/roles/common/tasks/main.yml new file mode 100644 index 0000000..893fda8 --- /dev/null +++ b/ansible/roles/common/tasks/main.yml @@ -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' diff --git a/ansible/roles/common/templates/hosts.j2 b/ansible/roles/common/templates/hosts.j2 new file mode 100644 index 0000000..a2480d4 --- /dev/null +++ b/ansible/roles/common/templates/hosts.j2 @@ -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 diff --git a/ansible/roles/mailserver/defaults/main.yml b/ansible/roles/mailserver/defaults/main.yml new file mode 100644 index 0000000..9fefab1 --- /dev/null +++ b/ansible/roles/mailserver/defaults/main.yml @@ -0,0 +1,12 @@ +$ANSIBLE_VAULT;1.1;AES256 +62656635343535363437303935663462656438363731363763373039303830656261623531646362 +3036653865663464643836626233383238643931613236340a343566623134323565333766326165 +64646533643836323734303739383761396463633464373732383230656461396131626334303735 +3166323135393565390a303538353031346632653336366363353739653639613661346539383535 +37393330356262363233336439336566623064386261306433613962306531366339373930363838 +38376161633933643633393665386432353734373866333437656335343764663933393366623931 +37343639353730333834373466336439653836313135386162343963653430306238386665383362 +36343364626132333430333261373237333136313337333638366136303931663930613737633163 +66336364646262656666643361626133343637383566626163343366616566306462326566353161 +30663438366232646332363937636639306130313130386137363138626635333364393630303063 +656161633037633830353064666236356632 diff --git a/ansible/roles/mailserver/files/classifier-bayes.conf b/ansible/roles/mailserver/files/classifier-bayes.conf new file mode 100644 index 0000000..e3dd51a --- /dev/null +++ b/ansible/roles/mailserver/files/classifier-bayes.conf @@ -0,0 +1 @@ +backend = "redis"; diff --git a/ansible/roles/mailserver/files/default_website.html b/ansible/roles/mailserver/files/default_website.html new file mode 100644 index 0000000..3d9db70 --- /dev/null +++ b/ansible/roles/mailserver/files/default_website.html @@ -0,0 +1 @@ +

mail2.nbit.ch

diff --git a/ansible/roles/mailserver/files/disable_dns.conf b/ansible/roles/mailserver/files/disable_dns.conf new file mode 100644 index 0000000..d435aba --- /dev/null +++ b/ansible/roles/mailserver/files/disable_dns.conf @@ -0,0 +1,2 @@ +[main] +dns=none diff --git a/ansible/roles/mailserver/files/dovecot.conf b/ansible/roles/mailserver/files/dovecot.conf new file mode 100644 index 0000000..c1b6b84 --- /dev/null +++ b/ansible/roles/mailserver/files/dovecot.conf @@ -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 =