From 69af908f6b1265334c4178e9cac50714ce8d96aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Thu, 7 Dec 2023 14:02:37 +0100 Subject: [PATCH] Virtual domain configs --- .../kosmos_email/attributes/default.rb | 8 +- .../kosmos_email/recipes/dovecot.rb | 23 +++- .../kosmos_email/recipes/postfix.rb | 75 +++++++++---- .../templates/dovecot_10-auth.conf.erb | 2 +- .../templates/dovecot_10-mail.conf.erb | 61 +--------- .../templates/dovecot_15-mailboxes.conf.erb | 106 ++++++++++++++++++ ...aliases.cf.erb => postfix_ldap-map.cf.erb} | 3 + 7 files changed, 188 insertions(+), 90 deletions(-) create mode 100644 site-cookbooks/kosmos_email/templates/dovecot_15-mailboxes.conf.erb rename site-cookbooks/kosmos_email/templates/{ldap-aliases.cf.erb => postfix_ldap-map.cf.erb} (73%) diff --git a/site-cookbooks/kosmos_email/attributes/default.rb b/site-cookbooks/kosmos_email/attributes/default.rb index 0276203..c77e52b 100644 --- a/site-cookbooks/kosmos_email/attributes/default.rb +++ b/site-cookbooks/kosmos_email/attributes/default.rb @@ -1,3 +1,5 @@ -node.default["email"]["domain"] = "example.com" -node.default["email"]["hostname"] = "mail.example.com" -node.default["email"]["report_contact"] = "abuse@example.com" +node.default["email"]["domain"] = "example.com" +node.default["email"]["hostname"] = "mail.example.com" +node.default["email"]["report_contact"] = "abuse@example.com" +node.default["email"]["ldap_host"] = "ldap.kosmos.local" +node.default["email"]["ldap_search_base"] = "cn=users,dc=kosmos,dc=org" diff --git a/site-cookbooks/kosmos_email/recipes/dovecot.rb b/site-cookbooks/kosmos_email/recipes/dovecot.rb index fff9274..9ebafd6 100644 --- a/site-cookbooks/kosmos_email/recipes/dovecot.rb +++ b/site-cookbooks/kosmos_email/recipes/dovecot.rb @@ -17,6 +17,9 @@ domain = node["email"]["domain"] hostname = node["email"]["hostname"] ip_addr = node["knife_zero"]["host"] +ldap_search_base = node["email"]["ldap_search_base"] +ldap_user_filter = "(&(objectClass=person)(mailRoutingAddress=%u))" + credentials = Chef::EncryptedDataBagItem.load('credentials', 'email') user "vmail" do @@ -41,11 +44,11 @@ template "/etc/dovecot/dovecot-ldap.conf.ext" do variables uris: "ldap://ldap.kosmos.local", # TODO add list of all IPs instead? dn: credentials['ldap_dn'], dnpass: credentials['ldap_dnpass'], - base: "ou=kosmos.org,cn=users,dc=kosmos,dc=org", - user_attrs: "mailhome=home", - user_filter: "(&(objectClass=person)(cn=%u))", - pass_attrs: "cn=user,mailpassword=password", - pass_filter: "(&(objectClass=person)(cn=%u))", + base: ldap_search_base, + user_filter: ldap_user_filter, + user_attrs: "", + pass_filter: ldap_user_filter, + pass_attrs: "mailRoutingAddress=user,mailpassword=password", default_pass_scheme: "BLF-CRYPT" notifies :restart, "service[dovecot]", :delayed end @@ -60,7 +63,9 @@ template "/etc/dovecot/conf.d/10-mail.conf" do source "dovecot_10-mail.conf.erb" mode 0644 variables mail_uid: "vmail", - mail_gid: "mail" + mail_gid: "mail", + mail_location: "mbox:~/mail:INBOX=~/mail/INBOX", + mail_home: "/var/vmail/%d/%n" notifies :restart, "service[dovecot]", :delayed end @@ -79,6 +84,12 @@ template "/etc/dovecot/conf.d/10-ssl.conf" do notifies :restart, "service[dovecot]", :delayed end +template "/etc/dovecot/conf.d/15-mailboxes.conf" do + source "dovecot_15-mailboxes.conf.erb" + mode 0644 + notifies :restart, "service[dovecot]", :delayed +end + service "dovecot" do action [:enable, :start] end diff --git a/site-cookbooks/kosmos_email/recipes/postfix.rb b/site-cookbooks/kosmos_email/recipes/postfix.rb index d8892bd..a66dbf1 100644 --- a/site-cookbooks/kosmos_email/recipes/postfix.rb +++ b/site-cookbooks/kosmos_email/recipes/postfix.rb @@ -14,17 +14,19 @@ domain = node["email"]["domain"] hostname = node["email"]["hostname"] ip_addr = node["knife_zero"]["host"] +ldap_host = node["email"]["ldap_host"] +ldap_search_base = node["email"]["ldap_search_base"] + credentials = Chef::EncryptedDataBagItem.load('credentials', 'email') node.normal["postfix"]["mail_type"] = "master" node.normal["postfix"]["use_relay_restrictions_maps"] = true node.normal["postfix"]["relay_restrictions"] = { domain => "OK", hostname => "OK" } -node.normal['postfix']['main']['mydomain'] = domain -node.normal['postfix']['main']['myorigin'] = domain node.normal['postfix']['main']['myhostname'] = hostname +node.normal['postfix']['main']['mydomain'] = "$myhostname" +node.normal['postfix']['main']['myorigin'] = "$myhostname" node.normal['postfix']['main']['mynetworks'] = ["10.1.1.0/24", "127.0.0.0/8"] -node.normal['postfix']['main']['mydestination'] = [domain, hostname, 'localhost.localdomain', 'localhost'].compact node.normal['postfix']['main']['smtp_use_tls'] = "yes" node.normal['postfix']['main']['smtp_tls_security_level'] = "may" node.normal['postfix']['main']['smtpd_use_tls'] = "yes" @@ -35,8 +37,13 @@ node.normal['postfix']['main']['mailbox_transport'] = "lmtp:unix:private/dovecot node.normal['postfix']['main']['virtual_transport'] = "lmtp:unix:private/dovecot-lmtp" node.normal['postfix']['main']['smtputf8_enable'] = "no" node.normal['postfix']['main']['recipient_delimiter'] = "+" -node.normal['postfix']['main']['alias_maps'] = "hash:/etc/aliases, ldap:/etc/postfix/ldap-aliases.cf" -node.normal['postfix']['main']['smtpd_sender_login_maps'] = "ldap:/etc/postfix/ldap-username-aliases.cf" + +# node.normal['postfix']['main']['virtual_alias_domains'] = "ldap:/etc/postfix/ldap-virtual_alias_domains.cf" +node.normal['postfix']['main']['virtual_alias_maps'] = "hash:/var/vmail/aliases, ldap:/etc/postfix/ldap-virtual_alias_maps.cf" +node.normal['postfix']['main']['virtual_mailbox_domains'] = "ldap:/etc/postfix/ldap-virtual_mailbox_domains.cf" +node.normal['postfix']['main']['virtual_mailbox_maps'] = "ldap:/etc/postfix/ldap-virtual_mailbox_maps.cf" +node.normal['postfix']['main']['smtpd_sender_login_maps'] = "ldap:/etc/postfix/ldap-smtpd_sender_login_maps.cf" + node.normal['postfix']['main']['milter_protocol'] = "6" node.normal['postfix']['main']['milter_default_action'] = "accept" node.normal['postfix']['main']['smtpd_milters'] = "inet:localhost:12301 local:spamass/spamass.sock" @@ -70,7 +77,7 @@ node.normal['postfix']['master'] = { "-o smtpd_sasl_auth_enable=yes", "-o smtpd_sender_restrictions=reject_sender_login_mismatch", "-o smtpd_relay_restrictions=permit_sasl_authenticated,reject", - "-o smtpd_recipient_restrictions=permit_mynetworks,reject_sender_login_mismatch,permit_sasl_authenticated,reject", + "-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject", "-o smtpd_sasl_type=dovecot", "-o smtpd_sasl_path=private/auth", "-o smtpd_upstream_proxy_protocol=haproxy", @@ -123,27 +130,51 @@ node.normal['postfix']['master'] = { } } -template "/etc/postfix/ldap-aliases.cf" do - source "ldap-aliases.cf.erb" +ldap_default_variables = { + server_host: ldap_host, + bind_dn: credentials['ldap_dn'], + bind_pw: credentials['ldap_dnpass'], + search_base: ldap_search_base +} + +template "/etc/postfix/ldap-virtual_mailbox_domains.cf" do + source "postfix_ldap-map.cf.erb" mode 0600 - variables server_host: "ldap.kosmos.local", - bind_dn: credentials['ldap_dn'], - bind_pw: credentials['ldap_dnpass'], - search_base: "ou=kosmos.org,cn=users,dc=kosmos,dc=org", - query_filter: "(&(objectClass=person)(cn=%u))", - result_attribute: "maildrop" + variables ldap_default_variables.merge({ + query_filter: "mailRoutingAddress=*@%s", + result_attribute: "mailRoutingAddress", + result_format: "%d" + }) notifies :restart, "service[postfix]", :delayed end -template "/etc/postfix/ldap-username-aliases.cf" do - source "ldap-aliases.cf.erb" +template "/etc/postfix/ldap-virtual_alias_maps.cf" do + source "postfix_ldap-map.cf.erb" mode 0600 - variables server_host: "ldap.kosmos.local", - bind_dn: credentials['ldap_dn'], - bind_pw: credentials['ldap_dnpass'], - search_base: "ou=kosmos.org,cn=users,dc=kosmos,dc=org", - query_filter: "(&(objectClass=person)(cn=%u))", - result_attribute: "cn" + variables ldap_default_variables.merge({ + query_filter: "(&(mailRoutingAddress=%s)(mailForwardingAddress=*))", + result_attribute: "mailForwardingAddress" + }) + notifies :restart, "service[postfix]", :delayed +end + +template "/etc/postfix/ldap-virtual_mailbox_maps.cf" do + source "postfix_ldap-map.cf.erb" + mode 0600 + variables ldap_default_variables.merge({ + query_filter: "mailRoutingAddress=%s", + result_attribute: "mailRoutingAddress" + }) + notifies :restart, "service[postfix]", :delayed +end + +template "/etc/postfix/ldap-smtpd_sender_login_maps.cf" do + source "postfix_ldap-map.cf.erb" + mode 0600 + variables ldap_default_variables.merge({ + query_filter: "mailRoutingAddress=%s", + result_attribute: "mailRoutingAddress, mailForwardingAddress" + }) notifies :restart, "service[postfix]", :delayed end diff --git a/site-cookbooks/kosmos_email/templates/dovecot_10-auth.conf.erb b/site-cookbooks/kosmos_email/templates/dovecot_10-auth.conf.erb index f3270b1..7c079aa 100644 --- a/site-cookbooks/kosmos_email/templates/dovecot_10-auth.conf.erb +++ b/site-cookbooks/kosmos_email/templates/dovecot_10-auth.conf.erb @@ -48,7 +48,7 @@ disable_plaintext_auth = yes # the standard variables here, eg. %Lu would lowercase the username, %n would # drop away the domain if it was given, or "%n-AT-%d" would change the '@' into # "-AT-". This translation is done after auth_username_translation changes. -auth_username_format = %n +auth_username_format = %Lu # If you want to allow master users to log in by specifying the master # username within the normal username string (ie. not using SASL mechanism's diff --git a/site-cookbooks/kosmos_email/templates/dovecot_10-mail.conf.erb b/site-cookbooks/kosmos_email/templates/dovecot_10-mail.conf.erb index 8833f28..21c0ee2 100644 --- a/site-cookbooks/kosmos_email/templates/dovecot_10-mail.conf.erb +++ b/site-cookbooks/kosmos_email/templates/dovecot_10-mail.conf.erb @@ -27,7 +27,9 @@ # # # -mail_location = mbox:~/mail:INBOX=~/mail/INBOX +mail_location = <%= @mail_location %> + +mail_home = <%= @mail_home %> # If you need to set multiple mailbox locations or want to change default # namespace settings, you can do it by defining namespace sections. @@ -40,63 +42,6 @@ mail_location = mbox:~/mail:INBOX=~/mail/INBOX # users can access all the shared mailboxes, assuming they have permissions # on filesystem level to do so. namespace inbox { - type = private - inbox = yes - - mailbox Drafts { - special_use = \Drafts - auto = subscribe - } - - mailbox Junk { - special_use = \Junk - auto = create - } - - mailbox spam { - special_use = \Junk - auto = no - } - - mailbox Spam { - special_use = \Junk - auto = no - } - - mailbox Trash { - special_use = \Trash - auto = subscribe - } - - mailbox TRASH { - special_use = \Trash - auto = no - } - - mailbox Sent { - special_use = \Sent - auto = subscribe - } - - mailbox "Sent Mail" { - special_use = \Sent - auto = no - } - - mailbox "Sent Messages" { - special_use = \Sent - auto = no - } - - mailbox Archive { - special_use = \Archive - auto = create - } - - mailbox "Archives" { - special_use = \Archive - auto = no - } } # Example shared namespace configuration diff --git a/site-cookbooks/kosmos_email/templates/dovecot_15-mailboxes.conf.erb b/site-cookbooks/kosmos_email/templates/dovecot_15-mailboxes.conf.erb new file mode 100644 index 0000000..a2c2c59 --- /dev/null +++ b/site-cookbooks/kosmos_email/templates/dovecot_15-mailboxes.conf.erb @@ -0,0 +1,106 @@ +## +## Mailbox definitions +## + +# Each mailbox is specified in a separate mailbox section. The section name +# specifies the mailbox name. If it has spaces, you can put the name +# "in quotes". These sections can contain the following mailbox settings: +# +# auto: +# Indicates whether the mailbox with this name is automatically created +# implicitly when it is first accessed. The user can also be automatically +# subscribed to the mailbox after creation. The following values are +# defined for this setting: +# +# no - Never created automatically. +# create - Automatically created, but no automatic subscription. +# subscribe - Automatically created and subscribed. +# +# special_use: +# A space-separated list of SPECIAL-USE flags (RFC 6154) to use for the +# mailbox. There are no validity checks, so you could specify anything +# you want in here, but it's not a good idea to use flags other than the +# standard ones specified in the RFC: +# +# \All - This (virtual) mailbox presents all messages in the +# user's message store. +# \Archive - This mailbox is used to archive messages. +# \Drafts - This mailbox is used to hold draft messages. +# \Flagged - This (virtual) mailbox presents all messages in the +# user's message store marked with the IMAP \Flagged flag. +# \Important - This (virtual) mailbox presents all messages in the +# user's message store deemed important to user. +# \Junk - This mailbox is where messages deemed to be junk mail +# are held. +# \Sent - This mailbox is used to hold copies of messages that +# have been sent. +# \Trash - This mailbox is used to hold messages that have been +# deleted. +# +# comment: +# Defines a default comment or note associated with the mailbox. This +# value is accessible through the IMAP METADATA mailbox entries +# "/shared/comment" and "/private/comment". Users with sufficient +# privileges can override the default value for entries with a custom +# value. + +# NOTE: Assumes "namespace inbox" has been defined in 10-mail.conf. +namespace inbox { + type = private + inbox = yes + + mailbox Drafts { + special_use = \Drafts + auto = subscribe + } + + mailbox Junk { + special_use = \Junk + auto = create + } + + mailbox spam { + special_use = \Junk + auto = no + } + + mailbox Spam { + special_use = \Junk + auto = no + } + + mailbox Trash { + special_use = \Trash + auto = subscribe + } + + mailbox TRASH { + special_use = \Trash + auto = no + } + + mailbox Sent { + special_use = \Sent + auto = subscribe + } + + mailbox "Sent Mail" { + special_use = \Sent + auto = no + } + + mailbox "Sent Messages" { + special_use = \Sent + auto = no + } + + mailbox Archive { + special_use = \Archive + auto = create + } + + mailbox "Archives" { + special_use = \Archive + auto = no + } +} diff --git a/site-cookbooks/kosmos_email/templates/ldap-aliases.cf.erb b/site-cookbooks/kosmos_email/templates/postfix_ldap-map.cf.erb similarity index 73% rename from site-cookbooks/kosmos_email/templates/ldap-aliases.cf.erb rename to site-cookbooks/kosmos_email/templates/postfix_ldap-map.cf.erb index 3b266a6..2711e0d 100644 --- a/site-cookbooks/kosmos_email/templates/ldap-aliases.cf.erb +++ b/site-cookbooks/kosmos_email/templates/postfix_ldap-map.cf.erb @@ -5,3 +5,6 @@ bind_pw = <%= @bind_pw %> search_base = <%= @search_base %> query_filter = <%= @query_filter %> result_attribute = <%= @result_attribute %> +<% if @result_format %> +result_format = <%= @result_format %> +<% end %>