Заощадьте 15% на всіх хостингових послугах

Перевірте свої навички і отримайте Знижку на будь-який план хостингу

Використовуй код: Skills Почати
Рубрики
Адміністрація Віртуальні сервери

Вебсайт не працює, але сервер доступний? Відстежте збій від DNS до додатку

«SSH працює, сайт не працює» — почніть з правильного питання

Сигнали тривоги починають спрацьовувати, користувачі кажуть, що сайт не працює, а ваш перший тест дає вам дивну розраду: SSH все ще дозволяє вам увійти. Цей момент здається заспокійливим, тому що сервер не зник. Але це також місце, де починається багато поганого усунення несправностей, тому що «я все ще можу увійти» — це не те саме, що «веб-сайт повинен працювати».

problem

Корисне питання — не «що я можу перезавантажити першим?» Це «який рівень вийшов з ладу першим?» Робоча сесія SSH доводить, що машина досяжна на порту 22. Вона не доводить, що домен правильно розпізнається. Вона не доводить:

  • порти 80 та 443 досяжні
  • HTTPS здоровий
  • програма за веб-сервером відповідає

Цей посібник побудований навколо цієї відмінності та залишається зосередженим на діагностиці, а не намагається стати повним посібником з nginx, DNS, TLS, Docker або баз даних.

⚠️ Попередження: Сліпе перезавантаження nginx, Docker, PHP-FPM або всього VPS у перші хвилини інциденту може стерти докази, які вам потрібні. Спочатку зберіть один раунд доказів, а потім змініть лише той рівень, який насправді вийшов з ладу.

Карта тріажу за одну хвилину

info

Перш ніж заглиблюватися, орієнтуйтеся. Форма збою часто підказує, на який рівень варто звернути увагу першим, навіть якщо ви ще не знаєте основної причини.

Розглядайте наступну таблицю як скорочений шлях тріажу, а не остаточний вердикт.

Що ви бачитеЩо це зазвичай означаєЩо перевірити першимЧого не варто припускати
🧭 Could not resolve hostІм’я не розпізналося на адресуDNS записи, шлях резолвера, опечаткиВеб-сервер обов’язково є проблемою
⏱️ TimeoutТрафік заблокований, неправильно маршрутизований або зависає далі в ланцюзіЗовнішній curl, шлях брандмауера, маршрутизація, доступність слухачаУсі timeout означають одне й те саме
🚫 Connection refusedХост доступний, але там нічого корисного не приймає з’єднанняss -ltnp, стан сервісу, адреса прив’язкиВесь сервер вийшов з ладу
🔐 Попередження TLS або сертифікатаHTTPS досяг 443, але рівень ідентифікації або handshake не пройшовПоданий сертифікат, збіг імені хоста, ланцюг, стан поновленняДодаток точно не мертвий
⚠️ 502 / 503 / 504Доступний фронтенд або сервіс не працює вище в ланцюзіПередача upstream, доступність сервісу, місце timeoutКожна помилка 5xx означає одне й те саме виправлення
🏠 Працює локально, але не зовніСтек може бути в порядку на сервері, але зовнішній шлях зламанийБрандмауер хоста, брандмауер провайдера, шлях CDN, маршрутизаціяЛокальний успіх доводить публічну доступність

Важливо, який перший зламаний етап. Якщо DNS не працює, пізніші рівні — це шум. Якщо 443 відповідає, але TLS не пройшов, додаток — це не ваше перше питання. Ментальна модель нижче — це те, що робить цю послідовність логічною замість випадкової.

Чому SSH не доводить, що веб-сайт працює

SSH і веб-трафік — це різні шляхи з різними завданнями. SSH на порту 22 доводить, що ви можете досягти машини через її двері дистанційного управління. Веб-сайт залежить від портів 80 і 443, плюс шари за ними. Це окремі тести, тому “сервер доступний” і “веб-сайт доступний” — це не взаємозамінні твердження.

why

Найпростіший спосіб це уявити — як офісну будівлю. DNS допомагає відвідувачу знайти адресу будівлі. Порти 80 і 443 — це стійка реєстрації для публічних відвідувачів. Веб-сервер — це рецепціоніст, який приймає запит і вирішує, куди його далі спрямувати. Додаток — це офіс, який виконує реальну роботу. База даних або інша залежність може знаходитися глибше в будівлі. SSH — це зовсім інший вхід. Він корисний для персоналу, але він не доводить, що стійка реєстрації відкрита або що передача в офіс працює.

Browser
  ↓
DNS lookup
  ↓
IP address
  ↓
Port 80 / 443
  ↓
Web server
  ↓
App / upstream
  ↓
Database / dependency

Коли люди кажуть, що служба “слухає”, вони мають на увазі, що вона насправді приймає з’єднання на очікуваній кінцевій точці. Це розрізнення, яке перетворює розпливчасте “сервер працює” на відстежуваний шлях запиту.

Це важливо, тому що HTTPS може не спрацювати до того, як додаток коли-небудь відповість, а помилки проксі або додатків можуть статися після того, як фронтенд уже доступний. Тому наступний крок завжди той самий: дивіться ззовні спочатку і знайдіть останній успішний етап запиту.

Крок 1: Відтворіть збій ззовні сервера

Почніть з боку клієнта, а не з усередини VPS. Якщо можливо, спочатку протестуйте з іншої мережі або пристрою, щоб не сплутати локальний DNS кеш, старий запис /etc/hosts або проблему локального брандмауера/VPN з реальним збоєм сервера.

Використовуйте детальний зовнішній запит, щоб побачити, як далеко запит проходить перед тим, як він припиниться:

curl -v --connect-timeout 5 --max-time 15 https://example.com/

curl -v — це не інструмент тільки для експертів. Читайте його як трасування прогресу. Якщо він ніколи не розв’язує ім’я, ви в гілці DNS. Якщо він підключається, а потім говорить Connection refused, хост відповів, але нічого корисного там не приймає трафік. Якщо він зависає до тайм-ауту, думайте про фільтрацію, маршрутизацію або глибший зависання пізніше в шляху запиту. Якщо ви отримуєте HTTP відповідь, навіть сторінку помилки, ви вже пройшли повз рівень з’єднання і в вищу гілку.

💡 Порада: Порівняйте IPv4 та IPv6 на ранньому етапі. Забутий запис AAAA може зробити збій непослідовним, оскільки деякі клієнти віддають перевагу IPv6 спочатку, а інші — ні.

Запустіть той самий тест один раз для кожної сім’ї протоколів, коли задіяна двостекова архітектура:

curl -4 -v --connect-timeout 5 --max-time 15 https://example.com/
curl -6 -v --connect-timeout 5 --max-time 15 https://example.com/

Якщо IPv4 працює, а IPv6 не працює, або навпаки, ви вже звузили інцидент швидше, ніж перезавантаження служби коли-небудь могло б. Якщо збій починається з розв’язування імен або вибору призначення, DNS — це наступна чиста гілка для перевірки.

Крок 2: Перевірте DNS та підтвердіть правильну адресу призначення

Перед тим, як налагоджувати nginx, переконайтеся, що домен насправді відправляє відвідувачів на сервер, який ви думаєте. Це особливо важливо після міграцій, змін IP, коригувань CDN або часткових редагувань записів.

Спочатку перевірте публічні записи:

dig +short A example.com
dig +short AAAA example.com

Ці два рядки відповідають на дуже практичне питання: де інтернет вважає, що example.com знаходиться прямо зараз? Одна поширена форма помилки — це коли SSH за IP досягає нового VPS, але домен все ще вказує на стару адресу. Інша — це коли запис A був оновлений, але запис AAAA все ще вказує на щось застаріле. У цьому випадку лише частина вашого трафіку не працює.

📝 Примітка: curl --resolve безпечніший за зміну публічного DNS під час інциденту. Це дозволяє вам протестувати походження, яке ви маєте намір використовувати, зберігаючи при цьому ім’я хоста та SNI.

Використовуйте curl --resolve, щоб примусово протестувати IP, який ви очікуєте, без дотику до публічних записів:

curl --resolve example.com:443:203.0.113.10 https://example.com/

Якщо це працює, а публічний домен все ще не працює, сервер може бути в порядку, а DNS може бути все ще розбитим шаром. Одна обмежена примітка CDN варта уваги тут. Якщо ваше походження заблоковано для прийняття трафіку лише з діапазонів IP CDN, прямий тест походження може не пройти просто тому, що походження очікує трафіку від edge, а не довільних публічних запитів. Після підтвердження адреси призначення наступне питання полягає в тому, чи щось корисне відповідає на 80 або 443 там.

Крок 3: Перевірте, що прослуховує порти 80/443

Тепер перейдіть на сервер і задайте вузьке питання: чи дійсно щось приймає веб-з’єднання на очікуваних портах? Машина може бути активною, SSH може працювати, а nginx навіть може бути встановлений. Проте публічні веб-порти все ще можуть не мати корисного прослуховувача.

Спочатку перевірте прослуховувачі:

sudo ss -ltnp

Порожній вивід для :80 або :443 означає, що там нічого корисного не прослуховує. Прослуховувач на 127.0.0.1 означає, що сервіс приймає з’єднання лише з локальної машини. Прослуховувач на 0.0.0.0 означає, що він прив’язаний до IPv4 інтерфейсів. [::] зазвичай означає IPv6 інтерфейси. Не припускайте, що прив’язка IPv6 автоматично гарантує потрібний вам шлях IPv4.

Потім використайте невеликий пакет перевірки здоров’я nginx перед будь-якими змінами:

sudo systemctl status nginx --no-pager -l
sudo nginx -t
sudo journalctl -u nginx --since '-30 minutes' --no-pager
  • Якщо systemctl показує active (running), це лише доводить, що процес сервісу існує
  • nginx -t повідомляє, чи конфіг є дійсним
  • journalctl показує, чи нещодавна перезавантаження не вдалася, файл сертифіката зник, або vhost зламався під час запуску.

Для читачів Apache еквівалентний синтаксис перевірки — apachectl configtest. Коли ви дізнаєтеся, що щось прослуховує, наступний доказ є більш конкретним: чи відповідає правильний сайт локально, коли ви виключаєте зовнішню мережу з рівняння?

💡 Порада: Спочатку перевірте конфіг, потім віддавайте перевагу reload замість сліпого перезапуску, коли це доречно. Перезавантаження перевіряє новий конфіг і зберігає старих робітників, якщо новий конфіг поганий; сліпий перезапуск набагато грубіший посередині інциденту.

Крок 4: Локально протестуйте сайт з правильним хостом та SNI

Це найважливіший розгалуження в усьому дослідженні. Простий curl 127.0.0.1 може бути оманливим. Багато серверів розміщують кілька сайтів і вибирають відповідь на основі заголовка Host або, для HTTPS, SNI. Ви не запитуєте, чи щось відповідає локально. Ви запитуєте, чи відповідає правильний шлях сайту локально.

Використовуйте локальні тести, які зберігають логіку імені хосту:

curl -I http://127.0.0.1/ -H 'Host: example.com'
curl -v --resolve example.com:443:127.0.0.1 https://example.com/

# Only as a one-off diagnostic if you already know the cert is bad:
curl -vk --resolve example.com:443:127.0.0.1 https://example.com/

Змістовний успіх — це очікувана сторінка, очікуване перенаправлення або очікувана відповідь програми з правильного сайту. Це не хост nginx за замовчуванням, неправильний сертифікат або загальне “він повернув HTML”. Звідси є три чистих результати: локальний успіх, локальна поведінка неправильного сайту або сертифіката за замовчуванням, або локальна помилка/тайм-аут. Хороший локальний результат вказує назовні на брандмауер, провайдера, CDN або перевірки маршрутизації. Поганий локальний результат тримає вас всередині стека, у гілках upstream або TLS.

Крок 5: Якщо локально працює, але зовні ні, простежте мережевий шлях

Коли локальний тест пройшов успішно, припиніть на момент сумніватися в nginx. Стек сайту, ймовірно, живий на сервері, а відсутня частина зазвичай знаходиться десь між відвідувачем і цим робочим локальним сервісом. Почніть з брандмауера хоста, оскільки це найближча зовнішня межа, яку ви контролюєте.

Перевірте правила на стороні хоста за допомогою інструменту, який насправді використовує ваша система, і виконайте одну швидку перевірку розуму для самостійного блокування, поки ви там:

sudo nft list ruleset

# Or, on systems still using iptables directly:
sudo iptables-save
sudo ip6tables-save

# Fast sanity check for self-inflicted blocking:
sudo fail2ban-client status

Цей вивід показує лише рівень гостьової ОС. Він не показує фільтрування на стороні провайдера, групи безпеки або правила брандмауера на рівні панелі, які знаходяться поза самим VPS. На VPS AlexHost, наприклад, брандмауер машини та будь-які елементи керування мережею на рівні панелі — це окремі питання. Обидва мають значення, коли локальні тести працюють, але публічні відвідувачі все ще не можуть отримати доступ.

⚠️ Попередження: Якщо Docker публікує порти на хості, не припускайте, що вивід UFW розповідає всю історію. Docker може маршрутизувати опубліковану трафік контейнера через NAT перед звичайними ланцюгами UFW. Це означає, що «UFW виглядає добре» не завжди означає, що шлях пакета добре.

CDN та балансувальники навантаження також заслуговують на власну гілку тут. Джерело може бути здоровим і все ще недосяжним безпосередньо, оскільки дозволено розмовляти з ним лише діапазонам IP edge. Коли вам потрібен доказ того, чи пакети взагалі прибувають, використовуйте tcpdump як інструмент «так чи ні»:

📝 Примітка: Невдалий тест прямого походження за дозволом CDN зазвичай вказує на політику edge, а не на мертве походження. У цій конфігурації походження розроблено для довіри до шляху CDN, а не до кожного прямого відвідувача.

sudo tcpdump -ni any 'tcp port 80 or tcp port 443'

Якщо ви взагалі не бачите пакетів SYN, трафік не досягає сервера. Якщо SYN прибувають і SYN-ACK не залишає, сервер або шлях брандмауера все ще блокує передачу. Якщо жоден із цих шаблонів не здається блокатором, решта збоїв зазвичай сидять позаду фронтенду в передачі вище за течією.

Крок 6: Якщо Frontend відповідає, але сайт все ще не працює, слідуйте Upstream

У цій гілці веб-сервер доступний, але наступний хоп за ним недостатньо здоровий для завершення запиту. Тут “upstream” означає сервіс, якому nginx передає запит далі: процес додатку, runtime на основі сокета, контейнер або іншу внутрішню залежність.

Статичні сторінки працюють, а вхід, пошук, оформлення замовлення або маршрути API не працюють — це сильна ознака того, що frontend присутній, а збій починається на передачі за ним.

📝 Примітка: Розглядайте 502 як “наступний хоп відповів погано” і 504 як “наступний хоп відповів занадто повільно.” Обидва — ознаки для слідування шляхом upstream, а не зупинки на frontend.

Перевірте активну передачу, потім протестуйте upstream безпосередньо:

sudo nginx -T

# Direct HTTP upstream example
curl -i http://127.0.0.1:3000/

# Unix-socket-backed HTTP example
curl --unix-socket /run/app.sock http://localhost/

У виводі nginx шукайте директиви такі як proxy_pass, fastcgi_pass або uwsgi_pass. Ви перевіряєте, чи nginx вказує на правильну ціль, через правильний протокол, на правильному порту або сокеті. Якщо задіяні контейнери, додайте коротку перевірку здоров’я контейнера замість здогадок:

docker ps
docker logs --tail 50 <container_name>
docker inspect --format '{{json .State.Health}}' <container_name>
docker port <container_name>

Якщо прямий тест додатку не вдається, проблема знаходиться за веб-сервером. Якщо він працює безпосередньо, але не працює через nginx, конфігурація передачі — це гілка для перевірки. Доступність бази даних має значення лише як перевірка залежності тут, а не як окремий глибокий аналіз. Якщо цей шаблон збою upstream продовжує повторюватися, це правильний момент для переходу на спеціалізований посібник з усунення неполадок замість розтягування одного інциденту на здогадки.

Крок 7: Ізолювання збоїв TLS та сертифіката

Ця гілка вужча: щось відповідає на 443, але браузер все ще не може завершити чисту, надійну сеанс HTTPS. Успішне TCP-з’єднання до порту 443 не доводить, що сертифікат, збіг імені хоста або шлях рукостискання здорові.

Перевірте, який сертифікат насправді подається:

openssl s_client -connect example.com:443 -servername example.com -verify_hostname example.com -brief

Тут ви ловите типові форми збоїв: неправильне ім’я хоста, закінчений сертифікат, неповний ланцюг або поновлення, яке ніколи не завершилося чисто. Простою мовою, SNI повідомляє серверу, яке ім’я хоста ви мали на увазі. -verify_hostname перевіряє, чи сертифікат, який він подав, відповідає цьому імені хоста. Після відновлення перевірте шлях поновлення, щоб це не стало наступним збоєм:

⚠️ Попередження: Якщо ви покладаєтеся на валідацію HTTP-01 для поновлення сертифіката, вхідний порт 80 повинен бути доступним. Брандмауер або правило провайдера, яке блокує 80, може тихо зламати поновлення задовго до того, як користувачі повідомлять, що HTTPS виглядає мертвим.

sudo certbot renew --dry-run

Крок 8: Перевірте навантаження на ресурси перед тим, як назвати це випадковим

Деякі інциденти взагалі не є збоями доступності. Маршрут технічно цілий, але сервер занадто виснажений, заблокований або перевантажений, щоб відповісти вчасно. Саме тоді сайт може виглядати «частково живим» з одного боку і все ще здаватися мертвим для користувачів.

Запустіть невеликий пакет ресурсів першого проходу:

df -h
df -i
free -h
uptime
vmstat 1 5
sudo journalctl -k -g 'oom|out of memory|killed process'

Читайте результати в закономірностях, а не ізольовано.

  • df -h показує звичайне вичерпання диска.
  • df -i виявляє вичерпання inode, коли місце здається існуючим, але файлова система не може створити більше записів.
  • free -h найважливіша, коли доступна пам’ять падає і активність swap зростає.
  • uptime може показати високе навантаження навіть коли CPU не максимально навантажений, що часто означає, що завдання чекають на диск або тиск пам’яті, а не активні обчислення.
  • Рядки журналу ядра про події OOM повідомляють вам, чи система почала вбивати процеси, щоб вижити.

Графіки провайдера можуть підтвердити часову шкалу. На VPS AlexHost вони можуть бути корисні для перевірки того, чи збігаються сплески RAM, диска або I/O з перебоєм. Але термінальні докази все ще повинні вести діагностику. Цей розділ не є посібником з налаштування; це гілка, яка говорить вам, що сайт може відмовляти під тиском, а не відмовляти маршрутизувати.

Думайте шарами, а не панікуйте

end

Коли SSH працює, але веб-сайт не відкривається, тримайте ланцюг коротким і повторюваним:

  1. відтворіть збій зовні
  2. визначте останній успішний етап
  3. підтвердіть DNS та призначення
  4. перевірте реальний слухач на 80/443
  5. протестуйте правильний сайт локально
  6. розгалужуйтесь у мережевий шлях, upstream, TLS або ресурси

💡 Порада: Не закривайте останній робочий SSH сеанс, поки не підтвердите, що свіжий вхід все ще працює, і у вас все ще є резервний шлях доступу, наприклад доступ через консоль провайдера. Під час живого інциденту збереження контролю важливо так само, як і виправлення першого симптому.

Тримайте звички легкими: моніторьте зовні, ведіть журнали та тестуйте сертифікати за допомогою certbot renew –dry-run. Захистіть доступ резервними копіями та шляхом консолі. Інструменти провайдера — брандмауер, графіки, консоль (включаючи AlexHost) — повинні підтримувати усунення неполадок, а не замінювати його. Зосередьтесь на виправленні першого зламаного шару, щоб кожен інцидент розглядався з яснішими доказами та меншою панікою.