From b81f4874e693483c5b08abac6d449bb66fdbfcdc Mon Sep 17 00:00:00 2001 From: "jacob.eva" Date: Thu, 21 Sep 2023 12:58:14 +0100 Subject: [PATCH 01/13] Correct grammatical and phrasing errors --- emailwiz.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/emailwiz.sh b/emailwiz.sh index b48fc1f..ce8e1f5 100644 --- a/emailwiz.sh +++ b/emailwiz.sh @@ -64,7 +64,7 @@ postconf -e "smtpd_tls_key_file=$certdir/privkey.pem" postconf -e "smtpd_tls_cert_file=$certdir/fullchain.pem" postconf -e "smtp_tls_CAfile=$certdir/cert.pem" -# Enable, but do not require TLS. Requiring it with other server would cause +# Enable, but do not require TLS. Requiring it with other servers would cause # mail delivery problems and requiring it locally would cause many other # issues. postconf -e 'smtpd_tls_security_level = may' @@ -99,8 +99,8 @@ postconf -e 'smtpd_helo_restrictions = permit_mynetworks, permit_sasl_authentica # NOTE: the trailing slash here, or for any directory name in the home_mailbox # command, is necessary as it distinguishes a maildir (which is the actual -# directories that what we want) from a spoolfile (which is what old unix -# boomers want and no one else). +# directory that we want) from a spoolfile (which is what old unix boomers want +# and no one else). postconf -e 'home_mailbox = Mail/Inbox/' # Prevent "Received From:" header in sent emails in order to prevent leakage of public ip addresses @@ -201,7 +201,7 @@ namespace inbox { } } -# Here we let Postfix use Dovecot's authetication system. +# Here we let Postfix use Dovecot's authentication system. service auth { unix_listener /var/spool/postfix/private/auth { mode = 0660 From a8f5d0fddddf7384e1fb284833340005a0f91277 Mon Sep 17 00:00:00 2001 From: amnweb <16545063+amnweb@users.noreply.github.com> Date: Fri, 22 Dec 2023 17:03:07 +0100 Subject: [PATCH 02/13] Update emailwiz.sh Open port 110 and 995 for POP3 support --- emailwiz.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emailwiz.sh b/emailwiz.sh index ce8e1f5..2bc983d 100644 --- a/emailwiz.sh +++ b/emailwiz.sh @@ -24,7 +24,7 @@ maildomain="$subdom.$domain" certdir="/etc/letsencrypt/live/$maildomain" # Open required mail ports, and 80, for Certbot. -for port in 80 993 465 25 587; do +for port in 80 993 465 25 587 110 995; do ufw allow "$port" 2>/dev/null done From bcfba987e41db1a34d9900b777f16677357f82bb Mon Sep 17 00:00:00 2001 From: aartoni Date: Fri, 29 Dec 2023 16:39:06 +0100 Subject: [PATCH 03/13] Short-term workaround to prevent SMTP smuggling --- emailwiz.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/emailwiz.sh b/emailwiz.sh index ce8e1f5..c7d952f 100644 --- a/emailwiz.sh +++ b/emailwiz.sh @@ -308,6 +308,10 @@ postconf -e 'smtpd_milters = inet:localhost:12301' postconf -e 'non_smtpd_milters = inet:localhost:12301' postconf -e 'mailbox_command = /usr/lib/dovecot/deliver' +# Short-term workaround to prevent SMTP smuggling +postconf -e 'smtpd_forbid_unauth_pipelining = yes' +postconf -e 'smtpd_discard_ehlo_keywords = chunking' + # A fix for "Opendkim won't start: can't open PID file?", as specified here: https://serverfault.com/a/847442 /lib/opendkim/opendkim.service.generate systemctl daemon-reload From e4ae00cd69e2651c03139487723173a0b0c9abde Mon Sep 17 00:00:00 2001 From: tfasano1 <54379134+tfasano1@users.noreply.github.com> Date: Wed, 17 Jan 2024 01:56:33 -0500 Subject: [PATCH 04/13] Add spf arg to lower gmail false positive spam --- emailwiz.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/emailwiz.sh b/emailwiz.sh index ce8e1f5..98151fd 100644 --- a/emailwiz.sh +++ b/emailwiz.sh @@ -347,10 +347,14 @@ for x in opendkim dovecot postfix fail2ban; do systemctl enable "$x" done +# In some cases, big name email services favor an spf record with certain mechanisms included. +# See http://www.open-spf.org/SPF_Record_Syntax +mailip=ip4:$(ping -c 1 $domain | grep -m1 -Eo '([0-9]+\.){3}[0-9]+') + 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=.*')" dkimentry="$subdom._domainkey.$domain TXT v=DKIM1; k=rsa; $pval" dmarcentry="_dmarc.$domain TXT v=DMARC1; p=reject; rua=mailto:dmarc@$domain; fo=1" -spfentry="$domain TXT v=spf1 mx a:$maildomain -all" +spfentry="$domain TXT v=spf1 mx a:$maildomain ip4:$mailip -all" mxentry="$domain MX 10 $maildomain 300" useradd -m -G mail dmarc From 0aa7a8df389ea4474f5cd97c6604133c5222edf1 Mon Sep 17 00:00:00 2001 From: tfasano1 <54379134+tfasano1@users.noreply.github.com> Date: Wed, 17 Jan 2024 02:25:46 -0500 Subject: [PATCH 05/13] Update emailwiz.sh --- emailwiz.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emailwiz.sh b/emailwiz.sh index 98151fd..3b1ee89 100644 --- a/emailwiz.sh +++ b/emailwiz.sh @@ -349,7 +349,7 @@ done # In some cases, big name email services favor an spf record with certain mechanisms included. # See http://www.open-spf.org/SPF_Record_Syntax -mailip=ip4:$(ping -c 1 $domain | grep -m1 -Eo '([0-9]+\.){3}[0-9]+') +mailip=$(ping -c 1 $domain | grep -m1 -Eo '([0-9]+\.){3}[0-9]+') 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=.*')" dkimentry="$subdom._domainkey.$domain TXT v=DKIM1; k=rsa; $pval" From bda15800886db4947b3f92d285e7fc5e46928134 Mon Sep 17 00:00:00 2001 From: tfasano1 <54379134+tfasano1@users.noreply.github.com> Date: Wed, 17 Jan 2024 22:48:14 -0500 Subject: [PATCH 06/13] add ipv6 mechanism --- emailwiz.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/emailwiz.sh b/emailwiz.sh index 3b1ee89..e3a3ed8 100644 --- a/emailwiz.sh +++ b/emailwiz.sh @@ -347,14 +347,14 @@ for x in opendkim dovecot postfix fail2ban; do systemctl enable "$x" done -# In some cases, big name email services favor an spf record with certain mechanisms included. -# See http://www.open-spf.org/SPF_Record_Syntax -mailip=$(ping -c 1 $domain | grep -m1 -Eo '([0-9]+\.){3}[0-9]+') +# Generate spf mechanisms +mailip4=$(host "$domain" | grep -m1 -Eo '([0-9]+\.){3}[0-9]+') +mailip6=$(host "$domain" | grep "IPv6" | awk '{print $NF}') 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=.*')" dkimentry="$subdom._domainkey.$domain TXT v=DKIM1; k=rsa; $pval" dmarcentry="_dmarc.$domain TXT v=DMARC1; p=reject; rua=mailto:dmarc@$domain; fo=1" -spfentry="$domain TXT v=spf1 mx a:$maildomain ip4:$mailip -all" +spfentry="$domain TXT v=spf1 mx a:$maildomain ip4:$mailip4 ip6:$mailip6 -all" mxentry="$domain MX 10 $maildomain 300" useradd -m -G mail dmarc From 3dd706e5a811d9681c55ce134741788bb6f6b82b Mon Sep 17 00:00:00 2001 From: tfasano1 <54379134+tfasano1@users.noreply.github.com> Date: Wed, 24 Jan 2024 10:22:11 -0500 Subject: [PATCH 07/13] Add checks with helpful debug information --- emailwiz.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/emailwiz.sh b/emailwiz.sh index e3a3ed8..d3212ab 100644 --- a/emailwiz.sh +++ b/emailwiz.sh @@ -23,6 +23,12 @@ subdom=${MAIL_SUBDOM:-mail} maildomain="$subdom.$domain" certdir="/etc/letsencrypt/live/$maildomain" +# Preliminary record checks +ipv4=$(host "$domain" | grep -m1 -Eo '([0-9]+\.){3}[0-9]+') +[ -z "$ipv4" ] && echo "\033[0;31mPlease point your domain ("$domain") to your server's ipv4 address." +ipv6=$(host "$domain" | grep "IPv6" | awk '{print $NF}') +[ -z "$ipv6" ] && echo "\033[0;31mPlease point your domain ("$domain") to your server's ipv6 address." + # Open required mail ports, and 80, for Certbot. for port in 80 993 465 25 587; do ufw allow "$port" 2>/dev/null @@ -347,14 +353,10 @@ for x in opendkim dovecot postfix fail2ban; do systemctl enable "$x" done -# Generate spf mechanisms -mailip4=$(host "$domain" | grep -m1 -Eo '([0-9]+\.){3}[0-9]+') -mailip6=$(host "$domain" | grep "IPv6" | awk '{print $NF}') - 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=.*')" dkimentry="$subdom._domainkey.$domain TXT v=DKIM1; k=rsa; $pval" dmarcentry="_dmarc.$domain TXT v=DMARC1; p=reject; rua=mailto:dmarc@$domain; fo=1" -spfentry="$domain TXT v=spf1 mx a:$maildomain ip4:$mailip4 ip6:$mailip6 -all" +spfentry="$domain TXT v=spf1 mx a:$maildomain ip4:$ipv4 ip6:$ipv6 -all" mxentry="$domain MX 10 $maildomain 300" useradd -m -G mail dmarc From e58b2bf426fe102211a5af6a41178923c73bc120 Mon Sep 17 00:00:00 2001 From: tfasano1 <54379134+tfasano1@users.noreply.github.com> Date: Wed, 24 Jan 2024 10:25:42 -0500 Subject: [PATCH 08/13] exit when records aren't setup --- emailwiz.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emailwiz.sh b/emailwiz.sh index d3212ab..b525e59 100644 --- a/emailwiz.sh +++ b/emailwiz.sh @@ -25,9 +25,9 @@ certdir="/etc/letsencrypt/live/$maildomain" # Preliminary record checks ipv4=$(host "$domain" | grep -m1 -Eo '([0-9]+\.){3}[0-9]+') -[ -z "$ipv4" ] && echo "\033[0;31mPlease point your domain ("$domain") to your server's ipv4 address." +[ -z "$ipv4" ] && echo "\033[0;31mPlease point your domain ("$domain") to your server's ipv4 address." && exit 1 ipv6=$(host "$domain" | grep "IPv6" | awk '{print $NF}') -[ -z "$ipv6" ] && echo "\033[0;31mPlease point your domain ("$domain") to your server's ipv6 address." +[ -z "$ipv6" ] && echo "\033[0;31mPlease point your domain ("$domain") to your server's ipv6 address." && exit 1 # Open required mail ports, and 80, for Certbot. for port in 80 993 465 25 587; do From 1d3d7e7ba954b702aff79886d4286d0130723ab0 Mon Sep 17 00:00:00 2001 From: aartoni Date: Sat, 10 Feb 2024 14:55:54 +0100 Subject: [PATCH 09/13] Long term fix to prevent SMTP smuggling --- emailwiz.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/emailwiz.sh b/emailwiz.sh index c7d952f..ee5440c 100644 --- a/emailwiz.sh +++ b/emailwiz.sh @@ -308,9 +308,9 @@ postconf -e 'smtpd_milters = inet:localhost:12301' postconf -e 'non_smtpd_milters = inet:localhost:12301' postconf -e 'mailbox_command = /usr/lib/dovecot/deliver' -# Short-term workaround to prevent SMTP smuggling -postconf -e 'smtpd_forbid_unauth_pipelining = yes' -postconf -e 'smtpd_discard_ehlo_keywords = chunking' +# Long-term fix to prevent SMTP smuggling +postconf -e 'smtpd_forbid_bare_newline = normalize' +postconf -e 'smtpd_forbid_bare_newline_exclusions = $mynetworks' # A fix for "Opendkim won't start: can't open PID file?", as specified here: https://serverfault.com/a/847442 /lib/opendkim/opendkim.service.generate From a02ff7539ebd7d8b818e64daeec1c7f4047e3336 Mon Sep 17 00:00:00 2001 From: Luke Smith Date: Wed, 13 Mar 2024 11:03:12 -0400 Subject: [PATCH 10/13] adddomain.sh to add an additional domain --- adddomain.sh | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100755 adddomain.sh diff --git a/adddomain.sh b/adddomain.sh new file mode 100755 index 0000000..d44b567 --- /dev/null +++ b/adddomain.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +domain="$1" +[ -z "$1" ] && exit + +domain="$1" +subdom="mail" + +# Add the domain to the valid postfix addresses. +grep -q "^mydestination.*$domain" /etc/postfix/main.cf || + sed -i "s/^mydestination.*/&, $domain/" /etc/postfix/main.cf + +# Create DKIM for new domain. +mkdir -p "/etc/postfix/dkim/$domain" +opendkim-genkey -D "/etc/postfix/dkim/$domain" -d "$domain" -s "$subdom" +chgrp -R opendkim /etc/postfix/dkim/* +chmod -R g+r /etc/postfix/dkim/* + +# Add entries to keytable and signing table. +echo "$subdom._domainkey.$domain $domain:$subdom:/etc/postfix/dkim/$domain/$subdom.private" >> /etc/postfix/dkim/keytable +echo "*@$domain $subdom._domainkey.$domain" >> /etc/postfix/dkim/signingtable + +systemctl reload opendkim postfix + +# Print out DKIM TXT entry. +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=.*')" + +dkimentry="$subdom._domainkey.$domain TXT v=DKIM1; k=rsa; $pval" +dmarcentry="_dmarc.$domain TXT v=DMARC1; p=reject; rua=mailto:dmarc@$domain; fo=1" +spfentry="$domain TXT v=spf1 mx a:$maildomain -all" +mxentry="$domain MX 10 $maildomain 300" + +echo "$dkimentry +$dmarcentry +$spfentry +$mxentry" >> "$HOME/dns_emailwizard_added" + +echo "=== ADD THE FOLLOWING TO YOUR DNS TXT RECORDS ===" +echo "$dkimentry +$dmarcentry +$spfentry +$mxentry" +echo "They have also been stored in ~/dns_emailwizard_added" From 9f9f2b2e63c8e60730ea82c203dbbd9dd7fea082 Mon Sep 17 00:00:00 2001 From: Luke Smith Date: Wed, 13 Mar 2024 11:24:06 -0400 Subject: [PATCH 11/13] bind added in case --- emailwiz.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emailwiz.sh b/emailwiz.sh index 83d65bc..5110e89 100644 --- a/emailwiz.sh +++ b/emailwiz.sh @@ -17,7 +17,7 @@ umask 0022 -apt-get install -y postfix postfix-pcre dovecot-imapd dovecot-pop3d dovecot-sieve opendkim opendkim-tools spamassassin spamc net-tools fail2ban +apt-get install -y postfix postfix-pcre dovecot-imapd dovecot-pop3d dovecot-sieve opendkim opendkim-tools spamassassin spamc net-tools fail2ban bind9-host domain="$(cat /etc/mailname)" subdom=${MAIL_SUBDOM:-mail} maildomain="$subdom.$domain" From 5f16c868d9c428c3233f684fa28d90bd4cda04ac Mon Sep 17 00:00:00 2001 From: kedom <71038454+kedom1337@users.noreply.github.com> Date: Thu, 28 Mar 2024 13:58:30 +0000 Subject: [PATCH 12/13] feat: turn user "dmarc" into "postmaster" for more generic use cases --- emailwiz.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/emailwiz.sh b/emailwiz.sh index 5110e89..f3005ae 100644 --- a/emailwiz.sh +++ b/emailwiz.sh @@ -363,16 +363,16 @@ dmarcentry="_dmarc.$domain TXT v=DMARC1; p=reject; rua=mailto:dmarc@$domain; fo= spfentry="$domain TXT v=spf1 mx a:$maildomain ip4:$ipv4 ip6:$ipv6 -all" mxentry="$domain MX 10 $maildomain 300" -useradd -m -G mail dmarc +useradd -m -G mail postmaster -# Create a cronjob that deletes month-old dmarc feedback: -cat < /etc/cron.weekly/dmarc-clean +# Create a cronjob that deletes month-old postmaster mails: +cat < /etc/cron.weekly/postmaster-clean #!/bin/sh -find /home/dmarc/Mail -type f -mtime +30 -name '*.mail*' -delete >/dev/null 2>&1 +find /home/postmaster/Mail -type f -mtime +30 -name '*.mail*' -delete >/dev/null 2>&1 exit 0 EOF -chmod 755 /etc/cron.weekly/dmarc-clean +chmod 755 /etc/cron.weekly/postmaster-clean grep -q '^deploy-hook = echo "$RENEWED_DOMAINS" | grep -q' /etc/letsencrypt/cli.ini || echo " From 58fe9ae27648a2aab315deef25078c54e48525b8 Mon Sep 17 00:00:00 2001 From: Luke Smith Date: Fri, 29 Mar 2024 13:07:20 -0400 Subject: [PATCH 13/13] dmarc to postmaster --- emailwiz.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emailwiz.sh b/emailwiz.sh index f3005ae..ddfbc13 100644 --- a/emailwiz.sh +++ b/emailwiz.sh @@ -359,7 +359,7 @@ done 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=.*')" dkimentry="$subdom._domainkey.$domain TXT v=DKIM1; k=rsa; $pval" -dmarcentry="_dmarc.$domain TXT v=DMARC1; p=reject; rua=mailto:dmarc@$domain; fo=1" +dmarcentry="_dmarc.$domain TXT v=DMARC1; p=reject; rua=mailto:postmaster@$domain; fo=1" spfentry="$domain TXT v=spf1 mx a:$maildomain ip4:$ipv4 ip6:$ipv6 -all" mxentry="$domain MX 10 $maildomain 300"