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

emailwiz.sh 13 KiB

5年前
5年前
5年前
5年前
5年前
5年前
5年前
2年前
2年前
5年前
3年前
3年前
3年前
3年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
3年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
3年前
5年前
5年前
3年前
5年前
2年前
2年前
2年前
4年前
4年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. #!/bin/sh
  2. # THE SETUP
  3. # Mail will be stored in non-retarded Maildirs because it's $currentyear. This
  4. # makes it easier for use with isync, which is what I care about so I can have
  5. # an offline repo of mail.
  6. # The mailbox names are: Inbox, Sent, Drafts, Archive, Junk, Trash
  7. # Use the typical unix login system for mail users. Users will log into their
  8. # email with their passnames on the server. No usage of a redundant mySQL
  9. # database to do this.
  10. # BEFORE INSTALLING
  11. # Have a Debian or Ubuntu server with a static IP and DNS records (usually
  12. # A/AAAA) that point your domain name to it.
  13. # NOTE WHILE INSTALLING
  14. # On installation of Postfix, select "Internet Site" and put in TLD (without
  15. # `mail.` before it).
  16. # AFTER INSTALLING
  17. # More DNS records will be given to you to install. One of them will be
  18. # different for every installation and is uniquely generated on your machine.
  19. umask 0022
  20. apt-get install -y postfix postfix-pcre dovecot-imapd dovecot-sieve opendkim spamassassin spamc net-tools fail2ban
  21. # Check if OpenDKIM is installed and install it if not.
  22. which opendkim-genkey >/dev/null 2>&1 || apt-get install opendkim-tools
  23. domain="$(cat /etc/mailname)"
  24. subdom=${MAIL_SUBDOM:-mail}
  25. maildomain="$subdom.$domain"
  26. certdir="/etc/letsencrypt/live/$maildomain"
  27. # Open required mail ports, and 80, for Certbot.
  28. for port in 80 993 465 25 587; do
  29. ufw allow "$port" 2>/dev/null
  30. done
  31. [ ! -d "$certdir" ] &&
  32. possiblecert="$(certbot certificates 2>/dev/null | grep "Domains:\.* \(\*\.$domain\|$maildomain\)\(\s\|$\)" -A 2 | awk '/Certificate Path/ {print $3}' | head -n1)" &&
  33. certdir="${possiblecert%/*}"
  34. [ ! -d "$certdir" ] &&
  35. certdir="/etc/letsencrypt/live/$maildomain" &&
  36. case "$(netstat -tulpn | grep ":80\s")" in
  37. *nginx*)
  38. apt install -y python3-certbot-nginx
  39. certbot -d "$maildomain" certonly --nginx --register-unsafely-without-email --agree-tos
  40. ;;
  41. *apache*)
  42. apt install -y python3-certbot-apache
  43. certbot -d "$maildomain" certonly --apache --register-unsafely-without-email --agree-tos
  44. ;;
  45. *)
  46. apt install -y python3-certbot
  47. certbot -d "$maildomain" certonly --standalone --register-unsafely-without-email --agree-tos
  48. ;;
  49. esac
  50. [ ! -d "$certdir" ] && echo "Error locating or installing SSL certificate." && exit 1
  51. echo "Configuring Postfix's main.cf..."
  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 server 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 obsolete, 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. # Sender, relay and recipient restrictions
  77. postconf -e "smtpd_sender_login_maps = pcre:/etc/postfix/login_maps.pcre"
  78. postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, reject_unknown_recipient_domain'
  79. postconf -e 'smtpd_relay_restrictions = permit_sasl_authenticated, reject_unauth_destination'
  80. # NOTE: the trailing slash here, or for any directory name in the home_mailbox
  81. # command, is necessary as it distinguishes a maildir (which is the actual
  82. # directories that what we want) from a spoolfile (which is what old unix
  83. # boomers want and no one else).
  84. postconf -e 'home_mailbox = Mail/Inbox/'
  85. # Prevent "Received From:" header in sent emails in order to prevent leakage of public ip addresses
  86. postconf -e "header_checks = regexp:/etc/postfix/header_checks"
  87. # strips "Received From:" in sent emails
  88. echo "/^Received:.*/ IGNORE
  89. /^X-Originating-IP:/ IGNORE" >> /etc/postfix/header_checks
  90. # Create a login map file that ensures that if a sender wants to send a mail from a user at our local
  91. # domain, they must be authenticated as that user
  92. echo "/^(.*)@$(sh -c "echo $domain | sed 's/\./\\\./'")$/ \${1}" > /etc/postfix/login_maps.pcre
  93. # master.cf
  94. echo "Configuring Postfix's master.cf..."
  95. sed -i '/^\s*-o/d;/^\s*submission/d;/^\s*smtp/d' /etc/postfix/master.cf
  96. echo "smtp unix - - n - - smtp
  97. smtp inet n - y - - smtpd
  98. -o content_filter=spamassassin
  99. submission inet n - y - - smtpd
  100. -o syslog_name=postfix/submission
  101. -o smtpd_tls_security_level=encrypt
  102. -o smtpd_sasl_auth_enable=yes
  103. -o smtpd_tls_auth_only=yes
  104. smtps inet n - y - - smtpd
  105. -o syslog_name=postfix/smtps
  106. -o smtpd_tls_wrappermode=yes
  107. -o smtpd_sasl_auth_enable=yes
  108. spamassassin unix - n n - - pipe
  109. user=debian-spamd argv=/usr/bin/spamc -f -e /usr/sbin/sendmail -oi -f \${sender} \${recipient}" >> /etc/postfix/master.cf
  110. # By default, dovecot has a bunch of configs in /etc/dovecot/conf.d/ These
  111. # files have nice documentation if you want to read it, but it's a huge pain to
  112. # go through them to organize. Instead, we simply overwrite
  113. # /etc/dovecot/dovecot.conf because it's easier to manage. You can get a backup
  114. # of the original in /usr/share/dovecot if you want.
  115. mv /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.backup.conf
  116. echo "Creating Dovecot config..."
  117. echo "# Dovecot config
  118. # Note that in the dovecot conf, you can use:
  119. # %u for username
  120. # %n for the name in name@domain.tld
  121. # %d for the domain
  122. # %h the user's home directory
  123. ssl = required
  124. ssl_cert = <$certdir/fullchain.pem
  125. ssl_key = <$certdir/privkey.pem
  126. ssl_min_protocol = TLSv1.2
  127. 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'"
  128. ssl_prefer_server_ciphers = yes
  129. ssl_dh = </usr/share/dovecot/dh.pem
  130. auth_mechanisms = plain login
  131. auth_username_format = %n
  132. protocols = \$protocols imap
  133. # Search for valid users in /etc/passwd
  134. userdb {
  135. driver = passwd
  136. }
  137. #Fallback: Use plain old PAM to find user passwords
  138. passdb {
  139. driver = pam
  140. }
  141. # Our mail for each user will be in ~/Mail, and the inbox will be ~/Mail/Inbox
  142. # The LAYOUT option is also important because otherwise, the boxes will be \`.Sent\` instead of \`Sent\`.
  143. mail_location = maildir:~/Mail:INBOX=~/Mail/Inbox:LAYOUT=fs
  144. namespace inbox {
  145. inbox = yes
  146. mailbox Drafts {
  147. special_use = \\Drafts
  148. auto = subscribe
  149. }
  150. mailbox Junk {
  151. special_use = \\Junk
  152. auto = subscribe
  153. autoexpunge = 30d
  154. }
  155. mailbox Sent {
  156. special_use = \\Sent
  157. auto = subscribe
  158. }
  159. mailbox Trash {
  160. special_use = \\Trash
  161. }
  162. mailbox Archive {
  163. special_use = \\Archive
  164. }
  165. }
  166. # Here we let Postfix use Dovecot's authetication system.
  167. service auth {
  168. unix_listener /var/spool/postfix/private/auth {
  169. mode = 0660
  170. user = postfix
  171. group = postfix
  172. }
  173. }
  174. protocol lda {
  175. mail_plugins = \$mail_plugins sieve
  176. }
  177. protocol lmtp {
  178. mail_plugins = \$mail_plugins sieve
  179. }
  180. plugin {
  181. sieve = ~/.dovecot.sieve
  182. sieve_default = /var/lib/dovecot/sieve/default.sieve
  183. #sieve_global_path = /var/lib/dovecot/sieve/default.sieve
  184. sieve_dir = ~/.sieve
  185. sieve_global_dir = /var/lib/dovecot/sieve/
  186. }
  187. " > /etc/dovecot/dovecot.conf
  188. # If using an old version of Dovecot, remove the ssl_dl line.
  189. case "$(dovecot --version)" in
  190. 1|2.1*|2.2*) sed -i '/^ssl_dh/d' /etc/dovecot/dovecot.conf ;;
  191. esac
  192. mkdir /var/lib/dovecot/sieve/
  193. echo "require [\"fileinto\", \"mailbox\"];
  194. if header :contains \"X-Spam-Flag\" \"YES\"
  195. {
  196. fileinto \"Junk\";
  197. }" > /var/lib/dovecot/sieve/default.sieve
  198. grep -q '^vmail:' /etc/passwd || useradd vmail
  199. chown -R vmail:vmail /var/lib/dovecot
  200. sievec /var/lib/dovecot/sieve/default.sieve
  201. echo 'Preparing user authentication...'
  202. grep -q nullok /etc/pam.d/dovecot ||
  203. echo 'auth required pam_unix.so nullok
  204. account required pam_unix.so' >> /etc/pam.d/dovecot
  205. # OpenDKIM
  206. # A lot of the big name email services, like Google, will automatically reject
  207. # as spam unfamiliar and unauthenticated email addresses. As in, the server
  208. # will flatly reject the email, not even delivering it to someone's Spam
  209. # folder.
  210. # OpenDKIM is a way to authenticate your email so you can send to such services
  211. # without a problem.
  212. # Create an OpenDKIM key in the proper place with proper permissions.
  213. echo 'Generating OpenDKIM keys...'
  214. mkdir -p "/etc/postfix/dkim/$domain"
  215. opendkim-genkey -D "/etc/postfix/dkim/$domain" -d "$domain" -s "$subdom"
  216. chgrp -R opendkim /etc/postfix/dkim/*
  217. chmod -R g+r /etc/postfix/dkim/*
  218. # Generate the OpenDKIM info:
  219. echo 'Configuring OpenDKIM...'
  220. grep -q "$domain" /etc/postfix/dkim/keytable 2>/dev/null ||
  221. echo "$subdom._domainkey.$domain $domain:$subdom:/etc/postfix/dkim/$domain/$subdom.private" >> /etc/postfix/dkim/keytable
  222. grep -q "$domain" /etc/postfix/dkim/signingtable 2>/dev/null ||
  223. echo "*@$domain $subdom._domainkey.$domain" >> /etc/postfix/dkim/signingtable
  224. grep -q '127.0.0.1' /etc/postfix/dkim/trustedhosts 2>/dev/null ||
  225. echo '127.0.0.1
  226. 10.1.0.0/16' >> /etc/postfix/dkim/trustedhosts
  227. # ...and source it from opendkim.conf
  228. grep -q '^KeyTable' /etc/opendkim.conf 2>/dev/null || echo 'KeyTable file:/etc/postfix/dkim/keytable
  229. SigningTable refile:/etc/postfix/dkim/signingtable
  230. InternalHosts refile:/etc/postfix/dkim/trustedhosts' >> /etc/opendkim.conf
  231. sed -i '/^#Canonicalization/s/simple/relaxed\/simple/' /etc/opendkim.conf
  232. sed -i '/^#Canonicalization/s/^#//' /etc/opendkim.conf
  233. sed -i '/Socket/s/^#*/#/' /etc/opendkim.conf
  234. grep -q '^Socket\s*inet:12301@localhost' /etc/opendkim.conf || echo 'Socket inet:12301@localhost' >> /etc/opendkim.conf
  235. # OpenDKIM daemon settings, removing previously activated socket.
  236. sed -i '/^SOCKET/d' /etc/default/opendkim && echo "SOCKET=\"inet:12301@localhost\"" >> /etc/default/opendkim
  237. # Here we add to postconf the needed settings for working with OpenDKIM
  238. echo 'Configuring Postfix with OpenDKIM settings...'
  239. postconf -e 'smtpd_sasl_security_options = noanonymous, noplaintext'
  240. postconf -e 'smtpd_sasl_tls_security_options = noanonymous'
  241. postconf -e "myhostname = $domain"
  242. postconf -e 'milter_default_action = accept'
  243. postconf -e 'milter_protocol = 6'
  244. postconf -e 'smtpd_milters = inet:localhost:12301'
  245. postconf -e 'non_smtpd_milters = inet:localhost:12301'
  246. postconf -e 'mailbox_command = /usr/lib/dovecot/deliver'
  247. postconf -e 'smtpd_helo_required = yes'
  248. postconf -e 'smtpd_helo_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_helo_hostname'
  249. postconf -e 'smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_sender_login_mismatch, reject_unknown_reverse_client_hostname, reject_unknown_sender_domain'
  250. # A fix for "Opendkim won't start: can't open PID file?", as specified here: https://serverfault.com/a/847442
  251. /lib/opendkim/opendkim.service.generate
  252. systemctl daemon-reload
  253. # Enable fail2ban security for dovecot and postfix.
  254. [ ! -f /etc/fail2ban/jail.d/emailwiz.local ] && echo "[postfix]
  255. enabled = true
  256. [postfix-sasl]
  257. enabled = true
  258. [sieve]
  259. enabled = true
  260. [dovecot]
  261. enabled = true" > /etc/fail2ban/jail.d/emailwiz.local
  262. for x in spamassassin opendkim dovecot postfix fail2ban; do
  263. printf "Restarting %s..." "$x"
  264. service "$x" restart && printf " ...done\\n"
  265. systemctl enable "$x"
  266. done
  267. 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=.*')"
  268. dkimentry="$subdom._domainkey.$domain TXT v=DKIM1; k=rsa; $pval"
  269. dmarcentry="_dmarc.$domain TXT v=DMARC1; p=reject; rua=mailto:dmarc@$domain; fo=1"
  270. spfentry="$domain TXT v=spf1 mx a:$maildomain -all"
  271. mxentry="$domain MX 10 $maildomain 300"
  272. useradd -m -G mail dmarc
  273. grep -q '^deploy-hook = echo "$RENEWED_DOMAINS" | grep -q' /etc/letsencrypt/cli.ini ||
  274. echo "
  275. deploy-hook = echo \"\$RENEWED_DOMAINS\" | grep -q '$maildomain' && service postfix reload && service dovecot reload" >> /etc/letsencrypt/cli.ini
  276. echo "NOTE: Elements in the entries might appear in a different order in your registrar's DNS settings.
  277. $dkimentry
  278. $dmarcentry
  279. $spfentry
  280. $mxentry" > "$HOME/dns_emailwizard"
  281. printf "\033[31m
  282. _ _
  283. | \ | | _____ ___
  284. | \| |/ _ \ \ /\ / (_)
  285. | |\ | (_) \ V V / _
  286. |_| \_|\___/ \_/\_/ (_)\033[0m
  287. Add these three records to your DNS TXT records on either your registrar's site
  288. or your DNS server:
  289. \033[32m
  290. $dkimentry
  291. $dmarcentry
  292. $spfentry
  293. $mxentry
  294. \033[0m
  295. NOTE: You may need to omit the \`.$domain\` portion at the beginning if
  296. inputting them in a registrar's web interface.
  297. Also, these are now saved to \033[34m~/dns_emailwizard\033[0m in case you want them in a file.
  298. Once you do that, you're done! Check the README for how to add users/accounts
  299. and how to log in.\n"