Ubuntu

Ubuntu20.04 デュアルスタックな環境でPostfixの送信元をIPv4アドレスに固定する

最近、家庭内のIPv6が大体思い通りに動くようになってきているので、PostfixもIPv6での接続を受け付けるのだが、テストの都合上、とあるホストだけ
 受信は複数あるIPv6とIPv4のアドレス達すべて受け付ける。
 送信はIPv4のアドレス1つだけに絞る。
ということがやりたくなった。



広告


今回は、あまり良い結論が得られていない。調査の過程でやったことが、後でひょっとしたら役に立つかもなー、ということでメモしておく。

 

設定方法

結論からすると、現実的な設定方法なし。
リレー先やトランスポート先をIPv4アドレスで指定するしかなかった。

/etc/postfix/main.cf

relayhost = [192.168.0.77]

とか、transport_mapsとか。宛先がIPv4なら、IPv4から送り出すしかないので。

Postfix Configuration Parameters

IPv4とIPv6混在環境の設定

Postfixは使えるインターフェースをランダムに使用してリレーを試みるのが仕様。
IPv6が使える&リレー先をルックアップしたときにIPv6アドレスが返ってくる → 選択するインターフェースに【必ずIPv6を含める】という動作。
MTAがダウンした状態にならないよう、常に色々な経路を確保しておきたい、という思想なのだと想像される。

色々とやってみた感じでは、ローカルネットワークをIPv6対応していく場合、

  • それでもPostfixだけはかたくなにIPv4だけで動作させ、名前解決でも必ずIPv4だけが返るようにしておく。
  • IPv6に対応させる場合、IPv6アドレスを幾つかあるうちから1つに絞って、送信元としてこのGUAを設定する。
    かつ、どちらでも問題がないようにローカルもインターネット側もDNSを設定。
    さらに、SPFやDKIM、DMARCも、確実に1つのGUAに対応させる。

のいずれかを選択することになりそう。現時点では。

GUAを1つに絞る、と書いたのは少し言い過ぎ。でも、IPv6アドレスって固定のものを設定してもRA(Router Advertisement)が飛んでくると、自動で構成されていったりするので、複数使うにしても色々なところを適切にコントロールしていくことが大切。

この観点で気になったので、宛先となるドメインについて、/etc/hostsに fe80::nnnn:nnnn:nnnn:nnnn%ens33とか設定してみたら、メール転送できたりして。へー、という感じ。
Ubiquiti Community / ipv6 Invalid argument ? [Solved]

IPv4に限定

SMTPサーバーを独立させているなら、当面はこの選択しかできないのではないか。

/etc/postfix/main.cf

inet_interfaces = all
inet_protocols = ipv4
smtp_bind_address = 192.168.0.3

内部・外部のDNSにはIPv6のアドレスは伝えない。

そして、IPv6対応のサーバーを他に立ててこのサーバーにリレーするようにして、DNSで新サーバーのIPv6を通知。
内部を徐々にIPv6対応させていき、準備ができたある日、DNSの名前解決結果を元のサーバーに切り替える。
この時、SPFとかもしっかりとコントロールしながら、完全移行していくのかなぁと。

IPv6も動かす

ウチみたいに、たいした仕事量はないからWebサーバーとSMTPサーバーを同居させてしまえ!という雑な運用をしている場合、IPv6を使うなら一気にすべてを対応させるという選択肢しかない。
また、ウチの中ではLUAをメインで使っているので、Postfixで使いたいGUAアドレスをbindするのが必須だった。

/etc/postfix/main.cf

inet_interfaces = all
inet_protocols = all
smtp_bind_address = 192.168.0.3
smtp_bind_address6 = 24nn:nnnn:nnnn:nnnn:192:168:0:3

内部・外部のDNSにIPv6のアドレスを伝え、その上で、これらのIPアドレスをベースとした「よそのMTAに信用してもらうための設定」をしていく。
(環境によって、できることは限られるかもしれないが、できる限り…)

やったこと

冒頭の結論に至るまでに試したことをメモしておく。
テストは面倒だし、時間がたつと忘れてしまうので。

環境

こんな環境でテストしている。

ホストIPアドレス備考
work.hogeserver.hogeddns.jp192.168.0.3/24
fdnn:nnnn:nnnn:nnnn:192:168:0:3
24nn:nnnn:nnnn:nnnn:192:168:0:3
Ubuntu 20.04 LTS。今回色々と設定を試した環境。
temp.hogeserver.hogeddns.jp192.168.0.2/24Ubuntu 18.04 LTS。メール送信の為に使った。
hoge.myhome.local192.168.0.55/24メールを送ったり受け取ったりして試すクライアント。

main.cfでの設定あれこれ

IPv6の接続を受けられるようにすると、リレーするときにもランダムにIPv6のアドレスが使われる。
ここに示すパターンで運用上の問題がなければラッキーだが、今回の目的は達成できなかった。

例えば、この設定だとListenするIPアドレスが1つになる。
localhost内部からの依頼とかは受けられないので、あんまり使わない設定。

/etc/postfix/main.cf

inet_interfaces = 192.168.0.3
inet_protocols = all

IPv4のアドレス1つ+IPv6のアドレス1つに限定する場合はこの設定。
ListenするIPアドレスが4つになって、書いたIPアドレスだけで依頼を受け付ける。

/etc/postfix/main.cf

inet_interfaces = 192.168.0.3 fdnn:nnnn:nnnn:nnnn:192:168:0:3 127.0.0.1 ::1
inet_protocols = all

ありったけのIPアドレスでListenするが、リレー元のIPアドレスを限定する場合はこの設定。
Listenが 0.0.0.0:25 と [::]:25 になって、どのIPアドレスでも依頼を受けられる。

/etc/postfix/main.cf

inet_interfaces = all
inet_protocols = all
smtp_bind_address = 192.168.0.3
smtp_bind_address6 = fdnn:nnnn:nnnn:nnnn:192:168:0:3

では、smtp_bind_address6を無指定にしたらどうか…と、一応試してみたが、これデフォルト設定。
Listenが 0.0.0.0:25 と [::]:25 になって、どのIPアドレスでも依頼を受けられて、リレー元のIPv6アドレスが幾つかある24nn:~なんかも使われるようになる。

/etc/postfix/main.cf

inet_interfaces = all
inet_protocols = all
smtp_bind_address = 192.168.0.3
smtp_bind_address6 = ←無指定はデフォルト

これらを変更した場合、Postfixをrestartして反映させる。
reloadでは変更を検知してもワーニングを出すだけで、実際に変更が反映されるのはrestartしたタイミングだった。

master.cfでの設定(失敗例)

ここでは失敗例として記載しているが、本来はこちらが推奨されている設定方法
 -o 設定項目 = 設定値
とすれば、サービスごとの設定ができるから、設定の影響を明確にできる。
main.cfのところで書いた設定のなかで好きなものをこちらで設定するだけ。

何をどうして失敗したのかというと…

master.cfで設定をするなら、main.cfではすべてのインターフェースとプロトコルが使えるようにしておく。
これがデフォルト設定だし、他に影響を与えない意味で良い。
/etc/postfix/main.cf

inet_interfaces = all
inet_protocols = all

この状態で、master.cfの設定を試してみた。
/etc/postfix/master.cf

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (no)    (never) (100)
# ==========================================================================
smtp      inet  n       -       y       -       -       smtpd
  -o smtp_bind_address=192.168.0.3
  -o inet_protocols=ipv4

つまり、全体としてはIPv4とIPv6のすべてのIPアドレスを受け付けるけれども、smtpはIPv4の192.168.0.3に限定するよ、という指定。
これだったら、一応はIPv6でもListenするんだから、もしかしたら意図に気付いて受け付けてくれるんじゃないかと。

この設定を反映して様子を見ると、このような状態になった。

$ sudo systemctl restart postfix
$ sudo ss -p -n -A tcp state listening state unconnected | grep "^State\|:25"
State     Recv-Q    Send-Q       Local Address:Port        Peer Address:Port    Process
LISTEN    0         100                0.0.0.0:25               0.0.0.0:*        users:(("master",pid=54686,fd=13))
LISTEN    0         100                   [::]:25                  [::]:*        users:(("master",pid=54686,fd=14))

今回狙ったリレー元IPアドレスをIPv4に絞れたか!と思ったが、残念、IPv6での依頼を受けられなくなっていた。

Sep 26 07:21:56 work postfix/smtpd[67821]: fatal: cannot handle socket type AF_INET6 with "inet_protocols = ipv4"
Sep 26 07:21:57 work postfix/master[67813]: warning: process /usr/lib/postfix/sbin/smtpd pid 67821 exit status 1
Sep 26 07:21:57 work postfix/master[67813]: warning: /usr/lib/postfix/sbin/smtpd: bad command startup -- throttling

このテストをした際に、メール送信元に出ていたログはこれ。

(1) クライアントからメールを受け付けたが…
Sep 26 07:21:55 temp postfix/smtpd[5568]: connect from hoge.myhome.local[192.168.0.55]
Sep 26 07:21:55 temp postfix/smtpd[5568]: 1018210011D: client=hoge.myhome.local[192.168.0.55]
Sep 26 07:21:56 temp postfix/cleanup[5571]: 1018210011D: message-id=<104D7B25BBEEF2DDDFBEDB8@temp.hogeserver.hogeddns.jp>
Sep 26 07:21:56 temp postfix/qmgr[4387]: 1018210011D: from=<hoge@temp.hogeserver.hogeddns.jp>, size=652, nrcpt=1 (queue active)
Sep 26 07:21:56 temp postfix/smtpd[5568]: disconnect from hoge.myhome.local[192.168.0.55] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5

(2) リレーできない。
Sep 26 07:21:57 temp postfix/smtp[5572]: 1018210011D: to=<hoge@work.hogeserver.hogeddns.jp>, relay=work.hogeserver.hogeddns.jp[fdnn:nnnn:nnnn:nnnn:172:168:0:77]:25, delay=2.6, delays=1.5/0.01/1.1/0, dsn=4.4.2, status=deferred (lost connection with work.hogeserver.hogeddns.jp[fdnn:nnnn:nnnn:nnnn:172:168:0:77] while receiving the initial server greeting)

メール送信元のサーバーは確かにIPv6でリレーしようとしているのだが、受信するサーバーが即座に拒否している。
これはむしろ危険な状態でしかなく、採用できなかった。

さいごに

ほんのちょっとのことなんだけど、まずは内部だけでもIPv6に対応させていこう、というところでは高いハードルとして立ち塞がる事柄。

今回のケースでは、内部と外部を一気にきっちりと設定しないと、問題が発生しそう。
DNSでSPFレコードを設定しているとすると、IPv6を設定したら即座に反映させないと、メールが出ていったときに受信を拒否されるかもしれない。
(ウチみたいに委託しないから -all なんて設定したら、確実に拒否される)
かといって、先にMTAのIPアドレスを先にDNSに登録なんかしようものなら、メールが受信できず、メールを送ってくるサーバーに迷惑を掛ける。

ウチみたいに家庭内でサービス提供しているなら「ごめんごめん、テヘペロ」ってな勢いで設定をやりきってしまえば、まぁ、どうにかなるかもしれないが、業務でサービスを提供しているような場合には、こうした些細な仕様のことで「順を追って段階的な対応」というわけにはいかなくなって、格段にハードルが上がってしまう。

だから、やらない。どうやら相手もやってない。だから後回し、今使えるし。
ということで、IPv6対応を進めるのは本当に大変なんだと思う。

え?ウチの家庭内環境?徐々にやってますよ(こういう回答をしているときは、やってないんだよなー)。

コメントはこちらから お気軽にどうぞ ~ 投稿に関するご意見・感想・他