Try   HackMD
tags: МДК02.05 Организация администрирования операционных систем Linux Linux

Лабораторная работа №10. Настройка веб сервера Nginx.

Тема: Настройка веб сервера Nginx.

Цель работы: Научиться настраивать web сервер Nginx на OC Linux.
Необходимые материалы: Пк с доступом в интернет. Виртуальные машины с Linux Debian и Ubuntu.

Теоретическая часть

Nginx был создан 2004 году российским разработчиком Игорем Владимировичем Сысоев из-за того что он был разочарован в Apache он хотел создать замену способную выдержать 10 тысяч одновременных запросов. Он сфокусировался на высокой производительности большом количестве одновременных соединений и низком потреблении памяти. В результате Nginx стал очень популярен. На сегодняшний день Nginx обслуживает большую часть сайтов из топ 1000 это произошло благодаря его производительности и так же произошло потому что с Nginx относительно легко начать работать. Конечно это не в коем случае не простой софт, но он позволяет легко реализовать такие функции как caching и streaming video, также существует огромное количество модулей как от разработчиков, так и от третьих лиц которые помогают расширить функционал.

Веб-сервер Nginx по сути просто отдает пользователю файлы по протоколу http. А уже браузеры интерпретируют эти файлы и отображают веб-страницу. Браузеры умеют отображать язык гипертекстовой разметки html и исполнять скрипты на JavaScript. Про php, python, ruby и прочие языки ни веб-сервер с базовыми настройками, ни браузер не имеют ни малейшего понятия. Если запросить файл php, то мы увидим код страницы, вместо сайта.

Принцип работы:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Apache был медленным?

Apache является самым функциональным веб-сервером на данный момент. В свое время он стал прорывом и двигателем развития интернета. Почти под любые задачи существуют модули. Однако платой за это все является большая ресурсоемкость. Для небольших проектов, либо проектов, которым эта функциональность избыточна лучше использовать легковесный веб-сервер вроде nginx или lighthttpd.

Nginx работает в связке с PHP-FPM.
Подробнее про PHP – FRM.( https://perfect-inc.com/journal/nginx-php-fpm-i-chto-eto-voobshche/).
Nginx - это разработанный Игорем Сысоевым http-proxy-сервер (он сам чаще называет его proxy-сервером, чем web-сервером). Это и есть его основное отличие от Apache (обычно к nginx приходят те, кто испытывает проблемы с Apache). Благодаря тому, что Nginx сам не выполняет никакой тяжелой работы, Игорь смог заложить в него прекрасную асинхронную событийную архитектуру.

Благодаря этой архитектуре nginx на порядки быстрее обрабатывает запросы, чем любой другой сервер и благодаря ей же потребляет при этом сильно меньше ресурсов. Как это происходит?

Один рабочий процесс nginx обрабатывает не один запрос пользователя (как apache), а тысячи этих запросов. Ввиду того, что nginx - это proxy-сервер, для него не составляет никакого труда получить запрос пользователя, отправить его на backend (например php-fpm), а пока бакенд занят трудом, nginx обрабатывает остальные запросы пользователей, когда FPM ответит Nginx-у о том что запрос обработан и отдаст ответ, nginx передаст ответ назад пользователю.

В качестве интерператора PHP мы возьмем пакет PHP-FPM. Он специально разработан как прослойка между интерпретатором PHP и ПО, которое хочет работать с интерпретатором через FastCGI. В то же время FPM это не просто прослойка, а полноценный менеджер процессов, который следит за выполнение процессов, ограничениями, утечками памяти и т.д. Внешне для нас это выглядит так: мы отправили код на php, а в ответ получаем текст-результат выполнения кода.

Просто и прозрачно.

Ты ввел в Chrome адрес auto.ru, твой запрос поймал Nginx от auto.ru и передал его в php-fpm , а дальше PHP-fpm запустил PHP, который подключился к базе данных выбрал все картинки и информацию о машинах, php-fpm отгрузил его в nginx, а nginx отправил твоему Chrome.

Конфигурационный файл

Разберем структуру основного конфигурационного файла /etc/nginx/nginx.conf:

user www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 768; # multi_accept on; } http { sendfile on; tcp_nopush on; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POO> ssl_prefer_server_ciphers on; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; gzip on; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }

И так что же означают эти строки:

  • main{} - Хотя мы это и не видим но весь конфиг собираеться в один main файл. Основным контекстом является main. Этот глобальный контекст является единственным, который не содержится в типичных блоках контекста. Любая директива, которая существует полностью за пределами других блоков, относится к глобальному контексту main. Имейте в виду, если ваша конфигурация Nginx настроена модульным способом, некоторые файлы будут содержать инструкции, которые существуют вне контекста, но они будут включены в контекст при объединении конфигурации. Контекст main представляет собой самую широкую среду для конфигурации Nginx. Он используется для настройки параметров, которые влияют на все приложение на базовом уровне. Хотя директивы в этом разделе влияют на другие контексты, многие из них не наследуются, потому что их нельзя переопределить на более низких уровнях.
  • user www-data; - Тут указываеться пользователь nginx от которого стортует сервис, важно чтобы доступ к файлам сайтов с которыми взаимодействует nginx был открыт для этого пользователя.
  • worker_processes auto; и worker_connections 768; - (кол-во ядер и макс. подключений). Если Nginx выполняет работу нагружающую процессор (например SSL или gzipping), то оптимально установить эту директиву в значение, равное количеству ядер процессора. Выигрыш при большем значении вы получите только в случае обработки очень большого количества статики.Также, директива worker_processes, умноженная на worker_connections из секции event, даст максимально возможное количество клиентов.
  • pid /run/nginx.pid; - В данной директиве указываеться путь до файла в который записываеться главный номер процесса nginx. Файл PID содержит идентификационный номер процесса демона или программы, работающей в системе на основе Linux и UNIX
  • include /etc/nginx/modules-enabled/*.conf; - Все дерективы include в качестве значения принимают путь до конфигурационных файлов nginx. В процессе запуска nginx обьеденяет все конфигуарационные файлы в один большой, это похоже на то как вы и импортируете файлы кода в основной файл программы. В данном случае конфиги по указанному пути записываються в секцию main.
  • events {} - Контекст (секция) events находится внутри контекста main. Он определяет глобальные параметры, влияющие на то, как Nginx обрабатывает соединения. В конфигурации Nginx может быть только один контекст events. Nginx использует модель обработки соединения на основе событий, поэтому директивы, определенные в этом контексте, указывают, как рабочие процессы должны обрабатывать соединения. В основном, директивы этого контекста используются либо для определения технологии обработки соединений, либо для изменения способа реализации этих методов.
  • http {} - При настройке Nginx как веб-сервера или обратного прокси-сервера большую часть конфигурации будет содержать контекст http. Этот контекст хранит все директивы и другие контексты, необходимые для настройки обработки соединений HTTP или HTTPS. Контексты http и events принадлежат одному уровню, потому они не вкладываются друг в друга, а определяются как одноранговые. Оба они являются дочерними по отношению к контексту main.
  • sendfile on; tcp_nopush on; types_hash_max_size 2048; - Эти параметры относяться к настройкам простокола tcp. Сейчас вам не стоит обращать на них внимание.
  • include /etc/nginx/mime.types; - Важно про файл mime.types. Если удалить эту директиву и перейти на какой-то из сайтов обслуживаемых nginx то мы заметим следующие:
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
    Что то не так правда? Если вы откроете инструменты разработчика то увидите что css и остальные файлы загрузились однако на сайте у нас явно простой html. Дело в том что Nginx не совсем корректно отправляет mime.types. Можем в этом убедиться выполнив curl -I.
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
    Как видно из это скриншота в заголовке Content-Type у нас указан text/plain. Что не корректно для css файла. И так файл mime.types выглядит следующим образом:
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
    В этом файле перечисляются тип контента и расширение файлов котором данный тип соответствует. Вот так выглядит сайт если есть это параметр:
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
  • ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; и ssl_prefer_server_ciphers on - Параметры определяющие с какми версиями протокола TLS будет работать веб сервер.
  • access_log /var/log/nginx/access.log; и error_log /var/log/nginx/error.log; - Эти параметры определяют где будут лежать файлы логов.
  • gzip on; - Включает сжатие трафика, значительно ускоряет работ web сервера.
  • include /etc/nginx/conf.d/*.conf; и include /etc/nginx/sites-enabled/*; - Пути по котором nginx ищит файлы конфигурации виртуальных хостов и вкладывает их в секцию http.

Конфигурация виртуального хоста nginx

Конфигурационный файл nginx отчищенный от коментариев:

server {
        listen 80 default_server;
        listen [::]:80 default_server;

root /var/www/html;

server_name _;

        location / {
                try_files $uri $uri/ =404;
        }
}

И так давайте разберем минимальную конфигурацию виртуального хоста в nginx:

  • server {} - Контекст server обычно объявляется в контексте http. Это первый пример вложенного контекста в этом мануале. Это также первый контекст, который можно объявить несколько раз.Этот контекст можно объявлять много раз потому, что каждый отдельный контекст server отвечает за настройку отдельного виртуального хоста для обработки клиентских запросов. Вы можете создать любое количество блоков server, каждый из которых может обрабатывать определенное подмножество соединений. Блоки server очень похожи друг на друга, потому Nginx должен использовать алгоритм выбора для определения нужного контекста. Каждый запрос клиента будет обрабатываться в соответствии с конфигурацией, определенной в одном из существующих блоков server, поэтому веб-сервер Nginx на основе данных самого запроса должен решить, какой контекст server больше всего подходит. Вот директивы, которые решают, будет ли блок server использоваться для обслуживания запроса:
    • listen: комбинация ip–адреса и порта, которую прослушивает этот блок server. Если запрос выполняется клиентом, который запрашивает эти значения, этот блок будет выбран для обработки соединения.
    • server_name: эта директива также используется для выбора блока server для обработки запроса. Если в файле есть несколько блоков server с одинаковыми директивами listen, Nginx будет анализировать заголовок Host запроса и сопоставлять его с этой директивой.

Директивы в этом контексте могут переопределять многие из директив контекста http, включая логирование, document root, сжатие и т.п. В дополнение к директивам контекста http, тут можно также настроить использование найденных файлов для обработки запроса (try_files), перенаправление и перезапись (return и rewrite) и установить произвольные переменные (set).

  • root /var/www/html; - Путь до директории с статическим контентом сайта который нужно вернуть клиенту.
  • location{} - Контексты location имеют много общего с контекстами server. Например, вы можете определить несколько контекстов location, каждый из которых используется для обработки определенного типа клиентского запроса. Блок location выбирается в результате сопоставления местоположения с запросом клиента с помощью алгоритма выбора. Если директивы, определяющие, следует ли выбирать блок server, определяются в контексте server, то компонент, который позволяет выбрать location, находится в самом определении location (в строке, которая открывает блок location). Блоки location находятся в контексте server и, в отличие от блоков server, могут вкладываться друг в друга. Это может быть полезно для создания более общего контекста location и для улавливания определенного подмножества трафика, а также для дальнейшей обработки его на основе более конкретных критериев с дополнительными контекстами.Хотя контексты сервера выбираются на основе запрошенной комбинации из IP-адреса, порта и имени хоста в заголовке Host, блоки location дополнительно делят обработку запросов в блоке server, просматривая URI запроса. URI запроса – это часть запроса, которая идет после имени домена или комбинации IP-адреса/порта. Таким образом, если клиент запрашивает http://www.example.com/blog по порту 80, то для определения нужного блока server будут использоваться http, www.example.com и порт 80. После выбора блока будет оцениваться URI запроса – в данном примере это часть /blog – чтобы определить, какой дополнительный контекст должен использоваться для ответа на запрос.

Обратный прокси сервер.

Обратный прокси-сервер — это служба, которая принимает запрос клиента, отправляет запрос одному или нескольким прокси-серверам, получает ответ и доставляет ответ сервера клиенту.
Использование Nginx в качестве обратного прокси дает вам несколько дополнительных преимуществ:

  • Балансировка нагрузки — Nginx может выполнять балансировку нагрузки для распределения запросов клиентов по прокси-серверам, что повышает производительность, масштабируемость и надежность.
  • Кеширование. Используя Nginx в качестве обратного прокси-сервера, вы можете кэшировать предварительно обработанные версии страниц, чтобы ускорить загрузку страницы. Он работает путем кэширования содержимого, полученного от ответов прокси-серверов, и использования его для ответа клиентам без необходимости каждый раз связываться с прокси-сервером для получения одного и того же содержимого.
  • Завершение SSL — Nginx может выступать в качестве конечной точки SSL для соединений с клиентами. Он будет обрабатывать и расшифровывать входящие SSL-соединения и шифровать ответы прокси-сервера.
  • Сжатие — если прокси-сервер не отправляет сжатые ответы, вы можете настроить Nginx для сжатия ответов перед их отправкой клиентам.
  • Смягчение DDoS-атак — вы можете ограничить входящие запросы и количество подключений на один IP-адрес до значения, типичного для обычных пользователей. Nginx также позволяет блокировать или ограничивать доступ в зависимости от местоположения клиента и значения заголовков запроса, таких как «User-Agent» и «Referer».

Как работает обратный прокси сервер?

Обратный прокси-сервер (англ. reverse proxy) — тип прокси-сервера, который ретранслирует запросы клиентов из внешней сети на один или несколько серверов, логически расположенных во внутренней сети. При этом для клиента это выглядит так, будто запрашиваемые ресурсы находятся непосредственно на прокси-сервере.

Для того чтобы настроить проксирование используеться директива proxy-pass.

Балансировка нагрузки

Балансировка нагрузки подразумевает эффективное распределение входящего сетевого трафика между группой бэкенд-серверов. Задача же регулятора — распределить нагрузку между несколькими установленными бэкенд-серверами.

Что такое балансировка нагрузки Nginx?

Nginx — это высокопроизводительный веб-сервер, который также может использоваться в качестве регулятора нагрузки — это процесс распределения веб-трафика между несколькими серверами с помощью Nginx.

Он гарантирует, что ни один сервер не будет перегружен и что все запросы будут обработаны своевременно. Nginx использует различные алгоритмы для определения оптимального распределения трафика, а также может быть настроен для обеспечения отказоустойчивости в случае выхода из строя одного из серверов.

Вы можете использовать либо Nginx open source, либо Nginx Plus для балансировки нагрузки HTTP-трафика на группу серверов.

Преимущества

Балансировка нагрузки помогает масштабировать приложение, справляясь со скачками трафика без увеличения расходов на облако. Она также помогает устранить проблему единой точки отказа. Поскольку нагрузка является распределённой, то в случае сбоя одного из серверов — сервис всё равно продолжит работу.

Nginx SSL/HTTPS

Что такое SSL-сертификат?

SSL-сертификат – это цифровой сертификат, удостоверяющий подлинность веб-сайта и позволяющий использовать зашифрованное соединение. Аббревиатура SSL означает Secure Sockets Layer – протокол безопасности, создающий зашифрованное соединение между веб-сервером и веб-браузером.

Компаниям и организациям необходимо добавлять SSL-сертификаты на веб-сайты для защиты онлайн-транзакций и обеспечения конфиденциальности и безопасности клиентских данных.

Зачем нужен SSL-сертификат?

SSL-сертификаты сайтов требуются для обеспечения безопасности данных пользователей, подтверждения прав собственности на сайт, предотвращения создание поддельной версии сайта злоумышленниками и обеспечения доверия со стороны пользователей.

Если использование веб-сайта предполагает вход в систему, ввод личных данных, таких как номера кредитных карт, или просмотр конфиденциальной информации, такой как данные медицинской страховки, или финансовой информации, то важно сохранить конфиденциальность этих данных. SSL-сертификаты помогают сохранить конфиденциальность онлайн-транзакций и гарантируют пользователям, что веб-сайт является подлинным и безопасным для ввода личных данных.

Для бизнеса более актуален тот факт, что SSL-сертификаты требуются для веб-адресов HTTPS. HTTPS – это безопасная форма HTTP, то есть трафик веб-сайтов HTTPS зашифрован с помощью SSL. Большинство браузеров помечают сайты HTTP, не имеющие SSL-сертификатов, как небезопасные. Это сигнал пользователям о том, что сайт может быть небезопасным, а для компаний это стимул перейти на HTTPS.

SSL-сертификат помогает защитить такую информацию, как:

  • Учетные данные для входа в систему.
  • Операции по кредитной карте и информацию о банковском счете.
  • Личную информацию: полное имя, адрес, дату рождения, номер телефона.
  • Юридические документы и контракты.
  • Медицинские документы.
  • Конфиденциальную информацию.

Подробнее про SSL/TLS и HTTPs вы узнаете на старших курсах.

Остальную информацию про nginx вы можете найти в официальной документации: https://nginx.org/ru/docs/.

Практическая часть

Знакомство с nginx.

  1. Установите nginx на Debian.
apt install nginx
  1. Откройте в браузере ip адрес своей виртуальной машины для проверки работы nginx.
  2. Перейдите в директорию /etc/nginx и выполните команду ls:
    Обратите внимание на следующие файлы и директории:
    • sites-available/ - в этой директории лежит конфигурационный файл nginx сайта по умолчанию и называеться он default.
    • nginx.conf - Основной конфигурационный файл nginx. В нем описаны такие параметры как: пользователь веб сервера, путь до .pid файла, пути до директорий из которых брать конфиг и другая важная информация.
    • conf.d - Директория предназначенная для складирования пользовательских конфигурационных файлов.
  3. Создайте файл виртуального хоста с именим фамилия.conf, произведите базовую настроку, в качестве server_name, укажите доменное имя фамилия.local. Пропишите необходимую запись в файл hosts на основной машине. В качестве содержимого веб сайта укажите <h1>Nginx лучший веб сервер</h1>, если получите ошибку 403 номера проверьте владельцев на директорию и файл html, укажите пользователя nginx по умолчанию.
  4. Скачайте bootstrap сайт и создайте на основе него виртуальный хост имя.local. Пропишите необходимую запись в файл hosts на основной машине.
  5. Добавьте для сайта фамилия.local обработку uri /test. В качестве внутрений директивы используйте return 200 "Обработчик uri /test работает". Проверьте что произойдет если перейти по фамилия.local/test
  6. Проведите исследования на тему: виды кодов http ответа? В крации опишите их.

Обратный прокси сервер Nginx

  1. Вам понадобиться две виртуальные машины. Установите на обе nginx. А также установите php.
apt install nginx php
  1. Создайте конфигурационный файл в домашней папке пользователя root.
  2. Запустим nginx конкретно с этим файлом конфигурации.
    и проверьте ответ от сервера с помощью curl:
  3. Создадим файл на 2 машине для php в папке root пользователя:
  4. Запустим сервер PHP:
    Проверим. С первой машины выполним curl запрос:
  5. Мы посмотрели как быстро запустить nginx и php сервер. Теперь настроим обратный прокси сервер. Допустим нам хочется получить доступ к php серверу (2 машина) через наш сервер Nginx (1 машина). Давайте предоставим доступ к нашему php серверу через блок location /php. Добавим в конфигурацию следущий текст. Указываем адрес php сервера:
  6. Перезагружаем nginx. И выполним curl запрос на наш сервер nginx.
    Nginx получил запрос и перенаправил его на сервер php и выдал нам ответ php сервера.
  7. Если выполним curl без /php то снова получим ответ от nginx.
  8. Сделайте проксирование на web сайт nginx:
    Перезагружаем nginx как это делали в 7 пункте. И делаем curl:
    Откроем в браузере:

Балансировака нагрузки

  1. Создайте на виртуальной машине с установленным php три файла:
  2. Запустите три сервера php на 2 машине в фоновом режиме для этого в конце команды напишите знак &:
  3. Проверьте работают ли они:
  4. Обычно три сервера php к примеру обслуживают один и тот же сайт и информации не отличается но нам для тестирования работы балансировщика нагрузки их нужно различать. Давайте создадим новый файл конфигурации для nginx. Создаем блок upstream это такой пул адресов серверов на которые будет делаться прокcирование. В директиве proxy_pass указываем имя upstream пула:
  5. Запутите nginx с созданным файлом:
  6. Запустите цикл для проверки:
  7. Убейте один из процессов php сервера:
  8. Повторите цикл на 1 машине:

Nginx HTTPS

  1. Для начала создайте ssl сертификат и ключ. Если понадобиться создайте директорию /etc/nginx/ssl.
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
  1. Создайте файл конфига по пути:
nano /etc/nginx/conf.d/site.conf
  1. Заполните следующим содержимым:
server{
        listen 80;
        return 301 "https://$host$request_uri";
}
  1. Создайте второй конфиг:
nano /etc/nginx/conf.d/https_site.conf
  1. Заполните следующим содержимым в качестве содержимого сайта index.html укажите <p>Привет Мир</p> :
server{
        listen 443 ssl http2;
        ssl_certificate /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key /etc/nginx/ssl/nginx.key;
        root /var/www/mysite
}

Что у нас тут есть:

  • server - это блок в котором пишеться конфиг для сайта.
  • listen - тут указываем порты на которых будет доступен сайт.
  • server_name - обычно пишеться доменное имя но так как у нас его нету можем либо указать IP сервера либо пропустить запись тогда сайт будет работать на всех IP сервера.
  • ssl_certificate - указываем путь до ssl сертификата.
  • ssl_certificate_key - указываем путь до ключа.
  • return 301 "https://$host$request_uri" перенаправляем весь трафик на https.
  1. Перезагрузите nginx:
systemctl restart nginx

Перейдите по IP адресу машины. Вы получите предупреждение что сайт не явлеяеться безопасным оно выглядит так:


Так как мы сами подписывали ssl сертификат ваш ПК не может доверять ему. Жмите "подробнее" после "всеравно перейти".

Сайт открываеться по https.

Контрольные вопросы

  1. Раскажите о возможностях Nginx?
  2. Опишите структуру конфигурационного файла Nginx.
  3. Что такое прокси-сервер и как работает обратное проксирование?
  4. Распределение нагрузки в Nginx что это?
  5. Какой код ответа возвращает "успех" в http?