Dzisiaj będzie o głupim błędzie w konfiguracji Exima, który wynikł z bezrefleksyjnego kopiowania i wklejania opublikowanych w Internecie przykładowych konfiguracji.
Ze zdziwieniem przeczytałem maila z serwerowni informującego, że z mojego serwera jest wysyłany spam. Dołączony w załączniku mail wyglądał na wysłany z mojego serwera, a w logach Exima znalazłem informację o wysłaniu inkryminowanej wiadomości, więc o pomyłce serwerowni nie było mowy.
2012-06-22 09:34:16 1ShyNj-0000KH-Cx <= harun@digit0.com H=server177288-1.santrex.net [37.59.45.10] P=esmtpa A=plain_pgsql:sales S=3593 id=73D566338398i-49A3A971B01x025-29B991E@PHRSBS 2012-06-22 09:34:18 1ShyNj-0000KH-Cx => altairhosttest@hotmail.com R=dnslookup T=remote_smtp H=mx2.hotmail.com [65.54.188.94] 2012-06-22 09:34:18 1ShyNj-0000KH-Cx Completed
Z powyższego wycinka logów wynika, że spamer z adresu 37.59.45.10
z powodzeniem autoryzował się jako użytkownik sales
przy użyciu autoryzacji plain_pgsql
. Stosowna regułka wyglądała tak:
plain_pgsql: driver = plaintext public_name = PLAIN server_condition = ${if eq{$auth3}{${lookup pgsql{SELECT password FROM exim_virtual_users WHERE login = '${quote_pgsql:$auth2}'}}}{yes}{no}} server_set_id = $auth2 server_prompts = :
Powyższy mechanizm wyszukuje w bazie dane użytkownika o podanym loginie ($auth2) i uzyskane w ten sposób hasło porównuje z hasłem podanym przez użytkownika ($auth3). Gdzie tkwi problem? Otóż powyższy mechanizm działa świetnie dla użytkowników, którzy istnieją w bazie. Jeśli jednak sprytny spamer poda nieistniejącego użytkownika i puste hasło to autoryzacja przebiega pomyślnie! Dzieje się tak ponieważ dla nieistniejącego użytkownika zwracane jest puste hasło, a puste hasło = puste hasło.
Dokładnie ten przypadek został opisany w dokumentacji Exima, więc sobie ku pamięci i wszystkim zainteresowanym powtarzam: RTFM!
Dla porządku podaję jeszcze poprawną wersję regułki autoryzującej:
plain_pgsql: driver = plaintext public_name = PLAIN server_condition = ${if and{{!eq{$auth2}{}} {!eq{$auth3}{}} {eq{$auth3}{${lookup pgsql{SELECT password FROM exim_virtual_users WHERE login = '${quote_pgsql:$auth2}'}}}}} {yes}{no}} server_set_id = $auth2 server_prompts = :