postfix.sh 9.1 KB

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