Защита WordPress (Часть 1). Несанкционированный доступ
8
“Сайты банков ломают ради денег, Пентагон — ради шпионажа, а мой проект никому не нужен”, — к сожалению, именно так полагает большинство владельцев личных блогов, интернет-визиток, виртуальных представительств небольших компаний. О том, как защитить сайт, задумываются лишь единицы, а зря. В современных реалиях абсолютно любая площадка, независимо от типа или популярности, представляет интерес в глазах хакеров. Кому и для чего может понадобиться ваш ресурс? Давайте разбираться:
1. Шалости скрипткиддис. Жаргонизм обозначает начинающих хакеров, которые делают первые шаги на “темной стороне”. Обзаведясь несколькими инструментами, или написав пару собственных программ, они горят желанием проверить их работоспособность на первой попавшейся жертве, и выбирают, как правило, наиболее легкие (слабо защищённые и не обновленные CMS) цели.
2. Черное SEO. Услуги нечистых на руку оптимизаторов все еще в ходу — размещение скрытых ссылок в коде проектов, имеющих тИЦ более 10, по прежнему практикуется. И, в первую очередь, под удар попадают ресурсы на движках с открытым исходным кодом (Joomla, Drupal, OpenCart и так далее).
3. Построение бот-нета. Защита WordPress с помощью htaccess и плагинов актуальна еще и потому, что абсолютно любой ресурс может быть использован для создания зомби-сети, используемой в ходе DDoS-атак, рассылки спама и т.д.
4. Сопутствующий ущерб. Наконец, атаковать могут не вас — основной целью будет являться хостинг, а сайт послужит лишь в качестве одной большой уязвимости IT-инфраструктуры провайдера. Разумеется, его судьба будет безразлична хакерам.
Последствия взлома могут быть самые неприятные: утрата контента, или ресурса в целом, пессимизация в выдаче поисковых систем, потеря аудитории из-за надписи “Сайт может угрожать безопасности компьютера или мобильного устройства”, и даже риск стать фигурантом уголовного дела в том случае, если на базе вашего веб-ресурса были совершены противоправные действия.
А значит, можно с уверенностью утверждать — вопросы безопасности затрагивают абсолютно каждого веб-мастера. И если ими пренебречь, все усилия по поисковому продвижению (а это — деньги и драгоценное время) способны в одночасье пойти прахом. Проблема весьма актуальна, поэтому я решил начать серию статей, посвященных сетевым угрозам и методам борьбы с ними. В трех выпусках будет рассмотрена популярная CMS система — Вордпресс.
Методы защиты сайта на WordPress
Один из наиболее примитивных способов взлома — брутфорс. Дословно термин переводится как “грубая сила”, и означает получение пары логин/пароль методом полного перебора возможных вариантов. Зачастую брутфорсеры стараются облегчить свою жизнь, воспользовавшись погрешностями в настройках движка и сервера — это помогает им, например, узнать имя учетной записи, что существенно сокращает количество комбинаций. Именно об устранении этих уязвимостей, а также о методах борьбы с попытками несанкционированного доступа и пойдет речь.
1. Используйте уникальный логин администратора
По умолчанию система предлагает создать пользователя с именем admin. Однако в целях защиты сайта на WordPress лучше всего использовать логин, состоящий из набора случайных букв и цифр. На действующем ресурсе имя администрататора можно без особых проблем сменить, используя один из двух способов:
• Через админку. Зайдите в раздел “Пользователи”, нажмите кнопку “Добавить нового” и создайте учетную запись. В поле “Роль” выберите “Администратор” и подтвердите операцию. Затем перелогиньтесь от имени только что созданной учетки, вернитесь в раздел “Пользователи”, выберите “admin” и нажмите “Удалить”. В открывшемся окне выставьте радиокнопку в позицию “Связать все содержимое” и выберите нового администратора из выпадающего списка, а затем нажмите на “Подтвердить удаление”.
• Используя phpMyAdmin. Гораздо проще осуществить эту же процедуру через панель управления базами данных. Выберите необходимую БД, найдите таблицу wp_users, отыщите строчку “admin” (ID=1), нажмите на “Изменить” и впишите желаемое имя.
2. Заведите специальный аккаунт для публикаций
Если “не светить” администратора, это обеспечит дополнительную защиту. Создайте отдельную учетную запись для размещения статей и привяжите к ней все опубликованные ранее материалы способом, описанным в пункте 1. Далее добавляйте информацию и общайтесь с читателями только с нового аккаунта.
3. Поставьте сложный пароль
Соблюдайте общепринятые рекомендации: длина пароля должна составлять не менее 10 символов, он должен быть уникальным и состоять из случайной последовательности прописных и заглавных букв, цифр и специальных знаков.
Ни в коем случае нельзя:
• составлять пароль из значимых фраз
• использовать любые фактические данные (дата рождения, девичья фамилия, номер банковского счета, текущий год…)
Это исключит риск подбора кодовой фразы по словарю, а также существенно увеличит время, требующееся для брутфорса. Так, взлом последовательности из 10-ти символов, состоящей только из строчных букв и цифр (hki458p1fa), займет 10 дней машинного времени для одного ПК, но стоит добавить заглавные буквы и дополнительные знаки (Nv6$3PZ~w1), как этот период увеличится до 526 лет, гарантируя практически абсолютную защиту WordPress. Придумывать и запоминать подобные пароли достаточно сложно, особенно если вы курируете несколько проектов. Поэтому, для их генерации и хранения лучше использовать специальные менеджеры, например — распространяемый бесплатно KeePassX, либо обычный тестовый документ (лучше, если он будет запакован в архив с паролем).
4. Смените пароль для базы данных
Перечисленные выше правила справедливы и для безопасности кода доступа к MySQL. Ведь именно там содержится весь контент, а также хэш секретной фразы админа. Если вы уже используете слабый пароль, стоит озаботиться тем, чтобы его поменять. Делается это следующим образом:
1. Зайдите в панель управления phpMyAdmin
2. Откройте вкладку “Пользователи” и выберите владельца БД
3. Нажмите на “Редактирование привилегий”
4. Найдите графу “Изменить пароль” и впишите новую секретную последовательность в соответствующие поля
5. Сохраните изменения, нажав на “Ок”
Теперь осталось отредактировать wp-config.php, иначе Вордпресс не сможет подключиться к базе данных. Найдите строчку define(‘DB_PASSWORD’, ‘password’); и впишите новый пароль вместо слова password. Обратите внимание: поскольку знак (‘) применяется для обособления SQL-команд, его не следует использовать в составе секретной фразы.
5. Регулярно обновляйте пароли
Их стоит менять по крайней мере раз в полгода. Внеочередная же смена кодовых фраз должна ОБЯЗАТЕЛЬНО осуществляться после:
• передачи данных для аутентификации третьим лицам (программистам, системным администраторам, оптимизаторам, и другим специалистам, даже если они работают в штате хостинговой компании)
• входа на веб-ресурс с чужого компьютера (в гостях, в интернет-кафе)
• авторизации с оборудования, которое могло быть скомпрометировано (машина, зараженная вирусом)
6. Не забудьте поменять секретные ключи для куки
Они располагаются в файле wp-config.php. Всего их 8:
define('AUTH_KEY', 'unique key'); define('SECURE_AUTH_KEY', 'unique key'); define('LOGGED_IN_KEY', 'unique key'); define('NONCE_KEY', 'unique key'); define('AUTH_SALT', 'unique key'); define('SECURE_AUTH_SALT', 'unique key'); define('LOGGED_IN_SALT', 'unique key'); define('NONCE_SALT', 'unique key'); |
Как нетрудно догадаться по названиям переменных, ключи отвечают за шифрование файлов куки (известный жаргнозим: cookie — печенье, salt — соль, кормим хакеров соленым печеньем), которые используются для того, чтобы сайт “запомнил” ваш компьютер после авторизации. Суть в том, что даже если злоумышленник получит в свое распоряжение хэш админского пароля, он не сможет сгенерировать куки, необходимые для доступа к сайту без перечисленных секретных фраз.
В целях повышения безопасности, последовательности символов по умолчанию необходимо заменить на уникальные сразу после развертывания CMS. Для удобства разработчики создали веб-генератор, расположенный по адресу www.api.wordpress.org/secret-key/1.1/salt/ — при заходе вам покажутся ключи, а если обновить страницу, то комбинации актуализируются.
7. Двойная авторизация для админки
Htaccess позволяет дополнительно защитить сайт Вордпресс, путем добавления аутентификации на уровне сервера. Код будет выглядеть следующим образом:
# Выбираем файл скрипта авторизации: <Files wp-login.php> # Задаем базовый тип аутентификации - это означает, что при попытке # обращения к указанному каталогу или файлу будет запрошен пароль: AuthType basic # Вписываем текст, который будет отображаться в заголовке формы: AuthName 'Identify yourself' # Указываем путь к файлу, содержащему кодовую фразу: AuthUserFile '/home/tekseo.su/.htpasswd' # Указываем, что при обращении к файлу wp-login.php необходимо ввести пароль: Require valid-user </Files> # Запрещаем доступ к файлу .htpasswd третьим лицам: <Files .htpasswd> order allow,deny deny from all </Files> |
Заодно неплохо бы позаботиться о безопасности самого htaccess. Строго говоря, такая директива должна быть прописана в основных настройках хостинга, но учитывая безалаберность некоторых провайдеров, стоит перестраховаться:
<Files .htaccess> order allow,deny deny from all </Files> |
Теперь необходимо создать .htpasswd. Он должен содержать всего одну строчку:
login:password |
Вместо “login” подставляем желаемое имя. Осталось сгенерировать сам пароль, а также зашифровать его, ведь хранить подобные данные в открытом виде — непозволительная роскошь. Для этого существует масса сервисов, но лучше написать нужный скрипт самостоятельно. Делается это следующим образом:
1) Создайте в блокноте файл с расширением .php, например, crypt.php
2) Внесите туда код, подставив вместо слова “Password” придуманный вами пароль:
<?php $pass = "Password"; $pathz = substr(md5(uniqid($pass)), 0, 3) . "-56"; $pass=crypt($pass,$pathz); echo $pass; ?> |
3) Сохраните файл и загрузите в корневую директорию
4) Перейдите по ссылке имя_сайта.ru/crypt.php — на экране появится хэш пароля
5) Сохраните это значение в файле .htpasswd, и загрузите его в корневой каталог, а crypt.php удалите
Последний штрих — запрет просмотра содержимого директории веб-ресурса. Достаточно добавить в htaccess единственную строчку:
Options All -Indexes |
Это делается для того, чтобы хакеры не могли узнать, какие именно файлы лежат в каталогах проекта. На многих хостингах данная директива уже внесена в настройки сервера, но если этот момент упущен из виду, стоит прописать ее самостоятельно.
8. Установите капчу
Использование капчи позволит отсечь если не всех, то, по крайней мере, большую часть ботов-брутфорсеров, а заодно избавиться от спама в комментариях. Каталог плагинов для защиты сайта на WordPress предлагает множество вариантов. Помимо подключения фирменного решения от Google, большой интерес представляет Captcha by BestWebSoft смешанного (графика и текст) типа, в основе которой лежат математические действия. Независимость от сервисов, наглядность и приемлемый уровень сложности делает модуль одним из лучших.
Настройка не представляет особых проблем. Вкладка “Базовые” позволяет выбрать, где следует отображать капчу, а также указать заголовок и символ для пометки полей, обязательных к заполнению.
Ниже можно настроить уровень сложности. Рекомендуется проставить галочки в каждом чекбоксе — это гарантирует максимальную защиту.
Раздел “Расширенные” обеспечивает возможность создания собственных сообщений об ошибках, а также активации дополнительных пакетов изображений, чтобы еще больше усложнить жизнь ботам.
Еще одна полезная возможность — встроенный белый список IP-адресов, для которых капча отображаться не будет.
Результатом установки и активации плагина станет появление формы на странице авторизации:
9. Измените адрес админки
Рассказывая о том, как защитить сайт на WordPress, стоит упомянуть более радикальный, но и более сложный способ — изменение URL страницы авторизации на уровне скриптов. Процедура осуществляется в несколько этапов:
1. Переименуйте файл wp-login.php. Используйте случайную последовательность строчных латинских букв, цифры и тире. Например: abc-123.php
2. В получившемся файле найдите все упоминания wp-login.php и замените их на новое название.
3. Для корректной работы сайта замену необходимо проделать также в: wp-activate.php, general-template.php, post-template.php, functions.php, class-wp-customize-manager.php, general-template.php, link-template.php, admin-bar.php, post.php, pluggable.php, ms-functions.php, canonical.php, functions.wp-scripts.php, wp-signup.php, my-sites.php, schema.php, ru_RU.po
После этих манипуляций админка будет располагаться по адресу tekseo.su/abc-123.php. Доступ к новому файлу следует ограничить и защитить паролем так, как указано выше. Кроме того, можно ввести в заблуждение потенциальных хакеров, создав подложный файл wp-login.php, и также установив для него пароль.
Еще более простой вариант — использование дополнения «Rename wp-login.php». После установки плагина для защиты сайта в меню “Настройки” — > “Постоянные ссылки” появится новое поле:
Здесь ссылку на админку можно изменить по своему вкусу, после чего не забудьте нажать на кнопку “Сохранить изменения”
10. Укажите IP админа
Дополнительную безопасность можно обеспечить в том случае, если у вас имеется статический IP-адрес. Запретив доступ к wp-login.php с любого другого компьютера, кроме собственного, вы значительно усложните жизнь взломщикам:
<Files wp-login.php> order deny,allow deny from all allow from 127.0.0.1, 127.0.02 #Через запятую указываем ваши IP-адреса </Files> |
11. Отключите ошибки авторизации
При переборе паролей злоумышленнику очень пригодится информация о том, что введенные данные оказались неверны. Такие сообщения выводятся при каждой неудачной попытке входа, причем WordPress также сообщает, что именно было введено неверно, логин или пароль. Чтобы от них избавиться, достаточно добавить в functions.php всего одну строчку:
add_filter('login_errors',create_function('$a', "return null;")); |
Для этого выберите в админке “Внешний вид” — > “Редактор” — > “Функции темы”. Прописывать код необходимо после открывающего тега <?php. По завершении изменений не забудьте нажать “Обновить файл”.
12. Используйте защищенное соединение.
Для шифрования трафика между компьютером пользователя и веб-сервером существует протокол https, использование которого исключает возможность перехвата важных данных, в нашем случае — идентификационных. Чтобы его активировать, сперва требуется приобрести SSL-сертификат, выполняющий сразу две функции: удостоверение подлинности веб-ресурса и шифрование передаваемой информации. Получить его можно в специализированных центрах, или у ряда регистраторов доменных имен. Для некоммерческих целей вполне достаточно обзавестись бесплатным сертификатом начального уровня (такие предлагает компания www.startssl.com). Что же касается процесса установки, как правило он подробно описан в справочном разделе хостера.
Заполучив SSL-сертифкат, необходимо настроить переадресацию административной части веб-ресурса на защищенное соединение. В случае Вордпресс это делается с помощью следующей конструкции:
<IfModule mod_rewrite.c> Options +FollowSymlinks RewriteEngine On RewriteCond %{HTTPS} =off RewriteCond %{REQUEST_URI} =/wp-login.php RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] </IfModule> |
Также форсировать использование сертификатов SSL можно на уровне движка. Для этого откройте файл wp-config.php и добавьте после <?php строчку:
define('FORCE_SSL_ADMIN', true); |
Помимо этого, можно установить глобальную переадресацию с http на https. Для новых сайтов такой подход является оптимальным, учитывая, что Google поощряет защищенные проекты, отдавая им некоторый приоритет в поисковой выдаче:
<IfModule mod_rewrite.c> Options +FollowSymlinks RewriteEngine on RewriteCond %{HTTPS} =off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] </IfModule> |
13. Блокируйте злоумышленников
При обнаружении подозрительной активности с определенных IP стоит заблокировать для них доступ к сайту. Делается это по аналогии с предыдущим способом. Разница в том, что директивы прописываются для проекта в целом, а перечисляем мы адреса тех, кого хотим забанить:
Order Allow,Deny Allow from all Deny from 127.0.0.1, 127.0.02 #Указываем нежелательные IP |
Метод надежен, однако неэффективен. Во-первых, каким-то образом необходимо фиксировать запросы брутфорсеров и отделять их от добропорядочных посетителей. Во-вторых, при массированной атаке вы попросту не сможете отслеживать и вбивать IP хакеров и ботов вручную. Данный способ хорош только если администратор располагает достоверным “черным списком” адресов.
В остальных случаях можно воспользоваться плагином для защиты сайта на WordPress под названием WP Cerber. Данное решение является абсолютно бесплатным, при этом предлагая весьма внушительный набор инструментов, призванных предотвратить взлом CMS. Установить его можно непосредственно из админки.
По умолчанию предлагаются достаточно толковые параметры. Впрочем, число попыток стоит увеличить до 5, во избежание недоразумений.
Галочку напротив “Блокировать IP при любом запросе wp-login.php” стоит ставить в том случае, если вы поменяете адрес админки способом, описанным ранее.
Для этих целей можно использовать и собственный инструмент WP Cerber:
Режим плагина для защиты сайта “Цитадель” также не нуждается в дополнительной настройке. Он предназначен для “консервации” проекта при массированной брутфорс-атаке. Галочку напротив “Записывать попытки входа в файл” лучше снять — это поможет исключить дополнительную нагрузку на сервер.
Вкладка “Списки доступа” служит для создания “черного” и “белого” списка IP (если у вас есть статический адрес, обязательно внесите его в перечень доверенных), а раздел “Инструменты” позволяет осуществлять импорт и экспорт внесенных ранее настроек. Впрочем, эти возможности не нуждаются в отдельном рассмотрении.
14. Переместите конфигурационный файл
Как мы выяснили выше, в wp-config.php хранятся такие критически важные данные, как логин и пароль для доступа к MySQL, а также ключи API. Следующий шаг, вроде бы, очевиден — защита WordPress через htaccess с помощью ограничения доступа к файлу:
<Files wp-config.php> Order allow,deny Deny from all </Files> |
Однако есть и более надежный метод. У WordPress имеется весьма интересная особенность, о которой мало кто знает. Движок допускает размещение конфигурационного файла на один уровень выше корневой директории. То есть, если CMS находится в папке /tekseo.su/public_html, wp-config.php можно перенести в каталог tekseo.su. В этом случае файл станет вообще недоступен через Интернет, при этом, содержащаяся в нем информация будет все так же считываться CMS.
15. Добавьте проверку REFERER
Метод, хорошо зарекомендовавший себя при защите WordPress от спама, поможет и в случае противостояния брутфорсерам. Ведь перебор паролей — отнюдь не ручная работа: для этих целей используются специализированные программы. А значит, включив проверку заголовков во входящих запросах, можно отсечь “пришедших из ниоткуда” ботов с пустым HTTP REFERER:
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_METHOD} POST RewriteCond %{REQUEST_URI} .(wp-comments-post|wp-login)\.php* RewriteCond %{HTTP_REFERER} !.*tekseo.su.* [OR] RewriteCond %{HTTP_USER_AGENT} ^$ RewriteRule (.*) http://%{REMOTE_ADDR}/$1 [R=301,L] </ifModule> |
16. Защитите XML-RPC
Начиная с версии 3.5 из Вордпресс пропала возможность отключения протокола вызова удаленных процедур XML-RPC. В основном он нужен для взаимодействия с мобильными приложениями, однако подобный функционал требуется далеко не каждому. При этом, xmlrpc.php активно используется для проведения DDoS-атак, являясь ахиллесовой пятой всего проекта.
Кроме того, хакеры додумались использовать XML-RPC для брутфорса. Использование метода wp.getUsersBlogs позволяет осуществлять перебор учетных данных гораздо быстрее, нежели через форму админки. Так как многие вызовы XML-RPC требуют авторизации, запрос вида:
<methodCall> <methodName>wp.getUsersBlogs</methodName> <params><param><value><string>admin</string></value></param> <param><value><string>12345</string></value></param></params> </methodCall> |
приведет к тому, что движок сообщит, является ли переданная комбинация верной. Чтобы избавиться от этой напасти, необходимо полностью отключить протокол. Сделать это можно несколькими способами:
1) Заблокировав доступ к файлу xmlrpc.php через htaccess
<Files xmlrpc.php> Satisfy any Order allow,deny Deny from all </Files> |
2) Отредактировав wp-config.php — после строки
require_once(ABSPATH . 'wp-settings.php'); |
необходимо прописать
add_filter('xmlrpc_enabled', '__return_false'); |
3) Отключив уведомления через functions.php активного шаблона (код вставлять после <?php):
function remove_x_pingback($headers) { unset($headers['X-Pingback']); return $headers; } add_filter('wp_headers', 'remove_x_pingback'); |
4) Используя плагин Control XML-RPC publishing, возвращающий в “Настройки” -> “Написание” соответствующую опцию:
Обратите внимание: дополнение отключает протокол сразу после активации, а в настройках вы можете включить его, проставив галочку в соответствующий чекбокс.
17. Отслеживайте брутфорс-атаки
Напоследок стоит упомянуть об интересном плагине для логирования попыток взлома — Authentication and xmlrpc log writer. Хотя тот же WP Cerber имеет встроенные средства мониторинга, данный модуль будет все равно полезен, особенно тем, кому нужны возможности описанного выше протокола. AX LogWriter умеет отслеживать брутфорс через xmlrpc.php, благодаря чему можно оценить степень угрозы и целесообразности полного отказа от использования его возможностей. Наконец, тем, кто вовсе не занимался безопасностью своего проекта, плагин для защиты сайта откроет глаза на важность перечисленных мероприятий.
Использование AX LogWriter не представляет сложностей. После установки в меню админки появится соответствующий раздел, где можно внести все необходимые изменения:
В поле “Error Type” выберите способ сохранения. Поддерживается запись в системный лог, лог сервера Апач, а также возможность создания кастомного файла. В последнем случае для него можно также настроить имя (Custom Error Log Name) и директорию (Custom Error Log Path). Это открывает широкие возможности для системного администратора — например, решение можно использовать вместе с fail2ban. Также не забудьте выбрать подходящий часовой пояс в графе Timezone.
Кастомный лог можно просматривать непосредственно из админки на странице Custom Log Viewer:
Подытожим:
Перечисленные методы помогут существенно повысить безопасность вашего ресурса и уберечь его от ботов-брутфорсеров, сетевых хулиганов и практикующихся скрипткиддис. Однако все, что описано выше — лишь верхушка айсберга. В арсенале злоумышленников есть и куда более изощренные методы. И уже в следующей статье мы поговорим о том, как защититься от настоящих хакеров, использующих различные уязвимости движка и серверного программного обеспечения. Как и в данном материале, помимо общих “правил гигиены” будут рассмотрены ключевые настройки CMS, способы модификации кода, а также наиболее актуальные плагины.
Tweet |
Но если злоумышленник нацелен на взлом именно вашего сайта или вы хотите максимально обезопаситься в этом направлении, то на вооружение можно взять несколько дополнительных метода защиты автономного блога на базе WordPress.
Я шизею с разрабов — зачем отключать то, что может понадобиться?! Я думал, XML-RPC вообще убрали из кода, а оно вон как. Спасибо, что просветили! С Джумлой была та же песня, тупо вырезали несколько настроек SEF, теперь или плагин ставь, или ручками код правь, запарился в свое время…
А я хохму вспомнил, как у Яндекса метрики утекли в сеть и попали в выдачу Гугла 😀 Ну там типа было так: нужно вбить имя сайта + статистика или метрика, уже не помню. Правда смотреть можно было только проиндексированные странички, так просто по аккаунту не погуляешь. Вот. А вы говорите контроль доступа. Тут все ваше и без вашего участия сольют.
Мне вот интересно, почему никто не прикрутил аутентификацию по ключам? И удобно, и никто ничего не ломал бы.
Потому, что ты потеряешь флешку с ключами и с горя снесешь свой блог? 😉
Мы с вами на брудершафт не пили вроде
Ой, простите великодушно, не признал, ваше сиятельство! Да ладно, расслабься, я в сети со всеми на “ты”, мне норм since 2000. А по теме: ок, у тебя будет ключ, может быть ты его даже не потеряешь. Но. Ты же не будешь предлагать своим юзерам переходить на ассиметричное шифрование, так ведь? Для них это слишком сложно. Значит форма логина останется, в нее будут ломиться боты и захламлять логи, иногда это хуже ддоса. Выходит, придется ставить защиту (методика — другой вопрос). А если у тебя есть защищенная авторизация, значит ты и сам сможешь спокойно юзать логин-пароль. На сайте большего не нужно.
Все хорошо, но самое действенное, имхо — скрытые поля, тут и посетителям не придется париться с капчей, и боты не пройдут, и плагины есть, и самому дописать можно, мануалов куча по этой теме.