summaryrefslogtreecommitdiffstats
path: root/roles/common
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2014-07-01 23:02:45 +0200
committerGuilhem Moulin <guilhem@fripost.org>2015-06-07 02:52:13 +0200
commitde4859456f1de54540c96ad97f62858dd089a980 (patch)
tree4b4904258ae3daf6a6b4f852cbc9821acdfa8cc4 /roles/common
parent170dc68f9275dffb48fbe3f8ebb2183cd7ddf111 (diff)
Replace IPSec tunnels by app-level ephemeral TLS sessions.
For some reason giraff doesn't like IPSec. App-level TLS sessions are less efficient, but thanks to ansible it still scales well.
Diffstat (limited to 'roles/common')
-rw-r--r--roles/common/files/etc/postfix/master.cf5
-rw-r--r--roles/common/tasks/ipsec.yml6
-rw-r--r--roles/common/tasks/mail.yml59
-rw-r--r--roles/common/tasks/main.yml3
-rw-r--r--roles/common/templates/etc/iptables/services.j213
-rw-r--r--roles/common/templates/etc/postfix/main.cf.j217
-rw-r--r--roles/common/templates/etc/postfix/tls_policy.j26
7 files changed, 88 insertions, 21 deletions
diff --git a/roles/common/files/etc/postfix/master.cf b/roles/common/files/etc/postfix/master.cf
index e845371..70f7f4e 100644
--- a/roles/common/files/etc/postfix/master.cf
+++ b/roles/common/files/etc/postfix/master.cf
@@ -8,49 +8,44 @@
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (yes) (never) (100)
# ==========================================================================
smtp inet n - - - - smtpd
submission inet n - - - - smtpd
pickup fifo n - - 60 1 pickup
cleanup unix n - - - 0 cleanup
qmgr fifo n - n 300 1 qmgr
tlsmgr unix - - - 1000? 1 tlsmgr
rewrite unix - - - - - trivial-rewrite
bounce unix - - - - 0 bounce
defer unix - - - - 0 bounce
trace unix - - - - 0 bounce
verify unix - - - - 1 verify
flush unix n - - 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - - - - smtp
smtpl unix - - - - - smtp
-o smtp_bind_address=127.0.0.1
-smtps unix - - - - - smtp
- -o smtp_bind_address=172.16.0.1
relay unix - - - - - smtp
# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq unix n - - - - showq
error unix - - - - - error
retry unix - - - - - error
discard unix - - - - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - - - - lmtp
anvil unix - - - - 1 anvil
scache unix - - - - 1 scache
127.0.0.1:16132 inet n - - - - smtpd
2525 inet n - - - - smtpd
2526 inet n - - - - smtpd
2527 inet n - - - - smtpd
- -o mynetworks=0.0.0.0/0
127.0.0.1:2580 inet n - - - - smtpd
-127.0.0.1:smtp inet n - - - - smtpd
- -o inet_interfaces=127.0.0.1
reserved-alias unix - n n - - pipe
flags=Rhu user=nobody argv=/usr/local/sbin/reserved-alias.pl ${sender} ${original_recipient} @fripost.org
mlmmj unix - n n - - pipe
flags=Rhu user=mlmmj argv=/usr/bin/mlmmj-receive -L /var/spool/mlmmj/${domain}/${user}
amavisfeed unix - - n - 2 lmtp
-o lmtp_destination_recipient_limit=1000
-o lmtp_send_xforward_command=yes
-o lmtp_data_done_timeout=1200s
diff --git a/roles/common/tasks/ipsec.yml b/roles/common/tasks/ipsec.yml
index 51d717f..36807d2 100644
--- a/roles/common/tasks/ipsec.yml
+++ b/roles/common/tasks/ipsec.yml
@@ -1,42 +1,46 @@
- name: Install strongSwan
apt: pkg=strongswan-ikev2
- name: Generate a private key and a X.509 certificate for IPSec
command: genkeypair.sh x509
--pubkey=/etc/ipsec.d/certs/{{ inventory_hostname }}.pem
--privkey=/etc/ipsec.d/private/{{ inventory_hostname }}.key
--dns={{ inventory_hostname }}
-t ecdsa -b secp521r1 -h sha512
register: r1
changed_when: r1.rc == 0
failed_when: r1.rc > 1
notify:
- Restart IPSec
+ tags:
+ - genkey
- name: Fetch the public part of IPSec's host key
- sudo: False
# Ensure we don't fetch private data
+ sudo: False
fetch: src=/etc/ipsec.d/certs/{{ inventory_hostname }}.pem
dest=certs/ipsec/
fail_on_missing=yes
flat=yes
+ tags:
+ - genkey
# Don't copy our pubkey due to a possible race condition. Only the
# remote machine has authority regarding its key.
- name: Copy IPSec host pubkeys (except ours)
copy: src=certs/ipsec/{{ item }}.pem
dest=/etc/ipsec.d/certs/{{ item }}.pem
owner=root group=root
mode=0644
with_items: groups.all | difference([inventory_hostname])
register: r2
notify:
- Restart IPSec
- name: Configure IPSec's secrets
template: src=etc/ipsec.secrets.j2
dest=/etc/ipsec.secrets
owner=root group=root
mode=0600
register: r3
notify:
diff --git a/roles/common/tasks/mail.yml b/roles/common/tasks/mail.yml
index 8572784..74919c8 100644
--- a/roles/common/tasks/mail.yml
+++ b/roles/common/tasks/mail.yml
@@ -27,34 +27,89 @@
notify:
- Restart Postfix
- name: Configure Postfix (1)
copy: src=etc/postfix/master.cf
dest=/etc/postfix/master.cf
owner=root group=root
mode=0644
notify:
- Reload Postfix
- name: Configure Postfix (2)
template: src=etc/postfix/main.cf.j2
dest=/etc/postfix/main.cf
owner=root group=root
mode=0644
register: r3
notify:
- Restart Postfix
-- name: Update the static local Postfix database
+- name: Create directory /etc/postfix/ssl
+ file: path=/etc/postfix/ssl
+ state=directory
+ owner=root group=root
+ mode=0755
+ tags:
+ - genkey
+
+- name: Generate a private key and a X.509 certificate for Postfix
+ command: genkeypair.sh x509
+ --pubkey=/etc/postfix/ssl/{{ ansible_fqdn }}.pem
+ --privkey=/etc/postfix/ssl/{{ ansible_fqdn }}.key
+ --dns={{ ansible_fqdn }}
+ -t ecdsa -b secp384r1 -h sha512
+ register: r4
+ changed_when: r4.rc == 0
+ failed_when: r4.rc > 1
+ tags:
+ - genkey
+
+- name: Fetch Postfix's X.509 certificate
+ # Ensure we don't fetch private data
+ sudo: False
+ fetch: src=/etc/postfix/ssl/{{ ansible_fqdn }}.pem
+ dest=certs/postfix/
+ fail_on_missing=yes
+ flat=yes
+ tags:
+ - genkey
+
+- name: Compile the static local Postfix database
postmap: cmd=postalias src=/etc/aliases db=cdb
owner=root group=root
mode=0644
# We're using CDB
- name: Delete /etc/aliases.db
file: path=/etc/aliases.db state=absent
+- name: Build the Postfix TLS policy map
+ sudo: False
+ # smtp_tls_fingerprint_digest MUST be sha256!
+ local_action: shell openssl x509 -in certs/postfix/{{ item }}.pem -noout -fingerprint -sha256 | cut -d= -f2
+ with_items: groups.out | sort
+ register: tls_policy
+ changed_when: False
+ when: "'out' not in group_names"
+
+- name: Copy the Postfix TLS policy map
+ template: src=etc/postfix/tls_policy.j2
+ dest=/etc/postfix/tls_policy
+ owner=root group=root
+ mode=0644
+ when: "'out' not in group_names"
+
+- name: Compile the Postfix TLS policy map
+ postmap: cmd=postmap src=/etc/postfix/tls_policy db=cdb
+ owner=root group=root
+ mode=0644
+ when: "'out' not in group_names"
+ register: r5
+ notify:
+ - Restart Postfix
+
- name: Start Postfix
service: name=postfix state=started
- when: not (r1.changed or r2.changed or r3.changed)
+ when: not (r1.changed or r2.changed or r3.changed or r5.changed)
- meta: flush_handlers
diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml
index 0048443..464abd0 100644
--- a/roles/common/tasks/main.yml
+++ b/roles/common/tasks/main.yml
@@ -1,38 +1,37 @@
---
- include: sysctl.yml tags=sysctl
- include: hosts.yml
- include: apt.yml tags=apt
- include: firewall.yml tags=firewall,iptables
- include: samhain.yml tags=samhain
- include: rkhunter.yml tags=rkhunter
- include: clamav.yml tags=clamav
- include: fail2ban.yml tags=fail2ban
- include: smart.yml tags=smartmontools,smart
- include: haveged.yml tags=haveged,entropy
- name: Copy genkeypair.sh
copy: src=usr/local/bin/genkeypair.sh
dest=/usr/local/bin/genkeypair.sh
owner=root group=root
mode=0755
tags:
- - genkeypair
-- include: ipsec.yml tags=strongswan,ipsec
+ - genkey
- include: logging.yml tags=logging
- include: ntp.yml tags=ntp
- include: mail.yml tags=mail,postfix
- name: Install common packages
apt: pkg={{ item }}
with_items:
- ca-certificates
- daemontools
- etckeeper
- ethtool
- git
- harden-clients
- harden-servers
- htop
- molly-guard
- rsync
- screen
- telnet-ssl
diff --git a/roles/common/templates/etc/iptables/services.j2 b/roles/common/templates/etc/iptables/services.j2
index 923aa35..3e31f04 100644
--- a/roles/common/templates/etc/iptables/services.j2
+++ b/roles/common/templates/etc/iptables/services.j2
@@ -1,34 +1,39 @@
# {{ ansible_managed }}
# Do NOT edit this file directly!
#
# direction protocol destination port source port
# (in|out|inout)[46]? (tcp|udp|..) (port|port:port|port,port) (port|port:port|port,port)
-inout udp 500 500 # ISAKMP
-#inout udp 4500 4500 # IPSec NAT Traversal
-
out tcp 80,443 # HTTP/HTTPS
out udp 53 # DNS
out udp 67 # DHCP
{% if 'NTP-master' in group_names %}
out udp 123 123 # NTP
{% endif %}
in tcp {{ ansible_ssh_port|default('22') }} # SSH
{% if 'MX' in group_names %}
in tcp 25 # SMTP
{% endif %}
{% if 'out' in group_names %}
-#out tcp 25 # SMTP
+in tcp {{ postfix_instance.out.port }}
+out tcp 25 # SMTP
+{% else %}
+out tcp {{ postfix_instance.out.port }}
{% endif %}
{% if 'IMAP' in group_names %}
in tcp 993 # IMAPS
in tcp 4190 # ManageSieve
{% endif %}
+{% if 'MDA' in group_names %}
+in tcp {{ postfix_instance.mda.port }}
+{% endif %}
{% if 'MSA' in group_names %}
in tcp 587 # SMTP-AUTH
{% endif %}
{% if 'webmail' in group_names %}
in tcp 80,443 # HTTP/HTTPS
+out tcp 993 # IMAP # TODO imapc
+out tcp 4190
{% endif %}
diff --git a/roles/common/templates/etc/postfix/main.cf.j2 b/roles/common/templates/etc/postfix/main.cf.j2
index 70d4b98..1abce71 100644
--- a/roles/common/templates/etc/postfix/main.cf.j2
+++ b/roles/common/templates/etc/postfix/main.cf.j2
@@ -1,65 +1,68 @@
########################################################################
# Nullmailer configuration
#
# {{ ansible_managed }}
# Do NOT edit this file directly!
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
readme_directory = no
mail_owner = postfix
myorigin = /etc/mailname
myhostname = {{ ansible_fqdn }}
mydomain = {{ ansible_domain }}
append_dot_mydomain = no
# This server is for internal use only
mynetworks_style = host
inet_interfaces = loopback-only
-inet_protocols = ipv4
# No local delivery
mydestination =
local_transport = error:5.1.1 Mailbox unavailable
alias_maps =
local_recipient_maps =
# All aliases are virtual
default_database_type = cdb
virtual_alias_maps = cdb:/etc/aliases
alias_database = $virtual_alias_maps
-# Forward everything to our internal mailhub
+# Forward everything to our internal outgoing proxy
{% if 'out' in group_names %}
relayhost = [127.0.0.1]:{{ postfix_instance.out.port }}
{% else %}
relayhost = [outgoing.fripost.org]:{{ postfix_instance.out.port }}
{% endif %}
relay_domains =
-# Tunnel everything through IPSec
-smtp_tls_security_level = none
{% if 'out' in group_names %}
-smtp_bind_address = 127.0.0.1
+smtp_tls_security_level = none
+smtp_bind_address = 127.0.0.1
{% else %}
-smtp_bind_address = 172.16.0.1
+smtp_tls_security_level = encrypt
+smtp_tls_cert_file = $config_directory/ssl/{{ ansible_fqdn }}.pem
+smtp_tls_key_file = $config_directory/ssl/{{ ansible_fqdn }}.key
+smtp_tls_session_cache_database = btree:$data_directory/smtp_tls_session_cache
+smtp_tls_policy_maps = cdb:$config_directory/tls_policy
+smtp_tls_fingerprint_digest = sha256
{% endif %}
-smtpd_tls_security_level = none
+smtpd_tls_security_level = none
# Turn off all TCP/IP listener ports except that dedicated to
# samhain(8), which sadly cannot use pickup through the sendmail binary.
master_service_disable = !127.0.0.1:16132.inet inet
{% set multi_instance = False %}
{%- for g in postfix_instance.keys() | sort -%}
{%- if g in group_names -%}
{%- if not multi_instance -%}
{%- set multi_instance = True -%}
## Other postfix instances
multi_instance_wrapper = $command_directory/postmulti -p --
multi_instance_enable = yes
multi_instance_directories =
{%- endif %} /etc/postfix-{{ postfix_instance[g].name }}
{%- endif %}
{% endfor %}
diff --git a/roles/common/templates/etc/postfix/tls_policy.j2 b/roles/common/templates/etc/postfix/tls_policy.j2
new file mode 100644
index 0000000..b4fc453
--- /dev/null
+++ b/roles/common/templates/etc/postfix/tls_policy.j2
@@ -0,0 +1,6 @@
+# {{ ansible_managed }}
+
+[outgoing.fripost.org]:{{ postfix_instance.out.port }} fingerprint ciphers=high protocols=TLSv1.2
+{% for x in tls_policy.results %}
+ match={{ x.stdout }}
+{% endfor %}