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

emailwiz.sh 17 KiB

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