【Ubuntu 20.04】 フィッシングメール、スパムメールなどの迷惑メール対策、Postfixの設定

# まえがき
　スパマーは「下手な鉄砲も数打ちゃ当たる」の精神の鏡。相手はヒトではなく「プログラム」。根気で戦うとこちらが負ける。一度こちらのメールアドレスが有効だとわかると、毎日数百通のスパムメールが来るようになってしまう💦
　メールクライアントで振り分けルールを作ってみたけど上手くいかない。Outlookはしばしばルールスクリプトが壊れてメーラーが不安定になる。やはりPostfixサイドでスパムメールをある程度防ぐための対策はしておく必要がある。

　最近（2021年6月）多いスパムは発信、中継が海外で、最終的に日本のIPをリレーして送ってくるのが多い。国内にもスパムの土台（踏み台ではないスパム送信サーバー）が存在する。SPFやDKIMにも対応したスパムメールが来る時代。コロナ禍に乗じたフィッシングにはくれぐれもご注意ください。

## よく来るスパムメールの内容

1. ブランドのコピー品安く売ります（フィッシング）
2. ○○カードの利用が停止されたので下記サイトにアクセスして本人確認してください（フィッシング）
3. ○○サービスの利用が停止されたので下記サイトにアクセスして本人確認してください（フィッシング）
4. 突然のメール失礼します。商品やサービス買いませんか（存在しない企業名、いそうな日本人名を名乗る）
5. 人材紹介します、お金貸します、物貸しますこんなサービスどうっすか（フィッシング）

# 運用している環境とか
　零細企業のオンプレサーバーです。個人自宅サーバーの参考になるかも？。海外とのやりとりは限定的で、大陸系など英語圏ではないところとのやりとりは無い環境です。
　普通にメールのやりとりができている設定だけど、迷惑メールを多く受信してて困ったなぁという人向けの記事です。

# お世話になります（なっております）
fetus：国、地域別のIPアドレス　https://ipv4.fetus.jp/
spamcop：海外からのスパム抑止　https://www.spamcop.net/
Postfixのぺーじ：公式マニュアルの和訳サイト　http://www.postfix-jp.info/

# Postfixの設定ファイル
　Postfixには`main.cf`と`master.cf`の2つの設定ファイルがある。基本設定は`main.cf`に書いてポートごとの設定は`master.cf`に書く仕組みになっている。`master.cf`では、理由がなければセキュリティやフィルタリングに関する設定（ -o smtpd_何とか_restrictions）は上書き設定しない方が良い。

## 設定パラメータの注意点（ややこしいところ）
　Postfixはサーバーとしての機能とクライアントとしての機能の両方を持っているため、設定はそれぞれの場合の項目がある。

```:Postfixの設定項目
 smtp_何とか　　 自身がクライアントとして動作する場合の設定。相手サーバーに接続するときにどう振る舞うか。
 smtpd_何とか　　自身がサーバーとして動作する場合の設定。相手サーバー含めユーザーが接続してきたときにどう振る舞うか。
```

## SMTP-AUTHで認証する
　Postfixは設定なしだと誰でも接続できて、どこへでもメール送信が可能。その状態でインターネットに公開しているとスパムの元になるので、踏み台の対策として`smtp-auth`というユーザーID、パスワードの認証機能がある。ほとんどの場合、この方法でまず最初の踏み台対策を行うと思う。

```:/etc/postfix/main.cf
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
```

　接続をしてくるユーザーに対して認証しますよ（こっちはサーバーですよ）、という設定をしたいので、`smtp_sasl_auth_enable`ではないことに注意。gmailを中継するために相手サーバーのアカウント認証をする等の設定で`smtp_sasl_auth_enable`を使う。
 同様に、TLS関連も`smtp_tls_何とか`と`smtpd_tls_何とか`があるので、注意しながら設定を行う。`d`一文字で意味する事が全然違うよ！

　SASL関連の設定項目のマニュアルは以下。

http://www.postfix-jp.info/trans-2.3/jhtml/SASL_README.html


## Postfixのバージョンを隠す
　bannerの最初は$myhostnameを記載しなければいけない。これを消すと相手の設定によっては拒否されるので注意。

```:/etc/postfix/main.cf
smtpd_banner = $myhostname ESMTP
```

## リレー制限設定
 ver2.10以降この記述でリレーの抜け穴を防止するようになったらしい。それ以前のバージョンは単語が異なるようなので注意。

```:/etc/postfix/main.cf
smtpd_relay_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        defer_unauth_destination
```

## 自分の送信メールのヘッダからローカルIPを消す
　ただし、相手には行儀よく！

```:/etc/postfix/main.cf
header_checks= regexp:/etc/postfix/header_checks
always_add_missing_headers = yes
```

　正規表現タイプのテーブル`header_checks`ファイルに以下を記載する。

```bash
vi /etc/postfix/header_checks
```


```:/etc/postfix/header_checks
/^Received:.*192\.168\..*/ IGNORE
/^Received:.*127\.0\.0\.1.*/ IGNORE
```



## ユーザー存在確認を禁止
　VRFYコマンドは禁止する。「誰々さんっています？」には答えない！

```:/etc/postfix/main.cf
disable_vrfy_command = yes
```

## 接続後の挨拶（HELO）を強制
　挨拶しないやつは拒否！ここで相手はホスト名を名乗るらしい（あくまで自称）。

```:/etc/postfix/main.cf
smtpd_helo_required = yes
```

## RCPT TO及びMAIL FROMで正しい文法を強制
　言葉遣いが悪い奴は拒否！

```:/etc/postfix/main.cf
strict_rfc821_envelopes = yes
```

## スパムの踏み台を防止（デフォルト）

```:/etc/postfix/main.cf
allow_untrusted_routing = no
```

## DATAコマンドの場面を待て
　前もってコマンドを送ってくる無礼なやつは拒否！

```:/etc/postfix/main.cf
smtpd_data_restrictions = reject_unauth_pipelining
```

## その他
　誤作動防止とETRNコマンドも制限しておく。

```:/etc/postfix/main.cf
smtpd_delay_reject = yes
smtpd_etrn_restrictions =
        permit_mynetworks,
        reject
```


# フィルタリング関係
　メールの送受信の仕組み。僕は覚えられないので`main.cf`に以下を書いている。

```:/etc/postfix/main.cf
##       ########## SMTPの仕組み覚書 ##########
## メール送信は以下のコマンドを順番に送信し、すべての段階で相手サーバにOK応答
## してもらうことで実際にメールが送られる。即ち、メールとはコマンドの送受信。
## main.cf では各コマンドに制限をつける条件が設定できる。
## ポートごとの設定は master.cf で行う。何も指定がなければ main.cf の記載が標準となる。
#
# コマンドのやりとりの順序は以下。
# SMTP: Postfixサーバー(TCP 25 or 587 or 465) へコネクションを確立する。220を返す。
#        全体に渡ってチェックする制限は smtpd_client_restrictions
# EHLO or HELO: 挨拶する。250(OK)を返す。制限は smtpd_helo_restrictions
# MAIL FROM: どこから来たか名乗る。250(OK)を返す。制限は smtpd_sender_restrictions
# RCPT TO: どこへ行くか名乗る。250(OK)を返す。制限は smtpd_recipient_restrictions
# DATA: メール内容を伝える。354(OK)を返す。転送が開始され、終了後250(OK)を返す。
#       転送中はさらに細かいコマンドのやりとりがある。
# QUIT: さよならする。221(OK)を返す。
#
## 評価される順番は以下のようになる
# 1. smtpd_helo_restrictions : HELO
# 2. smtpd_sender_restrictions : MAIL FROM
# 3. smtpd_recipient_restrictions : RCPT TO
# 0. smtpd_client_restrictions : whole timing
# 4. smtpd_data_restrictions : DATA
# 5. smtpd_end_of_data_restrictions : END OF DATA
# 0. smtpd_etrn_restrictions : independing
#
# smtpd_recipient_restrictions （RCPT TOコマンドの段階）で
# check_sender_access （送信者の情報）をチェックしてフィルタする、という設定も可能。
# どの段階で相手のどの情報を使ってコマンドを制限するかは、自由に設定できる。
```

## テーブルファイルの指定で注意すること
　ルールを記載したテーブルファイルを指定するには、`check_何とか_access`を記載する。テーブルは種類によって指定の記載方法とファイルの書き方が異なる。IPアドレス、メールアドレスを直接指定してREJECT, DISCARD, OKを記載するテーブルならhash、正規表現でドメインやユーザー名を抽出するならregexp、cidrで記載したIPアドレスならcidrといった具合。

```
check_helo_access hash:/etc/postfix/"hashテーブル"
check_sender_access regexp:/etc/postfix/"正規表現テーブル"
check_client_access cidr:/etc/postfix/"cidrテーブル"
```

　hashテーブルのものはハッシュdbを作成する必要がある。***.dbというファイルができるが、main.cf の設定はそのままで良い。リストを編集した場合、再度postmapを実行してdbを更新する必要がある。

```:例：regexpとcidrは不要
postmap /etc/postfix/reject_client
```

　正規表現`regexp`の指定ファイルも`postmap`するように紹介しているサイトもあるが、`regexp`は`postmap`不要。ただし、編集後は`reload`または`restart`が必要。`postmap`マニュアルの`file_type`を参照。

http://www.postfix-jp.info/trans-2.3/jhtml/DATABASE_README.html#detect

http://www.postfix-jp.info/trans-2.3/jhtml/postmap.1.html

## smtpd_helo_restrictions
　`reject_unknown_hostname`は必要なメールが拒否される場合もあるため注意が必要。`warn_if_reject`でしばらく様子を見たところ、送られてくるメールは全てスパムだったので記載することにした。それぞれの環境で取引先等が拒否されないか検証した方がよい。

```:/etc/postfix/main.cf
smtpd_helo_restrictions =
        permit_mynetworks,
        check_helo_access regexp:/etc/postfix/permit_helo_clients,
        reject_invalid_hostname,
        reject_unknown_hostname,
        permit
```

　なんと行政関係の組織が`reject_invalid_hostname`で`reject`されることがある。heloは名前解決できるように設定することがRFC2821で記載されている。`smtp_helo_name`で簡単に偽装できるから無意味って主張も理解できるが、それはそれ。相手に対してせっかくのフィルタに穴を空けさせることになるので、設定はちゃんとして欲しい。

```:/etc/postfix/permit_helo_clients
/\.(ad|ac|ed|go|lg)\.jp$/    OK
```

https://datatracker.ietf.org/doc/html/rfc2821#section-4.1.1.1

## iPadのHELOがREJECTされる場合の対処

　iPadやiPhoneを使用している場合、iOSは独特なheloを出すために`reject`されることがある。iOSのアップデートで変わったりする。

```:/etc/postfix/permit_helo_clients
# iOSデバイス用として追記
/^smtpclient\.apple$/    OK
```

 2022年7月に以下を追記。上記の記載（regexpテーブル）でHELOが通る場合と通らない場合があるため、設定を以下のようにした。

```:/etc/postfix/main.cf
smtpd_helo_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        check_helo_access hash:/etc/postfix/permit_helo_apple,
        check_helo_access regexp:/etc/postfix/permit_helo_clients,
        reject_invalid_hostname,
        reject_unknown_hostname,
        permit
```

 apple用のテーブルを作成し、`postmap`する。

```bash
vi /etc/postfix/permit_helo_apple
```

```:/etc/postfix/permit_helo_apple
smtpclient.apple        OK
```

```bash
postmap /etc/postfix/permit_helo_apple
```

　`permit_sasl_authenticated`を追記したので、そちらの方が有効かもしれない。`smtpd_client_restrictions`にも同様に追記した。

## 必要なメールがREJECTされすぎる場合

　上記でいろいろやってきたが、2022年10月以降は以下の設定で落ち着いている。

```:/etc/postfix/main.cf
smtpd_helo_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        # check_helo_access hash:/etc/postfix/permit_helo_apple,
        # check_helo_access regexp:/etc/postfix/permit_helo_clients, 
        # reject_invalid_hostname, 
        # reject_unknown_hostname,
        check_helo_access regexp:/etc/postfix/reject_helo_clients,
        permit
```

　`reject_helo_clients`の中身は以下（環境により要検証）。

```:/etc/postfix/reject_helo_clients
/\.(cn|domain|eu|hk|in|ir|kp|kr|ru|xyz)$/  REJECT
```

　指定したものを許可する方式から、基本ほぼ通して指定したものを拒否する方式へ変更。最近IT化の煽りでいろいろなところでメールが必要になり、ネット上のサーバーはあまりにも名前解決できないホスト名を使っているものが多い。

## smtpd_sender_restrictions
　ドメイン、メールアドレスを直接指定するファイルは`reject_senders`、正規表現で指定するファイルを`regexp_reject_senders`としている。

```:/etc/postfix/main.cf
smtpd_sender_restrictions =
        check_sender_access hash:/etc/postfix/reject_senders,
        check_sender_access regexp:/etc/postfix/regexp_reject_senders,
        reject_unknown_sender_domain,
        reject_non_fqdn_sender
```

　それぞれの中身の一部を抜粋。メールアドレス、ドメインは詐称できるので、ここでのフィルタの効果は弱い。挙げているドメインは実際にスパムを送信してきたもの。すぐ変わるだろうなぁ。

```:/etc/postfix/reject_senders
saiyo-shien.work                                DISCARD
ke-i.co                                         DISCARD
jms-support.jp                                  DISCARD
hr2020-support.work                             DISCARD
mail.btob-mail.work                             DISCARD
telecomsquare.co.jp                             DISCARD
sender-attach01.hcm-nc.jp                       DISCARD
rutile-works.com                                DISCARD
sugilite-docs.com                               DISCARD
```


```:/etc/postfix/regexp_reject_senders
/gemini\-mail\.net$/                   DISCARD
/univ\.co\.jp$/                       DISCARD
/allplus\.tokyo$/                     DISCARD
/shien\.work$/                        DISCARD
/support\.work$/                      DISCARD
/agate\-box\.com$/                     DISCARD
/spacer\..*@gmail\.com$/              DISCARD
/melma\-kun\.biz$/                     DISCARD
/pezzottaite\-media\.com$/             DISCARD
/hematite\-tech\.com$/                 DISCARD
```

　鉱石名-部署名のドメイン名で送ってくる業者がかなり厄介。正規表現の例は以下だが、これで全部ではない。

```
/(hematite|garnet|spinel|diamond|vesuvianite|chiastolite|kyanite|nephrite|zircon|zirconia|sapphire|serpentine|scheelite|citrine|jet|tourmalin|ruby|sinhalite|scapolite|sodalite|axinite|iolite|iron|agate|aquamarine|topaz|apatite|amazonite|ametrine|amethyst|emerald)-(info|tech|media|sales|work|works|net|com|jp)\.(com|net|jp)$/	DISCARD

鉱石英名は「ite」で終わるものが多いので、以下でも良いかもしれない。ただし、巻き添えの可能性も高くなる。

/ite\-(info|tech|media|sales|work|works|net|com|jp)\.(com|net|jp)$/  DISCARD
```


## smtpd_recipient_restrictions
　ここは特記なし。パラメータを設定したら`reject`、`defer`、`defer_if_permit`、`reject_unauth_destination`のどれかを最低一つ記載しないと全て拒否される。

```:/etc/postfix/main.cf
smtpd_recipient_restrictions =
        permit_mynetworks,
        permit_auth_destination,
        permit_sasl_authenticated,
        reject
```


## smtpd_client_restrictions
　メインのフィルタを書くところ。`reject_unknown_client`および`reject_unkown_hostname`は必要なメールが拒否されてしまうので設定していない（それぞれの環境で要検証）。
　僕自身最初は誤解していたが、接続そのものを制限するわけではない。あくまでも接続後のコマンドを制限するフィルタ。接続そのものを制限したい場合は、ファイヤウォールやネットワーク経路中のルーター、スイッチ等で制限する。
　`smtpd_delay_reject = yes`を記載していると、上記までのフィルタリングはこの段階で動作・・・ってこまけぇこたぁいい！


```:/etc/postfix/main.cf
smtpd_client_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        check_client_access regexp:/etc/postfix/permit_clients,
        sleep 1,
        check_client_access cidr:/etc/postfix/krfilter,
        check_client_access cidr:/etc/postfix/irfilter,
        check_client_access regexp:/etc/postfix/permit_mildlist,
        check_client_access hash:/etc/postfix/permit_ip_mildlist,
        sleep 1,
        # reject_unknown_hostname,
        check_client_access hash:/etc/postfix/reject_client,
        check_client_access cidr:/etc/postfix/cidr_reject_client,
        reject_rbl_client bl.spamcop.net,
        permit
```

　`permit_clients`には国フィルタごと通過させたい相手（国フィルタで`REJECT`されてしまう相手）を、国フィルタは有効としたいけどその後のフィルタで拒否されるとまずい相手（業務上必要な取引先や行政公共機関など）を`permit_mildlist`および`permit_ip_mildlist`に記載している。日本ドメイン（ne.jpとか）や大手日本企業なら全て許可、という設定を紹介しているところもあるが、最近は日本のドメインやgmailからもスパムやフィッシングが来るので、理由なく設定するのはNG。そこそこ大きな日本国内の企業から不正認証アタック、スパムリレーチャレンジを受けた経験もある（おそらくウイルス感染した端末が社内にあったと思われる）。
　2回目の`sleep 1`の入れどころがミソ。`reject_client`で指定されたスパマーはREJECTされるために合計2秒待たされるので、相手からするとイヤなメールサーバーになる。

## krfilter（国別IPでフィルタリング）を使う
　スパムメールの送信元として多い国からのメールを丸ごとブロックする。
　https://ipv4.fetus.jp/ からkrfilterのip一覧をDLして設置する。その後のメンテを自動化。送受信が必要な相手が該当国にいる場合は`permit_clients`等のホワイトリストで除外する。
　fetus.jpさんに迷惑がかからないよう、落ち着いたらweeklyからmonthlyにファイルを移しましょう。IPアドレスの更新はそんな頻繁にはありません。また、利用規約にある通り`wget`のオプション`--user-agent`に連絡用メールアドレスを、`--referer`にドメインと感謝、御礼の言葉を記載しましょう。


```bash
vi /etc/cron.weekly/dl_krfilter
```


```bash:/etc/cron.weekly/dl_krfilter
#!/bin/bash

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

##################################################
# Postfix filter file auto downloading scripts.  #
##################################################

## krfilter3
rm -f /etc/postfix/krfilter.old
mv /etc/postfix/krfilter /etc/postfix/krfilter.old
wget -q -O /etc/postfix/krfilter https://ipv4.fetus.jp/krfilter.3.postfix.txt --user-agent='XXX@XXXXX.jp' --referer='Thanks from XXXXX.jp'

if [ $? -ne 0 ]; then
        echo "Couldn't download krfilter from fetus." | mail -s 'dl_krfilter failed' root
        cp /etc/postfix/krfilter.old /etc/postfix/krfilter
        exit
fi

if [ -s /etc/postfix/krfilter ]; then
        rm -f /etc/postfix/krfilter.old
else
        rm -f /etc/postfix/krfilter
        mv /etc/postfix/krfilter.old /etc/postfix/krfilter
fi

```

 ファイルのダウンロードが成功しても、ファイルの中身が空のことがまれにあるので確認してから反映するスクリプトとしている。

　ダウンロードしたファイルは`REJECT`の設定となっているので、わざわざ拒否通知を相手に送り返したくない場合は以下を追記する。というかむしろ推奨。

```bash:/etc/cron.weekly/dl_krfilter
sed -i -e 's/REJECT/DISCARD/' /etc/postfix/krfilter
```

　コピペでやってるだけで設置をどうすれば良いかわからんって人は、ここまでの段階で一度スクリプトを実行する。

```bash
bash /etc/cron.weekly/dl_krfilter
```

 フィルタが問題なく動作するようになったら、週一動作を月一動作へ変更。

```bash
mv /etc/cron.weekly/dl_krfilter /etc/cron.monthly/dl_krfilter
```


## 国内のスパマーを拒否
　`reject_client`、`cidr_reject_client`で日本のIPアドレスを使ってスパムメールを送ってくる送信サーバー（たぶん中身は海外勢）を指定し拒否する。ここに挙げているIPは実際の送信元だが、そのうちIPを変えることが予想されるので、あくまでも参考程度に。

```:/etc/postfix/reject_client
180.222.184.211 DISCARD
126.160.151.220 DISCARD
160.251.0.35    DISCARD
164.46.33.221   DISCARD
180.211.87.180  DISCARD
122.221.182.38  DISCARD
163.44.187.149  DISCARD
219.117.245.65  DISCARD
```

　2022年3月、cidrの記載をより限定的に改定。

```:/etc/postfix/cidr_reject_client
# Gemini-Mail spam sender : 103.49.142.141 - 103.49.142.255
# 
103.49.142.141/32       DISCARD  Gemini-Mail is a Fishing SPAM sender.
103.49.142.192/26       DISCARD  Gemini-Mail is a Fishing SPAM sender.
```

# 番外：本文の一部を書き換える

　業務用複合機など、FAXをJPEGやPDFでメールに添付し、送信元や時刻等を本文に記載して指定したアドレスに転送する、という複合機側の機能を活用したTIPS。特に昨今はリモートワークの需要があり応用できる。

```
メールの例、Canon imageRUNNER ADVANCEの場合

タイトル：Attached Image

以下本文
FROM="送信元のFAX番号"
TO="受信FAX番号"
DATE=YYYY/MM/DD
TIME=HH:MM:SS
TIMEZONE=+09:00
FCODE=
RJOBNUM=XXXX
```

　FAXの内容は添付ファイルとして送られてくるが、できればメール本文プレビューでどこから送られてきたか判断できれば捗る。これらは複合機で定型文として記載されているため、たとえば`FROM=`の部分を`body_checks`の機能を使用して書き換えることができる。

```:/etc/postfix/main.cf
body_checks = regexp:/etc/postfix/body_checks
```


```:/etc/postfix/body_checks
/FROM="FAX送信元番号1"/    REPLACE    Name1
/FROM="FAX送信元番号2"/    REPLACE    Name2
/FROM="FAX送信元番号3"/    REPLACE    日本語だと文字化けします

・
・
・

```

　送信元ごとに`Name`を記載すればFAX番号記載を文字列記載にすることができるので、どこからのFAXかわかりやすい。日本語そのまま記載はメールで文字化けするためアルファベット記載。エンコード方式を指定してみたが、上手く動作はしなかった。
　また、営業のFAXしか送ってこないFAX番号を`DISCARD`で登録しておくことで、不要なメールを防ぐことができる。注意点として、相手が送信情報に自分の正しいFAX番号を設定していることが条件。


# 文字列で拒否する具体例

　迷惑メール対策をしていて相手の手口が分かってきた。送信元は`REJECT`されてメールが返ってくると、別の文字列パターンのメールを複数送る、という挙動をしている。そうすることで相手はどのパターンなら届くのか、というデータを蓄積しているように思う。従って、設定を`REJECT`にすると更に複数のパターンのフィッシングメールが来ることになり、負荷が増すだけなので、「やり返したい！」とは考えない事！送信元は複数サーバーを設置、パターンをデータベースに蓄積しており、到達率に応じてレンタルサーバーの契約、契約解除等全て自動化しているかも。そんなのを相手にしていたら時間の無駄です。

## header_checksでスパム対策の例

　`cnode.io`はGMOが運営する日本のドメイン。そこで日本のIPアドレスを取得してメールアドレスを偽装しているメールが多いので、実在会社名を語ってメールアドレスを詐称し`cnode.io`から送られてくるものや`unknown`を`DISCARD`としている。一応フォローしておくと、レンサバ業者に非は全くないと思う。環境によっては他のドメインの方が多いよってこともあるかも。

　`body_checks`にも記載するが、中華文字セットを`DISCARD`する設定とすると効果は大きい。

```:/etc/postfix/header_checks
/^Subject:.*(Michael Kors|Ray Ban)/     DISCARD

# dmarcレポートをgzファイルで送ってくるプロバイダがいるので、受け取りたい場合はgzは書かない。
/name=\".*\.(inf|vbs|reg|gz)\"/         REJECT  You can't send that file.
/^Received: from.*(jaccs|daimaru|rakuten|amazon|orico|epos|card|saison|paypay|admin|sales|info|customer|myts|ts3).*(cnode\.io|unknown|\.cn>)/ DISCARD  Looks like spam.

/charset.*gb2312/    DISCARD
/charset.*gb18030/   DISCARD
/charset.*euc\-gb/    DISCARD
```

 2022年3月版。EMOTETとか不正アクセスとか最近凄い。書き方とかよくわからんって人はとりあえず以下を書いとくと良い。

```:/etc/postfix/header_checks
/^Received:.*127\.0\.0\.1.*/                    IGNORE
/^Received:.*192\.168\..*/                      IGNORE

# 米国の法律（RFC2369）への対応
/^Content-Transfer-Encoding:/i PREPEND List-Unsubscribe: mailto:?subject=unsubscribe>"

/^Subject:.*(Michael.Kors|Ray.Ban)/             DISCARD  Fishing SPAM.

/name=\".*\.(inf|vbs|reg)\"/                    REJECT  You can't send that file.

# カード会社等をのアドレスを詐称し、unknown、中華の場合は破棄
/^Received: from.*(admin|aeon|aexp|amazon|american|aplus\.|camera|card|customer|daimaru|eki\-net|epos|evernote|info|jaccs|japannet|jcb\.co|meijiyasuda|meisai|mercari|mufg|myts|orico|paypay|rakuten|saison|sales|smbc|update|vpass|yodobashi).*(unknown|\.cn>|\.tk>)/                DISCARD         Fishing SPAM. This mail is not official.

# カード会社等のアドレスを詐称し、送信元がVPSの場合はREJECT
/^Received: from.*(admin|aeon|aexp|amazon|american|aplus\.|camera|card|customer|daimaru|eki\-net|epos|evernote|info|jaccs|japannet|jcb\.co|meijiyasuda|meisai|mercari|mufg|myts|orico|paypay|rakuten|saison|sales|smbc|update|vpass|yodobashi).*(cnode\.io|sakura\.ne\.jp|\.arena\.ne\.jp)/         REJECT                Fishing SPAM. Your mail address is not official.

# 信用できないドメインでunknownを丸ごと破棄。心配な人はコメントアウトなり、REJECTにするなり。
/^Received: from.*\.(cn|com|shop|site|tokyo|xyz)>.*unknown/             DISCARD  Fishing SPAM. Can't trust your domain.
/^Received: from.*gemini\-mail\.net/             DISCARD  Fishing SPAM.

/^From:.*SFIbJEIlNSVdITwlSCVHJTklLxsoQg/        DISCARD  Fishing SPAM.
/^From:.*hr2020\-support\.work/                  DISCARD  Fishing SPAM.
/^From:.*alafeefkitchens\.com/                  DISCARD  Fishing SPAM.
/^From:.*schlil\.se/                            DISCARD  Fishing SPAM.
/^From:.*Amazon.*amozon/                        DISCARD  Fishing SPAM.
/^From:.*yauheng\.com/                          DISCARD  Fishing SPAM.

/charset.*gb2312/                               DISCARD  Fishing SPAM from China.
/charset.*gb18030/                              DISCARD  Fishing SPAM from China.
/charset.*euc\-cn/                               DISCARD  Fishing SPAM from China.
```


## body_checksでスパム対策の例

　`body_checks`では自称する部分（メルカリとか三井住友とかジャックスとか）は変わるので、なるべく変化のない部分で複数の単語にマッチしたら`DISCARD`とするのが良いかも。
　ただし相手も助詞の部分を変えてきたり、単語の途中にドットを入れたり、見間違える良く似た文字を使ったりして工夫を凝らしている（お願い⇒お原い、ログイン⇒コグイン）。エンコード後の文字列の途中で改行を入れているものもある。Postfixのフィルタリングはデフォルトでは1行ずつの評価となり、途中で改行されるとフィルタを通過するので、`mオプション`を有効化する。が、あくまでも気休め程度のもの。彼らのメールの日本語がおかしいのは知識が乏しいからでなく、改行位置の調整をしているからかも知れない。


```:/etc/postfix/body_checks
# 残念ながら.*アカウント.*更新できま
/5q6L5b\+144Gq44GM44KJ.*44Ki44Kr44Km44Oz44OI.*5pu05paw44Gn44GN44G\+/m           DISCARD                                 
/GyRCO0RHMCRKJCwkaRsoQg.*GyRCJSIlKyUmJXMlSBsoQg.*GyRCOTk\/NyRHJC0kXhsoQg/m      DISCARD

# のアカウントを更新できませんでした
/44Gu44Ki44Kr44Km44Oz44OI44KS5pu05paw44Gn44GN44G\+44Gb44KT44Gn/m                DISCARD
/GyRCJE4lIiUrJSYlcyVIJHI5OT83JEckLSReJDskcyRHJDckPxsoQg/m                       DISCARD

# カード.*利用.*(確認|制限).*(協力|継続)
/44Kr44O844OJ.*5Yip55So.*(56K66KqN|5Yi26ZmQ).*(5Y2U5Yqb|57aZ57aa)/m             DISCARD                                 
/GyRCJSshPCVJGyhC.*GyRCTXhNURsoQg.*(GyRCM05HJxsoQg|GyRCQCk4QhsoQg).*(GyRCNihOTxsoQg|GyRCN1FCMxsoQg)/m   DISCARD

# (カード|取引).*不正.*(使用|利用).*(確認|検出|検知)
/(44Kr44O844OJ|5Y\+W5byV).*5LiN5q2j.*(5L2\/55So|5Yip55So).*(56K66KqN|5qSc5Ye6|5qSc55\+l)/m    DISCARD
/(GyRCJSshPCVJGyhC|GyRCPGgwehsoQg).*GyRCSVRANRsoQg.*(GyRCO0hNURsoQg|GyRCTXhNURsoQg).*GyRCM05HJxsoQg|GyRCOCE9UBsoQg|GyRCOCFDThsoQg)/m    DISCARD

# アカウント.*異常.*(検出|検知)
/44Ki44Kr44Km44Oz44OI.*55Ww5bi4(5qSc5Ye6|5qSc55\+l)/m                           DISCARD                                 
/GyRCJSIlKyUmJXMlSBsoQg.*GyRCMFs\+bxsoQg.*(GyRCOCE9UBsoQg|GyRCOCFDThsoQg)/m     DISCARD

# セキュリティシステム.*大幅なアップグレード
/44K744Kt44Ol44Oq44OG44Kj44K344K544OG44Og.*5aSn5bmF44Gq44Ki44OD44OX44Kw44Os44O844OJ/m   DISCARD                  
/GyRCJTslLSVlJWolRiUjJTclOSVGJWAbKEI.*GyRCQmdJfSRKJSIlQyVXJTAlbCE8JUkbKEI/m             DISCARD
/pbulraXlpeqlxqWjpbeluaXGpeA.*tPO3\-aTKpaKlw6XXpbCl7Klgpck/m                            DISCARD
```

　変換した後、`+`や`/`はエスケープしないといけないらしい・・・。

 https://qiita.com/katsukii/items/1c1550f064b4686c04d4

　副作用は大きくなるが、中華ドメインサイトへ誘導するurlの本文記載があるものや、中華文字コード指定のメールを廃棄すると効果が大きい。gb2312、gb18030、euc-gbにもひらがなの文字セットがあり、独特のフォントで送られてくるメールがそれに該当する。


```:/etc/postfix/body_checks
# gb2312を指定しているhtmlメールを廃棄
/charset.*gb2312/        DISCARD
/charset.*gb18030/       DISCARD
/charset.*euc-gb/        DISCARD

# 中華ドメインへリンクが張られているメール本文があるメールは全て廃棄
/http.*\.cn$/       DISCARD
/http.*\.cn\//      DISCARD
/http.*\.cn\?/      DISCARD
```

# フィッシングメールの費用対効果
　相手の立場に立って考えてみる。他国の不特定多数のサーバーにスパムフィッシングとかをメールで送りたい。そんなとき、接続先がどんな対策をしていると嫌だなぁとかここは無理だなぁとか、ターゲットから除外するだろうか？

1. ファイヤーウォール、フィルタが通過できるIPを取得する必要がある。つまりコストが継続的にかかる。
2. 名前解決可能なHELOが要求される。ドメインを取得し、DNSに登録しなければならない。これも継続的にコストがかかるうえ、偽装しやすいドメインはスパマー同士で争奪戦となる。
3. ヘッダ、本文にNGワードが設定されている。ターゲット国の言語に精通していないと難しい。
4. `reject`やスパム判定されたら一定期間ブロックされる。2通目を送るためには長期にIP、ドメイン、VPSの契約を継続する必要があるので、コストがかかる。

　ということで、しっかり設定すればフィッシングメールの費用対効果はスパマーにとって悪くなりまっせ。

　2022年12月追記：アクセスに波がある。おそらく、しばらくしたらリストを別の業者に闇販売し、購入したところがアクセスを試みるも、できねーじゃねーかっとなって再度転売する、というような流れになっていると推測する。


# logwatchの報告を静かにさせる

　　`logwatch`レポートで`Unmatched Entries`が長～くなるのを対処。


```:/etc/postfix/main.cf
smtpd_tls_loglevel = 2
```

　`logwatch`のスクリプトを原本からコピー。

```
cp /usr/share/logwatch/scripts/services/postfix /etc/logwatch/scripts/services/postfix
```

　コピーしたスクリプトを編集。

```:/etc/logwatch/scripts/services/postfix
3976行目から追記

3966    # non-anchored
3967    #push @ignore_list, qr/: Greylisted for /;
3968    push @ignore_list, qr/certificate verification (?:depth|failed for)/;
3969    push @ignore_list, qr/re-using session with untrusted certificate, look for details earlier in the log$/;
3970    push @ignore_list, qr/socket: wanted attribute: /;
3971    push @ignore_list, qr/ smtpd cache$/;
3972    push @ignore_list, qr/ old session$/;
3973    push @ignore_list, qr/fingerprint=/;
3974    push @ignore_list, qr/TLS cipher list "/;
3975
3976    # 追記
3977    push @ignore_list, qr/message repeated/;
3978    push @ignore_list, qr/Issuing session ticket, key expiration/;
3979    push @ignore_list, qr/SSL3 alert read:fatal:bad certificate/;
3980 }
```

# おわりに
　上記の設定で現在は週1～2通の状況。届いたらそのたびに登録している。IPベース、正規表現ベースの2重、3重の登録があれば、どれかが変わったとしても別のルールでフィルタリングできるが、相手も狡猾なのでイタチごっこ。特定電子メール法がもう少し厳しく機能して欲しい。HELOは制度化しても良いと思う。名前解決できないHELOを送るメールサーバーを国内で公開してたら罰金とか。

　2021年8月追記：`header_checks`、gb文字セット指定のメール、中華サイト誘導リンク記載のメールを廃棄する設定を追加し、さらに`mail.log`を`swatch`で見張って廃棄メールが多いipを自動でブロックする設定にしたところ、フィッシングメールはほぼ無くなった。

　2021年11月追記：迷惑メールはほぼ来ない...月1程度。来るたびに特有のパターン等をしかるべき場所に追記している。

　2022年3月追記：一部ルールや文言等を改定しました。フィッシングメールは月に5通も届きません。新しいパターン来ないかな・・・。

　2022年8月追記：月2～3通程度、内1通がスパム判定されず届くかどうか。判定されなかった場合ルールを改定している。ここらへんが限界なのかもしれない。

　2022年11月追記：`smtpd_helo_restrictions`を変更。ホスト名で判断するタイプの設定はrejectしすぎるようになってしまった。

# 参考

http://www.gabacho-net.jp/anti-spam/anti-spam-system.html

　ただし記事中ではyahooや日本の携帯会社のドメインを丸ごとホワイトリストに入れている。繰り返しになるが、gmailやyahoo等のフリーメールからもスパムが来るので、理由がない限りドメイン丸ごとホワイトリスト化はしてはいけないと僕は考えている。


# これだけで対策万全ではない

　`postfix`だけで対策しきることはできないのでスタッフへのリテラシー研修、システム、ネットワーク全体でフィッシングに引っかからないようにする。メールユーザーがスパムであることを判断しやすくすれば、仕事の効率も上がる、かも。

　`spamassassin`と`amavis`編。

https://qiita.com/yukisku/items/b25938b4d34c54c9cf14

　ウイルス対策編。

https://qiita.com/yukisku/items/d8b87a86a66fc322e627

　`Dovecot`のSASL認証制限編。

https://qiita.com/yukisku/items/f707d4923c95eec54067