■fetchmailからSMTP転送された不正なヘッダーを持つメールがPostfixに拒否された
fetchmailを利用してPOP3サーバーからメールを取得して、それをPostfixへ転送する流れとなるはずだった。
しかし下記のログの通り、
fetchmailから転送された際にPostfixにおいて「Illegal address syntax」という警告が発せられ、失敗した。
fetchmaiは、「not flushed」と伝えたきりである。
fetchmaiのエラー「SMTP error: 501 5.1.7 Bad sender address syntax」からわかるように、
メールのヘッダーの送信者アドレスが不正な形式であることがわかった。
実際、調べてみると、xxxxxx@example.comのような形式になっていなかった。
こういうメールが、下記のログの通り、102件にもなっていて、
メールサーバーから削除されずに残存していた。
これでは困るので、処理できなかったメールをPOP3サーバーから一括消去したい。
postfix/smtpd[6510]: warning: Illegal address syntax from localhost[127.0.0.1] in MAIL command: <ここに不正な形式のアドレス>
fetchmail[6583]: reading message example@example.com:1 of 102 (17659 octets) (log message incomplete)
fetchmail[6583]: SMTP error: 501 5.1.7 Bad sender address syntax
fetchmail[6583]: not flushed
postfix/smtpd[6510]: warning: Illegal address syntax from localhost[127.0.0.1] in MAIL command: <ここに不正な形式のアドレス>
fetchmail[6583]: reading message example@example.com:2 of 102 (8588 octets) (log message incomplete)
fetchmail[6583]: SMTP error: 501 5.1.7 Bad sender address syntax
fetchmail[6583]: not flushed
postfix/smtpd[6510]: warning: Illegal address syntax from localhost[127.0.0.1] in MAIL command: <ここに不正な形式のアドレス>
fetchmail[6583]: reading message example@example.com:3 of 102 (3479 octets) (log message incomplete)
fetchmail[6583]: SMTP error: 501 5.1.7 Bad sender address syntax
fetchmail[6583]: not flushed
<略>
■telnetでPOP3サーバーにアクセスし、残存するメールを確認し、削除する手順
方法は、telnetコマンドを利用して、直接POP3サーバーにログインし、
メール一覧を取得して不要なメールであることを確認してから、
一括で削除してしまう。
そこで、スクリプトを作成しtelnetコマンドを通して処理コマンドをPOP3サーバーに送出するようにした。
スクリプトは3種類用意した。以下で順に挙げていく。
1、サーバー内にあるメールのリスト番号を取得するためのコマンドを送出するスクリプト
2、各メールのヘッダーを取得するためのコマンドを送出するスクリプト
3、各メールを全て消去するためのコマンドを送出するスクリプト
ポイントは、これらのスクリプトはパイプでtelnetコマンドと組み合わせて使うことである。
$ script | telnet xxx.example.com 110 という基本の形式で用いるわけだ。
後で述べるように結果をさらにパイプで受けて処理するようなこともする。
telnetは、yum install telnet でインストールできた。
■スクリプトの実装と実際
○先ず、サーバー内にあるメールのリスト番号を取得しメールの件数を確認した。
スクリプト1を実装した。
サーバー内にあるメールのリスト番号を取得するためのコマンドをtelnetコマンドに送出するのに用いるスクリプトである。
$ ./LIST_POP3 | telnet xxx.example.com 110 という様に用いて、パイプでコマンドをtelnetに送る。
最初に、POP3サーバーにアクセスするまでに2秒の待機時間を設定している。
次に、USERコマンド名と、PASSコマンド名と共にログイン情報を送り、
各々処理のために待機時間も2秒設定している。(これは必須である。)
その上で、LISTコマンドを送出している。
全てのメールのリストを受け取るまで待機するように、5秒設定している。
そして、QUITで切断している。
必要に応じて、各待ち時間は調整した方が良い。
$ vi LIST_POP3
#!/bin/bash
username="myusername";
password="HereIsPassword";
sleep 2
echo USER $username
sleep 2
echo PASS $password
sleep 2
# Send LIST Command to Get list of mails
echo LIST
# Wait until all list is retrieved
sleep 5
echo QUIT
スクリプトに実行パーミッションを与えた。
$ chmod +x LIST_POP3
実際に用いると、次のようになった。
$ ./LIST_POP3 | telnet xxx.example.com 110
Trying xxx.xxx.xxx.xxx...
Connected to xxx.example.com.
Escape character is '^]'.
+OK <xxxxx.xxxxx@xxx.xxx.example.com>
+OK
+OK
+OK
1 17659
2 8588
3 3479
4 3376
5 4115
6 4579
7 9360
8 9427
9 8706
10 10263
11 9196
12 10253
13 10322
<略>
98 23229
99 23517
100 23439
101 23263
102 11367
. ←ここで設定した分だけの待ち時間
Connection closed by foreign host.
102通のメールが残存しているとわかった。
○そして、各々のメールの題名を確認した。
同様にしてまず、スクリプト2を実装した。
これはメールヘッダーを取得する。
下記、MAX_MESS=$1 の部分は、スクリプト実行時に指定した「最初の引数」を保存している。
そして、「最初の引数」には処理するべきメールの数を指定する。
ヘッダーを取得するためにループを利用しているのでループの回数として使用している。
(注意)
echo TOP $j 0 のところは、TOPコマンドを受け付けないPOP3サーバの場合には、
echo RETR $j を用いてメール全文を取得しても良い。
$ vi TOP_POP3
#!/bin/bash
username="myusername";
password="HereIsPassword";
MAX_MESS=$1
[ $# -eq 0 ] && exit 1 || :
sleep 2
echo USER $username
sleep 2
echo PASS $password
sleep 2
for (( j = 1 ; j <= $MAX_MESS; j++ ))
do
#Send command to get header of a mail
echo TOP $j 0
sleep 1
done
echo QUIT
スクリプトに実行パーミッションを与えた。
$ chmod +x TOP_POP3
このように作成したスクリプトとtelnetとを組み合わせ、メールサーバーにコマンドを送出し、
そして、さらにその結果をパイプで繋いで、grepで「Subject:」を抽出した。
これにより、メールのタイトルを表示することができた。
指定している102は、前述の通り処理するべきメール数である。
$ ./TOP_POP3 102 | telnet xxx.example.com 110 | grep Subject:
Subject: Wow, what a handsome...
Subject: What are your plans for tomorrow?
Subject: what are we going to do?
Subject: I could not resist and pass by!
Subject: You seem to know how to make a girl turn on...
Subject: God, how many fantasies you awake in my head!
Subject: can you meet me
Subject: I'm asking you
Subject: Interestingly, are you as cool in the conversation as on the photo?
Subject: let's do it tomorrow
Subject: can you meet me tomorrow?
Subject: It's incredibly confusing and drives me on simultaneously. Watch until I removed it from the access.
Subject: Oh, where have you been all my life!
Subject: That's why I love our parties! Just look here
Subject: I would like to ask you
Subject: can you meet me
Subject: Is your character as hard as your muscles?
Subject: What are we going to do today?
Subject: let's do it today
Subject: Remind myself
Subject: =?iso-2022-jp?B?GyRCIVobKEIyMDE5GyRCRy8bKEI1GyRCN24hW0BBNWEzWyROJDRPIk1tGyhC?=
Subject: Me and this bottle of red wine ;)
Subject: can we schedule an appointment for tomorrow?
Subject: could you meet me tomorrow?
Subject: Not sure, it had to be spread in the network, but it's a little late. Rate here
Subject: Wow, what a handsome...
<略>
Subject: what are your plans for the weekend?
Subject: Haven't you seen it yet? Oh hell, and why I have not found it before
Subject: I want to meet you today
Subject: =?utf-8?B?44GC44Gq44Gf44Gv6Ieq55Sx44Gg77yf?=
Connection closed by foreign host.
タイトルがエンコードされて読めない場合は、
次のようにして解読すればよかった。
$ echo "=?iso-2022-jp?B?GyRCIVobKEIyMDE5GyRCRy8bKEI1GyRCN24hW0BBNWEzWyROJDRPIk1tGyhC?=" | nkf -mB
8♡躊桴」、0C【2019年5月】請求額のご連絡$ echo "=?utf-8?B?44GC44Gq44Gf44Gv6Ieq55Sx44Gg77yf?=" | nkf -w8
あなたは自由だ?$ echo "=?Shift_JIS?B?gXWJZYu/l82CzINHg2yDi4NNgVuBdoLwjYKC34LpiciKd5NJgsiO6JZAgqqM9opK?=" | nkf -B
「影響力のエネルギー」を高める科学的な手法が公開$ echo "=?utf-8?B?Y2FuIHlvdSBtZWV0IG1l?=" | nkf -w8
can you meet me
このようにして、メールの題名からサーバ内のメールが全てジャンクメールであることを確認した。
次にこれらを一括して消去する。
○サーバー内のメールを全て消去した。
スクリプト3はメールを指定した件数だけ削除する。
最後のQUITコマンドの送出によって、実際にメールが削除される。
そのためQUITコマンドがきちんとPOP3サーバーに伝達するように、待ち時間を最後に設定した。
(注意)
最後の待ち時間のsleepを省くと、うまくメールが削除されなかった。
$ vi DELE_POP3
#!/bin/bash
username="myusername";
password="HereIsPassword";
MAX_MESS=$1
[ $# -eq 0 ] && exit 1 || :
sleep 2
echo USER $username
sleep 2
echo PASS $password
sleep 2
for (( j = 1 ; j <= $MAX_MESS; j++ ))
do
# !!!! Send Command to delete a mail !!!!
echo DELE $j
sleep 1
done
echo QUIT
sleep 5
スクリプトに実行パーミッションを与えた。
$ chmod +x DELE_POP3
次のようにして用いる。メールが102件削除された。
# ./DELE_POP3 102 | telnet xxx.example.com 110
Trying xxx.xxx.xxx.xxx...
Connected to xxx.example.com.
Escape character is '^]'.
+OK <xxxxx.xxxxx@xxx.xxx.example.com>
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
<略>
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
+OK
Connection closed by foreign host.
削除されたかを確認するには、最初のコマンドをもう一度実行すれば良い。
$ ./LIST_POP3 | telnet xxx.example.com 110
Trying xxx.xxx.xxx.xxx...
Connected to xxx.example.com.
Escape character is '^]'.
+OK <xxxxx.xxxxx@xxx.xxx.example.com>
+OK
+OK
+OK
.
Connection closed by foreign host.
以上
<参考>
・Remove or Delete all emails message from a POP3 server
< https://www.cyberciti.biz/tips/remove-or-delete-all-emails-message-from-a-pop3-server.html > 2019年10月30日
・nkfで文字コード変換したいときはこうする!!
< https://qiita.com/hirohiro77/items/9e57fff12a3ef0907594 > 2019年10月30日
・【Linux CentOS 7 (1511)】nkfコマンドを使って文字化けしたメールの内容を解読する方法
< http://akira-arets.blogspot.com/2016/12/linux-nkf-makes-mojibake-be-right.html > 2019年10月30日