RHEL9で作る自宅サーバ:mailサーバの構築 その1 postfixのインストールと設定

mailサーバRHEL9パソコン自宅サーバ

postfixの設定方針

メールサーバの基本方針は、こちらの記事に従っています。

smtp(25番)

  • 基本、ローカルのメールアドレス宛のメールしか受け付けない。特定のIPアドレス(LAN内など)からのものだけ、メールの転送を行う。
  • ログイン試行を行わせないため、認証はしない。
  • 相手の都合に合わせて、STARTTLSで暗号化を行う。

submission(587番)

  • 必ず認証は行う。
  • 認証が通ったことを前提に、メールの転送を行う。
  • 相手の都合に合わせて、STARTTLSで暗号化を行う。

smtps(465番)

  • 認証は必ず行う。
  • 認証が通ったことを前提に、メールの転送を行う。
  • 暗号化は必ず行う。

このような方針でpostfixを構築していきます。

postfixのインストール

メールサーバとして、postfixをインストールします。

[root@ace ~]# dnf install postfix
サブスクリプション管理リポジトリーを更新しています。
メタデータの期限切れの最終確認: 2:46:08 前の 2024年02月19日 22時22分31秒 に実施 しました。
依存関係が解決しました。
================================================================================
 パッケージ
           Arch     バージョン         リポジトリー                       サイズ
================================================================================
インストール:
 postfix   x86_64   2:3.5.9-24.el9     rhel-9-for-x86_64-appstream-rpms   1.5 M

トランザクションの概要
================================================================================
インストール  1 パッケージ

ダウンロードサイズの合計: 1.5 M
インストール後のサイズ: 4.4 M
これでよろしいですか? [y/N]: y
:
省略
:
インストール済み:
  postfix-2:3.5.9-24.el9.x86_64

完了しました!
[root@ace ~]#

お手軽パッケージインストール完了です。

main.cfの編集

[root@ace ~]# cp -p /etc/postfix/main.cf /etc/postfix/main.cf.orig
[root@ace ~]# vi /etc/postfix/main.cf
[root@ace ~]# diff /etc/postfix/main.cf /etc/postfix/main.cf.orig
96d95
< myhostname = mail.zeke.ne.jp
104d102
< mydomain = zeke.ne.jp
121d118
< myorigin = $myhostname
138c135
< inet_interfaces = all
---
> inet_interfaces = localhost
141c138
< inet_protocols = ipv4
---
> inet_protocols = all
186,189c183
< mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain,
<       ace.zeke.ne.jp, cafe.zeke.ne.jp, myhome.zeke.ne.jp,
---
> mydestination = $myhostname, localhost.$mydomain, localhost
289c283
< mynetworks = 192.168.1.0/24, 127.0.0.0/8
---
> #mynetworks = 168.100.189.0/28, 127.0.0.0/8
434c428
< recipient_delimiter = +
---
> #recipient_delimiter = +
444c438
< home_mailbox = Maildir/
---
> #home_mailbox = Maildir/
493d486
< mailbox_transport = lmtp:unix:private/dovecot-lmtp
598c591
< smtpd_banner = $myhostname ESMTP $mail_name
---
> #smtpd_banner = $myhostname ESMTP $mail_name
716c709
< smtpd_tls_cert_file = /etc/letsencrypt/live/zeke.ne.jp/fullchain.pem
---
> smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
722c715
< smtpd_tls_key_file = /etc/letsencrypt/live/zeke.ne.jp/privkey.pem
---
> smtpd_tls_key_file = /etc/pki/tls/private/postfix.key
744,749d736
<
< smtpd_tls_auth_only = yes
< smtpd_tls_received_header = yes
< smtp_tls_loglevel = 1
< smtp_tls_note_starttls_offer = yes
<
752,793d738
<
< # SASL parameters
< smtpd_sasl_auth_enable = no
< smtpd_sasl_type = dovecot
< smtpd_sasl_path = private/auth
< smtpd_sasl_tls_security_options = noanonymous
< smtpd_sasl_local_domain = $myhostname
<
< # Anti-Abuse
< disable_vrfy_command = yes
< smtpd_peername_lookup = no
< anvil_rate_time_unit = 60s
< smtpd_client_connection_rate_limit = 120
< smtpd_client_message_rate_limit = 120
< smtpd_client_recipient_rate_limit = 120
< smtpd_client_connection_count_limit = 25
<
< smtpd_recipient_restrictions =
<       permit_mynetworks,
<       reject_invalid_helo_hostname,
<       reject_unknown_sender_domain,
<       reject_unauth_destination,
<       check_sender_access hash:/etc/postfix/sender_access,
<       reject_rbl_client bl.spamcop.net,
<       reject_rbl_client zen.spamhaus.org=127.0.0.[2..11],
<       reject_rhsbl_sender dbl.spamhaus.org=127.0.1.[2..99],
<       reject_rhsbl_helo dbl.spamhaus.org=127.0.1.[2..99],
<       reject_rhsbl_reverse_client dbl.spamhaus.org=127.0.1.[2..99],
<       warn_if_reject reject_rbl_client zen.spamhaus.org=127.255.255.[1..255]
<
< # Performance and Regulation
< message_size_limit = 10485760
< mailbox_size_limit = 0
< default_process_limit = 50
< default_destination_concurrency_limit = 10
< initial_destination_concurrency = 3
<
[root@ace ~]#

設定ファイルについては

こちらのページも参考にさせていただきました!

各変更箇所を見ていきます。

138c135
< inet_interfaces = all
---
> inet_interfaces = localhost
141c138
< inet_protocols = ipv4
---
> inet_protocols = all

inet_interfacesはだれからもつなげられるようにall、inet_protocolsはIPv6を使わず、IPv4だけにしています。

これは、IPv6では逆引きができないIPアドレスを使っていることと、迷惑メール対策のためのブラックリストを使うとき範囲が狭いIPv4の方が都合が良いからです。

493d486
< mailbox_transport = lmtp:unix:private/dovecot-lmtp

dovecotとはLMTPで配送を行います。

598c591
< smtpd_banner = $myhostname ESMTP $mail_name
---
> #smtpd_banner = $myhostname ESMTP $mail_name

相手のメールサーバと接続したときに出すバナーには、Postfixのバージョンを出さないように設定しています。

716c709
< smtpd_tls_cert_file = /etc/letsencrypt/live/zeke.ne.jp/fullchain.pem
---
> smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
722c715
< smtpd_tls_key_file = /etc/letsencrypt/live/zeke.ne.jp/privkey.pem
---
> smtpd_tls_key_file = /etc/pki/tls/private/postfix.key
744,749d736
<
< smtpd_tls_auth_only = yes
< smtpd_tls_received_header = yes
< smtp_tls_loglevel = 1
< smtp_tls_note_starttls_offer = yes
<

今回の証明書は現行のサーバからコピーしたものを使います。移行したあとは、Let’s Encryptからとてきたものを使います。

[root@ace etc]# cd /etc
[root@ace etc]# scp -pr 現行のホスト:/etc/letsencrypt/ .
[root@ace zeke.jp]# cd /etc/letsencrypt/live/zeke.ne.jp
[root@ace zeke.ne.jp]# ls -l
合計 20
-rw-r--r-- 1 root root  692  2月 14 23:52 README
-rw-r--r-- 1 root root 1822  2月 14 23:52 cert.pem
-rw-r--r-- 1 root root 1826  2月 14 23:52 chain.pem
-rw-r--r-- 1 root root 3648  2月 14 23:52 fullchain.pem
-rw------- 1 root root 1708  2月 14 23:52 privkey.pem
[root@ace zeke.ne.jp]# rm -f cert.pem chain.pem fullchain.pem privkey.pem
[root@ace zeke.ne.jp]# ln -s ../../archive/zeke.ne.jp/cert1.pem cert.pem
[root@ace zeke.ne.jp]# ln -s ../../archive/zeke.ne.jp/chain1.pem chain.pem
[root@ace zeke.ne.jp]# ln -s ../../archive/zeke.ne.jp/fullchain1.pem fullchain.pem
[root@ace zeke.ne.jp]# ln -s ../../archive/zeke.ne.jp/privkey1.pem privkey.pem
[root@ace zeke.ne.jp]#
:
その他のドメインもリンクを張りなおす。

その他にもRedHat社のドキュメントを参考に細かい設定を追加しておきました。

< # SASL parameters
< smtpd_sasl_auth_enable = no
< smtpd_sasl_type = dovecot
< smtpd_sasl_path = private/auth
< smtpd_sasl_tls_security_options = noanonymous
< smtpd_sasl_local_domain = $myhostname

認証の設定では、「smtpd_sasl_auth_enable = no」とし、smtp(25番ポート)では認証なしにしておきます。

設定例では「smtpd_sasl_auth_enable = yes」になっていることが多いですが、これだとsmtpで認証が有効になり、それを狙ってパスワードをクラックしようとする攻撃を受けることになります。(こちらでは1日当たり2000アクセスほどあります)

submissionやsmtpsを定義するmaster.cfの中で「smtpd_sasl_auth_enable = yes」を設定します。

また、認証自体はdovecotのものをそのまま使います。smtpでは関係ありませんが、master.cfの方に設定が引き継がれるので、ここで設定しておきます。

< # Anti-Abuse
< disable_vrfy_command = yes
< smtpd_peername_lookup = no
< anvil_rate_time_unit = 60s
< smtpd_client_connection_rate_limit = 120
< smtpd_client_message_rate_limit = 120
< smtpd_client_recipient_rate_limit = 120
< smtpd_client_connection_count_limit = 25
<
< smtpd_recipient_restrictions =
<       permit_mynetworks,
<       reject_invalid_helo_hostname,
<       reject_unknown_sender_domain,
<       reject_unauth_destination,
<       check_sender_access hash:/etc/postfix/sender_access,
<       reject_rbl_client bl.spamcop.net,
<       reject_rbl_client zen.spamhaus.org=127.0.0.[2..11],
<       reject_rhsbl_sender dbl.spamhaus.org=127.0.1.[2..99],
<       reject_rhsbl_helo dbl.spamhaus.org=127.0.1.[2..99],
<       reject_rhsbl_reverse_client dbl.spamhaus.org=127.0.1.[2..99],
<       warn_if_reject reject_rbl_client zen.spamhaus.org=127.255.255.[1..255]
<

disable_vrfy_command = yes でメールアドレスの存在をわからないようにします。これが有効だと適当なアドレスを試行して有効なものを探す人がいるので。

smtpd_peername_lookup = no でIPアドレスからホスト名への逆引きをしません。かつてはクライアントパソコンがウィルスに感染してSPAMメールを送信、パソコンには逆引きホスト名がついていないことが多いのでそのようなホストはブロック!という手段も有効でした。しかし、今ではOP25Bが普及してクライアントパソコンがメールサーバのふりをしてメールを送信できなくなったので、ホスト名への逆引きしてできないのをブロックする意味はなくなっています。

anvil_rate_time_unit から smtpd_client_connection_count_limit まではユーザーが乗っ取られてSPAM送信に利用されたときに制限をかけるものです。通常の運用時には問題にならないほど大きな値にしています。
制限なくSPAMに利用されると、メールを送信しまくってログインすらできないほどサーバに負荷がかかります。(苦い思い出です)

smtpd_recipient_restrictions =で、各種接続制限を設定しています。
smtpd_client_restrictions やsmtpd_sender_restrictionsに分けて記述することもできます。拒否設定はどこに書いても同じですが、許可設定は拒否設定の直前に書いておかないと意味がないので、smtpd_recipient_restrictions に集約しています。

まずは最優先でLAN内のホストからのメールはどこ宛に出してもOKのpermit_mynetworks。

reject_invalid_helo_hostnameとreject_unknown_sender_domainでHELO時のホスト名がおかしな名前だったり、メールが届かないメールアドレスを送信者として書いていたりしたときは拒否。

次にreject_unauth_destinationで自サーバ内にメールアドレスがないものを拒否。(不正中継対策)

check_sender_access では特定の送信者のメールアドレスを許可。これは以降に続くブラックリストに引っかかるけどどうしても受信したいメールがあるときにsender_accessにメールのドメインを書いておいて許可できるようにしておきます。

[root@ace ~]# cat /etc/postfix/sender_access
# SYNOPSIS
#        postmap /etc/postfix/sender_access
# EXAMPLE
#        /etc/postfix/sender_access:
#            example.com OK
#            example.net REJECT
[root@ace ~]#


ファイル作成後「postmap /etc/postfix/sender_access」でDB化しておきます。DBになっているので再起動なしで変更が反映されます。

reject_rbl_client から warn_if_reject reject_rbl_client までは bl.spamcop.net 及び zen.spamhaus.org のブラックリストに載っているサーバからの接続を拒否する設定を入れてます。
以前はブラックリストの精度が悪くて必要なメールを拒否することもありましたが、今はパソコンがメールサーバのふりをできなくするOP25Bやメールアドレスのなりすましを防ぐDMARCが普及して、ブラックリストの精度が上がって無条件に拒否しても問題なさそうです。
ブラックリストの利用も20年以上たち「メールサーバ管理者ならブラックリストに載らないようにするのが当たり前」という考え方も浸透していると思います。

< # Performance and Regulation
< message_size_limit = 10485760
< mailbox_size_limit = 0
< default_process_limit = 50
< default_destination_concurrency_limit = 10
< initial_destination_concurrency = 3
<

パフォーマンス関係の設定では、送信できるメールの大きさなどを設定しています。プロセス関係は個人で使う送受信が少ないサーバなのでデフォルトの半分ぐらいにしています。

master.cfの編集

[root@ace ~]# vi /etc/postfix/master.cf
[root@ace ~]# diff /etc/postfix/master.cf /etc/postfix/master.cf.orig
17,20c17,20
< submission inet n       -       n       -       -       smtpd
<   -o syslog_name=postfix/submission
<   -o smtpd_tls_security_level=encrypt
<   -o smtpd_sasl_auth_enable=yes
---
> #submission inet n       -       n       -       -       smtpd
> #  -o syslog_name=postfix/submission
> #  -o smtpd_tls_security_level=encrypt
> #  -o smtpd_sasl_auth_enable=yes
26c26
<   -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
---
> #  -o smtpd_recipient_restrictions=
29,32c29,32
< smtps     inet  n       -       n       -       -       smtpd
<   -o syslog_name=postfix/smtps
<   -o smtpd_tls_wrappermode=yes
<   -o smtpd_sasl_auth_enable=yes
---
> #smtps     inet  n       -       n       -       -       smtpd
> #  -o syslog_name=postfix/smtps
> #  -o smtpd_tls_wrappermode=yes
> #  -o smtpd_sasl_auth_enable=yes
37c37
<   -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
---
> #  -o smtpd_recipient_restrictions=
[root@ace ~]#

submisshon(587番ポート)及びsmtps(465番ポート)を設定します。

両方とも -o smtpd_sasl_auth_enable=yes で認証を有効にしています。また、-o smtpd_relay_restrictions smtpd_recipient_restrictions=permit_sasl_authenticated,reject で認証を通れば外部のメールサーバにメールをリレーすることを許可しています。

*2024/5/29 修正 postfixではmain.cfの内容をデフォルトとしてmaster.cfで使われます。main.cfのsmtpd_recipient_restrictionsではリレーを許可しない設定になっているため、ここではsmtpd_relay_restrictionsではなくsmtpd_recipient_restrictionsを再定義する必要がありました。

[root@ace ~]# postfix check

postfix checkでエラーが出ないことを確認します。

デーモンの起動

[root@ace ~]# systemctl status postfix
○ postfix.service - Postfix Mail Transport Agent
     Loaded: loaded (/usr/lib/systemd/system/postfix.service; disabled; preset:>
     Active: inactive (dead)
[root@ace ~]# systemctl enable postfix
Created symlink /etc/systemd/system/multi-user.target.wants/postfix.service → /usr/lib/systemd/system/postfix.service.
[root@ace ~]# systemctl start postfix
[root@ace ~]# systemctl status postfix
● postfix.service - Postfix Mail Transport Agent
     Loaded: loaded (/usr/lib/systemd/system/postfix.service; enabled; preset: >
     Active: active (running) since Sun 2024-02-25 01:01:42 JST; 5s ago
    Process: 81901 ExecStartPre=/usr/sbin/restorecon -R /var/spool/postfix/pid >
    Process: 81902 ExecStartPre=/usr/libexec/postfix/aliasesdb (code=exited, st>
    Process: 81906 ExecStartPre=/usr/libexec/postfix/chroot-update (code=exited>
    Process: 81907 ExecStart=/usr/sbin/postfix start (code=exited, status=0/SUC>
   Main PID: 81975 (master)
      Tasks: 3 (limit: 23114)
     Memory: 3.8M
        CPU: 379ms
     CGroup: /system.slice/postfix.service
             tq81975 /usr/libexec/postfix/master -w
             tq81976 pickup -l -t unix -u
             mq81977 qmgr -l -t unix -u

 2月 25 01:01:42 ace.zeke.ne.jp systemd[1]: Starting Postfix Mail Transport Age>
 2月 25 01:01:42 ace.zeke.ne.jp postfix/postfix-script[81973]: starting the Pos>
 2月 25 01:01:42 ace.zeke.ne.jp postfix/master[81975]: daemon started -- versio>
 2月 25 01:01:42 ace.zeke.ne.jp systemd[1]: Started Postfix Mail Transport Agen>
[root@ace ~]#

とりあえず、デーモンを起動。システム起動時に自動起動もできるようにしておきます。

ステータスをチェックで、エラーも出ていないようですね。

[root@ace ~]# ss -natup | grep master
tcp   LISTEN 0      50                               0.0.0.0:587                                    0.0.0.0:*     users:(("master",pid=81975,fd=17))            
tcp   LISTEN 0      50                               0.0.0.0:465                                    0.0.0.0:*     users:(("master",pid=81975,fd=20))            
tcp   LISTEN 0      50                               0.0.0.0:25                                     0.0.0.0:*     users:(("master",pid=81975,fd=13))            
[root@ace ~]#

ポートの待受ができていることが確認できました。

DNSサーバの設定追加

こちらのページで設定したDNSサーバのゾーンファイルにMXレコードを入れなくてはいけません。

        IN      A       192.168.1.1
        IN      AAAA    2001:2c0:cd03:ca00::ace
        IN      MX      10      mail.zeke.ne.jp.
;
ns      IN      A       192.168.1.1
        IN      AAAA    2001:2c0:cd03:ca00::ace
        IN      MX      10      mail.zeke.ne.jp.
;
joeker  IN      A       192.168.1.1
        IN      AAAA    2001:2c0:cd03:ca00::ace
        IN      MX      10      mail.zeke.ne.jp.
;
mail    IN      A       192.168.1.1
        IN      AAAA    2001:2c0:cd03:ca00::ace
        IN      MX      10      mail.zeke.ne.jp.
;
www     IN      CNAME   ns
irc     IN      CNAME   ns
ftp     IN      CNAME   ns
redh    IN      CNAME   ns
shoot   IN      CNAME   ns
blog    IN      CNAME   ns
matomo  IN      CNAME   ns
info    IN      CNAME   ns
*.info  IN      CNAME   ns
;
myhome  IN      A       192.168.1.4
        IN      AAAA    2001:2c0:cd03:ca00::4
        IN      MX      10      mail.zeke.ne.jp.
;
ace     IN      A       192.168.1.1
        IN      AAAA    2001:2c0:cd03:ca00::ace
        IN      MX      10      mail.zeke.ne.jp.

Aレコードを持つドメインやホストにMXレコードを入れています。main.cfmydestinationには、こちらのホスト名を列挙しています。

また、メールサーバの動作確認を行うために、dnsサーバ及びメールサーバのIPアドレスを新しいサーバのものに変更しました。

Firewallの設定

以下のようにポートを開きます。

[root@ace ~]# firewall-cmd --list-all-zones
:
省略
:
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: dns ftp irc ssh
  ports: 5500-5501/tcp 20/tcp 20000-20200/tcp
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

trusted (active)
  target: ACCEPT
  icmp-block-inversion: no
  interfaces:
  sources: 192.168.1.0/24 2001:2c0:cd03:ca00::/64 fe80::/64
  services:
  ports:
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
:
省略
:
[root@ace ~]# firewall-cmd --add-service=smtp --zone=public --permanent
success
[root@ace ~]# firewall-cmd --add-service=smtp-submission --zone=public --permanent
success
[root@ace ~]# firewall-cmd --add-service=smtps --zone=public --permanent
success
[root@ace ~]#
[root@ace ~]# firewall-cmd --reload
success
[root@ace ~]#
[root@ace ~]# firewall-cmd --list-all-zones
:
省略
:
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: dns ftp irc smtp smtp-submission smtps ssh
  ports: 5500-5501/tcp 20/tcp 20000-20200/tcp
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

trusted (active)
  target: ACCEPT
  icmp-block-inversion: no
  interfaces:
  sources: 192.168.1.0/24 2001:2c0:cd03:ca00::/64 fe80::/64
  services:
  ports:
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
:
省略
:
[root@ace ~]#

ちゃんとpublicゾーンにpostfixに必要なポートが開いたようです。

軽く動作確認

[root@ace ~]# telnet localhost 25
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail.zeke.ne.jp ESMTP Postfix
EHLO
501 Syntax: EHLO hostname
EHLO localhost
250-mail.zeke.ne.jp
250-PIPELINING
250-SIZE 10485760
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING
AUTH LOGIN
503 5.5.1 Error: authentication not enabled
^]
telnet> quit
Connection closed.
[root@ace ~]#

telnetコマンドを使って軽くテストをしてみます。赤字が入力した内容です。
ipv6が無効になっているのでIPv4に切り替えてポート25番に入れました。
EHLOコマンドは問題なさそうです。
AUTH LOGINコマンドでログインを拒否されました。想定通りの動作です。
キーボードからCRTL+]で抜けてquitコマンドで終了です。

[root@ace ~]# cat /var/log/maillog
Feb 25 01:01:42 ace postfix/postfix-script[81973]: starting the Postfix mail system
Feb 25 01:01:42 ace postfix/master[81975]: daemon started -- version 3.5.9, configuration /etc/postfix
Feb 25 01:08:18 ace postfix/smtpd[82010]: connect from unknown[127.0.0.1]
Feb 25 01:09:26 ace postfix/smtpd[82010]: lost connection after AUTH from unknown[127.0.0.1]
Feb 25 01:09:26 ace postfix/smtpd[82010]: disconnect from unknown[127.0.0.1] ehlo=1/2 auth=0/1 commands=1/3
[root@ace ~]#

ログはこのようになります。IPアドレスの逆引きをしないのでホスト名はすべてunknownになります。
現行のメールサーバはこのようなパスワードクラックの試行が1日に2000件ぐらいあります。

まだdovecotをインストールしていないのでメールの送受信ができません。
動作確認はここまでとしておきます。

お勧めのKindle本です!

コメント