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

emailwiz.sh 15 KiB

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