Postfix 用のアクセス制限スクリプトを Python で

中国からのアクセスで、Amazon を偽装するメール送信などがありました。そこで Python を用いた国別アクセス制限スクリプトを作成しました。

Postfix と Python の連携方法などについても解説していますのでご活用下さい。


Amazon などを偽装したメール

こういった偽装メールの多くは中国や香港から送られいます。

Postfix SMTP server: errors from unknown[42.55.95.146]

Transcript of session follows.

Out: 220 magic-object.mydns.jp ESMTP Postfix
In: EHLO amazon.co.jp
Out: 250-XXXX.XXXXXX.mydns.jp
Out: 250-PIPELINING Out: 250-SIZE 10240000
Out: 250-VRFY Out: 250-ETRN Out: 250-STARTTLS Out: 250-ENHANCEDSTATUSCODES
Out: 250-8BITMIME Out: 250-DSN Out: 250-SMTPUTF8
Out: 250 CHUNKING In: MAIL FROM: <admin@amazon.co.jp>
Out: 250 2.1.0 Ok In: RCPT TO: <xxxxxx@XXXXXXXXXXX.mydns.jp>
Out: 450 4.7.25 Client host rejected: cannot find your hostname, [42.55.95.146]
$ whois 42.55.95.146

% Information related to ‘42.52.0.0/14AS4837’
route: 42.52.0.0/14
descr: China Unicom Liaoning Province Network
country: CN
origin: AS4837
mnt-by: MAINT-CNCGROUP-RR
last-modified: 2011-03-02T05:24:02Z
source: APNIC
% This query was served by the APNIC Whois Service version 1.88.16 (WHOIS-JP1)

Postfix 用のアクセス制限スクリプトの基本

データのやりとり

データのやりとりは基本的に標準入力と標準出力で行います。

形式:変数=値

参考:ポリシープロトコルの記述

標準入力

変数一覧(参考

client_addressclient_heloclient_hostnameclient_portclient_protocol
domainextensionmailboxnexthoporiginal_recipient
recipientsasl_methodsasl_sendersasl_usernamesender
sizeuser

標準出力

許可action=OK\n\n
拒否action=REJECT Deny Country in List\n\n

※ 送信する場合は必ず改行コードを2個追加してください。
※ 標準出力の「action」にはココで指定された文字列で返信してください。


コード

「/etc/postfix/geo-ip-countries.py」

#!/usr/bin/env python
##############################################
if __name__ == "__main__":
    import configparser
    import sys
    import re
    import pathlib
    import datetime
    import GeoIP

    configFile = '/etc/postfix/geo-ip-countries.cf'

    ################ 初期設定 #################

    # GeoIP の準備
    gi = GeoIP.new(GeoIP.GEOIP_MEMORY_CACHE)

    # 設定ファイルの準備
    config = configparser.ConfigParser()

    try:
        config.read( configFile )
    except:
        denyCountries = []

    if len( allowCountries ) < 1 and len( denyCountries ) < 1:
        exit( 0 )

    ######### 読み込みループ作成 ##############
    try:
        for line in sys.stdin:

            line = line.strip()
            if len( line ) < 1:
                continue

            patrList = re.split( r'\s*=\s*', line )
            if 'client_address' != patrList[0]:
                continue

            targetAddresStr = patrList[1].strip()

            if targetAddresStr in accpectAddress:
                print( "action=OK\n\n" )
                break

            targetCountry = gi.country_code_by_name( targetAddresStr )

            if targetCountry in allowCountries:
                print( "action=OK\n\n" )
                break
            elif targetCountry in denyCountries:
                print( "action=REJECT Deny Country in List\n\n" )
                break
            else:
                print( "action=OK\n\n" )
                break

        sys.stdout.flush()
        #exit( 0 )

    except:
        exit( 1 )

    ################## 終了 ###################
    exit( 0 )

※ IP アドレスから国のコードを取得する参考はコチラから。

# ### SELinux の実行権限を付与
# chcon -t postfix_exec_t /etc/postfix/geo-ip-countries.py
#
# ## 実行権の付与
# chmod +x /etc/postfix/geo-ip-countries.py

スクリプトの設定ファイル

「/etc/postfix/geo-ip-countries.cf」

[allow]
countries =

[deny]
countries = CN, HK, KR

[accpect address]
ip_address = 

Postfix の設定ファイル

「/etc/postfix/master.cf」

# ====================================================================
# GeoIP based Countries Blocking
# ====================================================================
# ===================================================================
# service       type  private unpriv  chroot  wakeup  maxproc command
#                     (yes)   (yes)   (yes)   (never) (100)
# ===================================================================
geoip-policy     unix  y       n       n       -       10       spawn
    user=nobody argv=/etc/postfix/geo-ip-countries.py

「/etc/postfix/main.cf」

smtpd_client_restrictions =     permit_mynetworks,
                                permit_sasl_authenticated,
                                check_policy_service unix:private/geoip-policy,
                                check_client_access mysql:/etc/postfix/mysql-check_client_access.cf,
                                reject_unknown_client,
                                reject_rbl_client bl.spamcop.net,
                                reject_rbl_client zen.spamhaus.org,
                                permit

postfix の再起動

# systemctl restart postfix
Facebooktwitterfoursquare

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です