Задача: открыть сайт на другом сервере по старому имени
Типичная ситуация: сайт переезжает на новый сервер. DNS ещё указывает на старый адрес, а проверить работу на новом нужно сейчас. Если просто обратиться к новому серверу по IP, результат окажется неверным: сервер не поймёт, какой сайт нужен, потому что на одном адресе обычно живёт множество сайтов, а выбор происходит по имени.
Правка файла hosts решает задачу, но требует прав администратора, меняет настройки на всём компьютере и легко забывается. Параметр --resolve делает то же самое, но действует только на одну команду curl. После её завершения всё возвращается как было, ничего чистить не придётся.
Это же приём помогает сравнивать два сервера за балансировщиком, проверять отдельный узел, когда часть пользователей получает ошибку, и убеждаться, что сайт отвечает после переноса, ещё до смены записей в DNS.
Синтаксис и пример
Формат параметра: --resolve имя:порт:адрес. Имя и порт задают, для какого запроса подставляется адрес, а адрес — куда фактически пойдёт соединение. Пример: curl --proto-default https --resolve example.com:443:192.0.2.10 -I example.com.
Разберём эту команду по частям.
- --proto-default https — если в адресе не указана схема, использовать https; это удобно, чтобы не печатать схему целиком;
- --resolve example.com:443:192.0.2.10 — для имени example.com и порта 443 использовать адрес 192.0.2.10;
- -I — запросить только заголовки ответа;
- example.com — имя сайта, которое попадёт в заголовок Host и в расширение SNI при установке защищённого соединения.
Порт в параметре обязателен и должен совпадать с портом запроса: для https это 443, для http — 80. Если вы проверяете оба варианта, укажите параметр дважды с разными портами. Можно перечислить несколько адресов через запятую, тогда curl выберет подходящий. Адреса в примерах относятся к зарезервированным диапазонам, подставьте реальный адрес сервера.
Почему это лучше, чем обращение по IP
Если открыть сайт по адресу, ответ будет не таким, как при обращении по имени. Для защищённого соединения клиент должен сообщить серверу имя сайта: так сервер выбирает нужный сертификат. При обращении по IP имя не передаётся, сертификат не совпадёт, а curl сообщит об ошибке проверки.
| Способ | Заголовок Host | Имя в SNI | Сертификат проверяется по имени |
|---|---|---|---|
| curl по IP | IP-адрес | не передаётся | нет, возникает ошибка |
| curl --resolve | Имя сайта | Имя сайта | да |
| Правка hosts | Имя сайта | Имя сайта | да, но для всей системы |
Поэтому --resolve даёт самую близкую к реальности картину: сервер видит тот же запрос, что и от настоящего посетителя, и отвечает так же. Отличие только в адресе, куда доставляется пакет.
Не применяйте параметр -k, отключающий проверку сертификата, чтобы «заставить» работать обращение по IP. Он скрывает проблему, а не решает её, и результат нельзя считать достоверным.
Сравнение двух серверов и разбор результата
Практичный порядок проверки нового сервера перед переключением DNS.
- Выполните команду с адресом старого сервера и сохраните вывод: curl --proto-default https --resolve example.com:443:СТАРЫЙ_АДРЕС -sS -o /dev/null -w "%{http_code}\n" example.com.
- Повторите её с адресом нового сервера.
- Сравните код ответа, заголовки и время. Подробности об измерении времени есть на странице про curl -w.
- Откройте несколько ключевых страниц, не только главную.
- Если ответ отличается, посмотрите заголовки командой с ключом -I и сравните их, особенно Location при перенаправлениях.
Если на новом сервере ошибка сертификата, чаще всего для этого имени там ещё не выпущен или не подключён нужный сертификат. Ошибка соединения означает, что на этом адресе не слушает нужный порт или соединение закрыто файерволом. Сами тексты ошибок разобраны на страницах про коды curl 6, 7 и 60.
Результат относится только к тому, что вы запросили: проверка одной страницы не заменяет полной проверки сайта после переноса.
Родственный параметр --connect-to и ограничения
Помимо --resolve есть параметр --connect-to в формате узел1:порт1:узел2:порт2. Он перенаправляет соединение с одного узла и порта на другой, при этом имя сайта в запросе остаётся прежним. Он нужен, когда новый сервер слушает нестандартный порт или когда требуется подменить не только адрес, но и порт.
Есть и ограничения. Параметр действует только в curl: браузер, другие утилиты и приложения на компьютере продолжат ходить по записям DNS. Если нужно проверить сайт глазами в браузере, придётся временно менять hosts, как описано на странице про этот файл, и затем вернуть как было.
Параметр не заменяет проверку DNS: он показывает, как отвечает сервер, но не доказывает, что записи в DNS настроены правильно. После переключения всегда запросите имя через dig и убедитесь, что он возвращает новый адрес.
Наконец, если перед сайтом стоит сеть доставки содержимого или балансировщик, адрес, который вы подставили, может вести на другой узел, чем у обычных посетителей. Учитывайте это при сравнении.
Короткий чек-лист перед переключением DNS
Перед тем как менять записи, пройдите по краткому списку проверок на новом сервере с помощью --resolve.
- Главная страница и несколько внутренних отвечают кодом 200.
- Перенаправления ведут туда, куда нужно, без петель.
- Сертификат выпущен для нужного имени и не просрочен.
- Статические файлы, изображения и стили загружаются.
- Формы и вход работают, если это важно для сайта.
- Время ответа сопоставимо со старым сервером.
После проверки измените запись в DNS и дождитесь истечения срока хранения старой. Пока он не истёк, часть посетителей будет попадать на старый сервер, поэтому не отключайте его сразу. Срок хранения указан в ответе на запрос dig как TTL. Заранее уменьшите значение, если планируете переезд, чтобы переключение прошло быстрее.