From 94c82143038ad02b0d0b7f8607d0b432c4831fe2 Mon Sep 17 00:00:00 2001
From: Tom Hughes <tom@compton.nu>
Date: Fri, 5 Oct 2018 19:10:10 +0100
Subject: [PATCH] Use a letsencrypt certificate for the main mail server

---
 cookbooks/exim/metadata.rb                    |  1 +
 cookbooks/exim/recipes/default.rb             | 34 ++++++++++----
 cookbooks/exim/templates/default/apache.erb   | 46 +++++++++++++++++++
 .../exim/templates/default/exim4.conf.erb     |  5 ++
 roles/mail.rb                                 |  4 ++
 5 files changed, 80 insertions(+), 10 deletions(-)
 create mode 100644 cookbooks/exim/templates/default/apache.erb

diff --git a/cookbooks/exim/metadata.rb b/cookbooks/exim/metadata.rb
index 19ab6af9d..e095f164e 100644
--- a/cookbooks/exim/metadata.rb
+++ b/cookbooks/exim/metadata.rb
@@ -8,3 +8,4 @@ version           "1.0.0"
 supports          "ubuntu"
 depends           "networking"
 depends           "ssl"
+depends           "apache"
diff --git a/cookbooks/exim/recipes/default.rb b/cookbooks/exim/recipes/default.rb
index 6b20f5181..c46606dbf 100644
--- a/cookbooks/exim/recipes/default.rb
+++ b/cookbooks/exim/recipes/default.rb
@@ -33,21 +33,35 @@ group "ssl-cert" do
   append true
 end
 
-openssl_x509_certificate "/etc/ssl/certs/exim.pem" do
-  key_file "/etc/ssl/private/exim.key"
-  owner "root"
-  group "ssl-cert"
-  mode 0o640
-  org "OpenStreetMap"
-  email "postmaster@openstreetmap.org"
-  common_name node[:fqdn]
-  expire 3650
+if node[:exim][:certificate_names]
+  include_recipe "apache"
+
+  apache_site node[:exim][:certificate_names].first do
+    template "apache.erb"
+    variables :aliases => node[:exim][:certificate_names].drop(1)
+  end
+
+  ssl_certificate node[:exim][:certificate_names].first do
+    domains node[:exim][:certificate_names]
+    notifies :restart, "service[exim4]"
+  end
+else
+  openssl_x509_certificate "/etc/ssl/certs/exim.pem" do
+    key_file "/etc/ssl/private/exim.key"
+    owner "root"
+    group "ssl-cert"
+    mode 0o640
+    org "OpenStreetMap"
+    email "postmaster@openstreetmap.org"
+    common_name node[:fqdn]
+    expire 3650
+    notifies :restart, "service[exim4]"
+  end
 end
 
 service "exim4" do
   action [:enable, :start]
   supports :status => true, :restart => true, :reload => true
-  subscribes :restart, "execute[/etc/ssl/certs/exim.pem]"
 end
 
 relay_to_domains = node[:exim][:relay_to_domains]
diff --git a/cookbooks/exim/templates/default/apache.erb b/cookbooks/exim/templates/default/apache.erb
new file mode 100644
index 000000000..f7a5c8ada
--- /dev/null
+++ b/cookbooks/exim/templates/default/apache.erb
@@ -0,0 +1,46 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+<VirtualHost *:80>
+  ServerName <%= @name %>
+<% @aliases.each do |alias_name| -%>
+  ServerAlias <%= alias_name %>
+<% end -%>
+  ServerAdmin webmaster@openstreetmap.org
+
+  CustomLog /var/log/apache2/<%= @name %>-access.log combined
+  ErrorLog /var/log/apache2/<%= @name %>-error.log
+
+  RedirectPermanent /.well-known/acme-challenge/ http://acme.openstreetmap.org/.well-known/acme-challenge/
+  RedirectPermanent / https://<%= @name %>/
+</VirtualHost>
+<% unless @aliases.empty? -%>
+
+<VirtualHost *:443>
+  ServerName <%= @aliases.first %>
+<% @aliases.drop(1).each do |alias_name| -%>
+  ServerAlias <%= alias_name %>
+<% end -%>
+  ServerAdmin webmaster@openstreetmap.org
+
+  SSLEngine on
+  SSLCertificateFile /etc/ssl/certs/<%= @name %>.pem
+  SSLCertificateKeyFile /etc/ssl/private/<%= @name %>.key
+
+  CustomLog /var/log/apache2/<%= @name %>-access.log combined
+  ErrorLog /var/log/apache2/<%= @name %>-error.log
+
+  RedirectPermanent / https://<%= @name %>/
+</VirtualHost>
+<% end -%>
+
+<VirtualHost *:443>
+  ServerName <%= @name %>
+  ServerAdmin webmaster@openstreetmap.org
+
+  SSLEngine on
+  SSLCertificateFile /etc/ssl/certs/<%= @name %>.pem
+  SSLCertificateKeyFile /etc/ssl/private/<%= @name %>.key
+
+  CustomLog /var/log/apache2/<%= @name %>-access.log combined
+  ErrorLog /var/log/apache2/<%= @name %>-error.log
+</VirtualHost>
diff --git a/cookbooks/exim/templates/default/exim4.conf.erb b/cookbooks/exim/templates/default/exim4.conf.erb
index f541cec17..18544c091 100644
--- a/cookbooks/exim/templates/default/exim4.conf.erb
+++ b/cookbooks/exim/templates/default/exim4.conf.erb
@@ -156,8 +156,13 @@ tls_require_ciphers = <%= node[:ssl][:gnutls_ciphers] %>:%SERVER_PRECEDENCE
 # need the first setting, or in separate files, in which case you need both
 # options.
 
+<% if node[:exim][:certificate_names] -%>
+tls_certificate = /etc/ssl/certs/<%= node[:exim][:certificate_names].first %>.pem
+tls_privatekey = /etc/ssl/private/<%= node[:exim][:certificate_names].first %>.key
+<% else -%>
 tls_certificate = /etc/ssl/certs/exim.pem
 tls_privatekey = /etc/ssl/private/exim.key
+<% end -%>
 
 # In order to support roaming users who wish to send email from anywhere,
 # you may want to make Exim listen on other ports as well as port 25, in
diff --git a/roles/mail.rb b/roles/mail.rb
index 6556b08ca..e2ec91ded 100644
--- a/roles/mail.rb
+++ b/roles/mail.rb
@@ -16,6 +16,10 @@ default_attributes(
       "osm.io"
     ],
     :daemon_smtp_ports => [25, 26],
+    :certificate_names => [
+      "mail.openstreetmap.org",
+      "a.mx.openstreetmap.org"
+    ],
     :smarthost_name => "mail.openstreetmap.org",
     :smarthost_via => false,
     :dns_blacklists => ["zen.spamhaus.org"],
-- 
2.39.5