IP — Блог Валерия Леонтьева https://valera.ws Место публикации личных заметок. Технологии, управление, бизнес, жизнь Sun, 28 Nov 2010 19:19:34 +0000 ru-RU hourly 1 https://wordpress.org/?v=5.6.2 https://valera.ws/wp-content/uploads/2020/02/favicon.png IP — Блог Валерия Леонтьева https://valera.ws 32 32 Делегирование обслуживания почтового домена: часть 2. Отправка почты через localhost (настройка Exim4 в Debian) https://valera.ws/2010.11.28~exim-mail-localhost/ https://valera.ws/2010.11.28~exim-mail-localhost/#comments Sun, 28 Nov 2010 19:18:55 +0000 http://valera.ws/?p=455 Читать далее Делегирование обслуживания почтового домена: часть 2. Отправка почты через localhost (настройка Exim4 в Debian) ]]> Настройка Exim и PHP mail() на примере Linux Debian

Чтобы решить проблему отказа серверов Gmail от обслуживания  при отправке большого числа писем на несуществующие адреса, используем для отправки почты из скриптов сайта локальный почтовый SMTP-сервер (MTA). Локальный сервер будет выступать в качестве mail relay. В дополнение мы откажемся от подключения из скрипта к удаленному серверу, что может быть медленно. Локальные подключения всегда должны быть быстрее и стабильнее.

Локальный сервер мы будем использовать только для отправки писем. Причем, не важно, как будет происходить отправка: непосредственно через SMTP, или с помощью MUA. Получение почты по-прежнему будет происходить с серверов Gmail.

В дистрибутиве Debian 5 по умолчанию устанавливается MTA Exim4. Он отлично подойдет для наших задач. Причем его настройка производится с помощью мастера и невероятно проста. Настроить сервер требуется на прием соединений исключительно с локального соединения. При этом не нужно поручать ему обслуживание доменов, кроме дефолтного локального (localhost).

Итак, если Exim у вас не установлен, то установим его:

# aptitude install exim4

Далее запускаем его конфигурацию:

# dpkg-reconfigure exim4-config

1. На первом шаге необходимо выбрать конфигурацию сервера. В Exim есть несколько стандартных конфигураций, предназначенных для разных случаев. Подробнее о них в мануале. Нам нужна конфигурация “internet site; mail is sent and received directly using SMTP”.

2. Далее укажите имя сервера. Оно будет передаваться в SMTP-протоколе в команде HELLO, т.е. будет видно получателям вашей почты. Лучше всего, чтобы это имя совпадало с доменом, с которого шлется почта. Например, valera.ws.

Если у вас на сервере несколько сайтов с разными доменами (см. ниже), то лучше это имя сделать нейтральным, чтобы «не палиться». Например, можно выбрать local-mail-agent.

3. Далее требуется указать, какие интерфейсы должен слушать Exim. В нашем случае удаленные подключения мало того, что не нужны, так еще и опасны: кто угодно сможет рассылать почту через ваш сервер. Указываем только 127.0.0.1.

4. Далее спрашивается, какие домены должен обслуживать сервер. Т.е. для каких доменов не нужно пересылать письма на удаленные SMTP-сервера, пользователь заберет их с этого сервера. Нам не нужно обслуживание наших доменов. Можно указать только localhost, т.к. его больше обслужить некому.

Не указывайте здесь адрес вашего сервера (подставляется по умолчанию), т.к. его обслуживание делегировано Gmail. Если его указать, то письма, отправленные на ящики вашего домена, в Gmail не попадут и останутся на сервере. Это не нужно.

5. Далее можно указать, для каких доменов сервер должен служить релеем (список через точку с запятой). Здесь не указываем ничего, так как на следующем шаге мы разрешим себе релей для всех доменов. Можете указать список ваших доменов.

6. Здесь укажем 127.0.0.1, чтобы раз-решить релей для всех запросов с локального IP.

При этой конфигурации есть один негативный момент. Если ваш сайт поломают, то злоумышленники смогут слать почту с любых доменов через ваш сервер. Если на сервере 1—2 сайта, то лучше на этом шаге оставить поле пустым, а на предыдущем шаге внести список этих доменов (для возврата на шаг назад нажмите кнопку “Cancel”). При появлении новых доменов не забывайте их заносить в конфиг. Если вы считаете свои сайты надежными, то проще всего указывать здесь 127.0.0.1.

7. Дале уточняется, является ли для нас проблемой постоянные DNS-запросы при отправке каждого письма. В 99,9% это не проблема, так что выбираем ответ на вопрос “Keep number of DNS-queries minimal (Dial-on-Demand)?” “No”.

8. Где хранить локальную почту (помните, мы указали серверу обслуживать домен localhost?) нам по сути не важно, так как этим как правило никто не пользуется. Можно выбрать вариант по умолчанию: складывать все в /var/mail.

9. Предпоследний шаг — выбор конфигурации. Хранить все в одном файле, или раскидать по множеству мелких файлов. В большой файл проще вносить большие изменения, а с мелкими проще работать в случае мелких правок. Выберите вариант на свой вкус. Я выбрал “unsplit configuration” (ответ “No”).

10. На последнем шаге укажем на какой аккаунт реального пользователя системы пересылать сообщения, отправленные на служебные аккаунты postmaster, root и т.д. Здесь имеет смысл указать ваше имя пользователя в системе.

Переконфигурировать Exim в любой момент можно тем же способом. Мастер подставит в значения по умолчанию текущие значения вашей конфигурации.

Правильная настройка SPF

Если кратко, то SPF — это способ борьбы со спамом.

Мы собираемся отправлять почту с сервера, PTR IP которого не равен одной из MX-записей сервера, а так же в большинстве случаев PTR IP не равен самому нашему домену (не всегда хостеры соглашаются менять PTR). В этом случае вероятность попадания писем в спам повышается. Но есть хороший способ ее понизить: указать правильно запись SPF нашего домена.

SPF-запись — это обыкновенная запись доменной зоны, имеющая тип TXT. Узнать текущее ее значение для домена можно с помощью команды host в Linux:

$ host -t TXT valera.ws
valera.ws TXT record currently not present

В данном примере SPF-запись не задана. Зададим ее. С моего домена почта может отправляться с серверов Gmail и с моего сервера. Для начала узнаем, какой PTR моего сайта (valera.ws):

$ nslookup valera.ws
Server:      194.224.52.4
Address:     194.224.52.4#53

Non-authoritative answer:
Name:     valera.ws
Address:  93.174.6.118

IP-адрес моего сервера 93.174.6.118. Узнаем PTR:

$ nslookup 93.174.6.118
Server:      194.224.52.4
Address:     194.224.52.4#53

Non-authoritative answer:
118.6.174.93.in-addr.arpa name = server.valera.ws.

Видно, что PTR IP, к которому привязан мой домен (IP моего сервера) — server.valera.ws.

v=spf1 a mx ptr include:_spf.google.com ~all

По порядку:

  • v=spf1 — версия SPF (первая);
  • a — разрешение отправлять почту с IP, указанного в A-записи домена (собственно с сервера, на который ваш домен ссылается);
  • mx — разрешение отправлять почту с IP, указанных в MX-записях домена (в нашем случае сервера Gmail);
  • ptr — разрешение отправлять почту с IP, PTR-запись которых содержит ваш домен (т.е. сам домен и поддомены);
  • include:_spf.google.com — подключение разрешений для серверов отправки почту Gmail (совсем не обязательно почта будет слаться с серверов, указанных в MX-записи);
  • ~all — нейтральная реакция на всю остальную почту; здесь можно указать -all, что будет значить, что почта, не попадающая под эти правила, — спам.

Если вы хотите отправлять почту с сервера, не попадающего под все эти правила, его можно указать по IP или домену PTR, например:

v=spf1 a mx ptr ptr:example.com include:_spf.google.com ~all

Запись указывается для вашего домена соответствующим образом, который определяет владелец DNS-сервера. Обычно сервером заведует хостер и предоставляет возможность вносить изменения в DNS-зоны через панель хостинга. Либо сам по запросу в саппорт меняет запись. В зональном файле должна появиться запись вида:

valera.ws.      TXT      v=spf1 a mx ptr include:_spf.google.com ~all

После обновления зоны host выдаст следующее:

$ host -t TXT valera.ws
valera.ws      TXT      «v=spf1 a mx ptr include:_spf.google.com ~all»

PHP mail()

После всей этой настройки функция mail() в PHP начнет слать почту через ваш локальный сервер на законных основаниях для антиспам-ботов. Но косяк будет в том, что в поле отправителя будет фигурировать адрес системного пользователя www-data@localdomain. Нас это не устраивает. Чтобы почта правильно слалась из mail(), необходимо использовать ее дополнительный параметр.

bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )

Именно $additional_parameters нас и интерисует. В него надо передавать реального отправителя:

mail($to, $subject, $message, $additional_headers, $additional_parameters.» -frealsender@valera.ws»);

Указывается отправитель слитно с параметром -f.

Теперь отправленные через mail() письма будут абсолютно адекватны (при условии, что вы указываете все нужные SMTP-заголовки, вроде “FROM:”, “TO:” и т.д.).

А если несколько сайтов с разными IP (настройка Exim для отправки писем с разных IP)?

Мы хотим использовать локальный SMTP-сервер для отправки почты со всех сайтов на сервере. Никаких проблем нет, если настроен Exim правильно (см. выше). Но проблема появляется, если разные сайты работают на разных IP. Мы не хотим в почте «палить» то, что все наши сайты живут на одном сервере. Но Exim по умолчанию шлет всю почту с основного (первого) IP сетевого интерфейса, а этот IP всем получателям в SMTP-заголовках “Received:” письма. Кроме того, там указывается и имя сервера, которые мы в случае с разными сайтами на сервере выбрали нейтральными.

Чтобы не «палить» IP сервера, нужно отсылать письмо на удаленный сервер с IP, равного A-записи домена сайта. Делается это несложно путем изменения конфига Exim. Внесем изменения в настройки транспорта SMTP Exim. Если вы выбрали монолитный конфиг, то нужно отредактировать файл:

# nano /etc/exim4/exim4.conf.template

Находим в файле строку “remote_smtp:” (поиск в nano — F6). Добавляем в конец этого блока:

interface = «${lookup{$sender_address_domain}lsearch{/usr/share/exim4/domain2ip}{$value}}»
helo_data = «$sender_address_domain»

Это значит, что при отправке письма нужно определить домен отправителя почты (для sender@valera.ws это valera.ws) и отправить почту с IP, к которому этот домен привязан. Само собой разумеется, что домен должен быть привязан к серверу, где установлен Exim.

Так же нужно создать файл в любом месте файл привязки доменов к IP (у домена может быть несколько IP, так что просто lookup-ить его не прокатит). Я выбрал для файла место: /usr/share/exim4/domain2ip

# nano /usr/share/exim4/domain2ip

Туда вводим наши домены по шаблону:

valera.ws: 123.123.123.123
vasya.ws: 123.123.123.124

Не забудьте дописать домен в файл в случае появления нового сайта.
Кстати, строку helo_data = «$sender_address_domain» можно добавить в файл даже если у вас один IP на все сайты. Тогда в команде HELLO SMTP-протокола (а, следовательно, и в заголовках писем) будет фигурировать ваш домен.

Идея с указанием интерфейса взята отсюда: http://www.directadmin.com/forum/showthread.php?t=36468

Проверка

Остается проверить, чтобы все ваши настройки работали верно. Для этого просто отправим письмо с локального сервера через консоль.

$ mail -a «From:feedbee@valera.ws» -s Test feedbee@gmail.com — -ffeedbee@valera.ws
Test <Ctrl-D>
Cc:

Проверяем отосланное письмо в ящике получателя:

А вот текст SMTP-протокола:

Delivered-To: feedbee@gmail.com
Received: by 10.236.109.139 with SMTP id s11cs13826yhg;
Wed, 24 Nov 2010 02:18:14 -0800 (PST)
Received: by 10.227.145.134 with SMTP id d6mr9025492wbv.195.1290593893066;
Wed, 24 Nov 2010 02:18:13 -0800 (PST)
Return-Path: feedbee@valera.ws
Received: from valera.ws (server.valera.ws [93.174.6.118])
by mx.google.com with ESMTP id b7si11085685wer.164.2010.11.24.02.18.12;
Wed, 24 Nov 2010 02:18:12 -0800 (PST)
Received-SPF: pass (google.com: domain of feedbee@valera.ws designates 93.174.6.118 as permitted sender) client-ip=93.174.6.118;
Authentication-Results: mx.google.com; spf=pass (google.com: domain of feedbee@valera.ws designates 93.174.6.118 as permitted sender) smtp.mail=feedbee@valera.ws
Received: from root by server.valera.ws with local (Exim 4.69)
(envelope-from <feedbee@valera.ws>)
id 1PLCQW-0006KD-Pc
for feedbee@gmail.com; Wed, 24 Nov 2010 10:18:12 +0000
To: feedbee@gmail.com
Subject: Test
From:feedbee@valera.ws
Message-Id: E1PLCQW-0006KD-Pc@server.valera.ws
Date: Wed, 24 Nov 2010 10:18:12 +0000

Test

P.S. Чтобы отправленная почта не попадала в спам, отправляйте письма только от имени реально существующих на серверах Gmail адресов на ваших доменах. Туда же повалятся уведомления о недоставках.

]]>
https://valera.ws/2010.11.28~exim-mail-localhost/feed/ 2
GeoLite City против CNGeoip https://valera.ws/2008.04.02~cngeoip/ Wed, 02 Apr 2008 10:02:32 +0000 http://valera.ws/2008.04.02~cngeoip/ Читать далее GeoLite City против CNGeoip ]]> Вчера я протестировал базу GeoLite City от Max Ming. Это бесплатная версия базы, почти ничем не отличающаяся от платной версии. После изучения содержимого базы пришел к неутешительным выводам.

В базе немало ошибок в написаниях городов, часто попадаются разные варианты написания (например, Chelyabinsk и Cheliabinsk), вместо городов иногда пишут области, а иногда улицы. Но самая большая проблема, что названия всех городов написаны только в английском/местном варианте латиницей. Для использования на русскоязычных ресурсах такая база практически непригодна. Составить соответствие английских названий русским в автоматическом режиме практически нереальная задача по причинам, описанным выше. А использовать труд операторов для обработки порядка 180 000 локаций в базе могут позволить себе только довольно крупные компании. Ругательство базы GeoLite City можно найти еще на этом форуме.

[Интересно, а какие базы используют Google, Яндекс?]

Других хороших полноценных баз городов (не стран) по IP я не нашел, ни платных, ни бесплатных, кроме одной — это CNGeoip — модуль определения города и страны по IP-адресу. Сразу скажу, что база платная. Стоимость базы на один сайт составляет 99 WMZ (при оплате по WebMoney, на 02.04.2008).

Теперь о возможностях. Я тестировал базу на сайте производителя. Для этого есть демо-версия. Все тестовые запросы дали результат не хуже, чем GeoLite City. Скорость работы нареканий не вызывает.

Но главное преимущество CNGeoip перед GeoLite City — все названия городов и стран доступны и на английском, и на русском языках! То есть применять базу легко можно на сервисах, ориентированных на Рунет.

Разработчики CNGeoip в своем блоге пишут:

«Задача определения города пользователя по IP адресу возникает не так редко как кажется, это и анализ статистики, таргетинг баннеров, автоматическая настройка профайлов пользователей и т.д.

Базу географии найти не то чтобы сложно — накладно.

Реальное качество есть у базы от MaxMinda (это та которую все юзают, но не платят (GeoIPCity :) ). Цена этой базы внушает, за тысячу баксов в год переваливает.

Но вот Россия и СНГ покрыты там с погрешностями, порой смешными. Типа город — ул. Ленина и т.д. Ну в общем все это и так знают.

Давно стали думать чтобы сделать свое решение. Поняли почему берут деньги Максмайндовцы. :)»

На самом деле качество базы CNGeoip по территории бывшего СССР намного превышает качество GeoLite City. [По моим скромным тестам. Если у вас есть контраргументы, добро пожаловать в комменты!]

Тестирование на практике. Во-первых, как я уже писал, протестировать базу всегда можно на демо-странице, там слева пишется ваш определившийся IP и местоположение. Есть и форма для ввода любого IP. Но мне этого конечно было мало. Хотелось бы протестировать базу в реальных условиях. Однако выложенной базы в Сети в открытом виде я не нашел. Пока раздумываю о покупке.

Вывод. Если вы собираетесь создавать коммерческий сервис в Рунете на русском языке, который требует определения страны и города по IP (например, автоподстановка значений в соответствующие поля при регистрации, или вывод информера погоды по городам), однозначно надо смотреть в сторону CNGeoip. Качественных альтернатив нет. 200 долларов за базу плюс год обновлений — копеечная цена.

]]>
Использование базы IP по городам от MaxMind https://valera.ws/2008.04.01~ip-to-city/ Tue, 01 Apr 2008 18:02:04 +0000 http://valera.ws/2008.04.01~ip-to-city/ Читать далее Использование базы IP по городам от MaxMind ]]> Используем базу IP по городам GeoLite City от MaxMind. Зона покрытия этой базы описана здесь. Лицензия проста как кактус: пользуйтесь на здоровье, даже в коммерческих целях, но все рекламные материалы и документация к продукту должны содержать фразу: «This product includes GeoLite data created by MaxMind, available from http://maxmind.com/». Ну и как обычно — никаких гарантий. От платной версии free-базу отличает чуть-чуть худшее покрытие. Но нам это не мешает.

Данная библиотека существует в виде PECL-расширения, которое не идет в стандартном наборе с PHP. Если модуль у вас на сервере установлен, пользуйтесь им, если нет — используйте библиотеку отдельно. Кстати, API базы есть для разных языков.

В репозитории PEAR находится библиотека для доступа к файлу базы. А сам файл базы необходимо скачать с сервера и ежемесячно обновлять. Скачали базу, скачали API. Распаковали базу (файл GeoLiteCity.dat и каталог GeoIP). Каталог GeoIP нужно положить в каталог Net (последний создать), или изменить строку 663 строку в файле GeoIP.php.

База готова к эксплуатации. Посмотрите, как работает пример отпределения IP посетителя сайта по базе. Вот код примера (index.php):

<?php 
    print "Search Started<br \>\r\n";    

    require('GeoIP.php'); 
    $geoip = Net_GeoIP::getInstance('GeoLiteCity.dat', Net_GeoIP::STANDARD); 
    $data = $geoip->lookupLocation( 
        isset($_SERVER['HTTP_REMOTE_ADDR']) ? $_SERVER['HTTP_REMOTE_ADDR'] : $_SERVER['REMOTE_ADDR'] //nginx? 
    );   

    if ( is_null($data) ) 
        print "Region wasn't found!<br \>\r\n"; 
    else 
        print "Found! You are from {$data->city}, {$data->countryName}<br \>\r\n";   

    print "© 2008, <a href=\"https://valera.ws/\">feedbee</a><br />\r\n";   

    print "This product includes GeoLite data created by MaxMind, available from <a href=\"http://www.maxmind.com/\">http://www.maxmind.com/</a>.";   

?>

Обратите внимание, что если не найден IP в базе, будет возвращен NULL. Но вомзможен случай, когда не будет найден только город, а страна найдется. В этом случае $data->city вернет NULL.

]]>