diff --git a/group_vars/all b/group_vars/all
index 5627b340f337b492a8402d6d4f92c02c93f8990a..5229bdf3d82c1da7e1b53f9186d976109a99366f 100644
--- a/group_vars/all
+++ b/group_vars/all
@@ -1,11 +1,14 @@
 # This should be some e-mail address where technical messages may go.
-admin_email: "michik@michik.net"
+# The idea here is, that this email address should exist for every host if
+# the services-base.yml playbook has been run.
+admin_email: "admins@{{ inventory_hostname }}"
 
 # Please feel free to add your favorite software you need absolutely everywhere
 # here. However, please do not leave too much stuff nobody else might use or
 # stuff that could be handy for an attacker.
 apt_essential_packages:
  - vim
+ - htop
 
 # This is all the stuff we neither need nor want on our computers.
 apt_unwanted_packages:
diff --git a/roles/acmetool/defaults/main.yml b/roles/acmetool/defaults/main.yml
index 5bfba53a9e765875cc13df6bafdcf3ac6f5ef2f3..2cc5dd0fa26412f6a3f767992117804fa89d9add 100644
--- a/roles/acmetool/defaults/main.yml
+++ b/roles/acmetool/defaults/main.yml
@@ -3,7 +3,7 @@
 # nginx (much simpler that way).
 
 acmetool_cert_domains:
- - "{{ ansible_fqdn }}"
+ - "{{ inventory_hostname }}"
 
 # This is the production environment. To use the staging environment, please
 # override for the host(s) in question with the following URL:
diff --git a/roles/acmetool/tasks/main.yml b/roles/acmetool/tasks/main.yml
index 6abd4a80cb58f53a7186f479cf82d35ed3bfd434..1aae1368ea7631ebcdb2d997a68149369404c64d 100644
--- a/roles/acmetool/tasks/main.yml
+++ b/roles/acmetool/tasks/main.yml
@@ -1,6 +1,8 @@
 - name: install acmetool
   apt:
     package: acmetool
+    update_cache: yes
+    cache_valid_time: 3600
     state: present
 
 - name: create acmetool conf and webroot directories
diff --git a/roles/nginx-http/tasks/main.yml b/roles/nginx-http/tasks/main.yml
index e9f5f11dd617c3631a7e94220e368a7ef90344e2..d3b74c6b8e7fe93ab69366e2a5f7b93ef45f2f77 100644
--- a/roles/nginx-http/tasks/main.yml
+++ b/roles/nginx-http/tasks/main.yml
@@ -1,6 +1,8 @@
 - name: install nginx
   apt:
     package: nginx
+    update_cache: yes
+    cache_valid_time: 3600
     state: present
 
 - name: enable nginx
diff --git a/roles/nginx-https/defaults/main.yml b/roles/nginx-https/defaults/main.yml
index 8f038c5a6e649dca6686840170b1f2598625fdba..8980b5553cbfcbe06a9d004aae31ff6545b915fd 100644
--- a/roles/nginx-https/defaults/main.yml
+++ b/roles/nginx-https/defaults/main.yml
@@ -6,7 +6,7 @@ nginx_ssl_dhparam_bits: 4096
 nginx_https_default_headers: null
 
 nginx_https_sites:
- - name: "{{ ansible_fqdn }}"
+ - name: "{{ inventory_hostname }}"
    locations:
     - location: "/"
       config: |
diff --git a/roles/nginx-https/tasks/main.yml b/roles/nginx-https/tasks/main.yml
index a27f5007a5fa39d67e2488fbf7e72be09e4e29d5..4f51cf6af18ac6cf473236e1521ed3dd26c673b9 100644
--- a/roles/nginx-https/tasks/main.yml
+++ b/roles/nginx-https/tasks/main.yml
@@ -2,7 +2,6 @@
   command: 'openssl dhparam -out "{{ nginx_ssl_dhparam }}" {{ nginx_ssl_dhparam_bits }}'
   args:
     creates: "{{ nginx_ssl_dhparam }}"
-  when: nginx_hmi_ssl_dhparam is not none
 
 - name: configure the https sites
   template:
diff --git a/roles/postfix/defaults/main.yml b/roles/postfix/defaults/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..39e9ae37b04615310170dafe6a52f8c0bec8daca
--- /dev/null
+++ b/roles/postfix/defaults/main.yml
@@ -0,0 +1,13 @@
+postfix_alias_maps:
+ - "hash:/etc/aliases"
+postfix_virtual_alias_domains: []
+postfix_virtual_alias_maps: []
+postfix_mailbox_size_limit: 0
+postfix_message_size_limit: 102400000
+postfix_tls_high_cipherlist: "ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA"
+postfix_smtpd_tls_mandatory_protocols: "TLSv1.2"
+postfix_ssl_dhparam: "/etc/postfix/dh_2048.pem"
+postfix_ssl_dhparam_bits: 2048
+
+opendkim_enabled: false
+
diff --git a/roles/postfix/handlers/main.yml b/roles/postfix/handlers/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3c53c32d915645e07bf72610fb21fe50d1e60c7c
--- /dev/null
+++ b/roles/postfix/handlers/main.yml
@@ -0,0 +1,7 @@
+- name: restart postfix
+  systemd:
+    name: postfix
+    state: restarted
+
+- name: newaliases
+  command: newaliases
diff --git a/roles/postfix/meta/main.yml b/roles/postfix/meta/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..20563e0213befa197dda0a80f225e4d8f44298c1
--- /dev/null
+++ b/roles/postfix/meta/main.yml
@@ -0,0 +1,2 @@
+dependencies:
+ - acmetool
diff --git a/roles/postfix/tasks/main.yml b/roles/postfix/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4c8b97660568c418d80be5b80a3d9b7edfd921bb
--- /dev/null
+++ b/roles/postfix/tasks/main.yml
@@ -0,0 +1,28 @@
+- name: install postfix
+  apt:
+    package: postfix
+    update_cache: yes
+    cache_valid_time: 3600
+    state: present
+
+- name: create dh parameters
+  command: 'openssl dhparam -out "{{ postfix_ssl_dhparam }}" {{ postfix_ssl_dhparam_bits }}'
+  args:
+    creates: "{{ postfix_ssl_dhparam }}"
+
+- name: configure postfix
+  template:
+    src: "main.cf.j2"
+    dest: "/etc/postfix/main.cf"
+  notify: restart postfix
+
+- name: load user info
+  include_vars:
+    file: "files/users/users.yml"
+    name: "user_info"
+
+- name: create aliases
+  template:
+    src: "aliases.j2"
+    dest: "/etc/aliases"
+  notify: newaliases
diff --git a/roles/postfix/templates/aliases.j2 b/roles/postfix/templates/aliases.j2
new file mode 100644
index 0000000000000000000000000000000000000000..89a3919becd1a2ed65b3f389bbaeef4f816d9517
--- /dev/null
+++ b/roles/postfix/templates/aliases.j2
@@ -0,0 +1,13 @@
+# {{ ansible_managed }}
+
+# admin email addresses from git
+admins: {% for user in user_info.users if 'email_address' in user and 'wants_admin_emails' in user and user['wants_admin_emails'] %}{{ user['email_address'] }}{{ "," if not loop.last else '' }}{% endfor %}
+
+
+# rfc 2142 and other role addresses
+abuse: admins
+noc: admins
+security: admins
+postmaster: admins
+webmaster: admins
+root: admins
diff --git a/roles/postfix/templates/main.cf.j2 b/roles/postfix/templates/main.cf.j2
new file mode 100644
index 0000000000000000000000000000000000000000..2c5630d37e425ec1eaca5fd7aa7b729203f940e2
--- /dev/null
+++ b/roles/postfix/templates/main.cf.j2
@@ -0,0 +1,62 @@
+# {{ ansible_managed }}
+
+biff = no
+
+compatibility_level = 2
+
+myhostname = {{ inventory_hostname }}
+mydestination = localhost, $myhostname
+
+alias_database = hash:/etc/aliases
+alias_maps = {{ postfix_alias_maps|join(', ') }}
+{% if postfix_virtual_alias_domains %}virtual_alias_domains = {{ postfix_virtual_alias_domains|join(', ') }}{% endif %}
+{% if postfix_virtual_alias_maps %}virtual_alias_maps = {{ postfix_virtual_alias_maps|join(', ') }}{% endif %}
+
+inet_interfaces = all
+inet_protocols = ipv6, ipv4
+
+mailbox_size_limit = {{ postfix_mailbox_size_limit }}
+message_size_limit = {{ postfix_message_size_limit }}
+{% if opendkim_enabled %}non_smtpd_milters = inet:localhost:11332{% endif %}
+
+tls_high_cipherlist = {{ postfix_tls_high_cipherlist }}
+
+smtp_tls_security_level = may
+smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
+smtp_use_tls = yes
+
+smtpd_banner = $myhostname loves ESMTP
+smtpd_tls_cert_file=/var/lib/acme/live/{{ inventory_hostname }}/fullchain
+smtpd_tls_key_file=/var/lib/acme/live/{{ inventory_hostname }}/privkey
+smtpd_tls_dh1024_param_file = {{ postfix_ssl_dhparam }}
+smtpd_tls_eecdh_grade = ultra
+smtpd_tls_loglevel = 0
+smtpd_tls_mandatory_ciphers = high
+smtpd_tls_mandatory_protocols = {{ postfix_smtpd_tls_mandatory_protocols }}
+smtpd_tls_received_header = yes
+smtpd_tls_security_level = may
+smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
+smtpd_use_tls=yes
+
+smtpd_helo_restrictions =
+ permit_mynetworks,
+ reject_invalid_helo_hostname,
+ reject_non_fqdn_helo_hostname
+
+smtpd_sender_restrictions =
+ permit_mynetworks,
+ reject_non_fqdn_sender,
+ reject_unauth_pipelining
+
+smtpd_relay_restrictions =
+ permit_mynetworks,
+ reject_unauth_pipelining,
+ reject_unauth_destination
+
+smtpd_recipient_restrictions =
+ permit_mynetworks,
+ reject_unauth_pipelining
+
+smtpd_data_restrictions =
+ permit_mynetworks,
+ reject_unauth_pipelining
diff --git a/services-base.yml b/services-base.yml
index 631d869aaddb5a5be85c303fbdb061a735ddac81..e5070ed91fb6a95008c44cd97c3deba3e0e6b16c 100644
--- a/services-base.yml
+++ b/services-base.yml
@@ -8,3 +8,4 @@
    - nginx-http
    - acmetool
    - nginx-https
+   - postfix