mirror of
https://github.com/nodemailer/wildduck.git
synced 2025-11-10 00:11:06 +08:00
DKIM and SPF correction, some renaming
I renamed some install scripts to be more clear. SPF: Suggest [MAILDOMAIN], [HOSTNAME] and [IP ADDRESS] Its a better practice to be more inclusive when it comes to dns SPF records. DKIM: Some dns registrars truncate dns TXT records at 255 chars. So 2048bit do not fit (about 390 vs. 230 chars). So 1024bit keys are a good choice, after all it is only a mail verification mechanism, do not encrypt the mail... Show tip how to stop systemd service (03_install_check_running_services.sh) sudo su prefered to become root, sudo su fails with npm permission errors when installing (dunno why). A mini tutorial is shown at the end about SPF, DKIM and how to add/remove/modify DKIM keys. This pull request closes issue 85,86.
This commit is contained in:
parent
6c02b5bc8e
commit
97e3b6ed41
7 changed files with 79 additions and 10 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
|
|
||||||
OURNAME=01_install_commit_variables.sh
|
OURNAME=01_install_commits.sh
|
||||||
|
|
||||||
WILDDUCK_COMMIT="538da537ca3cef0bbd714da70085cfd4cc734b49"
|
WILDDUCK_COMMIT="538da537ca3cef0bbd714da70085cfd4cc734b49"
|
||||||
ZONEMTA_COMMIT="f5f6a80ef6571c24afbb013eb18d74ec6e81ea1e" # zone-mta-template
|
ZONEMTA_COMMIT="f5f6a80ef6571c24afbb013eb18d74ec6e81ea1e" # zone-mta-template
|
||||||
|
|
@ -36,6 +36,7 @@ if ! [ -z $PORT25 ] ; then
|
||||||
echo -e "`systemctl status $PORT25`"
|
echo -e "`systemctl status $PORT25`"
|
||||||
echo -e "\nList all enabled services:"
|
echo -e "\nList all enabled services:"
|
||||||
echo -e "systemctl list-unit-files | grep enabled"
|
echo -e "systemctl list-unit-files | grep enabled"
|
||||||
|
echo -e "stop a service: systemctl stop [service]"
|
||||||
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
|
|
@ -55,6 +56,7 @@ if ! [ -z $PORT587 ] ; then
|
||||||
echo -e "`systemctl status $PORT587`"
|
echo -e "`systemctl status $PORT587`"
|
||||||
echo -e "\nList all enabled services:"
|
echo -e "\nList all enabled services:"
|
||||||
echo -e "systemctl list-unit-files | grep enabled"
|
echo -e "systemctl list-unit-files | grep enabled"
|
||||||
|
echo -e "stop a service: systemctl stop [service]"
|
||||||
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
|
|
@ -74,6 +76,7 @@ if ! [ -z $PORT993 ] ; then
|
||||||
echo -e "`systemctl status $PORT993`"
|
echo -e "`systemctl status $PORT993`"
|
||||||
echo -e "\nList all enabled services:"
|
echo -e "\nList all enabled services:"
|
||||||
echo -e "systemctl list-unit-files | grep enabled"
|
echo -e "systemctl list-unit-files | grep enabled"
|
||||||
|
echo -e "stop a service: systemctl stop [service]"
|
||||||
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
|
|
@ -93,6 +96,7 @@ if ! [ -z $PORT995 ] ; then
|
||||||
echo -e "`systemctl status $PORT995`"
|
echo -e "`systemctl status $PORT995`"
|
||||||
echo -e "\nList all enabled services:"
|
echo -e "\nList all enabled services:"
|
||||||
echo -e "systemctl list-unit-files | grep enabled"
|
echo -e "systemctl list-unit-files | grep enabled"
|
||||||
|
echo -e "stop a service: systemctl stop [service]"
|
||||||
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
|
|
@ -112,6 +116,7 @@ if ! [ -z $PORT80 ] ; then
|
||||||
echo -e "`systemctl status $PORT80`"
|
echo -e "`systemctl status $PORT80`"
|
||||||
echo -e "\nList all enabled services:"
|
echo -e "\nList all enabled services:"
|
||||||
echo -e "systemctl list-unit-files | grep enabled"
|
echo -e "systemctl list-unit-files | grep enabled"
|
||||||
|
echo -e "stop a service: systemctl stop [service]"
|
||||||
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
|
|
@ -131,6 +136,7 @@ if ! [ -z $PORT443 ] ; then
|
||||||
echo -e "`systemctl status $PORT443`"
|
echo -e "`systemctl status $PORT443`"
|
||||||
echo -e "\nList all enabled services:"
|
echo -e "\nList all enabled services:"
|
||||||
echo -e "systemctl list-unit-files | grep enabled"
|
echo -e "systemctl list-unit-files | grep enabled"
|
||||||
|
echo -e "stop a service: systemctl stop [service]"
|
||||||
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -95,10 +95,11 @@ authlogExpireDays=30
|
||||||
" > /etc/zone-mta/plugins/wildduck.toml
|
" > /etc/zone-mta/plugins/wildduck.toml
|
||||||
|
|
||||||
cd /opt/zone-mta/keys
|
cd /opt/zone-mta/keys
|
||||||
openssl genrsa -out "$MAILDOMAIN-dkim.pem" 2048
|
# Many registrar limits dns TXT fields to 255 char. 1024bit is almost too long:-\
|
||||||
|
openssl genrsa -out "$MAILDOMAIN-dkim.pem" 1024
|
||||||
chmod 400 "$MAILDOMAIN-dkim.pem"
|
chmod 400 "$MAILDOMAIN-dkim.pem"
|
||||||
openssl rsa -in "$MAILDOMAIN-dkim.pem" -out "$MAILDOMAIN-dkim.cert" -pubout
|
openssl rsa -in "$MAILDOMAIN-dkim.pem" -out "$MAILDOMAIN-dkim.cert" -pubout
|
||||||
DNS_ADDRESS="v=DKIM1;p=$(grep -v -e '^-' $MAILDOMAIN-dkim.cert | tr -d "\n")"
|
DKIM_DNS="v=DKIM1;k=rsa;p=$(grep -v -e '^-' $MAILDOMAIN-dkim.cert | tr -d "\n")"
|
||||||
|
|
||||||
DKIM_JSON=`DOMAIN="$MAILDOMAIN" SELECTOR="$DKIM_SELECTOR" node -e 'console.log(JSON.stringify({
|
DKIM_JSON=`DOMAIN="$MAILDOMAIN" SELECTOR="$DKIM_SELECTOR" node -e 'console.log(JSON.stringify({
|
||||||
domain: process.env.DOMAIN,
|
domain: process.env.DOMAIN,
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,71 @@ SPF
|
||||||
---
|
---
|
||||||
Add this TXT record to the $MAILDOMAIN DNS zone:
|
Add this TXT record to the $MAILDOMAIN DNS zone:
|
||||||
|
|
||||||
$MAILDOMAIN. IN TXT \"v=spf1 a:$HOSTNAME ~all\"
|
$MAILDOMAIN. IN TXT \"v=spf1 a:$HOSTNAME a:$MAILDOMAIN ip4:$PUBLIC_IP ~all\"
|
||||||
|
|
||||||
|
Or:
|
||||||
|
$MAILDOMAIN. IN TXT \"v=spf1 a:$HOSTNAME ip4:$PUBLIC_IP ~all\"
|
||||||
|
$MAILDOMAIN. IN TXT \"v=spf1 ip4:$PUBLIC_IP ~all\"
|
||||||
|
|
||||||
|
Some explanation:
|
||||||
|
SPF is basically a DNS entry (TXT), where you can define,
|
||||||
|
which server hosts (a:[HOSTNAME]) or ip address (ip4:[IP_ADDRESS])
|
||||||
|
are allowed to send emails.
|
||||||
|
So the receiver server (eg. gmail's server) can look up this entry
|
||||||
|
and decide if you(as a sender server) is allowed to send emails as
|
||||||
|
this email address.
|
||||||
|
|
||||||
|
If you are unsure, list more a:, ip4 entries, rather then fewer.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
company website: awesome.com
|
||||||
|
company's email server: mail.awesome.com
|
||||||
|
company's reverse dns entry for this email server: mail.awesome.com -> 11.22.33.44
|
||||||
|
|
||||||
|
SPF record in this case would be:
|
||||||
|
awesome.com. IN TXT \"v=spf1 a:mail.awesome.com a:awesome.com ip4:11.22.33.44 ~all\"
|
||||||
|
|
||||||
|
The following servers can send emails for *@awesome.com email addresses:
|
||||||
|
awesome.com (company's website handling server)
|
||||||
|
mail.awesome.com (company's mail server)
|
||||||
|
11.22.33.44 (company's mail server's ip address)
|
||||||
|
|
||||||
|
Please note, that a:mail.awesome.com is the same as ip4:11.22.33.44, so it is
|
||||||
|
redundant. But better safe than sorry.
|
||||||
|
And in this example, the company's website handling server can also send
|
||||||
|
emails and in general it is an outbound only server.
|
||||||
|
If a website handles email sending (confirmation emails, contact form, etc).
|
||||||
|
|
||||||
DKIM
|
DKIM
|
||||||
----
|
----
|
||||||
Add this TXT record to the $MAILDOMAIN DNS zone:
|
Add this TXT record to the $MAILDOMAIN DNS zone:
|
||||||
|
|
||||||
$DKIM_SELECTOR._domainkey.$MAILDOMAIN. IN TXT \"$DNS_ADDRESS\"
|
$DKIM_SELECTOR._domainkey.$MAILDOMAIN. IN TXT \"$DKIM_DNS\"
|
||||||
|
|
||||||
|
The DKIM .json text we added to wildduck server:
|
||||||
|
curl -i -XPOST http://localhost:8080/dkim \\
|
||||||
|
-H 'Content-type: application/json' \\
|
||||||
|
-d '$DKIM_JSON'
|
||||||
|
|
||||||
|
|
||||||
|
Please refer to the manual how to change/delete/update DKIM keys
|
||||||
|
via the REST api (with curl on localhost) for the newest version.
|
||||||
|
|
||||||
|
List DKIM keys:
|
||||||
|
curl -i http://localhost:8080/dkim
|
||||||
|
Delete DKIM:
|
||||||
|
curl -i -XDELETE http://localhost:8080/dkim/59ef21aef255ed1d9d790e81
|
||||||
|
|
||||||
|
Move DKIM keys to another machine:
|
||||||
|
|
||||||
|
Save the above curl command and dns entry.
|
||||||
|
Also copy the following two files too:
|
||||||
|
/opt/zone-mta/keys/[MAILDOMAIN]-dkim.cert
|
||||||
|
/opt/zone-mta/keys/[MAILDOMAIN]-dkim.pem
|
||||||
|
|
||||||
|
pem: private key (guard it well)
|
||||||
|
cert: public key
|
||||||
|
|
||||||
|
|
||||||
PTR
|
PTR
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ BASEURL="https://raw.githubusercontent.com/nodemailer/wildduck/master/setup/"
|
||||||
|
|
||||||
## declare an array
|
## declare an array
|
||||||
declare -a arr=(
|
declare -a arr=(
|
||||||
"00_install_variables.sh"
|
"00_install_global_functions_variables.sh"
|
||||||
"01_install_commit_variables.sh"
|
"01_install_commits.sh"
|
||||||
"02_install_prerequisites.sh"
|
"02_install_prerequisites.sh"
|
||||||
"03_install_check_running_services.sh"
|
"03_install_check_running_services.sh"
|
||||||
"04_install_import_keys.sh"
|
"04_install_import_keys.sh"
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@
|
||||||
# make sure the install script is started here
|
# make sure the install script is started here
|
||||||
OURNAME=install.sh
|
OURNAME=install.sh
|
||||||
INSTALLDIR=`pwd`
|
INSTALLDIR=`pwd`
|
||||||
source "$INSTALLDIR/00_install_variables.sh"
|
PUBLIC_IP=`curl -s https://api.ipify.org`
|
||||||
|
source "$INSTALLDIR/00_install_global_functions_variables.sh"
|
||||||
|
|
||||||
args=("$@")
|
args=("$@")
|
||||||
# echo $# arguments passed
|
# echo $# arguments passed
|
||||||
|
|
@ -22,14 +23,17 @@ if [ "$#" -gt "0" ]
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $EUID -ne 0 ]]; then
|
if [[ $EUID -ne 0 ]]; then
|
||||||
echo "This script must be run as root" 1>&2
|
# redirect stdout(1) to stderr(2)
|
||||||
|
# (&2, & means it is a filedescriptor and not a file named "2")
|
||||||
|
echo -e "${RED}ERROR:${NC}This script must be run as root" 1>&2
|
||||||
|
echo -e "Execute ${GREEN}sudo bash${NC} , ${ORANGE}sudo su${NC} or ${ORANGE}sudo sh${NC}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# source is for executing in the current shell, and not in a subset.
|
# source is for executing in the current shell, and not in a subset.
|
||||||
# defined variables persists across files
|
# defined variables persists across files
|
||||||
declare -a arr=(
|
declare -a arr=(
|
||||||
"01_install_commit_variables.sh"
|
"01_install_commits.sh"
|
||||||
"02_install_prerequisites.sh"
|
"02_install_prerequisites.sh"
|
||||||
"03_install_check_running_services.sh"
|
"03_install_check_running_services.sh"
|
||||||
"04_install_import_keys.sh"
|
"04_install_import_keys.sh"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue