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