家庭服务器搭建记:在Docker容器中安装Postfix/一个完整的邮件接收服务器
(2023/11/15 追记开始)
根据这篇文章的设定,如果发送给不存在该用户域名的用户的邮件会被转发为错误邮件。为了尽可能地抑制这种情况,我写了一篇微调过的文章。虽然不完美,但希望对您有所帮助。
私人服务器搭建日志:Postfix
(2023/11/15 追记结束)
书法能手
搭建家庭服务器故事:基于基本构想,继续安装Ubuntu 22.04 LTS的家庭服务器搭建,续篇。
不好意思,我在这里先道个歉。我之前对邮件服务器有些小看了。我很抱歉说了些自负的话,把邮件服务器当成了家用服务器。
现在建立邮件服务器(MTA)真的很困难。为了防止垃圾邮件,要加强安全措施,需要特别小心。技术上非常麻烦。而且全球领先的邮件服务提供商(如Google)也在强制要求这种加密措施。做起来虽然不是不可能,但真的很辛苦。
所以,我的家用服务器上的邮件服务器(MTA)将降低其志愿。
目标
首次进行与邮件服务器相关的工作时,重新列出了工作标题。
-
- Dovecot的LMTP-完成
-
- Dovecot的IMAP-完成
- Postfix-还在进行中
因此,这次我们将在Docker容器中部署Postfix。
并且将服务器设置为保持低调,不发送任何邮件至外部。也不会发送错误邮件。将接收所有域名的所有用户。
由于不向外部发送信息,因此也不需要SMTP-Auth。
这也有风险的哦。如果出现什么意外,变成了垃圾邮件的攻击对象之类的情况,就会不得不接收一大堆邮件了。
也许如果合理设置Postfix,可能可以解决这个问题,但是我对此并不了解。即使查找了相关的文章,也没有找到有关这方面设置的说明。似乎只有认真学习Postfix才行。只能接受这个风险了,没办法。
文献引用
关于Postfix基本设置的信息。
-
- CentOS 7 の Postfix で独自ドメインの設定 – Qiita
- LMTP_README – Postfixのぺーじ - 和訳ドキュメント (2.0.x)
我收集了一些将后缀设置为只收信的相关信息。有点儿多。
-
- Postfixで特定のドメイン宛以外のメールを削除したい – KITA-SAN.BLOG
-
- Postfixアドレス書き換え
-
- Postfix の拡張メールアドレス – tmtms のメモ
-
- Postfix 設定パラメータ
-
- [Postfix]特定のドメインのみ受信しそれ以外は別アドレスに転送する – OSSリファレンス
-
- 【postfix】送信元(From)によるメール拒否(smtpd_sender_restrictions ) – server-memo.net
-
- regexp_table – Postfix 正規表現テーブルの書式
-
- Postfix バーチャルドメインホスティング Howto
- バーチャルドメイン – Postfix チュートリアル
我在这篇文章中参考了如何在Docker中安装Postfix的方法。
- UbuntuのDockerコンテナにPostfixをインストールする
顺便提一下,我找到了一个案例,展示了一个既能够确保有效发送又能够稳定运行的电子邮件服务器,供您参考。
- Ubuntu 22.04にPostfix+Dovecot(SASL認証)を構築しGmail/Yahooメールの迷惑メール判定に合格するまで – 星空の下のプログラミング
以下是针对冒充邮件的防范措施的解释。
- 送信ドメイン認証(SPF / DKIM / DMARC)の仕組みと、なりすましメール対策への活用法を徹底解説 – エンタープライズIT COLUMNS – IIJ
准备
Docker容器构建用目录
首先,我们将准备一个文件夹,路径为/opt/postfix。
sudo mkdir /opt/postfix
sudo chgrp docker /opt/postfix
sudo chmod g+w /opt/postfix
经过这些操作后,/opt/postfix目录的权限将变成这样。
$ ls -dl /opt/postfix
drwxrwxr-x 2 root docker 2 Jun 4 11:34 /opt/postfix
後綴設定文件
请在上述目录中准备Postfix相关文件。
我已经将Postfix配置文件main.cf设置成了这个样子。
-
- ドメインexample.comは、説明用の仮設定です。お金を出して買った自分だけのドメインに置き換えて下さい。
-
- IPアドレス172.16.1.3とポート番号24は、Dovecotで設定したLMTPサーバーに合わせて下さい。LXDコンテナではなくて、そのホストマシンを設定します。
- ユーザーtaroは、色んな宛先に来たメールを受け取る、転送先ユーザーです。
MYDOMAIN=example.com
LMTP_IPADDR=172.16.1.3
LMTP_PORT=24
MYUSER=taro
cat <<___ >/opt/postfix/main.cf
compatibility_level = 3.6
mydomain = $MYDOMAIN
myhostname = mail.\$mydomain
myorigin = \$mydomain
inet_protocols = ipv4
inet_interfaces = all
mydestination = $MYDOMAIN
local_recipient_maps =
mynetworks = 127.0.0.0/8
alias_maps = hash:/etc/aliases
mailbox_transport = lmtp:inet:$LMTP_IPADDR:$LMTP_PORT
smtpd_banner = \$myhostname ESMTP
biff = no
readme_directory = no
virtual_alias_domains = regexp:/etc/virtual_domains
virtual_alias_maps = regexp:/etc/virtual_users
mailbox_size_limit = 0
recipient_delimiter = +
___
为了收到全域名的所有用户的邮件,我们使用Postfix的虚拟域设置。该设置如下:对于非$MYDOMAIN域名的邮件,全部转发至$MYUSER。
cat <<___ >/opt/postfix/virtual_domains
!/^$MYDOMAIN\$/ OK
___
cat <<___ >/opt/postfix/virtual_users
!/^.*@$MYDOMAIN\$/ $MYUSER@$MYDOMAIN
___
用Docker构建容器
准备相关文件
docker-compose.yml文件如下。
cat <<___ >/opt/postfix/docker-compose.yml
version: '3.8'
services:
postfix1:
build: .
volumes:
- ./main.cf:/etc/postfix/main.cf
- ./virtual_domains:/etc/virtual_domains
- ./virtual_users:/etc/virtual_users
ports:
- "25:25"
___
然后是Dockerfile文件。
cat <<___ >/opt/postfix/Dockerfile
FROM ubuntu:22.04
RUN apt update && apt upgrade -y
RUN DEBIAN_FRONTEND=noninteractive apt install postfix -y
COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
___
最后,是在启动时执行的entrypoint.sh。内容如下所示。详细信息请参考参考文献。
cat <<___ >/opt/postfix/entrypoint.sh
#!/bin/bash
postfix start
postmap /etc/virtual_domains
postmap /etc/virtual_users
cp /etc/resolv.conf /var/spool/postfix/etc/resolv.conf
postfix reload
tail -f /dev/null
___
chmod +x /opt/postfix/entrypoint.sh
构建
没有任何特别的事情。
cd /opt/postfix
docker compose up -d
确认操作
我不熟悉的域名目标。
我会将其发送到一个适当的域名和适当的电子邮件地址。
nc -C 172.16.1.3 25 <<___
ehlo sender.home
mail from: ubuntu@example.com
rcpt to: hanako@test.home
data
From: ubuntu@example.com
To: hanako@test.home
Subject: test mail
hello, world
.
quit
___
未知领域的陌生人邮件将发送到$MYUSER(此次为taro)的邮箱中。此次我们不使用IMAP,而是直接查看/home/taro/Maildir。新邮件应存放在Maildir/new目录中。
lxc shell dovecot1
cd /home/taro/Maildir/new
ls -t | head -n1 | xargs cat
exit
运行结果会是这样的感觉。
# cd /home/taro/Maildir/new
# ls -t | head -n1 | xargs cat
Return-Path: <ubuntu@example.com>
Delivered-To: taro@example.com
Received: from mail.example.com ([192.168.0.1])
by dovecot1 with LMTP
id RiRsKroZfGQeGQAA9sUnBg
(envelope-from <ubuntu@example.com>)
for <taro@example.com>; Sun, 04 Jun 2023 13:57:30 +0900
Received: from sender.home (unknown [172.16.1.3])
by mail.example.com (Postfix) with ESMTP id A02A93A8
for <hanako@test.home>; Sun, 4 Jun 2023 04:57:30 +0000 (UTC)
From: ubuntu@example.com
To: hanako@test.home
Subject: test mail
hello, world
# exit
logout
向真实的用户发送
只要是发送给实际存在于$MYDOMAIN域的用户,邮件会准确地送到该用户那里。
nc -C 172.16.1.3 25 <<___
ehlo sender.home
mail from: ubuntu@example.com
rcpt to: ubuntu@example.com
data
From: ubuntu@example.com
To: ubuntu@example.com
Subject: test mail
hello, world
.
quit
___
lxc shell dovecot1
cd /home/ubuntu/Maildir/new
ls -t | head -n1 | xargs cat
exit
执行结果。
# cd /home/ubuntu/Maildir/new
# ls -t | head -n1 | xargs cat
Return-Path: <ubuntu@example.com>
Delivered-To: ubuntu@example.com
Received: from mail.example.com ([192.168.0.1])
by dovecot1 with LMTP
id gITxHiojfGRDGQAA9sUnBg
(envelope-from <ubuntu@example.com>)
for <ubuntu@example.com>; Sun, 04 Jun 2023 14:37:46 +0900
Received: from sender.home (unknown [172.16.1.3])
by mail.example.com (Postfix) with ESMTP id 728883B0
for <ubuntu@example.com>; Sun, 4 Jun 2023 05:37:46 +0000 (UTC)
From: ubuntu@example.com
To: ubuntu@example.com
Subject: test mail
hello, world
# exit
logout
结束
通过这个设置,您可以默默地接收所有邮件,以避免不必要的中转。使用这一设置,您似乎还可以进行电子邮件发送的测试。
总之,现在我们成功地搭建了一个只用于“接收信息”的邮件服务器,不会给他人带来麻烦。太棒了!