Mail Queue: ตรวจและเคลียร์คิวอีเมลค้างบน Postfix

ตรวจ Mail Queue ของ Postfix ด้วย mailq และ postqueue -j อ่านเหตุผลที่อีเมลค้าง ลบ พัก หรือส่งซ้ำอย่างปลอดภัย หาต้นทางสแปม และตั้งอายุคิวกับการแจ้งเตือน

โดย ทีมงาน THAI DATA CLOUD อ่าน 12 นาที

แชร์FacebookXLINELinkedIn
Mail Queue — Mail Queue: ตรวจและเคลียร์คิวอีเมลค้างบน Postfix
Mail Queue: ตรวจและเคลียร์คิวอีเมลค้างบน Postfix

คำตอบสั้น ๆ: ตรวจ Mail Queue ของ Postfix ด้วย mailq และ postqueue -j อ่านเหตุผลที่อีเมลค้าง ลบ พัก หรือส่งซ้ำอย่างปลอดภัย หาต้นทางสแปม และตั้งอายุคิวกับการแจ้งเตือน

คู่มือนี้อธิบาย Mail Queue ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย

Mail Queue ของ Postfix คือที่พักอีเมลที่เซิร์ฟเวอร์รับมาแล้วแต่ยังส่งต่อไม่สำเร็จ ในภาวะปกติคิวแทบว่างตลอดเวลา เพราะอีเมลส่วนใหญ่ออกไปภายในไม่กี่วินาที เมื่อ Mail Queue โตผิดปกติ แปลว่ามีอะไรผิดพลาด เช่น ปลายทางปฏิเสธชั่วคราว เครื่องถูกปิดพอร์ต 25 ขาออก DNS มีปัญหา หรือมีบัญชีที่ถูกเจาะหรือสคริปต์บนเว็บใช้เซิร์ฟเวอร์ของคุณส่งสแปม

คู่มือนี้เหมาะกับผู้ดูแล Linux Server ที่ใช้ Postfix ไม่ว่าจะเป็นเครื่องส่งอีเมลแจ้งเตือน เมลเซิร์ฟเวอร์เต็มรูปแบบ หรือระบบที่มี Postfix อยู่ภายใน เช่น Mailcow และ Zimbra เมื่อทำครบ คุณจะอ่านคิวและเหตุผลที่อีเมลค้างได้ เปิดดูอีเมลในคิว ลบ พัก หรือส่งซ้ำอย่างปลอดภัย หาต้นทางสแปม และตั้งอายุคิวกับการแจ้งเตือนให้เหมาะกับบริษัท ถ้าใช้ DirectAdmin ซึ่งใช้ Exim ให้ดู คู่มือ Mail Queue บน DirectAdmin แทน

สิ่งที่ต้องเตรียม

  • สิทธิ์ root หรือ sudo บนเครื่องที่ใช้ Postfix 3.1 ขึ้นไป (Ubuntu 22.04/24.04, Debian 12 และ AlmaLinux 9 ใช้รุ่นใหม่กว่านี้อยู่แล้ว) เพราะคำสั่ง postqueue -j ที่ให้ผลเป็น JSON ต้องใช้ 3.1 ขึ้นไป
  • โปรแกรม jq สำหรับอ่าน JSON ติดตั้งด้วย apt install jq หรือ dnf install jq
  • รู้ว่า log ของ Postfix อยู่ที่ใด Ubuntu และ Debian ที่มี rsyslog ใช้ /var/log/mail.log ตระกูล RHEL ใช้ /var/log/maillog ถ้าไม่มีไฟล์ทั้งสองให้ใช้ journalctl | grep postfix
  • บน Mailcow ให้ขึ้นต้นทุกคำสั่งด้วย docker compose exec postfix-mailcow ในโฟลเดอร์ /opt/mailcow-dockerized
ลำดับขั้นอีเมลใน Mail Queue ของ Postfix ตั้งแต่ incoming ไป active ส่งสำเร็จหรือค้างใน deferred ลองใหม่ จนหมดอายุและตีกลับ
อีเมลที่ค้างใน deferred จะถูกลองส่งใหม่ตามรอบจนครบอายุคิว แล้วจึงตีกลับไปหาผู้ส่ง

ขั้นตอนที่ 1: ดู Mail Queue ด้วย mailq

mailq | tail -n 1
mailq | head -n 30

mailq ให้ผลเหมือน postqueue -p บรรทัดสุดท้ายบอกขนาดรวมและจำนวนอีเมลในคิว เช่น -- 1532 Kbytes in 412 Requests. แต่ละรายการเริ่มด้วย Queue ID ถ้าต่อท้ายด้วย * แปลว่ากำลังส่งอยู่ (active) ถ้าต่อท้ายด้วย ! แปลว่าถูกพักไว้ (hold) ข้อความในวงเล็บคือเหตุผลที่ส่งไม่สำเร็จครั้งล่าสุด และบรรทัดถัดไปคือผู้รับ

ถ้า Mail Queue มีหลายร้อยรายการ ใช้ qshape deferred ดูว่าค้างอยู่ที่โดเมนปลายทางใดและค้างมานานแค่ไหน บน Debian และ Ubuntu คำสั่งนี้มากับแพ็กเกจ postfix ส่วนตระกูล RHEL อยู่ในแพ็กเกจ postfix-perl-scripts

ผลคำสั่ง mailq แสดงอีเมลใน Mail Queue พร้อม Queue ID ขนาด เวลา ผู้ส่ง เหตุผลที่ค้าง และสรุปจำนวนเหตุผลด้วย postqueue -j กับ jq
ข้อความในวงเล็บคือเหตุผลล่าสุดที่ส่งไม่สำเร็จ และเป็นจุดเริ่มต้นของการแก้ทุกครั้ง

ขั้นตอนที่ 2: สรุปเหตุผลที่อีเมลค้างใน Mail Queue

อ่านเหตุผลทีละรายการไม่ไหวเมื่อ Mail Queue ยาว ให้ใช้ผล JSON นับเหตุผลที่ซ้ำกัน คำสั่งด้านล่างแทนเลข IP ด้วยคำว่า IP เพื่อรวมรายการที่เหมือนกัน

postqueue -j | jq -r '.recipients[].delay_reason // empty' \
  | sed -E 's/[0-9]{1,3}(\.[0-9]{1,3}){3}/IP/g' \
  | sort | uniq -c | sort -rn | head

เหตุผลที่เจอบ่อยและความหมาย

  • Connection timed out กับพอร์ต 25 ของหลายปลายทางพร้อมกัน: ผู้ให้บริการคลาวด์ปิดพอร์ต 25 ขาออก หรือไฟร์วอลล์ของเครื่องบล็อกไว้
  • Host or domain name not found: DNS ของเครื่องมีปัญหา หรือผู้ใช้พิมพ์โดเมนปลายทางผิด
  • 421-4.7.28 จาก Gmail หรือ 451 4.7.650 จาก Outlook.com: ปลายทางชะลอการรับเพราะชื่อเสียงของ IP หรือปริมาณส่งเพิ่มเร็วเกินไป ดู คู่มือ IP Warmup
  • ข้อความที่อ้างถึงรายการบล็อกหรือ Blacklist: IP ของเครื่องติด Blacklist ตรวจตาม คู่มือตรวจและถอด IP ออกจาก Blacklist

รหัสอื่นอ่านความหมายได้ที่ คู่มือ Bounce และ SMTP Error Code

ขั้นตอนที่ 3: เปิดดูอีเมลที่ค้างใน Mail Queue

postcat -hq 4F2A81C0B3
postcat -q 4F2A81C0B3 | less

-h แสดงเฉพาะ header ถ้าไม่ระบุตัวเลือก postcat จะแสดงทั้ง envelope, header และเนื้อหา ดูหัวเรื่อง ผู้ส่งจริง และ header Received เพื่อแยกว่าเป็นอีเมลงานปกติที่ค้างเพราะปลายทาง หรือเป็นสแปมที่ไม่ควรออกจากเครื่องตั้งแต่แรก ถ้าจะลบอีเมลที่อาจต้องใช้เป็นหลักฐาน ให้บันทึกตัวอย่างไว้ก่อน เช่น postcat -q 4F2A81C0B3 > /root/evidence-4F2A81C0B3.txt

ขั้นตอนที่ 4: ส่งซ้ำ พัก หรือลบอีเมลใน Mail Queue

คำสั่งลบใน Mail Queue ย้อนกลับไม่ได้ ไม่มีถังขยะ ก่อนลบจำนวนมากให้พักอีเมลไว้ด้วย postsuper -h แล้วตรวจให้แน่ใจก่อน อีเมลที่พักไว้จะไม่ถูกส่งและไม่หมดอายุจนกว่าจะปล่อยหรือลบ

# ส่งซ้ำทุกฉบับที่ค้างทันที (หลังแก้สาเหตุแล้วเท่านั้น)
postqueue -f
# ส่งซ้ำฉบับเดียว
postqueue -i 4F2A81C0B3
# พักไว้ และปล่อยกลับ
postsuper -h 4F2A81C0B3
postsuper -H 4F2A81C0B3
# จัดเส้นทางใหม่หลังแก้ relayhost หรือ transport
postsuper -r ALL
# ลบฉบับเดียว และลบทุกฉบับในคิว deferred
postsuper -d 4F2A81C0B3
postsuper -d ALL deferred

ลบเฉพาะอีเมลจากผู้ส่งรายเดียว เช่น สคริปต์บนเว็บที่ถูกใช้ส่งสแปม โดยไม่แตะอีเมลงานปกติ

postqueue -j | jq -r 'select(.sender == "[email protected]") | .queue_id' | postsuper -d -

อย่าสั่ง postqueue -f ซ้ำหลายครั้งเมื่อปลายทางกำลังชะลอการรับ ยิ่งส่งถี่ IP ยิ่งดูเหมือนผู้ส่งสแปม Postfix จะลองส่งใหม่เองตามรอบ โดยเว้นระยะเริ่มที่ 300 วินาทีและเพิ่มขึ้นจนถึง 4000 วินาทีตามค่าเริ่มต้น

ตารางเปรียบเทียบคำสั่งจัดการ Mail Queue ของ Postfix ทั้ง postqueue -f, postsuper -h, -H, -r และ -d ว่าทำอะไรและย้อนกลับได้หรือไม่
พักด้วย postsuper -h ก่อนลบเสมอ เพราะ postsuper -d ย้อนกลับไม่ได้

ขั้นตอนที่ 5: หาต้นทางเมื่อ Mail Queue เต็มไปด้วยสแปม

ถ้า Mail Queue มีอีเมลหลายพันฉบับถึงผู้รับที่ไม่รู้จัก ให้หยุดต้นทางก่อนลบ ไม่เช่นนั้นคิวจะเต็มใหม่ภายในไม่กี่นาที เริ่มจากดูว่าผู้ส่งรายใดมากที่สุด

postqueue -j | jq -r '.sender' | sort | uniq -c | sort -rn | head
grep -o 'sasl_username=[^ ,]*' /var/log/mail.log | sort | uniq -c | sort -rn | head
grep 'postfix/pickup' /var/log/mail.log | grep -o 'uid=[0-9]* from=<[^>]*>' | sort | uniq -c | sort -rn | head
  • ผู้ใช้ SASL รายเดียวส่งมากผิดปกติ: รหัสผ่านอีเมลของคนนั้นรั่ว เปลี่ยนรหัสผ่านทันที ปิดการล็อกอินชั่วคราว และตรวจว่ามีการตั้งส่งต่ออีเมลแปลก ๆ หรือไม่
  • pickup จาก uid ของเว็บเซิร์ฟเวอร์ เช่น uid=33 ซึ่งคือ www-data บน Debian และ Ubuntu: มีสคริปต์บนเว็บถูกใช้ส่งอีเมล เปิด mail.add_x_header = On ใน php.ini เพื่อให้ header ระบุไฟล์ PHP ที่ส่ง แล้วดู access log ของเว็บช่วงเวลาเดียวกันหาคำขอ POST ที่ผิดปกติ
  • ผู้ส่งเป็น MAILER-DAEMON จำนวนมาก: เครื่องรับอีเมลถึงผู้รับที่ไม่มีอยู่จริงแล้วตีกลับไปหาผู้ส่งปลอม (backscatter) ให้ตั้งให้ปฏิเสธผู้รับที่ไม่มีอยู่ตั้งแต่ขั้น SMTP

เมื่อหยุดต้นทางได้แล้วจึงลบสแปมตามขั้นตอนที่ 4 และตรวจว่า IP ติด Blacklist หรือไม่

ขั้นตอนที่ 6: ตั้งอายุคิวและแจ้งเตือนเมื่อ Mail Queue โต

ค่าเริ่มต้นของ Postfix เก็บอีเมลที่ส่งไม่สำเร็จไว้ลองใหม่ 5 วัน (maximal_queue_lifetime) และอีเมลตีกลับ 5 วัน (bounce_queue_lifetime) เมื่อครบจะตีกลับไปหาผู้ส่ง บริษัทที่อยากให้ผู้ส่งรู้เร็วขึ้นว่าอีเมลไปไม่ถึงลดเหลือ 2 วันได้ แลกกับการที่ปลายทางซึ่งล่มนานกว่านั้นจะไม่ได้รับอีเมล

postconf maximal_queue_lifetime bounce_queue_lifetime
postconf -e 'maximal_queue_lifetime = 2d' 'bounce_queue_lifetime = 2d'
systemctl reload postfix

ตั้งสคริปต์ตรวจขนาด Mail Queue ทุก 15 นาทีด้วย cron ให้แจ้งเตือนเมื่อเกินเกณฑ์ที่เหมาะกับเครื่อง เช่น 200 ฉบับ สคริปต์นี้ใช้คำสั่ง mail จากแพ็กเกจ mailutils

#!/bin/sh
# /usr/local/bin/check-mailq.sh
COUNT=$(postqueue -j | wc -l)
if [ "$COUNT" -gt 200 ]; then
  echo "Mail Queue on $(hostname) has $COUNT messages" | mail -s "Mail Queue alert" [email protected]
fi

ถ้าคิวค้างเพราะส่งออกไม่ได้ อีเมลแจ้งเตือนอาจค้างไปด้วย ควรใช้ช่องทางที่ไม่พึ่งเครื่องนี้ร่วมด้วย เช่น Healthchecks ความหมายของพารามิเตอร์ทั้งหมดอยู่ใน เอกสาร postqueue ของ Postfix

เช็กลิสต์ก่อนลบอีเมลจำนวนมากใน Mail Queue เช่น หยุดต้นทางสแปมแล้ว บันทึกตัวอย่างไว้เป็นหลักฐาน และพักอีเมลไว้ก่อน
ลบเฉพาะสิ่งที่แน่ใจว่าเป็นสแปม และหยุดต้นทางก่อนเสมอ

ปัญหาที่พบบ่อยเกี่ยวกับ Mail Queue

Mail Queue โตเป็นพันฉบับทั้งที่บริษัทส่งอีเมลไม่มาก เกิดจากอะไร?

Mail Queue ที่โตแบบนี้เกือบทุกครั้งเป็นสแปมจากบัญชีที่รหัสผ่านรั่ว สคริปต์บนเว็บที่ถูกเจาะ หรือ backscatter ให้ดูผู้ส่งที่มากที่สุดตามขั้นตอนที่ 5 และหยุดต้นทางก่อนลบ

ลบอีเมลออกจาก Mail Queue แล้วกู้คืนได้หรือไม่?

ไม่ได้ postsuper -d ลบไฟล์ออกจากคิวทันที ถ้าไม่แน่ใจให้ใช้ postsuper -h พักไว้ก่อน หรือบันทึกด้วย postcat แล้วจึงลบ

สั่ง postqueue -f แล้วอีเมลยังค้างเหมือนเดิม ทำไม?

คำสั่งนี้แค่สั่งให้ลองส่งทันที ถ้าสาเหตุยังอยู่ เช่น พอร์ต 25 ขาออกถูกปิดหรือปลายทางยังชะลอการรับ อีเมลก็กลับมาค้างด้วยเหตุผลเดิม ให้อ่านเหตุผลตามขั้นตอนที่ 2 แล้วแก้ที่ต้นเหตุ

คิวว่าง แต่ผู้รับบอกว่าไม่ได้รับอีเมล ต้องดูที่ไหน?

ค้น log ด้วยที่อยู่ผู้รับ เช่น grep 'to=<[email protected]>' /var/log/mail.log ถ้าเห็น status=sent แปลว่าปลายทางรับไปแล้ว อีเมลอาจอยู่ใน Spam ของผู้รับ ถ้าเห็น status=bounced ให้อ่านเหตุผลที่ปลายทางปฏิเสธ

ถ้าเซิร์ฟเวอร์ส่งสแปมออกไปแล้ว หรือต้องการให้ช่วยตรวจ Mail Queue และความปลอดภัยของเมลเซิร์ฟเวอร์ ติดต่อทีมงาน THAI DATA CLOUD ได้ องค์กรที่ต้องการเครื่องสำหรับเมลเซิร์ฟเวอร์ที่ผู้ดูแลจัดการเอง ดูรายละเอียดได้ที่ Cloud Linux Server

อ่านเพิ่มเติมเกี่ยวกับ Mail Queue

แชร์FacebookXLINELinkedIn

มีคำถามเรื่องบริการ? ติดต่อทีมงาน