Using a PHP Script on an Apache Server as the IMAP Auth Backend

Start with the configuration from IMAP Proxy Example. For detailed information about different configuration parameters, see the ngx_mail_core_module page.

  1. Your Proxy server for pop/imap is running on
  2. You have 2 backend pop/imap servers: and
  3. You have a webserver that you will use for the authentication and redirection logic
  4. The authentication script is /mail/auth.php


user  nobody;
worker_processes  1;
error_log  logs/error.log  info;
pid  logs/;

events {
  worker_connections  1024;
  multi_accept on;

mail {
  pop3_capabilities  "TOP"  "USER";
  imap_capabilities  "IMAP4rev1"  "UIDPLUS";

  server {
    listen     110;
    protocol   pop3;
    proxy      on;

  server {
    listen     143;
    protocol   imap;
    proxy      on;


NGINX sends headers as
Auth-User: somuser
Auth-Pass: somepass
On my php app server these are seen as
if (!isset($_SERVER["HTTP_AUTH_USER"] ) || !isset($_SERVER["HTTP_AUTH_PASS"] )){

$username=$_SERVER["HTTP_AUTH_USER"] ;
$userpass=$_SERVER["HTTP_AUTH_PASS"] ;

// default backend port

if ($protocol=="imap") {

if ($protocol=="smtp") {

// NGINX likes ip address so if your
// application gives back hostname, convert it to ip address here
$backend_ip["mailhost01"] ="";
$backend_ip["mailhost02"] ="";

// Authenticate the user or fail
if (!authuser($username,$userpass)){

// Get the server for this user if we have reached so far

// Get the ip address of the server
// We are assuming that you backend returns hostname
// We try to get the ip else return what we got back
$server_ip=(isset($backend_ip[$userserver]))?$backend_ip[$userserver] :$userserver;

// Pass!
pass($server_ip, $backend_port);


function authuser($user,$pass){
  // password characters encoded by nginx:
  // " " 0x20h (SPACE)
  // "%" 0x25h
  // see nginx source: src/core/ngx_string.c:ngx_escape_uri(...)
  $pass = str_replace('%20',' ', $pass);
  $pass = str_replace('%25','%', $pass);

  // put your logic here to authen the user to any backend
  // you want (datbase, ldap, etc)
  // for example, we will just return true;
  return true;

function getmailserver($user){
  // put the logic here to get the mailserver
  // backend for the user. You can get this from
  // some database or ldap etc
  // dummy logic, all users that start with a,c,f and g get mailhost01
  // the others get mailhost02
  if in_array(substr($user,0,1), array("a", "c", "f", "g")){
    return "mailhost01";
  } else {
    return "mailhost02";

function fail(){
  header("Auth-Status: Invalid login or password");

function pass($server,$port){
  header("Auth-Status: OK");
  header("Auth-Server: $server");
  header("Auth-Port: $port");