Script cài đặt Postfix chỉ gởi email

Giả sử chúng ta có website /ứng dụng web cần gởi email cho user (thí dụ như thông báo mật khẩu). Trong hầu hết trường hợp, user không cần trả lời cho email họ nhận được. Trong trường hợp này, chúng ta có thể cài đặt một SMTP server chỉ gởi mail trên web server bằng cách dùng Postfix, mặc dù cũng có những MTA khác như msmtp, smtp…

Ưu điểm của việc dùng Postfix là email người gởi có dạng user@mydomain.com. Ngoài ra vì Postfix không kiểm tra email người gởi có thuộc domain của mail server hay không, nên có thể gởi email nhân danh bất kỳ ai, thí dụ no-reply@apple.com. Tuy nhiên email mạo danh thường nằm trong thư mục spam của người nhận.

Chúng ta cũng sẽ dùng SMTP relayhost như GMail để đơn giản quá trình cài đặt, bởi vì yêu cầu căn bản nhất là IP của mail server phải không nằm trong danh sách đen của bất cứ tổ chức chống spam nào, điều mà các IP động không có được.

Chuẩn bị

  1. RPi đã cài đặt OS Debian/Ubuntu
  2. Internet domain hay subdomain hay tên miền động. Email sẽ có dạng user@domain.com
  3. User/Password của một tài khoản email thuộc một mail server nào đó làm SMTP relayhost
  4. DNS quản lý domain phải cho tạo ít nhất 4 record
  5. Mở port 25 cho RPi (option)

Nếu không có domain, có thể đăng ký free domain ở freenom.com. Tên miền .tk, .ml, .ga, .cf và .gq thuộc tên miền cấp 1 nhưng ít phổ biến.

Vì freenom.com chậm và ít tính năng nên có thể cho openDNS, cloudns.net quản lý tên miền. Cloudflare không nhận quản lý tên miền loại này.

Script cài đặt

Chọn Internet Site khi được hỏi, và điền System mail name, là tên miền đứng sau dấu @. Tất nhiên đây phải là internet domain, có thể dùng subdomain hay tên miền động.

Thay thế các dòng tô đậm trong script bằng các giá trị thực tế, hoặc có thể truyền domain qua tham số dòng lệnh

#!/bin/bash
# pfx-sendonly.sh v.20210420, Ly Anh Tuan <lnt@ly-le.info>
echo "Cài đặt mailserver dùng Postfix chỉ dùng gởi email đi"

# Gởi mail thông qua SMTP bên ngoài
relayhost='[smtp.gmail.com]:587'
# Gởi mail nhờ vào email account user:password
relayhost_account='user@gmail.com:password'

# Thay đổi HOSTNAME, DOMAIN theo thực tế
# Mặc định myhostname = hostname của RPi
HOSTNAME="$(hostname)"
if [ $# -eq 1 ]; then
  DOMAIN="$1"
else
  # Mặc định mydomain trích từ myhostname
  DOMAIN="${HOSTNAME#*.}"
fi
step=0
echo "✅ Bước $step: Chuẩn bị"
((step+=1))
echo '➤➤➤ Cập nhật hệ thống...'
sudo apt update
if [ -z $DOMAIN ]; then
  read -p "➤➤➤ Nhập tên miền để gởi email (eg. example.com): " DOMAIN
  echo
  [ "$DOMAIN" ] || exit
fi

echo "✅ Bước $step: Cài đặt Postfix"
((step+=1))
sudo apt-get install libsasl2-modules postfix -y

echo "✅ Bước $step: Cấu hình Postfix"
((step+=1))
SUFFIX=$(date +'%Y%m%d')
if [ -e /etc/postfix/main.cf.$SUFFIX ]; then
  cp -f /etc/postfix/main.cf.$SUFFIX /etc/postfix/main.cf
else
  cp -f /etc/postfix/main.cf /etc/postfix/main.cf.$SUFFIX
fi
sudo postconf -e "myhostname = $HOSTNAME"
sudo postconf -e "mydomain = $DOMAIN"
sudo postconf -e 'mydestination = $myhostname, localhost.$mydomain, localhost'

echo "$DOMAIN" | sudo tee /etc/mailname

echo "✅ Bước $step: Cài đặt và cấu hình OpenDkim"
((step+=1))
read -n1 -t5 -p "➤➤➤ Cài đặt OpenDkim cho mailserver $HOSTNAME [C/k]? " ans
echo
ans=${ans:-C}
if [[ "${ans^}" = 'C' ]]; then
  sudo apt install opendkim opendkim-tools -y
  sudo adduser postfix opendkim
  sudo sed -e 's|#\(\bCanonicalization\b\).*|\1 relaxed/simple|
s|#\(\bMode\b\).*|\1 s|
s|#\(\bSubDomains\b\).*|\1 no|' -i /etc/opendkim.conf
  grep -Eqs "UserID\s+opendkim" /etc/opendkim.conf || sudo cat << EOT >> /etc/opendkim.conf
# OpenDOMAINKIM user
# Remember to add user postfix to group opendkim
UserID        opendkim

# Map domains in From addresses to keys used to sign messages
KeyTable      refile:/etc/opendkim/key.table
SigningTable  refile:/etc/opendkim/signing.table

# A set of internal hosts whose mail should be signed
InternalHosts /etc/opendkim/trusted.hosts
EOT
  [ -d /etc/opendkim ] || sudo mkdir /etc/opendkim
  [ -d /etc/opendkim/keys ] || sudo mkdir /etc/opendkim/keys
  selection='sendonly'
  sudo cat <<EOT > /etc/opendkim/signing.table
*@$DOMAIN $selection._domainkey.$DOMAIN
EOT
  sudo cat <<EOT > /etc/opendkim/key.table
$selection._domainkey.$DOMAIN $DOMAIN:$selection:/etc/opendkim/keys/$DOMAIN/sendonly.private
EOT
  sudo cat > /etc/opendkim/trusted.hosts <<EOT
127.0.0.1
localhost

*.$DOMAIN
EOT

  echo '➤➤➤ Tạo cặp khóa Private/Public...'
  [ -d /etc/opendkim/keys/$DOMAIN ] || sudo mkdir /etc/opendkim/keys/$DOMAIN
  sudo opendkim-genkey -b 2048 -d $DOMAIN -D /etc/opendkim/keys/$DOMAIN -s $selection -v
  sudo chown opendkim:opendkim /etc/opendkim/keys/$DOMAIN/$selection.private

  echo "✅ Bước $step: Kết nối Postfix và OpenDkim"
  ((step+=1))
  sudo sed -e 's|\(Socket\s*local:\).*|\1/var/spool/postfix/opendkim/opendkim.sock|' -i /etc/opendkim.conf
  [ -d /var/spool/postfix/opendkim ] || sudo mkdir /var/spool/postfix/opendkim
  sudo chown opendkim:postfix /var/spool/postfix/opendkim
  sudo sed -e 's|\(^SOCKET=\).*|\1"local:/var/spool/postfix/opendkim/opendkim.sock"|' -i /etc/default/opendkim
  grep -Eqs 'local:opendkim/opendkim.sock' /etc/postfix/main.cf || sudo cat >> /etc/postfix/main.cf <<EOT
# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:opendkim/opendkim.sock
non_smtpd_milters = \$smtpd_milters
EOT
fi

echo "✅ Bước $step: Tạo A, SPF, PTR, DMARC, DKIM record"
((step+=1))
cIP=$(curl -s http://ifconfig.me/ip)
sudo tee ./DNS.txt <<EOT
Vào DNS manager của $DOMAIN để cấu hình A, SPF, PTR, DMARC, DKIM record
  + A	$HOSTNAME	$cIP
  + TXT	$DOMAIN	v=spfv1 mx ip4:$cIP ~all
  + TXT	_drmarc		v=DMARC1; p=none
  + TXT	$selection._domainkey	v=DKIM1; h=sha256; k=rsa; p=you-key-here-without-spaces
  + PTR	$cIP	$HOSTNAME
EOT

echo "✅ Bước $step: Bật TLS Encryption để gởi mail"
((step+=1))
read -n1 -t5 -p "➤➤➤ Cài đặt certbot để tạo chứng chỉ bảo mật (C/k)? " ans
echo
ans=${ans:-C}
if [[ "${ans^}" = 'C' ]]; then
  sudo apt install certbot &> /dev/null
  SVC=$(sudo ss -tulpn | sed -n '/:80 /{s/.*(("\([^"]*\)".*/\1/;p}')
  systemctl stop $SVC
  sudo certbot certonly --standalone -d $HOSTNAME
  systemctl start $SVC
fi
[ -f "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" ] && CERT="$DOMAIN"
[ -f "/etc/letsencrypt/live/$HOSTNAME/fullchain.pem" ] && CERT="$HOSTNAME"
if [ ! -f "/etc/letsencrypt/live/$CERT/fullchain.pem" ]; then
  echo "➤➤➤ ERROR: Không tìm thấy chứng chỉ bảo mật tại /etc/letsencrypt/live/$CERT"
  echo
  echo '➤➤➤ Tiếp tục cài đặt...'
fi
sudo postconf -e "smtpd_tls_cert_file = /etc/letsencrypt/live/$CERT/fullchain.pem"
sudo postconf -e "smtpd_tls_key_file = /etc/letsencrypt/live/$CERT/privkey.pem"
sudo postconf -e "smtpd_tls_security_level = may"
sudo postconf -e "smtp_tls_security_level = may"
sudo postconf -e 'smtp_tls_loglevel = 1'

echo "✅ Bước $step: Cài đặt SMTP relayhost"
((step+=1))
read -n1 -t5 -p "➤➤➤ Cài đặt SMTP relayhost cho mailserver [C/k]? " ans
echo
ans=${ans:-C}
if [[ "${ans^}" = 'C' ]]; then
  echo "➤➤➤ Đang cài đặt..."
  sudo postconf -e "relayhost = $relayhost"
  sudo grep -Esq 'hash:/etc/postfix/sasl_passwd' /etc/postfix/main.cf || 
sudo cat >> /etc/postfix/main.cf <<EOT
# enable SASL authentication
smtp_sasl_auth_enable = yes
# disallow methods that allow anonymous authentication.
smtp_sasl_security_options = noanonymous
# where to find sasl_passwd
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
# Enable STARTTLS encryption
smtp_use_tls = yes
# where to find CA certificates
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
header_size_limit = 4096000
EOT
  sudo cat <<EOT > /etc/postfix/sasl_passwd
$relayhost $relayhost_account
EOT
  sudo postmap /etc/postfix/sasl_passwd
  sudo chmod 0600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
  sudo postconf -e "inet_interfaces = loopback-only"
fi
echo '➤➤➤ Khởi động lại OpenDkim Postfix...'
sudo systemctl restart opendkim postfix

Chú thich

  • Script chạy chỉ trong vòng 1 phút, tuy nhiên dừng nhiều lần 5s để hỏi user về việc cài software
  • Phải cài đặt các DNS record như ghi chú trong file DNS.txt thì mail server mới có thể hoạt động
  • Sau khi cài đặt có thể gởi mail nhờ vào SMTP relay host
  • Nếu domain được quản lý bởi cloudflare.com, có thể cấu hình tự động A, SPF, PTR, DMARC, DKIM record
<?php
$sender = 'no-reply@mail.domain';
$recipient = 'you@gmail.com';
$subject = 'Subject here';
$message = 'Testing...';
$headers = 'From:' . $sender;
echo (mail($recipient, $subject, $message, $headers)) ? "Message accepted" : "Failed!"
?>

Comments Off on Script cài đặt Postfix chỉ gởi email

Filed under Software

Comments are closed.