It’s been a long times since i wrote my last article, i’ve been bussy with real life things.
As usual, I’ll get right to the subject of how to configure nginx as POP3/IMAP proxy server.
Nginx IP = 192.168.1.1 Postfix User Database IP = 192.168.1.5 (postfix + courier server + apache backend)
nginx server configuration
mail { server_name mail-proxy.example.com; # apache external backend auth_http 192.168.1.5:8081/auth.php; proxy on; proxy_pass_error_message on; imap_capabilities "IMAP4rev1" "UIDPLUS" "IDLE" "LITERAL +" "QUOTA"; pop3_auth plain apop cram-md5; pop3_capabilities "LAST" "TOP" "USER" "PIPELINING" "UIDL"; ssl_certificate /etc/nginx/ssl_keys/db.mail-proxy.crt; ssl_certificate_key /etc/nginx/ssl_keys/db.mail-proxy.key; ssl_session_timeout 5m; ssl_protocols SSLv2 SSLv3 TLSv1; ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; ssl_prefer_server_ciphers on; server { listen 143; protocol imap; starttls on; auth_http_header X-Auth-Port 143; auth_http_header User-Agent "Nginx POP3/IMAP4 proxy"; } server { protocol pop3; listen 110; starttls on; pop3_auth plain; auth_http_header X-Auth-Port 110; auth_http_header User-Agent "Nginx POP3/IMAP4 proxy"; } server { listen 993; ssl on; protocol imap; auth_http_header X-Auth-Port 993; auth_http_header User-Agent "Nginx POP3/IMAP4 proxy"; } server { protocol pop3; listen 995; ssl on; pop3_auth plain; auth_http_header X-Auth-Port 995; auth_http_header User-Agent "Nginx POP3/IMAP4 proxy"; } }
apache server configuration
First, we create a custom log format in apache server, which is useful to show the ip address of the user. nginx pass it in the form of Client-IP header.
LogFormat "\"%{Client-IP}i %{X-Auth-Port}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" cached
httpd.conf
CustomLog /var/log/httpd/authserver-access_log cached
auth.php
<?php /* Nginx sends headers as Auth-User: somuser Auth-Pass: somepass On my php app server these are seen as HTTP_AUTH_USER and HTTP_AUTH_PASS */ if (!isset($_SERVER["HTTP_AUTH_USER"] ) || !isset($_SERVER["HTTP_AUTH_PASS"] )) { fail(); } $username=$_SERVER["HTTP_AUTH_USER"] ; $userpass=$_SERVER["HTTP_AUTH_PASS"] ; $protocol=$_SERVER["HTTP_AUTH_PROTOCOL"] ; $backend_port=110; if ($protocol=="imap") { $backend_port=143; } if ($protocol=="smtp") { $backend_port=25; } if (!authuser($username,$userpass)) { fail(); exit; } $userserver=getmailserver($username); pass($userserver, $backend_port); // Authentication block function authuser($user,$pass) { // You can put a query for authentication with the DB here. // Since auth will be done post-proxy, we're just returning true return true; } // MySQL connection function function mysqlconn($user,$query) { $mail_dbuser="postfix-user"; $mail_dbpass="mypassword"; $mail_db="postfix-db"; $mail_dbhost="localhost"; mysql_connect($mail_dbhost,$mail_dbuser,$mail_dbpass); @mysql_select_db($mail_db) or die( "Unable to select database"); $res1 = mysql_query($query); $res = mysql_fetch_array($res1); $res2 = $res['active']; return $res2; mysql_close(); } // getmailserver function function getmailserver($user) { $query = "select active from mailbox where username='$user'"; $active = mysqlconn($user,$query); if (!isset($active)) { fail(); } elseif ($active == "1") { $server = "192.168.1.5"; return $server; } elseif ($active == "0") { fail(); } mysql_close(); } function fail() { header("Auth-Status: Invalid login or password"); exit; } function pass($server,$port) { header("Auth-Status: OK"); header("Auth-Server: $server"); header("Auth-Port: $port"); exit; } ?>
Testing
# telnet mail-proxy.example.com 110 Trying xxx.xxx.xxx.xxx... Connected to mail-proxy.example.com. Escape character is '^]'. +OK POP3 ready user user@example.com +OK pass password +OK logged in.
Log
"xxx.xxx.xxx.xxx 110" - - [31/Aug/2012:20:26:00 +0700] "GET /auth.php HTTP/1.0" 200 - "-" "Nginx POP3/IMAP4 proxy"
SSL/STARTTLS
openssl s_client -connect mail-proxy.example.com:993 ---snip--- New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA Server public key is 4096 bit Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE SSL-Session: ---snip--- Start Time: 1346419294 Timeout : 300 (sec) Verify return code: 18 (self signed certificate) --- * OK IMAP4 ready . login user@example.com mypass . OK LOGIN Ok. . logout * BYE Courier-IMAP server shutting down . OK LOGOUT completed closed
Log
"xxx.xxx.xxx.xxx 110" - - [31/Aug/2012:20:26:00 +0700] "GET /auth.php HTTP/1.0" 200 - "-" "Nginx POP3/IMAP4 proxy"
nggak salah judulnya Colourful website? kok nggak colourful?
ironi kan? 😀