Що браузер від вас ховає
Ви відкриваєте сайт у браузері й бачите одне: сторінку або помилку. Усе, що сталося дорогою, відкинуто — редіректи, коди, сертифікат, який показав сервер, скільки часу він думав перед відповіддю. Саме в цій відкинутій частині насправді вирішуються майже всі суперечки «сайт гальмує» і «у мене все працює».
Ця перевірка робить кожен крок видимим. Вона проходить ланцюг редіректів по одному кроку, замість дозволити HTTP-клієнту мовчки розв'язати його, записує код відповіді, адресу, з якої відповіли, і час для кожного кроку — а потім показує сертифікат і заголовки того, куди врешті потрапила.
Ланцюги редіректів: чому три кроки — це на два більше, ніж треба
Редірект не безкоштовний. Кожен з них — це повний обіг: DNS-запит, якщо змінилося ім'я вузла, рукостискання TCP, рукостискання TLS, запит, відповідь — і все це до того, як передали хоч байт вмісту. На швидкому підключенні крок коштує десятки мілісекунд; у мобільній мережі, де все вирішує затримка, — кілька сотень.
Класичний випадковий ланцюг виглядає так, і майже ніхто не будує його навмисно:
http://example.com/page→ 301 →https://example.com/page— правило про HTTPShttps://example.com/page→ 301 →https://www.example.com/page— правило про канонічний хостhttps://www.example.com/page→ 301 →https://www.example.com/page/— правило про кінцеву скісну
Три окремі правила, кожне саме по собі цілком розумне, застосовані в найгіршому
можливому порядку. Лікується тим, щоб перший редірект вів одразу на кінцеву адресу:
http://example.com/page має вести просто на
https://www.example.com/page/. Це згортає три кроки в один, не змінюючи змісту
жодного з правил.
Коди важать не менше за кількість:
- 301 і 308 — постійні
- Пошукові системи переносять сигнали ранжування на ціль, а браузери кешують такий редірект, інколи дуже надовго. Помилково виданий 301 виправляти незвично боляче: ті, у кого він уже в кеші, продовжують ним ходити.
- 302 і 307 — тимчасові
- Нічого не переноситься й надовго не кешується. Правильні для справді тимчасових ситуацій і неправильні для переїзду: постійний переїзд, відданий як 302, лишає стару адресу конкурувати з новою невизначено довго.
- Різниця 307/308
- 301 і 302 історично дозволяли клієнту перетворити POST на GET, і браузери саме так і роблять. 307 і 308 це забороняють: метод і тіло зберігаються. Якщо після редіректу відправлена форма загадково приходить порожньою — причина тут.
Як читати код, на якому ви опинилися
Кінцевий код — це власний підсумок сервера про те, що сталося. Ті, які варто впізнавати з першого погляду:
- 200 — сторінку віддано. Зверніть увагу: це нічого не каже про її правильність. Чимало сайтів віддають 200 із текстом помилки в тілі, і моніторинг, який дивиться лише на код, цього не бачить.
- 403 — сервер зрозумів і відмовив. Дуже часто це взагалі не про вас: фільтрація ботів, географічне блокування або правило проти адрес датацентрів. Якщо тут 403, а у вашому браузері сайт відкривається, найімовірніша причина саме така.
- 404 і 410 — не знайдено і навмисно прибрано. Різниця в намірі, і пошукові системи сприймають 410 як сильніший сигнал прибрати адресу з індексу.
- 429 — вас обмежують за частотою. Чесно й корисно: сервер просить сповільнитись, а не вдає поламаного.
- 500 — застосунок впав. Проблема у власному коді сайту, і подробиці будуть у його журналі помилок.
- 502 і 504 — фронтальний сервер не зміг отримати придатної відповіді від застосунку за собою. 502 означає, що відповідь була некоректною або з'єднання відхилили; 504 — що відповіді не було вчасно. Обидва вказують ЗА вебсервер, а не на нього — і це найкорисніша різниця в усьому переліку, коли щось лежить.
- 503 — навмисно недоступний: режим обслуговування або захист від перевантаження. Мав би нести заголовок
Retry-After, і зазвичай не несе.
Сертифікат і поломка, яку ховають браузери
Ми навмисно не перевіряємо сертифікат так, як це робить браузер: ми його отримуємо, перевіряємо окремо й показуємо результат. Це єдиний спосіб описати зламаний сертифікат, а не просто не під'єднатися й назвати це помилкою мережі.
У результаті варто прочитати три речі, і вони незалежні одна від одної:
- Чи перевіряється ланцюг. Саме це ловить найдорожчу тиху поломку TLS: сервер не надсилає проміжний сертифікат. Браузери це затуляють — вони кешують проміжні з інших сайтів і вміють дотягувати відсутні, — тож тому, хто налаштовував, сайт здається бездоганним. А тим часом
curl, застосунки на Java, пристрої Android і платіжні зворотні виклики падають з «unknown authority», і власник тиждень наполягає, що все працює. - Чи збігається ім'я. Сертифікат покриває конкретний перелік імен.
example.comіwww.example.com— два різні імені, а wildcard покриває рівно один рівень:*.example.comне покриваєa.b.example.com. - Скільки лишилося. Строки життя сертифікатів роками скорочуються, і автоматичне оновлення стало нормою — а отже, закінчення строку більше не питання календаря, а питання спостереження: оновлення падає мовчки, і ніхто не помічає, поки сертифікат не скінчиться. Менше двох тижнів на автоматизованому налаштуванні означає, що автоматика перестала працювати.
Заголовки безпеки: що саме кожен із них зупиняє
Ми показуємо, які з них сервер надсилає і з яким значенням. Оцінок не ставимо: чи потрібен конкретний заголовок — залежить від сайту, і в статичної сторінки-візитівки та в онлайн-банку правильні відповіді різні.
- Strict-Transport-Security
- Каже браузеру користуватися для цього хоста лише HTTPS протягом указаного строку, ні про що не питаючи. Закриває проміжок, у якому перший запит відвідувача йде відкритим HTTP і може бути перехоплений. З
preloadварто обережно: потрапити до списку швидко, вийти з нього довго, і доти кожен піддомен мусить вічно працювати через HTTPS. - Content-Security-Policy
- Обмежує, звідки можна вантажити скрипти, стилі й фрейми. Найдієвіший захист від міжсайтового скриптингу і водночас найпрацемісткіший, бо ламає все, що ви забули перелічити. Викочуйте спершу в режимі лише звітів.
- X-Content-Type-Options: nosniff
- Забороняє браузеру вгадувати тип файлу за вмістом, коли оголошений тип із ним не сходиться. Без нього завантажений файл, який сервер називає простим текстом, може виконатися як скрипт. Один рядок, без побічних наслідків і без налаштувань — вагомої причини його не ставити немає.
- X-Frame-Options і frame-ancestors
- Обидва не дають вбудувати вашу сторінку в чужий фрейм, а саме це потрібне для клікджекінгу.
frame-ancestorsусередині CSP — сучасна форма, і вона має перевагу; старий заголовок лишається заради дуже старих клієнтів. - Referrer-Policy
- Керує тим, скільки з поточної адреси піде разом із переходом за посиланням назовні. Значення за замовчуванням тепер розумні, але якщо у ваших адресах є ідентифікатори чи токени — саме це не дасть віддати їх кожному сайту, на який ви посилаєтесь.
- Permissions-Policy
- Оголошує, якими можливостями браузера — камерою, мікрофоном, геолокацією — можуть користуватися сторінка й усе, що вона вбудовує. Найкорисніший як спосіб сказати «тут нічого з цього не потрібно».
Час: думає чи віддає
Ми показуємо два числа, бо одне на це питання не відповідає. Час до першого байта — скільки сервер думав, перш ніж почати відповідати: це база даних, застосунок, промах кеша. Загальний час додає передавання відповіді, тобто розмір сторінки й канал. Сайт із першим байтом на 900 мс і загальним часом 950 мс має повільний застосунок; сайт із 80 мс і 2 с — важку сторінку. Ліки в цих двох випадків спільного не мають нічого, а єдине число «час завантаження» ховає, який із них ваш.
Чого ця перевірка сказати не може
Ми звертаємось до сторінки один раз, з одного місця і з User-Agent, який називає цей інструмент. Сайт за CDN може відповісти нам з іншого вузла, ніж відповідає вам. Сайт, що фільтрує трафік датацентрів, може дати нам 403, якого відвідувачу не дав би ніколи. І ми читаємо лише той HTML, який віддав сервер: нічого не виконується, тож сторінка, яка збирається в JavaScript, виглядатиме тут порожнішою, ніж у браузері.
Якщо відповідь виглядає неправильною, наступне питання зазвичай — де саме проблема. DNS-записи скажуть, чи вказує ім'я туди, куди ви думаєте, перевірка портів — чи слухає там хоч щось, а ping — чи досяжний вузол узагалі.