17 августа 2012 г.

DKIM и PHPMailer 5.1

UPDATE 2 В версии 5.2.9 тоже была ошибка с подписыванием DKIM. Но мой пул реквест поправил проблему. Актуальную рабочую версию брать тут https://github.com/PHPMailer/PHPMailer
 
UPDATE В версии 5.2.9 это всё уже поправлено. Всё что ниже касается версии 5.1


Решил настроить цифровую подпись DKIM для отправляемых писем с сайта.
Для начала решил возложить эту ответственную миссию на  хостера, но к сожалению он предоставлял только устаревший DomainKey-Signature.
Решил прикрутить DKIM на PHPMailer.
Небольшая инструкция:



1. Необходимо добавить DNS запись с публичным ключом. Генерировать публичный и приватный ключ можно тут http://www.port25.com/support/domainkeysdkim-wizard/
После того как получили ключи, необходимо добавить DNS запись для домена с которого будете слать подписанные письма. Запись должна иметь вид v=DKIM1; k=rsa; p=MI.....ваш_публичный_ключ.........AB;
Расшифровку параметров можно почитать тут http://www.zytrax.com/books/dns/ch9/dkim.html
Для начала установите ключ t=y, он будет означать что DKIM в режиме теста. Так ваши письма не пропадут. Ключ o может иметь значения ~ или -, первый означает что письма могут иметь подпись, а могут и не иметь, второй означает что все письма должны иметь подпись.
2. Необходимо внести изменения в PHPMailer. Я использовал версию 5.1.
Указываем переменные DKIM
public $DKIM_domain     = ''; домен с которого отсылаются письма, например example.com
public $DKIM_private    = ''; путь к вашему приватному ключу, которым и будут подписываться письма

Вносим правки в сам PHPMailer, без них не заработает.
Строка 569:
меняем
$header_dkim = $this->DKIM_Add($header,$this->Subject,$body); 
на
$header_dkim =  $this->DKIM_Add($header,$this->EncodeHeader($this->SecureHeader($this->Subject), 'phrase'),$body);
Строка 2282: меняем
$headers              = explode("\n\r",$headers_line);
на
$headers              = explode($this->LE,$headers_line);
Строки 2292 и 2293 меняем
$from     = str_replace('|','=7C',$this->DKIM_QP($from_header));
$to       = str_replace('|','=7C',$this->DKIM_QP($to_header));
на
$from     = str_replace('|','=7C',($from_header));
$to       = str_replace('|','=7C',($to_header));
Строка 2297 меняем
$DKIMb64  = base64_encode(pack("H*", sha1($body))) ; 
на
if ($this->ContentType == 'text/plain') {
    $DKIMb64  = base64_encode(pack("H*", sha1($body))) ; // Base64 of packed binary SHA-1 hash of body
}else{
    $DKIMb64 = base64_encode(pack("H*", sha1("\r\n" . preg_replace("/\r\n$/", "", $body)))) ; 
}

Номера строк могут немного отличатся. С помощью http://www.brandonchecketts.com/emailtest.php проверяем всё ли хорошо. Нужно отправить с помощью PHPMailer письмо на указанный адрес. Сервис сделает разбор полётов и скажет прошла ли проверку ваш DKIM подпись.

Полезные ссылки по теме:
http://www.dnswatch.info/dns/dnslookup?la=en&host=phpmailer._domainkey.alg.com.ua&type=TXT&submit=Resolve проверка добавилась ли ваша DNS запись
 http://www.port25.com/support/domainkeysdkim-wizard/ генератор ключей
 http://www.zytrax.com/books/dns/ch9/dkim.html описание DNS записи
http://www.ietf.org/rfc/rfc4871.txt документация о DKIM
 http://sourceforge.net/tracker/index.php?func=detail&aid=3404808&group_id=26031&atid=385707 описание бага PHPMailer с неправилним хешем для подписи
http://sourceforge.net/tracker/index.php?func=detail&aid=2960165&group_id=26031&atid=385707 описание бага с разделением заголовков
http://stackoverflow.com/questions/4313481/whats-the-difference-between-domainkey-signature-dkim-signature решение бага с кодирование поля subject
http://www.brandonchecketts.com/emailtest.php тестирование подписанных писем

Надеюсь кому то это поможет с настройкой DKIM

Комментариев нет:

Отправить комментарий