nginxで SMTP のラウンドロビン proxy をする

必要にかられて nginx の mail proxy機能で SMTP のラウンドロビン Proxy を実装してみた。
使用した nginx の version は 1.8.0

#環境
|用途|IP|
|---|---|
|SMTP クライアント|192.168.7.1|
|SMTP Proxy|192.168.7.2|
|Proxy先 SMTPサーバ1|192.168.7.3|
|Proxy先 SMTPサーバ2|192.168.7.4|

#nginx 設定
##1. SMTP Proxyサーバの設定を追加

```nginx.conf:nginx.conf
mail {
	auth_http 127.0.0.1/proxy/ ;
	proxy on;
	proxy_pass_error_message on;

	smtp_capabilities "SIZE 10485760" 8BITMIME ENHANCEDSTATUSCODES DSN ;
	smtp_auth none;

	server {
		listen 192.168.7.161:25;
		protocol   smtp;
		ssl        off;
		xclient    off;
		auth_http_header PORT 25;
	}
}

```
認証に使用するURLは http://127.0.0.1/proxy/

##2. 認証ページの応答用httpサーバの設定

```nginx.conf:conf.d/default.conf
server {
    listen       127.0.0.1:80;
    server_name  localhost;
    root /var/www/html;
    charset     utf-8;

    location ~ /proxy/ {
        add_header Auth-Status OK;
        set $proxyport "25";
        if ($msec ~* [0-4]$) { set $proxyip "192.168.7.163"; }
        if ($msec ~* [5-9]$) { set $proxyip "192.168.7.164"; }

        add_header Auth-Server $proxyip;
        add_header Auth-Port $proxyport;
        empty_gif;
    }
}
```
$msec 変数の末尾の数字でProxy先のSMTPサーバを決定する

##3. httpのlog_formatにProxyのログを追加

```nginx.conf:nginx.conf
'"$http_auth_smtp_helo" "$http_auth_smtp_from" "$http_auth_smtp_to" ${http_client_ip} ${proxyip}';
```
HELOコマンド、MAILコマンド、RCPTコマンド、クライアントIP、プロキシ先IP を access.logに出力

#テスト
```
SMTP接続
220 proxy.localdomain ESMTP ready
EHLO localhost
250-proxy.localdomain
250-SIZE 10485760
250-8BITMIME
250-ENHANCEDSTATUSCODES
250 DSN
MAIL FROM:<ma3ki@ma3ki.net>
250 2.0.0 OK
RCPT TO:<abuse@ma3ki.net>
250 2.1.5 Ok
QUIT
221 2.0.0 Bye

nginxのaccess.log
127.0.0.1 - - [28/Nov/2015:23:33:42 +0900] "GET /proxy/ HTTP/1.0" 200 43 "localhost" "MAIL FROM:<ma3ki@ma3ki.net>" "RCPT TO:<abuse@ma3ki.net>" 192.168.7.1 192.168.7.164

192.168.7.164のmaillog
Nov 28 23:33:41 mta02 postfix/smtpd[2472]: connect from unknown[192.168.7.161]
Nov 28 23:33:41 mta02 postfix/smtpd[2472]: AFA8E200AD: client=unknown[192.168.7.161]
Nov 28 23:33:41 mta02 postfix/smtpd[2472]: disconnect from unknown[192.168.7.161]
```
Proxy できた！

```
ツールでアタックした結果
127.0.0.1 - - [28/Nov/2015:23:36:49 +0900] "GET /proxy/ HTTP/1.0" 200 43 "localhost" "MAIL FROM:<ma3ki@ma3ki.net>" "RCPT TO:<abuse@ma3ki.net>" 192.168.7.1 192.168.7.163
127.0.0.1 - - [28/Nov/2015:23:36:49 +0900] "GET /proxy/ HTTP/1.0" 200 43 "localhost" "MAIL FROM:<ma3ki@ma3ki.net>" "RCPT TO:<abuse@ma3ki.net>" 192.168.7.1 192.168.7.164
127.0.0.1 - - [28/Nov/2015:23:36:49 +0900] "GET /proxy/ HTTP/1.0" 200 43 "localhost" "MAIL FROM:<ma3ki@ma3ki.net>" "RCPT TO:<abuse@ma3ki.net>" 192.168.7.1 192.168.7.164
127.0.0.1 - - [28/Nov/2015:23:36:49 +0900] "GET /proxy/ HTTP/1.0" 200 43 "localhost" "MAIL FROM:<ma3ki@ma3ki.net>" "RCPT TO:<abuse@ma3ki.net>" 192.168.7.1 192.168.7.163
127.0.0.1 - - [28/Nov/2015:23:36:49 +0900] "GET /proxy/ HTTP/1.0" 200 43 "localhost" "MAIL FROM:<ma3ki@ma3ki.net>" "RCPT TO:<abuse@ma3ki.net>" 192.168.7.1 192.168.7.163
127.0.0.1 - - [28/Nov/2015:23:36:49 +0900] "GET /proxy/ HTTP/1.0" 200 43 "localhost" "MAIL FROM:<ma3ki@ma3ki.net>" "RCPT TO:<abuse@ma3ki.net>" 192.168.7.1 192.168.7.163
127.0.0.1 - - [28/Nov/2015:23:36:49 +0900] "GET /proxy/ HTTP/1.0" 200 43 "localhost" "MAIL FROM:<ma3ki@ma3ki.net>" "RCPT TO:<abuse@ma3ki.net>" 192.168.7.1 192.168.7.164
127.0.0.1 - - [28/Nov/2015:23:36:49 +0900] "GET /proxy/ HTTP/1.0" 200 43 "localhost" "MAIL FROM:<ma3ki@ma3ki.net>" "RCPT TO:<abuse@ma3ki.net>" 192.168.7.1 192.168.7.163
```

いい感じにProxy先がバランシングされてる！