postfix.sh 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. #!/bin/bash
  2. trap "postfix stop" EXIT
  3. [[ ! -d /opt/postfix/conf/sql/ ]] && mkdir -p /opt/postfix/conf/sql/
  4. # Wait for MySQL to warm-up
  5. while ! mysqladmin status --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do
  6. echo "Waiting for database to come up..."
  7. sleep 2
  8. done
  9. cat <<EOF > /etc/aliases
  10. # Autogenerated by mailcow
  11. null: /dev/null
  12. ham: "|/usr/local/bin/rspamd-pipe-ham"
  13. spam: "|/usr/local/bin/rspamd-pipe-spam"
  14. EOF
  15. newaliases;
  16. cat <<EOF > /opt/postfix/conf/sql/mysql_relay_recipient_maps.cf
  17. # Autogenerated by mailcow
  18. user = ${DBUSER}
  19. password = ${DBPASS}
  20. hosts = unix:/var/run/mysqld/mysqld.sock
  21. dbname = ${DBNAME}
  22. query = SELECT DISTINCT
  23. CASE WHEN '%d' IN (
  24. SELECT domain FROM domain
  25. WHERE relay_all_recipients=1
  26. AND domain='%d'
  27. AND backupmx=1
  28. )
  29. THEN '%s' ELSE (
  30. SELECT goto FROM alias WHERE address='%s' AND active='1'
  31. )
  32. END AS result;
  33. EOF
  34. cat <<EOF > /opt/postfix/conf/sql/mysql_tls_policy_override_maps.cf
  35. # Autogenerated by mailcow
  36. user = ${DBUSER}
  37. password = ${DBPASS}
  38. hosts = unix:/var/run/mysqld/mysqld.sock
  39. dbname = ${DBNAME}
  40. query = SELECT CONCAT(policy, ' ', parameters) AS tls_policy FROM tls_policy_override WHERE active = '1' AND dest = '%s'
  41. EOF
  42. cat <<EOF > /opt/postfix/conf/sql/mysql_tls_enforce_in_policy.cf
  43. # Autogenerated by mailcow
  44. user = ${DBUSER}
  45. password = ${DBPASS}
  46. hosts = unix:/var/run/mysqld/mysqld.sock
  47. dbname = ${DBNAME}
  48. query = SELECT IF(EXISTS(
  49. SELECT 'TLS_ACTIVE' FROM alias
  50. LEFT OUTER JOIN mailbox ON mailbox.username = alias.goto
  51. WHERE (address='%s'
  52. OR address IN (
  53. SELECT CONCAT('%u', '@', target_domain) FROM alias_domain
  54. WHERE alias_domain='%d'
  55. )
  56. ) AND json_extract(attributes, '$.tls_enforce_in') LIKE '%%1%%' AND mailbox.active = '1'
  57. ), 'reject_plaintext_session', NULL) AS 'tls_enforce_in';
  58. EOF
  59. cat <<EOF > /opt/postfix/conf/sql/mysql_sender_dependent_default_transport_maps.cf
  60. # Autogenerated by mailcow
  61. user = ${DBUSER}
  62. password = ${DBPASS}
  63. hosts = unix:/var/run/mysqld/mysqld.sock
  64. dbname = ${DBNAME}
  65. query = SELECT GROUP_CONCAT(transport SEPARATOR '') AS transport_maps
  66. FROM (
  67. SELECT IF(EXISTS(SELECT 'smtp_type' FROM alias
  68. LEFT OUTER JOIN mailbox ON mailbox.username = alias.goto
  69. WHERE (address = '%s'
  70. OR address IN (
  71. SELECT CONCAT('%u', '@', target_domain) FROM alias_domain
  72. WHERE alias_domain = '%d'
  73. )
  74. )
  75. AND json_extract(attributes, '$.tls_enforce_out') LIKE '%%1%%'
  76. AND mailbox.active = '1'
  77. ), 'smtp_enforced_tls:', 'smtp:') AS 'transport'
  78. UNION ALL
  79. SELECT hostname AS transport FROM relayhosts
  80. LEFT OUTER JOIN domain ON domain.relayhost = relayhosts.id
  81. WHERE relayhosts.active = '1'
  82. AND domain = '%d'
  83. OR domain IN (
  84. SELECT target_domain FROM alias_domain
  85. WHERE alias_domain = '%d'
  86. )
  87. )
  88. AS transport_view;
  89. EOF
  90. cat <<EOF > /opt/postfix/conf/sql/mysql_transport_maps.cf
  91. # Autogenerated by mailcow
  92. user = ${DBUSER}
  93. password = ${DBPASS}
  94. hosts = unix:/var/run/mysqld/mysqld.sock
  95. dbname = ${DBNAME}
  96. query = SELECT CONCAT('smtp_via_transport_maps:', nexthop) AS transport FROM transports
  97. WHERE active = '1'
  98. AND destination = '%s';
  99. EOF
  100. cat <<EOF > /opt/postfix/conf/sql/mysql_virtual_resource_maps.cf
  101. # Autogenerated by mailcow
  102. user = ${DBUSER}
  103. password = ${DBPASS}
  104. hosts = unix:/var/run/mysqld/mysqld.sock
  105. dbname = ${DBNAME}
  106. query = SELECT 'null@localhost' FROM mailbox
  107. WHERE kind REGEXP 'location|thing|group' AND username = '%s';
  108. EOF
  109. cat <<EOF > /opt/postfix/conf/sql/mysql_sasl_passwd_maps_sender_dependent.cf
  110. # Autogenerated by mailcow
  111. user = ${DBUSER}
  112. password = ${DBPASS}
  113. hosts = unix:/var/run/mysqld/mysqld.sock
  114. dbname = ${DBNAME}
  115. query = SELECT CONCAT_WS(':', username, password) AS auth_data FROM relayhosts
  116. WHERE id IN (
  117. SELECT relayhost FROM domain
  118. WHERE CONCAT('@', domain) = '%s'
  119. OR domain IN (
  120. SELECT target_domain FROM alias_domain WHERE CONCAT('@', alias_domain) = '%s'
  121. )
  122. )
  123. AND active = '1'
  124. AND username != '';
  125. EOF
  126. cat <<EOF > /opt/postfix/conf/sql/mysql_sasl_passwd_maps_transport_maps.cf
  127. # Autogenerated by mailcow
  128. user = ${DBUSER}
  129. password = ${DBPASS}
  130. hosts = unix:/var/run/mysqld/mysqld.sock
  131. dbname = ${DBNAME}
  132. query = SELECT CONCAT_WS(':', username, password) AS auth_data FROM transports
  133. WHERE nexthop = '%s'
  134. AND active = '1'
  135. AND username != ''
  136. LIMIT 1;
  137. EOF
  138. cat <<EOF > /opt/postfix/conf/sql/mysql_virtual_alias_domain_maps.cf
  139. # Autogenerated by mailcow
  140. user = ${DBUSER}
  141. password = ${DBPASS}
  142. hosts = unix:/var/run/mysqld/mysqld.sock
  143. dbname = ${DBNAME}
  144. query = SELECT username FROM mailbox, alias_domain
  145. WHERE alias_domain.alias_domain = '%d'
  146. AND mailbox.username = CONCAT('%u', '@', alias_domain.target_domain)
  147. AND mailbox.active = '1'
  148. AND alias_domain.active='1'
  149. EOF
  150. cat <<EOF > /opt/postfix/conf/sql/mysql_virtual_alias_maps.cf
  151. # Autogenerated by mailcow
  152. user = ${DBUSER}
  153. password = ${DBPASS}
  154. hosts = unix:/var/run/mysqld/mysqld.sock
  155. dbname = ${DBNAME}
  156. query = SELECT goto FROM alias
  157. WHERE address='%s'
  158. AND active='1';
  159. EOF
  160. cat <<EOF > /opt/postfix/conf/sql/mysql_recipient_bcc_maps.cf
  161. # Autogenerated by mailcow
  162. user = ${DBUSER}
  163. password = ${DBPASS}
  164. hosts = unix:/var/run/mysqld/mysqld.sock
  165. dbname = ${DBNAME}
  166. query = SELECT bcc_dest FROM bcc_maps
  167. WHERE local_dest='%s'
  168. AND type='rcpt'
  169. AND active='1';
  170. EOF
  171. cat <<EOF > /opt/postfix/conf/sql/mysql_sender_bcc_maps.cf
  172. # Autogenerated by mailcow
  173. user = ${DBUSER}
  174. password = ${DBPASS}
  175. hosts = unix:/var/run/mysqld/mysqld.sock
  176. dbname = ${DBNAME}
  177. query = SELECT bcc_dest FROM bcc_maps
  178. WHERE local_dest='%s'
  179. AND type='sender'
  180. AND active='1';
  181. EOF
  182. cat <<EOF > /opt/postfix/conf/sql/mysql_recipient_canonical_maps.cf
  183. # Autogenerated by mailcow
  184. user = ${DBUSER}
  185. password = ${DBPASS}
  186. hosts = unix:/var/run/mysqld/mysqld.sock
  187. dbname = ${DBNAME}
  188. query = SELECT new_dest FROM recipient_maps
  189. WHERE old_dest='%s'
  190. AND active='1';
  191. EOF
  192. cat <<EOF > /opt/postfix/conf/sql/mysql_virtual_domains_maps.cf
  193. # Autogenerated by mailcow
  194. user = ${DBUSER}
  195. password = ${DBPASS}
  196. hosts = unix:/var/run/mysqld/mysqld.sock
  197. dbname = ${DBNAME}
  198. query = SELECT alias_domain from alias_domain WHERE alias_domain='%s' AND active='1'
  199. UNION
  200. SELECT domain FROM domain
  201. WHERE domain='%s'
  202. AND active = '1'
  203. AND backupmx = '0'
  204. EOF
  205. cat <<EOF > /opt/postfix/conf/sql/mysql_virtual_mailbox_maps.cf
  206. # Autogenerated by mailcow
  207. user = ${DBUSER}
  208. password = ${DBPASS}
  209. hosts = unix:/var/run/mysqld/mysqld.sock
  210. dbname = ${DBNAME}
  211. query = SELECT CONCAT(JSON_UNQUOTE(JSON_EXTRACT(attributes, '$.mailbox_format')), mailbox_path_prefix, '%d/%u/') FROM mailbox WHERE username='%s' AND active = '1'
  212. EOF
  213. cat <<EOF > /opt/postfix/conf/sql/mysql_virtual_relay_domain_maps.cf
  214. # Autogenerated by mailcow
  215. user = ${DBUSER}
  216. password = ${DBPASS}
  217. hosts = unix:/var/run/mysqld/mysqld.sock
  218. dbname = ${DBNAME}
  219. query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '1' AND active = '1'
  220. EOF
  221. cat <<EOF > /opt/postfix/conf/sql/mysql_virtual_sender_acl.cf
  222. # Autogenerated by mailcow
  223. user = ${DBUSER}
  224. password = ${DBPASS}
  225. hosts = unix:/var/run/mysqld/mysqld.sock
  226. dbname = ${DBNAME}
  227. # First select queries domain and alias_domain to determine if domains are active.
  228. query = SELECT goto FROM alias
  229. WHERE address='%s'
  230. AND active='1'
  231. AND (domain IN
  232. (SELECT domain FROM domain
  233. WHERE domain='%d'
  234. AND active='1')
  235. OR domain in (
  236. SELECT alias_domain FROM alias_domain
  237. WHERE alias_domain='%d'
  238. AND active='1'
  239. )
  240. )
  241. UNION
  242. SELECT logged_in_as FROM sender_acl
  243. WHERE send_as='@%d'
  244. OR send_as='%s'
  245. OR send_as='*'
  246. OR send_as IN (
  247. SELECT CONCAT('@',target_domain) FROM alias_domain
  248. WHERE alias_domain = '%d')
  249. OR send_as IN (
  250. SELECT CONCAT('%u','@',target_domain) FROM alias_domain
  251. WHERE alias_domain = '%d')
  252. AND logged_in_as NOT IN (
  253. SELECT goto FROM alias
  254. WHERE address='%s')
  255. UNION
  256. SELECT username FROM mailbox, alias_domain
  257. WHERE alias_domain.alias_domain = '%d'
  258. AND mailbox.username = CONCAT('%u','@',alias_domain.target_domain)
  259. AND mailbox.active ='1'
  260. AND alias_domain.active='1'
  261. EOF
  262. cat <<EOF > /opt/postfix/conf/sql/mysql_virtual_spamalias_maps.cf
  263. # Autogenerated by mailcow
  264. user = ${DBUSER}
  265. password = ${DBPASS}
  266. hosts = unix:/var/run/mysqld/mysqld.sock
  267. dbname = ${DBNAME}
  268. query = SELECT goto FROM spamalias
  269. WHERE address='%s'
  270. AND validity >= UNIX_TIMESTAMP()
  271. EOF
  272. sed -i '/User overrides/q' /opt/postfix/conf/main.cf
  273. echo >> /opt/postfix/conf/main.cf
  274. if [ -f /opt/postfix/conf/extra.cf ]; then
  275. cat /opt/postfix/conf/extra.cf >> /opt/postfix/conf/main.cf
  276. fi
  277. # Fix Postfix permissions
  278. chown -R root:postfix /opt/postfix/conf/sql/
  279. chmod 640 /opt/postfix/conf/sql/*.cf
  280. chgrp -R postdrop /var/spool/postfix/public
  281. chgrp -R postdrop /var/spool/postfix/maildrop
  282. postfix set-permissions
  283. # Check Postfix configuration
  284. postconf -c /opt/postfix/conf > /dev/null
  285. if [[ $? != 0 ]]; then
  286. echo "Postfix configuration error, refusing to start."
  287. exit 1
  288. else
  289. postfix -c /opt/postfix/conf start
  290. sleep 126144000
  291. fi