Зеркала сайта: исследование с точки зрения пентестера и настройка веб-мастером

Один сайт на нескольких IP (серверах)

На тему этой статьи меня подтолкнула практическая ситуация: из-за «спора хозяйствующих субъектов» у одного из моих хостеров оказался отключённым ЦОД (оборудование для обеспечения работы виртуальных черверов (VPS) и, как следствие, сайтов). В результате все сайты этого хостера (в том числе мой SuIP.biz) оказались офлайн.

Для веб-мастера и пользователей недоступность сайтов это всегда неприятно. Но такое случается из-за отключения электричества у хостера, из-за DDoS атак, из-за проблем с ПО или с оборудованием. Размышления, как можно предотвратить такую ситуацию в будущем, привели меня к довольно распространённому решению — создание зеркал сайта на нескольких серверах.

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

Примеры вопросов:

1. Для работы целевого сайта используется несколько серверов или один сервер с несколькими IP адресами? (когда есть уверенность, что сервер не подведёт, но нужно гарантировать Интернет-подключение, даже если у одного из провайдеров Интернет-услуг возникнут проблемы)

2. Если используется несколько серверов, на них установлено идентичное программное обеспечение, или разное? (синхронизация данных и обновление ПО требует затрат времени и усилий, поэтому есть шанс обнаружить сервер с более старым или просто другим программным обеспечением. Ещё один момент, если серверов несколько, то искать скрытые файлы (например, забытые резервные копии файлов и баз данных), нужно на каждом из них)

3. Если используется несколько серверов, к какому именно серверу делается запрос с компьютера атакующего?

4. Как выбрать сервер, к которому будут отправляться запросы?

Как увеличить надёжность сайтов с помощью DNS записей

На самом деле, схема довольно проста:

1. Сайт (онлайн сервис) с одинаковым содержимым (одинаковым контентом или программа для онлайн сервиса) настраивается на двух или более серверах у разных хостеров. Если имеется цель балансировка нагрузки, то нужно выбрать сервера в разных странах.

2. Веб-сервер настраивается на обработку запросов для одного и того же хоста

3. Необходимо скопировать или получить новые SSL сертификаты на каждый сервер

4. В DNS записях добавляются A и AAAA записи с IP адресами всех серверов

5. Если имеются сомнения в надёжности NS серверов домена, то для этого домена к имеющимся добавляются сторонние записи об NS серверах.

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

Ниже я покажу пример настройки, а пока давайте взглянем на распределённый по нескольким серверам сайт с точки зрения аудитора безопасности веб сайтов.

Использование зеркал для сайта: анализ с точки зрения пентестера

Рассмотрим, как мы можем найти ответы на вопросы аудитора безопасности веб-сайтов.

1. Как узнать все IP адреса сайта?

Это самый простой вопрос. Для ответа на него достаточно воспользоваться любой из утилит для просмотра DNS записей.

Утилита host сразу показывает все IP и IPv6 адреса сайтов:

host suip.biz
suip.biz has address 185.117.153.79
suip.biz has address 157.245.118.66
suip.biz has IPv6 address 2604:a880:800:c1::2ae:d001
suip.biz has IPv6 address 2a02:f680:1:1100::3d60

Также делает и утилита nslookup:

nslookup suip.biz
Server:		8.8.8.8
Address:	8.8.8.8#53

Non-authoritative answer:
Name:	suip.biz
Address: 185.117.153.79
Name:	suip.biz
Address: 157.245.118.66
Name:	suip.biz
Address: 2604:a880:800:c1::2ae:d001
Name:	suip.biz
Address: 2a02:f680:1:1100::3d60

Программа dig по умолчанию показывает только IP (без IPv6), то есть только A записи. Чтобы программа показала ещё и IPv6 адреса, нужно запустить её ещё раз указав AAAA или ANY (чтобы были выведены вообще все DNS записи для данного домена):

dig suip.biz

Чтобы узнать IPv6 сайта:

dig suip.biz AAAA

Чтобы увидеть все DNS записи сайта:

dig suip.biz ANY

Чтобы узнать NS записи для домена (сервера имён), можно запустить dig с ANY:

dig suip.biz ANY

либо посмотреть эту информацию во whois

whois suip.biz
Name Server: ns2.marosnet.ru
Name Server: ns1.marosnet.ru

2. Используется несколько серверов или один сервер с несколькими IP адресами?

Узнать, что сервера разные, можно по:

  • географическому расположению IP адресов
  • различному набору открытых портов
  • HTTP заголовкам ответа
  • хешу страницы
  • содержимому файла robots.txt
  • дате действия SSL сертификата, списку хостов сертификата
  • различным скрытым файлам

Для домена suip.biz получены следующие IP адреса:

  • 185.117.153.79
  • 157.245.118.66

Это два сетевых интерфейса на одном сервере или это два разных сервера?

Узнаем место нахождения IP адресов с помощью программы geoiplookup:

geoiplookup 185.117.153.79
geoiplookup 157.245.118.66

Один адрес находится в РФ, а второй — в США. Ещё у них разные AS. Уже на этом этапе можно почти с точностью утверждать, что это два разных сервера, а не один сервер с двумя IP.

С помощью программы Nmap, если указать опцию -A, можно предположительно узнать ОС и её версию:

sudo nmap -A 185.117.153.79
sudo nmap -A 157.245.118.66

Кроме этого, если использовать опцию -A, то показывается много другой дополнительной информации, которая также полезна для анализа: 

  • список открытых портов (даже если набор открытых портов разный, это не гарантирует, что это разные сервера! Поскольку можно настроить сетевые службы для работы только на определённых интерфейсах)
  • трассировку пути
  • банеры служб

Как видно на скриншоте, разный набор открытых портов. Различаются заголовки веб-серверов:

Apache httpd 2.4.41 ((Unix) OpenSSL/1.1.1d PHP/7.4.1)
|_http-server-header: Apache/2.4.41 (Unix) OpenSSL/1.1.1d PHP/7.4.1

Во втором случае:

Apache httpd 2.4.41
|_http-server-header: Apache/2.4.41 (Debian)

SSL сертификаты:

| ssl-cert: Subject: commonName=suip.biz
| Subject Alternative Name: DNS:suip.biz, DNS:www.suip.biz
| Not valid before: 2019-11-30T06:26:54
|_Not valid after:  2020-02-28T06:26:54

Во втором случае:

| ssl-cert: Subject: commonName=w-e-b.site
| Subject Alternative Name: DNS:w-e-b.site
| Not valid before: 2019-11-30T06:21:28
|_Not valid after:  2020-02-28T06:21:28

То есть у сертификатов не только разные даты действия, но даже разные домены — видимо, второй сервер по умолчанию предназначен для обслуживания другого сайта, а работа зеркалом хоста suip.biz идёт для него в качестве дополнительной нагрузки.

Также разные заголовки при запросах на 443 порт:

|_http-title: 403 Forbidden

И

|_http-title: 400 Bad Request

Получить более подробный вывод о сертификатах можно командой вида:

sudo nmap -v --script ssl-cert ДОМЕН:

Ещё больше информации будет показано, если вместо -v указать -vv.

Предположение об операционной системе:

Aggressive OS guesses: Linux 3.11 - 4.1 (98%), Linux 3.16 (98%), Linux 4.4 (98%), Linux 2.6.32 (98%), Linux 3.18 (97%), Linux 2.6.35 (97%), IGEL UD3 thin client (Linux 2.6) (97%), Linux 3.2 - 3.8 (97%), Linux 3.8 (97%), WatchGuard Fireware 11.8 (97%)
No exact OS matches for host (test conditions non-ideal).

Для второго IP:

Device type: general purpose|remote management|PBX
Running (JUST GUESSING): Linux 2.6.X|2.4.X (88%), OpenBSD 4.X (88%), Motorola embedded (87%), Cisco embedded (85%)
OS CPE: cpe:/o:linux:linux_kernel:2.6 cpe:/o:openbsd:openbsd:4.0 cpe:/h:motorola:rfs4000 cpe:/o:linux:linux_kernel:2.4.21 cpe:/h:cisco:uc320w
Aggressive OS guesses: Linux 2.6.18 - 2.6.22 (88%), OpenBSD 4.0 (88%), Motorola RFS4000 wireless controller (87%), Linux 2.4.21 (87%), Cisco UC320W PBX (Linux 2.6) (85%), Linux 2.6.5 (85%), Linux 2.6.9 - 2.6.18 (85%), Linux 2.6.29 (85%), Linux 2.6.32 (85%)
No exact OS matches for host (test conditions non-ideal).

Как можно увидеть, в обоих случай это какой-то Linux, но точнее сказать не получается.

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

У разных серверов, используемых для балансировки нагрузки и отказоустойчивости сайтов, может быть различное программное обеспечение как операционной системы, веб-сервера, подключённых модулях веб-сервера, так и различных версий самих рабочих скриптов, выполняющих функции того или иного онлайн сервиса. По логике, версии ПО сервера должно быть одинаковым, но это означает постоянную синхронизацию — что не всегда имеется на практике.

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

curl -I IP_АДРЕС -H 'Host: ДОМЕН'

Нужно указать действительные значения для IP_АДРЕС и ДОМЕН, также можно добавить опцию -A с User Agent, например:

curl -I 185.117.153.79 -A 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36' -H 'Host: suip.biz'

Для второго IP:


curl -I 157.245.118.66 -A 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36' -H 'Host: suip.biz'

Таким образом иногда можно увидеть версию веб-сервера и версию PHP.

О различии в скриптах может говорить неодинаковый HTML код. Самый простой способ сравнить его, это рассчитать хеш для разных серверов, для этого можно использовать команду вида:

curl -s IP_АДРЕС -H 'Host: ДОМЕН' | sha1sum

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

Вначале запустите команду несколько раз для одного сервера, чтобы убедиться, что вывод является стабильным и HTML код не меняется при каждом запросе.

Пример проверки:

curl -s 185.117.153.79 -A 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36' -H 'Host: suip.biz' | sha1sum
curl -s 157.245.118.66 -A 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36' -H 'Host: suip.biz' | sha1sum

Как видно на скриншоте, в моём случае HTML код разный — это означает, что скрипты, которые его генерируют, также различаются. И это почти точно подтверждает, что имеют место 2 разных сервера, а не один сервер с двумя IP адресами.

4. Если используется несколько серверов, к какому именно серверу делается запрос с компьютера атакующего?

Я не знаю, как определить, какой именно IP открывается при просмотре страницы в веб-браузере, но, например, cURL в вербальном режиме показывает IP адреса, к которым она пытается подключиться:

curl -v suip.biz
*   Trying 157.245.118.66:80...
* TCP_NODELAY set
*   Trying 2a02:f680:1:1100::3d60:80...
* TCP_NODELAY set
* Immediate connect fail for 2a02:f680:1:1100::3d60: Сеть недоступна
*   Trying 2604:a880:800:c1::2ae:d001:80...
* TCP_NODELAY set
* Immediate connect fail for 2604:a880:800:c1::2ae:d001: Сеть недоступна
* Connected to suip.biz (157.245.118.66) port 80 (#0)
> GET / HTTP/1.1
> Host: suip.biz
> User-Agent: curl/7.67.0
> Accept: */*
> 

Строка Trying 157.245.118.66:80 говорит о том, что делается попытка подключиться к IP 157.245.118.66, затем делаются попытки подключиться к 2a02:f680:1:1100::3d60 и 2604:a880:800:c1::2ae:d001 (IPv6 адреса этого сервера), но возникает ошибка «Сеть недоступна». Наконец строка «Connected to suip.biz (157.245.118.66)» говорит о том, что выполнено подключение к 157.245.118.66. Как можно увидеть, cURL пытается открыть сразу несколько из доступных адресов.

5. Как выбрать сервер, к которому будут отправляться запросы?

Можно явно указать IP адрес для определённого хоста, к которому должен подключаться компьютер. В Linux для этого нужно добавить запись в файл /etc/hosts, в Windows нужно отредактировать файл C:\Windows\System32\drivers\etc\hosts.

Настройка отказовоустойчивых сайтов

Сайт suip.biz по разным причинам иногда оказывается офлайн, поэтому я решил сделать его зеркало, на случай недоступности основного сайта. Я приведу свои действия как я их делал сам на Debian для домена suip.biz. В следующих командах и конфигурационных файлах везде вместо suip.biz используйте ваш домен.

Итак, начинаем с настройки нового виртуального хоста на втором сервере, создаём дополнительный файл конфигурации Apache:

vim /etc/apache2/sites-available/suip.biz.conf

И копируем в него примерно следующее

<VirtualHost *:80>
	ServerName suip.biz
	ServerAdmin proghoster@gmail.com
	DocumentRoot /var/www/html
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

<VirtualHost *:80>
	ServerName www.suip.biz
	ServerAdmin proghoster@gmail.com
	DocumentRoot /var/www/html
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Подключаем новый виртуальный хост и перезагружаем конфигурацию веб-сервера:

a2ensite suip.biz
systemctl reload apache2

Для хостинга ihor настройка DNS записей домена делается на страниице https://dns-manager.marosnet.net/dnsmgr

Добавляем новые адреса для домена:

Ждём, когда сделанные настройки вступят в силу:

nslookup suip.biz

Следующий шаг нужен только если ваш сервер использует HTTPS протокол. Если вы купили SSL сертификат, то просто скопируйте его на новый сервер. Я пользуюсь бесплатными сертификатами, поэтому вместо переноса уже имеющегося SSL сертификата на второй сервер, мне проще получить новый.

Автоматически получить SSL сертификат можно с помощью acme-tiny:

git clone https://github.com/diafygi/acme-tiny.git
cd bin/acme-tiny/

В первый раз набор команд такой (не забудьте suip.biz везде, в именах файлов и в командах, заменить на свой домен):

openssl genrsa 4096 > suip.biz.account.key
openssl genrsa 4096 > suip.biz.domain.key
openssl req -new -sha256 -key suip.biz.domain.key -subj "/CN=suip.biz" > suip.biz.domain.csr

Создаём папку .well-known/acme-challenge/ в директории сайта:

mkdir -p /var/www/html/.well-known/acme-challenge/

Делаем запрос для подписи сертификата:

python acme_tiny.py --account-key suip.biz.account.key --csr suip.biz.domain.csr --acme-dir /var/www/html/.well-known/acme-challenge/ > suip.biz.signed.crt

Переносим сертификаты:

mv suip.biz.signed.crt /etc/ssl/certs/suip.biz.server.crt
mv suip.biz.domain.key /etc/ssl/private/suip.biz.server.key

В последующие разы для получения новых сертификатов нужно будет выполнить:

openssl genrsa 4096 > suip.biz.domain.key
openssl req -new -sha256 -key suip.biz.domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:suip.biz,DNS:www.suip.biz")) > suip.biz.domain.csr
python acme_tiny.py --account-key suip.biz.account.key --csr suip.biz.domain.csr --acme-dir /srv/http/suip/.well-known/acme-challenge/ > suip.biz.signed.crt
mv suip.biz.signed.crt /etc/ssl/certs/suip.biz.server.crt
mv suip.biz.domain.key /etc/ssl/private/suip.biz.server.key

И перезапустить сервер:

systemctl restart httpd.service

Сейчас нам нужно создать новый конфигурационный файл для настройки хоста веб-сервера, который будет отвечать за работу сайта по HTTPS протоколу. Создаём конфигурационный файл:

vim /etc/apache2/sites-available/suip.biz-ssl.conf

И копируем в него примерно следующее:

<VirtualHost *:443>
        DocumentRoot "/var/www/html/"
        ServerName suip.biz
        ServerAdmin proghoster@gmail.com
        LogLevel info
        ErrorLog "/var/log/apache2/suip.biz-ssl-error_log"
        CustomLog "/var/log/apache2/suip.biz-ssl-access_log" combined

SSLEngine on

SSLCertificateFile "/etc/ssl/certs/suip.biz.server.crt"
SSLCertificateKeyFile "/etc/ssl/private/suip.biz.server.key"

<FilesMatch "\.(cgi|shtml|phtml|php)$">
    SSLOptions +StdEnvVars
</FilesMatch>
 
<Directory "/srv/http/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>
 
BrowserMatch "MSIE [2-5]" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

<Directory /> 
    Options +Indexes +FollowSymLinks +ExecCGI
    AllowOverride All
</Directory>

</VirtualHost>


<VirtualHost *:443>
        DocumentRoot "/var/www/html/"
        ServerName www.suip.biz
        ServerAdmin progoster@gmail.com
        ErrorLog "/var/log/apache2/suip.biz-ssl-error_log"
        CustomLog "/var/log/apache2/suip.biz-ssl-access_log" combined

SSLEngine on

SSLCertificateFile "/etc/ssl/certs/suip.biz.server.crt"
SSLCertificateKeyFile "/etc/ssl/private/suip.biz.server.key"


<FilesMatch "\.(cgi|shtml|phtml|php)$">
    SSLOptions +StdEnvVars
</FilesMatch>

<Directory "/srv/http/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>

BrowserMatch "MSIE [2-5]" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

<Directory />
    Options +Indexes +FollowSymLinks +ExecCGI
</Directory>

</VirtualHost>

Включаем новый хост:

a2ensite suip.biz-ssl
Enabling site suip.biz-ssl.
To activate the new configuration, you need to run:
  systemctl reload apache2

Перезагружаем конфигурацию веб-сервера:

systemctl reload apache2

Проверяем, всё ли нормально:

systemctl status apache2.service

Если веб-сервер не перезапустился, ошибки можно посмотреть так:

systemctl status apache2.service
journalctl -xe

Для перенаправления трафика с HTTP на HTTPS добавляем в файл .htaccess следующее (сделано исключение для папки .well-known):

RewriteEngine on
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} !^/.well-known/
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI}

Если вы используете сервера имён хостера, но не уверены в их надёжности, то можете добавить NS записи (для ihor это делается на странице https://billing.ihor.ru/manager/billmgr):

Я добавил сервера имён Хостлэнд — другого хостинга, где у меня есть учётная запись. 

На этом втором хостинге я припарковываю домен

и в настройках DNS добавляю все его IP адреса:

Рекомендуется Вам:

Добавить комментарий

Ваш адрес email не будет опубликован.