Защита сайта WordPress с помощью списка белых адресов, дополнительной аутентификации и ограничения типов разрешенных запросов HTTP

WordPress — самый популярный движок для CMS, который использует более 30% всех сайтов мира, что делает его самым популярным инструментом для разработки как небольших, так и больших сайтов. Основа популярности — поддержка огромного количества расширений и тем, которые позволяют разработчикам собирать сайт из как из конструктора с минимальным набором необходимых изменений. При этом вполне рабочий сайт можно получить в течение одного дня.

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

В этой статье мы рассмотрим подход, который позволит вам обезопасить свой сайт на WordPress от злоумышленников, даже если он использует ненадежные компоненты.

О том, как настроить минималистичный сервер с Nginx, WordPress, MariaDB и поддержкой сертификатов Let’s Encrypt читайте в нашем руководстве.

Решение основывается на двух подходах:

  • белый список ip-адресов, которые имеют доступ к административной зоне сайта (или закрытие административной зоны дополнительным паролем);
  • ограничение типов разрешенных HTTP-запросов к сайту из небезопасных источников.

Оба подхода будут применяться одновременно, что позволит достичь оптимального эффекта.

Белый список. Этот метод позволяет ограничить ip-адреса, с которых возможен вход в административную зону сайта.

Работает это следующим образом: если ip-адрес пользователя не находится в белом списке, web-сервер блокирует доступ к административным скриптам WordPress, препятствуя вредоносному воздействию.

Метод является удобным, если вы работаете с постоянного ip или нескольких мест, ip-адреса которых вам знакомы. Если же вы работаете из интернет-кафе, много путешествуете, данный способ вам не подойдет и стоит рассмотреть ограничение доступа с помощью внешней защиты добавлением базовой HTTP-авторизации.

Базовая HTTP-авторизация. Данный метод требует, чтобы еще до получения доступа к форме входа к WordPress, пользователь ввел дополнительные имя и пароль, которые задаются на уровне web-сервера.

Работает это так: пока пользователь не подтвердил свою личность перед web-сервером, он не может получить доступ к административным скриптам WordPress, а значит не может совершить вредоносное воздействие.

Ограничение разрешенных типов HTTP-запросов. Этот подход успешно работает для большинства сайтов WordPress, которые публикуют информацию, но не позволяют пользователям совершать сложные взаимодействия с сайтом (если, например, сайт является интернет-магазином).

Работает этот способ так: для получения контента страниц используется HTTP-метод GET, в то время как для загрузки вредоносных элементов используются методы POST, PUT, DELETE. Обычные пользователи, которые просто получают доступ к сайту будут успешно просматривать страницы, в то время как злоумышленники, которые пытаются загрузить на сайт вредоносное программное обеспечение получат страницу ошибки.

Защита с помощью белого списка IP и ограничения разрешенных типов HTTP-запросов

В рамках статьи предполагается, что вы имеете доступ к конфигурации Nginx, а сайт WordPress работает непосредственно под управлением Nginx или как приложение Apache2, который находится за Nginx.

Для внедрения решения достаточно добавить фрагмент следующего вида в секцию location вашего сайта:

location / {
        # ...
        # ...
        limit_except GET {
                allow ip1;
                allow ip2;
                deny  all;
  	}
        # ...
}

Где в списке вы просто задаете разрешенные ip-адреса. Если вам удобнее использовать отдельный файл с записями, то содержимое секции можно вынести в файл, а на ее месте использовать include:

location / {
        # ...
        # ...
        limit_except GET {
                include /etc/nginx/whitelist.conf;
                deny  all;
  	}
        # ...
}

После внесения правок необходимо выполнить проверку конфигурации Nginx с помощью команды:

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Если сообщения соответствуют примеру, значит все нормально, и вы можете перезапустить Nginx для применения изменений:

# Debian, Ubuntu
$ sudo service nginx restart

# CentOS
$ sudo systemctl restart nginx

Теперь, все запросы, отличные от GET, разрешены только для ip-адресов, которые находятся в белом списке.

Для усиления конфигурации вы можете вообще запретить доступ к пути /wp-admin ip-адресам не из белого списка. Для этого вы можете использовать дополнительную секцию location, размещенную перед секцией location /:

location /wp-admin {
        # ...
        # ...
        allow ip1;
        allow ip2;
        deny all;
        # ...
}

location / {
        # ...
        # ...
        limit_except GET {
    		deny  all;
  	}
        # ...
}

Не забудьте добавить другие необходимые директивы для доступа к WordPress в секцию location /wp-admin.

Защита с помощью базовой авторизации HTTP и ограничения разрешенных типов HTTP-запросов

За основу решения возьмем фрагмент конфигурации из предыдущего метода, немного его изменив:

location /wp-admin {
        # ...
        # здесь мы добавили проверку базовой авторизации HTTP
        #
        auth_basic "Restricted"; #For Basic Auth
        auth_basic_user_file /etc/nginx/.htpasswd; #For Basic Auth

}

location / {
        # ...
        # ...
        limit_except GET {
    		deny  all;
  	}
        # ...
}

Для секции location /, мы просто запрещаем все запросы, кроме GET. Для секции location /wp-admin, добавим запрос имени и пароля HTTP.

Теперь необходимо сгенерировать файл с именами пользователей и паролями /etc/nginx/.htpasswd:

# сгенерируйте имя и пароль
sudo sh -c "echo -n 'admin:' >> /etc/nginx/.htpasswd"
sudo sh -c "openssl passwd -apr1 >> /etc/nginx/.htpasswd"

# установите права
sudo chmod 644 /etc/nginx/.htpasswd

Если вам нужные дополнительные пользователи, кроме admin, добавляйте их таким же образом.

Проверим конфигурацию Nginx и перезапустим сервис:

# Debian, Ubuntu
$ sudo nginx -t && service nginx restart

# Centos
$ sudo nginx -t && systemctl restart nginx

Теперь, при попытке входа в административную зону WordPress, Nginx запросит у вас дополнительные имя пользователя и пароль, которые вы задали ранее. После успешного подтверждения личности, вы сможете ввести имя пользователя и пароль WordPress.

Дальнейшие рекомендации

Для поддержания своего сайта в рабочем и безопасном виде, вы должны следовать следующим рекомендациям:

  • регулярно проверяйте обновления WordPress и расширений;
  • не устанавливайте расширения, которые не имеют самого высокого рейтинга и большого количества активных скачиваний;
  • настройте инструмент анализа файлов access_log для Nginx и ищите в них подозрительные URL, которые используют злоумышленники, блокируйте их.