Имя и адрес
Чтение и практика ~60 мин
вы проверяете, куда на самом деле идёт запрос с нужным именем, и не принимаете «по IP отвечает» и «пинг есть» за доказательство, что служба работает для пользователей.
Лаборатория и подготовка — архив один для всех пяти глав. Перед новым сценарием остановите прежний через Ctrl+C.
Что нового
На одном адресе и порту веб-сервер может обслуживать несколько сайтов. Какой из них ответит, сервер решает по заголовку
Host, который клиент берёт из адреса: http://notes.lab.test:18080/… → Host: notes.lab.test:18080. Если обратиться
по адресу http://127.0.0.1:18080/…, заголовок будет Host: 127.0.0.1:18080 — и ответит другой сайт, если он настроен.
Отправить запрос с нужным именем на выбранный адрес можно двумя способами:
curl -i -H 'Host: notes.lab.test' http://127.0.0.1:18080/путь
curl -i --resolve notes.lab.test:18080:127.0.0.1 http://notes.lab.test:18080/путь
Для HTTP они равноценны. Чем они различаются для HTTPS, разберём в главе 5.
Подготовка
Из папки курса, в первом окне: python3 lab/netlab.py start ch2.
Ситуация
Суббота, 17 октября, 09:15. Ночью «Заметки 3.0» переехали на новый сервер. Старый (версия 2.9) пока не выключен —
«на всякий случай». Мобильное приложение 3.0 ходит на http://notes.lab.test:18080/api/v2/notes, и с утра пользователи
видят «Ошибка 404».
Администратор Пётр пишет:
Новый сервер работает, проверил:
$ curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:18080/health 200 $ ping -c 1 notes.lab.test # (вывод — учебная модель) PING notes.lab.test (127.0.0.2) 56(84) bytes of data. 64 bytes from notes.lab.test (127.0.0.2): icmp_seq=1 ttl=64 time=0.041 msС нашей стороны всё в порядке, это приложение.
Мини-задача
До разбора запишите:
-
Что именно доказывает каждая из двух проверок Петра и чего она не доказывает? По одной строке на проверку.
-
Повторите запрос пользователя и запишите участок (1–4 из главы 1) и одну строку вывода, которая на него указывает:
python3 lab/netlab.py fetch http://notes.lab.test:18080/api/v2/notes
Наблюдения, которые можно сделать (открывайте по одному)
Н1. Проверка Петра целиком, с телом ответа
python3 lab/netlab.py fetch http://127.0.0.1:18080/health
Н2. Что отвечает DNS
python3 lab/netlab.py dig notes.lab.test
Н3. Запрос с нужным именем на новый сервер
curl -sS -i --noproxy '*' -H 'Host: notes.lab.test' http://127.0.0.1:18080/api/v2/notes
Н4. Куда соединяется клиент пользователя
python3 lab/netlab.py fetch --verbose http://notes.lab.test:18080/api/v2/notes 2>&1 | grep -E 'Trying|Connected|X-App'
Разбор мини-задачи
Откройте, когда записали свои ответы
Проверка по IP. Тело ответа (Н1) — «Добро пожаловать… сайт по умолчанию». Запрос без имени попал в сайт по умолчанию,
который отвечает 200 на любой путь. Доказано: на 127.0.0.1:18080 принимают соединения и отвечает HTTP-сервер. Не
доказано: что сайт notes.lab.test там работает и что пользователи вообще приходят на этот адрес. -o /dev/null
спрятал тело — единственное, что отличало «наш сайт» от «чей-то».
Пинг. В строке ответа — адрес 127.0.0.2. Это старый сервер: имя у Петра разрешилось в старый адрес. Пинг
доказывает только, что этот адрес отвечает на служебные сообщения ICMP; он не проверяет ни порт, ни HTTP, ни сайт.
Петра пинг успокоил, хотя показал адрес, по которому видна причина.
Запрос пользователя. HTTP/1.1 404, X-App-Version: 2.9; в --verbose — Trying 127.0.0.2:18080 (Н4). Участки
1–3 работают, ответ приходит — но от старого сервера, где пути /api/v2/… нет. Причина на участке 1: DNS отдаёт старый
адрес (Н2: 127.0.0.2, TTL 3600). Новый сервер исправен: с правильным именем (Н3) — 200, X-App-Version: 3.0.
Развилка: 09:30, что делать
Запись DNS ведёт Ирина (инфраструктура), она в сети. Решения (порядок случайный):
- А. Перезапустить новый сервер: вдруг сайт
notes.lab.testне загрузился. - Б. Попросить Ирину поменять запись
notes.lab.testна127.0.0.1, проверитьdig; предупредить поддержку, что у части пользователей ошибка может держаться до часа; старый сервер пока не выключать. - В. Как Б, и на время до истечения старых ответов настроить старый сервер передавать запросы на новый; записать, что эту настройку нужно снять.
- Г. Выключить старый сервер: тогда клиенты увидят, что он не работает, и пойдут на новый.
- Д. Передать разработчикам, что маршрут
/api/v2/notesотвечает 404.
Для выбранного: что увидит пользователь в 09:45 и в 10:45.
Последствия
- А. Новый сервер и так отвечает правильно (Н3); перезапуск ничего не меняет, пользователи по-прежнему ходят на старый.
- Б. После смены записи
digотдаёт127.0.0.1. Клиенты и промежуточные резолверы, которые уже получили старый ответ, могут хранить его до конца TTL — до часа; у них 404 продолжится. После истечения старых ответов клиенты с обычным TTL-кэшированием получат новый адрес. Это не обещание для любого клиента: постоянная запись в hosts или дополнительный кэш требуют отдельной проверки. Допустимо, если час ошибок у части пользователей приемлем и об этом знает поддержка. - В. То же, но пользователи со старым ответом тоже получают ответ нового сервера сразу. Цена — изменение на старом сервере, которое нужно не забыть убрать. Допустимо, если час ошибок неприемлем.
- Г. Без смены записи пользователи будут ходить на выключенный адрес — вместо 404 получат отказ в соединении (код 7 из главы 1) до тех пор, пока запись не исправят. Причина не устранена, ошибка стала хуже.
- Д. На новом сервере маршрут работает (Н3); разработчики ничего не найдут.
Приёмка
- Для каждой проверки Петра записано, что она доказывает и чего нет, — со ссылкой на строку вывода (тело «сайт по умолчанию»,
адрес
127.0.0.2в пинге). - Есть команда, которая отправляет запрос с именем
notes.lab.testна127.0.0.1, и её ответ — 200 сX-App-Version: 3.0. - Есть вывод
digс адресом и TTL, и вы объясняете, как TTL влияет на то, когда пользователи перестанут видеть ошибку. - Выбранное решение называет условие: сколько ошибок допустимо и кто об этом предупреждён.
Подсказки
Подсказка 1 — направление
Проверки Петра касаются адреса и пинга. А что делает клиент пользователя: с каким именем и на какой адрес он идёт?
Подсказка 2 — нужное наблюдение
Посмотрите тело ответа Петра (Н1), адрес в строке пинга и что отвечает DNS (Н2). Затем отправьте запрос с нужным
именем на новый адрес (Н3) и сравните X-App-Version.
Подсказка 3 — разбор
Ответ по IP пришёл от сайта по умолчанию — это не notes.lab.test. Пинг показал старый адрес 127.0.0.2 и проверил
только ICMP. Пользователь получает 404 от старого сервера (2.9), потому что DNS отдаёт старый адрес с TTL 3600; новый
сервер с правильным именем отвечает 200 (3.0). Чинить — запись DNS (её владелец — Ирина). Допустимы Б (если час ошибок
у части пользователей приемлем и предупреждён) и В (если нет: старый сервер временно передаёт запросы на новый).
А и Д чинят то, что исправно; Г превращает 404 в отказ соединения. Альтернативный путь наблюдения: вместо -H 'Host: …' —
--resolve notes.lab.test:18080:127.0.0.1; для HTTP результат тот же.
Второй вариант
Та же суббота, 12:30. Опоры меньше. Перезапустите лабу со сценарием ch2b. Ирина поменяла запись в 10:00; у всех
пользователей ошибка прошла. Но скрипт выгрузки Бориса, который работает на отдельном сервере, всё ещё получает 404.
Вы подключились к серверу Бориса. В лабе его особенности воспроизводит учебная копия файла hosts: lab/hosts.boris.
Н1. DNS с сервера Бориса
python3 lab/netlab.py dig notes.lab.test
Н2. Запрос скрипта Бориса
python3 lab/netlab.py fetch --hosts lab/hosts.boris http://notes.lab.test:18080/api/v2/notes
Н3. Что отвечает резолвер сервера Бориса
python3 lab/netlab.py resolve --hosts lab/hosts.boris notes.lab.test
На настоящем сервере это getent hosts notes.lab.test: так имя разрешает сама система — по порядку из строки hosts:
в /etc/nsswitch.conf (обычно files dns: сначала /etc/hosts, потом DNS). dig спрашивает сервер имён напрямую
и /etc/hosts не читает.
Решения (порядок случайный):
- А. Попросить Ирину проверить запись ещё раз и уменьшить TTL.
- Б. Подождать ещё час: у сервера Бориса, наверное, свой кэш.
- В. Попросить владельца сервера Бориса убрать строку
notes.lab.testиз/etc/hosts, затем проверитьgetent hostsи запрос скрипта. - Г. Выключить старый сервер, чтобы скрипт Бориса перешёл на новый.
- Д. Сбросить кэш DNS на сервере Бориса.
- Е. Пока владелец сервера Бориса недоступен — оставить старый сервер и настроить его передавать запросы на новый;
записать, что снять после правки
/etc/hosts.
Подсказка 1
dig и запрос скрипта говорят разное. Кто из них спрашивает то же, что скрипт?
Подсказка 2
Посмотрите Н3: откуда взят адрес? Прочитайте lab/hosts.boris.
Подсказка 3 — разбор
DNS уже правильный (Н1: 127.0.0.1), но система на сервере Бориса сначала читает /etc/hosts, а там с 16 октября
осталась строка 127.0.0.2 notes.lab.test от проверки перед переездом (Н3: «источник: файл»). Буквальный повтор прошлого
решения — чинить DNS (А) — бесполезен: запись верна. Б и Д тоже: это не кэш, строка в файле не истечёт. Г — скрипт
получит отказ соединения вместо 404. Допустимы В (убрать строку — устранить причину) и Е (временная мера, пока владелец
недоступен, с записью, что снять). Факт, который меняет решение: dig и резолвер системы отвечают по-разному — значит,
причина не в DNS, а в том, что читается до него.
Источники
- Руководство curl: параметры и коды выхода.
- HTTP: имя целевого сервера, ошибки сервера.
- DNS: TTL записи.
- Linux: порядок источников имён в nsswitch.conf.
Тексты сообщений могут отличаться между сборками curl. Поведение учебного DNS и службы задаёт лаборатория; в главе 2 вывод ping обозначен как модель. TTL в опыте — поле ответа, кэширование всех реальных клиентов лаборатория не воспроизводит.
Прочитали и разобрались? Отметьте урок — прогресс сохранится в этом браузере.