Безопасность веб-сервера и Firewall

Продолжение занятия по Nginx: как защитить сервер на базовом уровне, открыть только нужные порты, не потерять SSH-доступ и диагностировать проблемы с сетевым доступом.

Цели занятия

На этом занятии не повторяется базовая настройка сайта в Nginx. Основной фокус — безопасность сервера: какие порты должны быть доступны, как работает firewall, почему важно защищать SSH и как проверять подозрительные подключения.

Фокус

Минимальная поверхность атаки

Открыты только те порты, которые действительно нужны для работы сервера.

Инструмент

UFW

Простой firewall для Ubuntu/Debian, удобный для учебной и базовой серверной практики.

Результат

Безопасный порядок действий

Студент понимает, как не закрыть себе доступ к серверу и как проверять правила.

После занятия студент должен уметь:

1. Базовая модель безопасности сервера

Безопасность сервера строится на простом принципе: всё лишнее должно быть закрыто. Если сервис не нужен пользователям из интернета, он не должен быть доступен извне.

Главный принцип

Запрещено всё, что явно не разрешено.

Для веб-сервера обычно нужно оставить доступными только:

Если на сервере открыты лишние порты, это увеличивает поверхность атаки. Поверхность атаки — это всё, через что злоумышленник потенциально может попытаться воздействовать на систему.

Примеры опасных ситуаций

Ситуация Почему опасно
Открыт порт базы данных наружу К базе могут пытаться подключиться посторонние пользователи.
SSH доступен всем с паролем Сервер могут атаковать перебором паролей.
Открыты тестовые панели и админки Их могут найти сканеры и попытаться взломать.
Нет логирования Сложнее понять, что произошло при атаке или ошибке.

2. Порты и сетевые службы

Порт — это номер, по которому клиент подключается к конкретной службе на сервере. Если порт закрыт firewall, подключение снаружи не пройдёт.

Основные порты

Порт Протокол Назначение Открывать наружу?
22/tcp SSH Удалённое администрирование сервера. Да, но лучше ограничить по IP или использовать нестандартный порт.
80/tcp HTTP Обычный веб-трафик. Да, если сайт должен открываться по HTTP.
443/tcp HTTPS Защищённый веб-трафик. Да, для публичного сайта.
3306/tcp MySQL/MariaDB База данных. Обычно нет.
5432/tcp PostgreSQL База данных. Обычно нет.
6379/tcp Redis Кэш и хранилище данных. Обычно нет.

Проверка слушающих портов

sudo ss -tulpn

Проверка конкретного порта

sudo ss -tulpn | grep ':80'
sudo ss -tulpn | grep ':443'
sudo ss -tulpn | grep ':22'
Если служба слушает порт, это ещё не значит, что порт доступен из интернета. Подключение может блокировать firewall или сетевые правила хостинга.

3. Firewall UFW

UFW — это удобный инструмент для управления firewall. Он позволяет быстро разрешать и запрещать подключения к портам.

Проверка состояния

sudo ufw status

Более подробный вывод:

sudo ufw status verbose

Безопасное включение firewall

Перед включением firewall обязательно нужно разрешить SSH, иначе можно потерять удалённый доступ к серверу.

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status
Ошибка новичка: выполнить sudo ufw enable, не разрешив SSH. На удалённом сервере это может отрезать администратора от системы.

Запрет входящих подключений по умолчанию

sudo ufw default deny incoming

Разрешение исходящих подключений по умолчанию

sudo ufw default allow outgoing

Удаление правила

sudo ufw delete allow 80/tcp

Просмотр правил с номерами

sudo ufw status numbered

Удаление правила по номеру

sudo ufw delete 3
При удалении правил нужно быть аккуратным. Перед удалением проверьте список командой sudo ufw status numbered.

4. Безопасность SSH-доступа

SSH — основной способ удалённого управления сервером. Именно поэтому его часто атакуют автоматические боты.

Базовые меры защиты SSH

Мера Что даёт
Использовать SSH-ключи Снижает риск подбора пароля.
Отключить вход root по SSH Уменьшает риск прямого взлома администратора.
Ограничить SSH по IP Подключиться смогут только разрешённые адреса.
Использовать нестандартный порт Уменьшает количество автоматического шума в логах.
Следить за логами Помогает увидеть попытки перебора.

Разрешить SSH только с конкретного IP

sudo ufw allow from 203.0.113.10 to any port 22 proto tcp

Вместо 203.0.113.10 нужно указать реальный IP администратора.

Запретить обычное правило SSH для всех

sudo ufw delete allow 22/tcp
Это действие нельзя выполнять, если вы не уверены, что новое правило по IP работает. Иначе можно потерять доступ к серверу.

Проверка SSH-логов

sudo journalctl -u ssh -n 50
sudo journalctl -u ssh -f
Задание: объясните, почему SSH-порт опасно оставлять открытым для всех, если вход разрешён по паролю.

5. Ограничение доступа к отдельным разделам сайта

Firewall работает на уровне портов и IP-адресов. Но иногда нужно ограничить доступ только к отдельной части сайта, например к служебной странице или внутренней панели.

Ограничение доступа по IP

location /admin/ {
    allow 203.0.113.10;
    deny all;
}

Такой блок разрешает доступ к /admin/ только с одного IP-адреса.

Запрет доступа к скрытым файлам

location ~ /\. {
    deny all;
}

Это правило запрещает доступ к скрытым файлам, например к .env, .git и другим служебным данным.

Файл .env не должен быть доступен через браузер. В нём часто хранятся пароли, токены и настройки подключения к базе данных.

Запрет доступа к директории с приватными файлами

location /private/ {
    deny all;
}
Такие ограничения не заменяют полноценную авторизацию в приложении, но помогают закрыть очевидно опасные места.

6. Базовые security headers

Security headers — это HTTP-заголовки, которые помогают браузеру безопаснее обрабатывать сайт. Они не заменяют firewall, но добавляют базовый уровень защиты.

Пример базовых заголовков

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header X-XSS-Protection "1; mode=block" always;
Заголовок Назначение
X-Frame-Options Ограничивает встраивание сайта во фреймы.
X-Content-Type-Options Запрещает браузеру угадывать тип файла вместо указанного сервером.
Referrer-Policy Управляет передачей информации об исходной странице.
X-XSS-Protection Включает устаревший, но всё ещё встречающийся механизм защиты от XSS в некоторых браузерах.
Для современных проектов часто дополнительно настраивают Content-Security-Policy, но это более сложная тема. Неправильная CSP может сломать загрузку скриптов и стилей.

7. Логи безопасности

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

Логи входа по SSH

sudo journalctl -u ssh -n 100

Логи firewall UFW

sudo ufw logging on
sudo tail -f /var/log/ufw.log

Логи веб-запросов

sudo tail -f /var/log/nginx/access.log

Логи ошибок веб-сервера

sudo tail -f /var/log/nginx/error.log

Что искать в логах

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

8. Диагностика проблем с доступом

Проблемы с доступом нужно проверять по цепочке: служба, порт, firewall, логи, внешнее подключение.

Сайт не открывается снаружи

Проверка Команда Что понять
Работает ли служба sudo systemctl status nginx Запущен ли веб-сервер.
Слушает ли порт sudo ss -tulpn | grep ':80' Есть ли процесс на порту 80.
Разрешён ли порт sudo ufw status Открыт ли порт в firewall.
Есть ли ошибки sudo tail -f /var/log/nginx/error.log Есть ли ошибки обработки запросов.

Проверка внешнего доступа с другого устройства

curl -I http://example.com
curl -I https://example.com

Проверка, кто слушает порт

sudo ss -tulpn | grep ':80'
sudo ss -tulpn | grep ':443'

Порт открыт в UFW, но сайт всё равно не доступен

Возможные причины:

9. Практическая работа

Задание 1. Проверьте состояние firewall.
sudo ufw status verbose
Нужно определить: включён ли firewall и какие порты разрешены.
Задание 2. Разрешите безопасный минимальный набор портов для веб-сервера.
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Нужно объяснить назначение каждого порта.
Задание 3. Проверьте, какие процессы слушают сетевые порты.
sudo ss -tulpn
Нужно найти процессы на портах 22, 80 и 443.
Задание 4. Посмотрите последние события SSH.
sudo journalctl -u ssh -n 50
Нужно определить, были ли неудачные попытки входа.
Задание 5. Найдите в access-логе подозрительные запросы.
sudo tail -n 100 /var/log/nginx/access.log
Нужно обратить внимание на запросы к /.env, /.git, /admin, /wp-admin.
Задание 6. Составьте безопасный порядок включения firewall на удалённом сервере.

В ответе должны быть: разрешение SSH, разрешение HTTP/HTTPS, включение UFW, проверка статуса.

10. Мини-проверка

Вопросы

  1. Зачем серверу firewall?
  2. Что означает принцип «запрещено всё, что явно не разрешено»?
  3. Для чего нужен порт 22/tcp?
  4. Для чего нужен порт 80/tcp?
  5. Для чего нужен порт 443/tcp?
  6. Почему опасно открывать порт базы данных наружу?
  7. Как проверить статус UFW?
  8. Почему перед включением UFW нужно разрешить SSH?
  9. Как посмотреть слушающие порты?
  10. Что означает адрес 127.0.0.1?
  11. Как ограничить SSH-доступ по IP?
  12. Зачем смотреть SSH-логи?
  13. Почему файл .env нельзя отдавать через сайт?
  14. Для чего нужны security headers?
  15. Какие запросы в access-логе можно считать подозрительными?

Ответы для самопроверки

  1. Чтобы фильтровать подключения и закрывать лишние порты.
  2. По умолчанию доступ закрыт, открываются только нужные сервисы.
  3. Для удалённого администрирования по SSH.
  4. Для обычного HTTP-доступа к сайту.
  5. Для защищённого HTTPS-доступа к сайту.
  6. К ней могут пытаться подключиться посторонние пользователи.
  7. Командой sudo ufw status или sudo ufw status verbose.
  8. Иначе можно потерять удалённый доступ к серверу.
  9. Командой sudo ss -tulpn.
  10. Это локальный адрес, доступный внутри самого сервера.
  11. Правилом sudo ufw allow from IP to any port 22 proto tcp.
  12. Чтобы видеть попытки входа и возможный перебор паролей.
  13. В нём могут быть пароли, токены и секретные настройки.
  14. Чтобы добавить браузерные механизмы защиты.
  15. Например, запросы к /.env, /.git, /admin, /wp-admin.

11. Итоговый чек-лист безопасности

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

1. Проверить firewall:
   sudo ufw status verbose

2. Разрешить только нужные порты:
   sudo ufw allow 22/tcp
   sudo ufw allow 80/tcp
   sudo ufw allow 443/tcp

3. Проверить слушающие порты:
   sudo ss -tulpn

4. Проверить SSH-логи:
   sudo journalctl -u ssh -n 50

5. Проверить веб-логи:
   sudo tail -n 100 /var/log/nginx/access.log
   sudo tail -n 100 /var/log/nginx/error.log

6. Закрыть доступ к служебным файлам:
   .env
   .git
   private-директории

7. Не открывать наружу:
   базы данных
   Redis
   внутренние панели
   тестовые сервисы
Главный вывод: безопасный сервер — это сервер, где открыто только необходимое, доступы контролируются, а логи регулярно проверяются.