Elasticsearch で収集している VTuber の情報を定期的にはてなブログに自動投稿しようかなと思ったのでメールサーバを構築した。久しぶりにやって忘れていたのでメモっておくことにする。CentOS の情報は多いけど Debian 系は少ない。
PRETTY_NAME="Debian GNU/Linux 10 (buster)" NAME="Debian GNU/Linux" VERSION_ID="10" VERSION="10 (buster)" VERSION_CODENAME=buster ID=debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/"
Postfix の設定
必要なパッケージをインストールする。
apt install postfix sasl2-bin bsd-mailx
Google のアカウントで二段階認証不要のアプリ用パスワードを作成しておく。16 文字のパスワードを発行される。
SASL 用のパスワードファイルを作成する。ユーザ名 foo、アプリケーション用のパスワードが aaaaaaaaaaaaaaaa の場合は下記のような書式になる。/etc/postfix に sasl というディレクトリが出来ているのでその中でもいいと思う。
[smtp.gmail.com]:587 foo@gmail.com:aaaaaaaaaaaaaaaa
平文で書いてあるのでパーミッションを変更しておく。
chmod 0600 /etc/postfix/sasl_passwd
postmap コマンドで Postfix ルックアップテーブルを作成する。sasl_passwd.db のようなファイルが作成される。
postmap /etc/postfix/sasl_passwd
main.cf の設定
/etc/postfix/main.cf に設定を追加する。最低限下記を追加しておけばメールの送信が出来るようになる。
relayhost = [smtp.gmail.com]:587 smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd smtp_sasl_tls_security_options = noanonymous smtp_tls_security_level = encrypt
デフォルトからの差分は下記の通り
--- /dev/fd/63 2019-11-17 15:11:02.659286299 +0900 +++ main.cf 2019-11-17 15:10:59.619368408 +0900 @@ -36,9 +36,13 @@ alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases mydestination = $myhostname, localhost, localhost.localdomain, , localhost -relayhost = +relayhost = [smtp.gmail.com]:587 mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 mailbox_size_limit = 0 recipient_delimiter = + inet_interfaces = all inet_protocols = all +smtp_sasl_auth_enable = yes +smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd +smtp_sasl_tls_security_options = noanonymous +smtp_tls_security_level = encrypt
Postfix を再起動(もしくは設定ファイルを再読み込み)する。
systemctl restart postfix
Postfix パラメータの詳細
デフォルト値は postconf -d で確認することも出来る。
smtp_sasl_auth_enable (default: no)
Enable SASL authentication in the Postfix SMTP client. By default,
the Postfix SMTP client uses no authentication.
Example:
smtp_sasl_auth_enable = yes
smtp_sasl_mechanism_filter (default: empty)
If non-empty, a Postfix SMTP client filter for the remote SMTP
server's list of offered SASL mechanisms. Different client and server
implementations may support different mechanism lists; by default, the
Postfix SMTP client will use the intersection of the two.
smtp_sasl_mechanism_filter specifies an optional third mechanism list
to intersect with.
Specify mechanism names, "/file/name" patterns or "type:table" lookup
tables. The right-hand side result from "type:table" lookups is
ignored. Specify "!pattern" to exclude a mechanism name from the list.
The form "!/file/name" is supported only in Postfix version 2.4 and
later.
This feature is available in Postfix 2.2 and later.
Examples:
smtp_sasl_mechanism_filter = plain, login
smtp_sasl_mechanism_filter = /etc/postfix/smtp_mechs
smtp_sasl_mechanism_filter = !gssapi, !login, static:rest
smtp_sasl_password_maps (default: empty)
Optional Postfix SMTP client lookup tables with one username:password
entry per sender, remote hostname or next-hop domain. Per-sender
lookup is done only when sender-dependent authentication is enabled.
If no username:password entry is found, then the Postfix SMTP client
will not attempt to authenticate to the remote host.
The Postfix SMTP client opens the lookup table before going to chroot
jail, so you can leave the password file in /etc/postfix.
Specify zero or more "type:name" lookup tables, separated by white‐
space or comma. Tables will be searched in the specified order until a
match is found.
smtp_sasl_security_options (default: noplaintext, noanonymous)
Postfix SMTP client SASL security options; as of Postfix 2.3 the list
of available features depends on the SASL client implementation that
is selected with smtp_sasl_type.
The following security features are defined for the cyrus client SASL
implementation:
Specify zero or more of the following:
noplaintext
Disallow methods that use plaintext passwords.
noactive
Disallow methods subject to active (non-dictionary) attack.
nodictionary
Disallow methods subject to passive (dictionary) attack.
noanonymous
Disallow methods that allow anonymous authentication.
mutual_auth
Only allow methods that provide mutual authentication (not
available with SASL version 1).
Example:
smtp_sasl_security_options = noplaintext
smtp_sasl_tls_security_options (default: $smtp_sasl_security_options)
The SASL authentication security options that the Postfix SMTP client
uses for TLS encrypted SMTP sessions.
This feature is available in Postfix 2.2 and later.
smtp_tls_security_level (default: empty)
The default SMTP TLS security level for the Postfix SMTP client; when a
non-empty value is specified, this overrides the obsolete parameters
smtp_use_tls, smtp_enforce_tls, and smtp_tls_enforce_peername.
Specify one of the following security levels:
none
No TLS. TLS will not be used unless enabled for specific desti‐
nations via smtp_tls_policy_maps.
may
Opportunistic TLS. Use TLS if this is supported by the remote
SMTP server, otherwise use plaintext. Since sending in the clear
is acceptable, demanding stronger than default TLS security
merely reduces interoperability. The "smtp_tls_ciphers" and
"smtp_tls_protocols" (Postfix >= 2.6) configuration parameters
provide control over the protocols and cipher grade used with
opportunistic TLS. With earlier releases the opportunistic TLS
cipher grade is always "export" and no protocols are disabled.
When TLS handshakes fail, the connection is retried with TLS
disabled. This allows mail delivery to sites with non-interop‐
erable TLS implementations.
encrypt
Mandatory TLS encryption. Since a minimum level of security is
intended, it is reasonable to be specific about sufficiently
secure protocol versions and ciphers. At this security level and
higher, the main.cf parameters smtp_tls_mandatory_protocols and
smtp_tls_mandatory_ciphers specify the TLS protocols and minimum
cipher grade which the administrator considers secure enough for
mandatory encrypted sessions. This security level is not an
appropriate default for systems delivering mail to the Internet.
dane
省略
dane-only
省略
fingerprint
省略
verify
省略
secure
省略
Examples:
# No TLS. Formerly: smtp_use_tls=no and smtp_enforce_tls=no.
smtp_tls_security_level = none
# Opportunistic TLS.
smtp_tls_security_level = may
# Postfix >= 2.6:
# Do not tweak opportunistic ciphers or protocol unless it is essential
# to do so (if a security vulnerability is found in the SSL library that
# can be mitigated by disabling a particular protocol or raising the
# cipher grade from "export" to "low" or "medium").
smtp_tls_ciphers = export
smtp_tls_protocols = !SSLv2, !SSLv3
# Mandatory (high-grade) TLS encryption.
smtp_tls_security_level = encrypt
smtp_tls_mandatory_ciphers = high
以下略
トラブルシュート
■ smtp_sasl_auth_enable = yes
これが無いと Authentication Required.
で失敗する。
Nov 16 08:10:23 debian postfix/smtp[5891]: 49F92409EE: to=foo@gmail.com, relay=smtp.gmail.com[74.125.204.108]:587, delay=1, delays=0.01/0/0.82/0.17, dsn=5.5.1, status=bounced (host smtp.gmail.com[74.125.204.108] said: 530-5.5.1 Authentication Required. Learn more at 530 5.5.1 https://support.google.com/mail/?p=WantAuthError 82sm14466130pfa.115 - gsmtp (in reply to MAIL FROM command))
■ smtp_sasl_password_maps = hash:/path/to/file
これが無いと specify a password table via the `smtp_sasl_password_maps' configuration parameter
で失敗する。
Nov 16 08:17:46 debian postfix/smtp[6345]: fatal: specify a password table via the `smtp_sasl_password_maps' configuration parameter
■ smtp_sasl_tls_security_options = noanonymous
デフォルトの noplaintext, noanonymous だと弾かれてしまうので noplaintext を外して noanonymous だけにする。
Nov 16 08:04:32 debian postfix/smtp[5265]: warning: SASL authentication failure: No worthy mechs found Nov 16 08:04:32 debian postfix/smtp[5265]: 6D638409F6: SASL authentication failed; cannot authenticate to server smtp.gmail.com[108.177.97.108]: no mechanism available Nov 16 08:04:32 debian postfix/smtp[5265]: connect to smtp.gmail.com[2404:6800:4008:c00::6c]:587: Network is unreachable
■ smtp_tls_security_level = encrypt
デフォルトが empty なので Must issue a STARTTLS command first.
で失敗する。encrypt ではなく may でも動くがこちらは TLS 接続に失敗した時にプレーンテキストを使うようなので encrypt にした。
Nov 16 08:12:56 debian postfix/smtp[6109]: 991C44085B: to=foo@gmail.com, relay=smtp.gmail.com[74.125.204.108]:587, delay=0.65, delays=0.05/0.01/0.41/0.17, dsn=5.7.0, status=bounced (host smtp.gmail.com[74.125.204.108] said: 530 5.7.0 Must issue a STARTTLS command first. y6sm12524933pfm.12 - gsmtp (in reply to MAIL FROM command))
メールの送信
とりあえず適当にメールを送ってみる。
echo "World" | mail -s "Hello" 宛先メールアドレス
特に問題無かったのではてなブログにメール投稿する方法を調べると投稿用と下書き用のメールアドレスで分かれているらしい。
下書き用のメールアドレスにメールを送ってみると何故かタイトルの日本語が文字化けする。調べてみるとタイトルは ISO-2022-JP で出力しなきゃいけないらしい。nkf コマンドを使ってエンコードする。入力と出力でオプションの大小文字が違う。
Usage: nkf -[flags] [--] [in file] .. [out file for -O flag]
j/s/e/w Specify output encoding ISO-2022-JP, Shift_JIS, EUC-JP
UTF options is -w[8[0],{16,32}[{B,L}[0]]]
J/S/E/W Specify input encoding ISO-2022-JP, Shift_JIS, EUC-JP
UTF option is -W[8,[16,32][B,L]]
m[BQSN0] MIME decode [B:base64,Q:quoted,S:strict,N:nonstrict,0:no decode]
M[BQ] MIME encode [B:base64 Q:quoted]
f/F Folding: -f60 or -f or -f60-10 (fold margin 10) F preserve nl
Z[0-4] Default/0: Convert JISX0208 Alphabet to ASCII
1: Kankaku to one space 2: to two spaces 3: HTML Entity
4: JISX0208 Katakana to JISX0201 Katakana
X,x Convert Halfwidth Katakana to Fullwidth or preserve it
O Output to File (DEFAULT 'nkf.out')
L[uwm] Line mode u:LF w:CRLF m:CR (DEFAULT noconversion)
--ic=<encoding> Specify the input encoding
--oc=<encoding> Specify the output encoding
--hiragana --katakana Hiragana/Katakana Conversion
--katakana-hiragana Converts each other
--{cap, url}-input Convert hex after ':' or '%'
--numchar-input Convert Unicode Character Reference
--fb-{skip, html, xml, perl, java, subchar}
Specify unassigned character's replacement
--in-place[=SUF] Overwrite original files
--overwrite[=SUF] Preserve timestamp of original files
-g --guess Guess the input code
-v --version Print the version
--help/-V Print this help / configuration
Network Kanji Filter Version 2.1.5 (2018-12-15)
Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa).
Copyright (C) 1996-2018, The nkf Project.
ja_JP.UTF-8 とかなら入力に -W(UTF)付けなくてもいいみたいだけど一応付けておく。
root@debian:~# echo "タイトル" | nkf -MWj =?ISO-2022-JP?B?GyRCJT8lJCVIJWsbKEI=?=
あとはこれを Cron に組み込んではてなブログの投稿用メールアドレスに送れば自動投稿が出来るようになる。
結果
VTuber の一週間の再生回数を土曜日の朝に自動投稿するようにした。週末はここから流行りの VTuber のチャンネルでも観てゆっくり過ごしたい。