Posted at

Ansible を使ったメール送信/転送サーバ構築

More than 3 years have passed since last update.


GOAL


Ansible を使って OS X から RaspberryPi 3 (Rasbian) 上にメールサーバを構築する。ただし送信と受信転送のみでメールボックスは不要。


宅鯖の Web サイト上で管理者のメールアドレスを公開する必要が出てきたので余っている RPi 上にメールサーバを構築した時の方法を記述します。受信したメールは全て普段使っている gmail アドレスに転送するので、まぁ会社の代表電話のようなものですね。

具体的なゴールは以下の3点となります。似たような要件であれば playbook を少し修正して対応可能かと思います。


  1. LAN 内 192.168.0.0/16 のPCやサーバから外部にメールを送信する SMTP サーバとする。

  2. 管理している複数のサイトの postmaster@foo.com, postmaster@bar.org, postmaster@baz.jp 宛てのメールが全て qux@gmail.com に転送される。

  3. 受信メールは全て転送するため mailbox としての機能は必要ない (POP3 や IMAP4 は不要)。

構成対象の RaspberryPi は IP アドレスやホスト名、それに raspi-config などの基本的な設定が済んでいるものとします。この文書では IP アドレス 192.168.100.1、ホスト名 garnet02 とします。

$ cat /etc/hostname

garnet02
$ cat /etc/hosts
...
192.168.100.1 garnet02

また OS X 上で Ansible が実行可能な状態で構成されているものとします。まだ Ansible が入っていない場合は以下の URL を参照してください。


構築手順

メールサーバにする RPi を inventory ファイルに既述します。

[mail-server]

192.168.100.1

以下の playbook ファイルを作成し playbook.yml で保存します。vars で定義した変数値は後述する template の内容に挿入されますので適当に変更してください。


playbook.yml

- hosts: mail-server

sudo: yes
gather_facts: no
vars:
hostname: garnet02
myhostname: mail.foo.com
mydomain: foo.com
mydestination: bar.org, baz.jp, {{ hostname }}
mynetworks: 192.168.0.0/16
forward_to: qux@gmail.com
tasks:
- apt: upgrade=full update_cache=yes
- apt: name=postfix state=present
- template: src=main.cf.j2 dest=/etc/postfix/main.cf
- template: src=aliases.j2 dest=/etc/aliases
- command: /usr/bin/newaliases
- command: /etc/init.d/postfix restart

vars 値は postfix の main.cf と同じですが localhost など自明な値は template 側に直接記述しています。

名前
意味

myhostname
このサーバのFQDN

mydomain
LAN内から外部へ送信する時に付加するドメイン

mydestination
宛先ドメインがこのどれかと一致したらこのサーバ宛て(それ以上リレーしない)

mynetwork
送り元がここに含まれたら外部へリレーして良い

forward_to
受信したメールの転送先メールアドレス

local から local 宛のメールは xxx@garnet02 のように hostname のドメインとなるため、mydestination には {{ hostname }} を付加する必要があります。

テンプレートに使用しているのは以下の 2 ファイル。コメントを省略して最小限の部分だけにスリム化しているので、コメントも必要なら RPi から直接持って来て編集してください。


main.cf.j2

smtpd_banner = $myhostname ESMTP

biff = no
append_dot_mydomain = no
readme_directory = no
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = {{ myhostname }}
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain, {{ mydestination }}
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 {{ mynetworks }}
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
home_mailbox = Maildir/


aliases.j2

# See man 5 aliases for format

postmaster: {{ forward_to }}


実行

以下を起動して pi ユーザの例のパスワードを入力するだけ。

$ ansible-playbook -i inventory -u pi --ask-pass playbook.yml -vvvv

以上。