IMAP Authentication with PHP¶
Use a PHP script to authenticate users and route to backend mail servers.
Setup¶
- Proxy server: 192.168.1.1
- Backend servers: 192.168.1.22, 192.168.1.33
- Auth web server: 192.168.1.44
NGINX Configuration¶
user nobody;
worker_processes 1;
error_log logs/error.log info;
pid logs/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
}
mail {
auth_http 192.168.1.44:80/mail/auth.php;
pop3_capabilities "TOP" "USER";
imap_capabilities "IMAP4rev1" "UIDPLUS";
server {
listen 110;
protocol pop3;
proxy on;
}
server {
listen 143;
protocol imap;
proxy on;
}
}
PHP Auth Script (/mail/auth.php)¶
<?php
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"];
// Default backend port
$backend_port = 110;
if ($protocol == "imap") {
$backend_port = 143;
}
if ($protocol == "smtp") {
$backend_port = 25;
}
// Backend IP mapping
$backend_ip["mailhost01"] = "192.168.1.22";
$backend_ip["mailhost02"] = "192.168.1.33";
// Authenticate
if (!authuser($username, $userpass)) {
fail();
exit;
}
// Get backend server
$userserver = getmailserver($username);
$server_ip = isset($backend_ip[$userserver]) ? $backend_ip[$userserver] : $userserver;
pass($server_ip, $backend_port);
function authuser($user, $pass) {
// Decode NGINX-encoded characters
$pass = str_replace('%20', ' ', $pass);
$pass = str_replace('%25', '%', $pass);
// Add your authentication logic here (LDAP, database, etc.)
return true;
}
function getmailserver($user) {
// Route users to backends
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");
exit;
}
function pass($server, $port) {
header("Auth-Status: OK");
header("Auth-Server: $server");
header("Auth-Port: $port");
exit;
}