選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

5年前
5年前
5年前
5年前
1年前
1年前
5年前
5年前
2年前
2年前
2年前
2年前
10ヶ月前
2年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
11ヶ月前
5年前
2年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
2年前
5年前
5年前
5年前
1年前
1年前
1年前
3年前
3年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. #!/bin/sh
  2. # BEFORE INSTALLING
  3. # Have a Debian or Ubuntu server with a static IP and DNS records (usually
  4. # A/AAAA) that point your domain name to it.
  5. # NOTE WHILE INSTALLING
  6. # On installation of Postfix, select "Internet Site" and put in TLD (without
  7. # `mail.` before it).
  8. # AFTER INSTALLING
  9. # More DNS records will be given to you to install. One of them will be
  10. # different for every installation and is uniquely generated on your machine.
  11. umask 0022
  12. apt-get install -y postfix postfix-pcre dovecot-imapd dovecot-pop3d dovecot-sieve opendkim opendkim-tools spamassassin spamc net-tools fail2ban bind9-host
  13. domain="$(cat /etc/mailname)"
  14. subdom=${MAIL_SUBDOM:-mail}
  15. maildomain="$subdom.$domain"
  16. certdir="/etc/letsencrypt/live/$maildomain"
  17. # Preliminary record checks
  18. ipv4=$(host "$domain" | grep -m1 -Eo '([0-9]+\.){3}[0-9]+')
  19. [ -z "$ipv4" ] && echo "\033[0;31mPlease point your domain ("$domain") to your server's ipv4 address." && exit 1
  20. ipv6=$(host "$domain" | grep "IPv6" | awk '{print $NF}')
  21. [ -z "$ipv6" ] && echo "\033[0;31mPlease point your domain ("$domain") to your server's ipv6 address." && exit 1
  22. # Open required mail ports, and 80, for Certbot.
  23. for port in 80 993 465 25 587 110 995; do
  24. ufw allow "$port" 2>/dev/null
  25. done
  26. [ ! -d "$certdir" ] &&
  27. possiblecert="$(certbot certificates 2>/dev/null | grep "Domains:\.* \(\*\.$domain\|$maildomain\)\(\s\|$\)" -A 2 | awk '/Certificate Path/ {print $3}' | head -n1)" &&
  28. certdir="${possiblecert%/*}"
  29. [ ! -d "$certdir" ] &&
  30. certdir="/etc/letsencrypt/live/$maildomain" &&
  31. case "$(netstat -tulpn | grep ":80\s")" in
  32. *nginx*)
  33. apt install -y python3-certbot-nginx
  34. certbot -d "$maildomain" certonly --nginx --register-unsafely-without-email --agree-tos
  35. ;;
  36. *apache*)
  37. apt install -y python3-certbot-apache
  38. certbot -d "$maildomain" certonly --apache --register-unsafely-without-email --agree-tos
  39. ;;
  40. *)
  41. apt install -y python3-certbot
  42. certbot -d "$maildomain" certonly --standalone --register-unsafely-without-email --agree-tos
  43. ;;
  44. esac
  45. [ ! -d "$certdir" ] && echo "Error locating or installing SSL certificate." && exit 1
  46. echo "Configuring Postfix's main.cf..."
  47. # Adding additional vars to fix an issue with receiving emails (relay access denied) and adding it to mydestination.
  48. postconf -e "myhostname = $maildomain"
  49. postconf -e "mail_name = $domain" #This is for the smtpd_banner
  50. postconf -e "mydomain = $domain"
  51. postconf -e 'mydestination = $myhostname, $mydomain, mail, localhost.localdomain, localhost, localhost.$mydomain'
  52. # Change the cert/key files to the default locations of the Let's Encrypt cert/key
  53. postconf -e "smtpd_tls_key_file=$certdir/privkey.pem"
  54. postconf -e "smtpd_tls_cert_file=$certdir/fullchain.pem"
  55. postconf -e "smtp_tls_CAfile=$certdir/cert.pem"
  56. # Enable, but do not require TLS. Requiring it with other servers would cause
  57. # mail delivery problems and requiring it locally would cause many other
  58. # issues.
  59. postconf -e 'smtpd_tls_security_level = may'
  60. postconf -e 'smtp_tls_security_level = may'
  61. # TLS required for authentication.
  62. postconf -e 'smtpd_tls_auth_only = yes'
  63. # Exclude insecure and obsolete encryption protocols.
  64. postconf -e 'smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1'
  65. postconf -e 'smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1'
  66. postconf -e 'smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1'
  67. postconf -e 'smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1'
  68. # Exclude suboptimal ciphers.
  69. # postconf -e 'tls_preempt_cipherlist = yes'
  70. # postconf -e 'smtpd_tls_exclude_ciphers = aNULL, LOW, EXP, MEDIUM, ADH, AECDH, MD5, DSS, ECDSA, CAMELLIA128, 3DES, CAMELLIA256, RSA+AES, eNULL'
  71. # Here we tell Postfix to look to Dovecot for authenticating users/passwords.
  72. # Dovecot will be putting an authentication socket in /var/spool/postfix/private/auth
  73. postconf -e 'smtpd_sasl_auth_enable = yes'
  74. postconf -e 'smtpd_sasl_type = dovecot'
  75. postconf -e 'smtpd_sasl_path = private/auth'
  76. # helo, sender, relay and recipient restrictions
  77. postconf -e "smtpd_sender_login_maps = pcre:/etc/postfix/login_maps.pcre"
  78. postconf -e 'smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_sender_login_mismatch, reject_unknown_reverse_client_hostname, reject_unknown_sender_domain'
  79. postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, reject_unknown_recipient_domain'
  80. postconf -e 'smtpd_relay_restrictions = permit_sasl_authenticated, reject_unauth_destination'
  81. postconf -e 'smtpd_helo_required = yes'
  82. postconf -e 'smtpd_helo_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_helo_hostname'
  83. # NOTE: the trailing slash here, or for any directory name in the home_mailbox
  84. # command, is necessary as it distinguishes a maildir (which is the actual
  85. # directory that we want) from a spoolfile (which is what old unix boomers want
  86. # and no one else).
  87. postconf -e 'home_mailbox = Mail/Inbox/'
  88. # Prevent "Received From:" header in sent emails in order to prevent leakage of public ip addresses
  89. postconf -e "header_checks = regexp:/etc/postfix/header_checks"
  90. # strips "Received From:" in sent emails
  91. echo "/^Received:.*/ IGNORE
  92. /^X-Originating-IP:/ IGNORE" >> /etc/postfix/header_checks
  93. # Create a login map file that ensures that if a sender wants to send a mail from a user at our local
  94. # domain, they must be authenticated as that user
  95. echo "/^(.*)@$(sh -c "echo $domain | sed 's/\./\\\./'")$/ \${1}" > /etc/postfix/login_maps.pcre
  96. # master.cf
  97. echo "Configuring Postfix's master.cf..."
  98. sed -i '/^\s*-o/d;/^\s*submission/d;/^\s*smtp/d' /etc/postfix/master.cf
  99. echo "smtp unix - - n - - smtp
  100. smtp inet n - y - - smtpd
  101. -o content_filter=spamassassin
  102. submission inet n - y - - smtpd
  103. -o syslog_name=postfix/submission
  104. -o smtpd_tls_security_level=encrypt
  105. -o smtpd_tls_auth_only=yes
  106. -o smtpd_enforce_tls=yes
  107. -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  108. -o smtpd_sender_restrictions=reject_sender_login_mismatch
  109. -o smtpd_sender_login_maps=pcre:/etc/postfix/login_maps.pcre
  110. -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject_unauth_destination
  111. smtps inet n - y - - smtpd
  112. -o syslog_name=postfix/smtps
  113. -o smtpd_tls_wrappermode=yes
  114. -o smtpd_sasl_auth_enable=yes
  115. spamassassin unix - n n - - pipe
  116. user=debian-spamd argv=/usr/bin/spamc -f -e /usr/sbin/sendmail -oi -f \${sender} \${recipient}" >> /etc/postfix/master.cf
  117. # By default, dovecot has a bunch of configs in /etc/dovecot/conf.d/ These
  118. # files have nice documentation if you want to read it, but it's a huge pain to
  119. # go through them to organize. Instead, we simply overwrite
  120. # /etc/dovecot/dovecot.conf because it's easier to manage. You can get a backup
  121. # of the original in /usr/share/dovecot if you want.
  122. mv /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.backup.conf
  123. echo "Creating Dovecot config..."
  124. echo "# Dovecot config
  125. # Note that in the dovecot conf, you can use:
  126. # %u for username
  127. # %n for the name in name@domain.tld
  128. # %d for the domain
  129. # %h the user's home directory
  130. ssl = required
  131. ssl_cert = <$certdir/fullchain.pem
  132. ssl_key = <$certdir/privkey.pem
  133. ssl_min_protocol = TLSv1.2
  134. ssl_cipher_list = "'EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA256:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EDH+aRSA+AESGCM:EDH+aRSA+SHA256:EDH+aRSA:EECDH:!aNULL:!eNULL:!MEDIUM:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4:!SEED'"
  135. ssl_prefer_server_ciphers = yes
  136. ssl_dh = </usr/share/dovecot/dh.pem
  137. auth_mechanisms = plain login
  138. auth_username_format = %n
  139. protocols = \$protocols imap pop3
  140. # Search for valid users in /etc/passwd
  141. userdb {
  142. driver = passwd
  143. }
  144. #Fallback: Use plain old PAM to find user passwords
  145. passdb {
  146. driver = pam
  147. }
  148. # Our mail for each user will be in ~/Mail, and the inbox will be ~/Mail/Inbox
  149. # The LAYOUT option is also important because otherwise, the boxes will be \`.Sent\` instead of \`Sent\`.
  150. mail_location = maildir:~/Mail:INBOX=~/Mail/Inbox:LAYOUT=fs
  151. namespace inbox {
  152. inbox = yes
  153. mailbox Drafts {
  154. special_use = \\Drafts
  155. auto = subscribe
  156. }
  157. mailbox Junk {
  158. special_use = \\Junk
  159. auto = subscribe
  160. autoexpunge = 30d
  161. }
  162. mailbox Sent {
  163. special_use = \\Sent
  164. auto = subscribe
  165. }
  166. mailbox Trash {
  167. special_use = \\Trash
  168. }
  169. mailbox Archive {
  170. special_use = \\Archive
  171. }
  172. }
  173. # Here we let Postfix use Dovecot's authentication system.
  174. service auth {
  175. unix_listener /var/spool/postfix/private/auth {
  176. mode = 0660
  177. user = postfix
  178. group = postfix
  179. }
  180. }
  181. protocol lda {
  182. mail_plugins = \$mail_plugins sieve
  183. }
  184. protocol lmtp {
  185. mail_plugins = \$mail_plugins sieve
  186. }
  187. protocol pop3 {
  188. pop3_uidl_format = %08Xu%08Xv
  189. pop3_no_flag_updates = yes
  190. }
  191. plugin {
  192. sieve = ~/.dovecot.sieve
  193. sieve_default = /var/lib/dovecot/sieve/default.sieve
  194. #sieve_global_path = /var/lib/dovecot/sieve/default.sieve
  195. sieve_dir = ~/.sieve
  196. sieve_global_dir = /var/lib/dovecot/sieve/
  197. }
  198. " > /etc/dovecot/dovecot.conf
  199. # If using an old version of Dovecot, remove the ssl_dl line.
  200. case "$(dovecot --version)" in
  201. 1|2.1*|2.2*) sed -i '/^ssl_dh/d' /etc/dovecot/dovecot.conf ;;
  202. esac
  203. mkdir /var/lib/dovecot/sieve/
  204. echo "require [\"fileinto\", \"mailbox\"];
  205. if header :contains \"X-Spam-Flag\" \"YES\"
  206. {
  207. fileinto \"Junk\";
  208. }" > /var/lib/dovecot/sieve/default.sieve
  209. grep -q '^vmail:' /etc/passwd || useradd vmail
  210. chown -R vmail:vmail /var/lib/dovecot
  211. sievec /var/lib/dovecot/sieve/default.sieve
  212. echo 'Preparing user authentication...'
  213. grep -q nullok /etc/pam.d/dovecot ||
  214. echo 'auth required pam_unix.so nullok
  215. account required pam_unix.so' >> /etc/pam.d/dovecot
  216. # OpenDKIM
  217. # A lot of the big name email services, like Google, will automatically reject
  218. # as spam unfamiliar and unauthenticated email addresses. As in, the server
  219. # will flatly reject the email, not even delivering it to someone's Spam
  220. # folder.
  221. # OpenDKIM is a way to authenticate your email so you can send to such services
  222. # without a problem.
  223. # Create an OpenDKIM key in the proper place with proper permissions.
  224. echo 'Generating OpenDKIM keys...'
  225. mkdir -p "/etc/postfix/dkim/$domain"
  226. opendkim-genkey -D "/etc/postfix/dkim/$domain" -d "$domain" -s "$subdom"
  227. chgrp -R opendkim /etc/postfix/dkim/*
  228. chmod -R g+r /etc/postfix/dkim/*
  229. # Generate the OpenDKIM info:
  230. echo 'Configuring OpenDKIM...'
  231. grep -q "$domain" /etc/postfix/dkim/keytable 2>/dev/null ||
  232. echo "$subdom._domainkey.$domain $domain:$subdom:/etc/postfix/dkim/$domain/$subdom.private" >> /etc/postfix/dkim/keytable
  233. grep -q "$domain" /etc/postfix/dkim/signingtable 2>/dev/null ||
  234. echo "*@$domain $subdom._domainkey.$domain" >> /etc/postfix/dkim/signingtable
  235. grep -q '127.0.0.1' /etc/postfix/dkim/trustedhosts 2>/dev/null ||
  236. echo '127.0.0.1
  237. 10.1.0.0/16' >> /etc/postfix/dkim/trustedhosts
  238. # ...and source it from opendkim.conf
  239. grep -q '^KeyTable' /etc/opendkim.conf 2>/dev/null || echo 'KeyTable file:/etc/postfix/dkim/keytable
  240. SigningTable refile:/etc/postfix/dkim/signingtable
  241. InternalHosts refile:/etc/postfix/dkim/trustedhosts' >> /etc/opendkim.conf
  242. sed -i '/^#Canonicalization/s/simple/relaxed\/simple/' /etc/opendkim.conf
  243. sed -i '/^#Canonicalization/s/^#//' /etc/opendkim.conf
  244. sed -i '/Socket/s/^#*/#/' /etc/opendkim.conf
  245. grep -q '^Socket\s*inet:12301@localhost' /etc/opendkim.conf || echo 'Socket inet:12301@localhost' >> /etc/opendkim.conf
  246. # OpenDKIM daemon settings, removing previously activated socket.
  247. sed -i '/^SOCKET/d' /etc/default/opendkim && echo "SOCKET=\"inet:12301@localhost\"" >> /etc/default/opendkim
  248. # Here we add to postconf the needed settings for working with OpenDKIM
  249. echo 'Configuring Postfix with OpenDKIM settings...'
  250. postconf -e 'smtpd_sasl_security_options = noanonymous, noplaintext'
  251. postconf -e 'smtpd_sasl_tls_security_options = noanonymous'
  252. postconf -e "myhostname = $maildomain"
  253. postconf -e 'milter_default_action = accept'
  254. postconf -e 'milter_protocol = 6'
  255. postconf -e 'smtpd_milters = inet:localhost:12301'
  256. postconf -e 'non_smtpd_milters = inet:localhost:12301'
  257. postconf -e 'mailbox_command = /usr/lib/dovecot/deliver'
  258. # Long-term fix to prevent SMTP smuggling
  259. postconf -e 'smtpd_forbid_bare_newline = normalize'
  260. postconf -e 'smtpd_forbid_bare_newline_exclusions = $mynetworks'
  261. # A fix for "Opendkim won't start: can't open PID file?", as specified here: https://serverfault.com/a/847442
  262. /lib/opendkim/opendkim.service.generate
  263. systemctl daemon-reload
  264. # Enable fail2ban security for dovecot and postfix.
  265. [ ! -f /etc/fail2ban/jail.d/emailwiz.local ] && echo "[postfix]
  266. enabled = true
  267. [postfix-sasl]
  268. enabled = true
  269. [sieve]
  270. enabled = true
  271. [dovecot]
  272. enabled = true" > /etc/fail2ban/jail.d/emailwiz.local
  273. sed -i "s|^backend = auto$|backend = systemd|" /etc/fail2ban/jail.conf
  274. # Enable SpamAssassin update cronjob.
  275. if [ -f /etc/default/spamassassin ]
  276. then
  277. sed -i "s|^CRON=0|CRON=1|" /etc/default/spamassassin
  278. printf "Restarting spamassassin..."
  279. service spamassassin restart && printf " ...done\\n"
  280. systemctl enable spamassassin
  281. elif [ -f /etc/default/spamd ]
  282. then
  283. sed -i "s|^CRON=0|CRON=1|" /etc/default/spamd
  284. printf "Restarting spamd..."
  285. service spamd restart && printf " ...done\\n"
  286. systemctl enable spamd
  287. else
  288. printf "!!! Neither /etc/default/spamassassin or /etc/default/spamd exists, this is unexpected and needs to be investigated"
  289. fi
  290. for x in opendkim dovecot postfix fail2ban; do
  291. printf "Restarting %s..." "$x"
  292. service "$x" restart && printf " ...done\\n"
  293. systemctl enable "$x"
  294. done
  295. pval="$(tr -d '\n' <"/etc/postfix/dkim/$domain/$subdom.txt" | sed "s/k=rsa.* \"p=/k=rsa; p=/;s/\"\s*\"//;s/\"\s*).*//" | grep -o 'p=.*')"
  296. dkimentry="$subdom._domainkey.$domain TXT v=DKIM1; k=rsa; $pval"
  297. dmarcentry="_dmarc.$domain TXT v=DMARC1; p=reject; rua=mailto:postmaster@$domain; fo=1"
  298. spfentry="$domain TXT v=spf1 mx a:$maildomain ip4:$ipv4 ip6:$ipv6 -all"
  299. mxentry="$domain MX 10 $maildomain 300"
  300. useradd -m -G mail postmaster
  301. # Create a cronjob that deletes month-old postmaster mails:
  302. cat <<EOF > /etc/cron.weekly/postmaster-clean
  303. #!/bin/sh
  304. find /home/postmaster/Mail -type f -mtime +30 -name '*.mail*' -delete >/dev/null 2>&1
  305. exit 0
  306. EOF
  307. chmod 755 /etc/cron.weekly/postmaster-clean
  308. grep -q '^deploy-hook = echo "$RENEWED_DOMAINS" | grep -q' /etc/letsencrypt/cli.ini ||
  309. echo "
  310. deploy-hook = echo \"\$RENEWED_DOMAINS\" | grep -q '$maildomain' && service postfix reload && service dovecot reload" >> /etc/letsencrypt/cli.ini
  311. echo "NOTE: Elements in the entries might appear in a different order in your registrar's DNS settings.
  312. $dkimentry
  313. $dmarcentry
  314. $spfentry
  315. $mxentry" > "$HOME/dns_emailwizard"
  316. printf "\033[31m
  317. _ _
  318. | \ | | _____ ___
  319. | \| |/ _ \ \ /\ / (_)
  320. | |\ | (_) \ V V / _
  321. |_| \_|\___/ \_/\_/ (_)\033[0m
  322. Add these three records to your DNS TXT records on either your registrar's site
  323. or your DNS server:
  324. \033[32m
  325. $dkimentry
  326. $dmarcentry
  327. $spfentry
  328. $mxentry
  329. \033[0m
  330. NOTE: You may need to omit the \`.$domain\` portion at the beginning if
  331. inputting them in a registrar's web interface.
  332. Also, these are now saved to \033[34m~/dns_emailwizard\033[0m in case you want them in a file.
  333. Once you do that, you're done! Check the README for how to add users/accounts
  334. and how to log in.\n"