Skip to content

Latest commit

 

History

History
1073 lines (717 loc) · 82.3 KB

lesson46.md

File metadata and controls

1073 lines (717 loc) · 82.3 KB

Урок 46. Linux. SSH. Symlinks. curl. CRON. Nginx/Apache. Daemons.

SSH

ЧТО ТАКОЕ SSH?

SSH (от англ. “Secure Shell”) — это протокол удаленного администрирования, разработанный для осуществления удаленного управления операционными системами и туннелирования TCP-соединения. Использование этого протокола допускает использование разных алгоритмов шифрования, что позволяет безопасно работать практически в любой незащищенной среде: работать с ПК через командную оболочку, передавать по шифрованному каналу любой тип данных (например, видеофайлы и аудиофайлы). Первый релиз протокола состоялся в 1995 г., а уже в 1996 году была представлена его усовершенствованная
версия, которая и стала основой для дальнейшего развития продукта. Сегодня для всех сетевых ОС доступны SSH сервер и SSH клиент, а сам протокол SSH является одним из самых популярных решений для удаленного управления системами и передачи важной информации.

а практике по SSH мы обычно будем подключаться к удалённым серверам и иногда передавать через этот протокол файлы (хотя чаще файлы всё-таки передаются через git, который в свою очередь использует SSH для аутентификации, если мы говорим о развёртывании серверов).

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

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

По умолчанию для работы протокола используется TCP-22 порт: на нем сервер (хост) ожидает входящее подключение и после получения команды и проведения аутентификации организует запуск клиента, открывая выбранную пользователем оболочку. При необходимости пользователь может менять используемый порт (на практике это очень часто делается). Для создания SSH подключения клиент должен инициировать соединение с сервером, обеспечив защищенное соединение и подтвердив свой идентификатор (проверяются соответствие идентификатора с предыдущими записями, хранящимися в RSA-файле, и личные данные пользователя, необходимые для аутентификации).

Преимущества протокола

Использование SSH подключения имеет ряд преимуществ:

  • безопасная работа на удаленном ПК с использованием командной оболочки; использование разных алгоритмов шифрования (симметричного, асимметричного и хеширования);
  • возможность безопасного использования любого сетевого протокола, что позволяет передавать по защищенному каналу файлы любого размера.

Как использовать SSH?

Чтобы обеспечить SSH доступ, пользователю необходимы SSH-клиент и SSH-сервер. Каждая операционная система имеет свой набор программ, обеспечивающих соединение. Так, для Linux - это lsh (server и client), openssh (server и client). Для Mac OS зачастую используется NiftyTelnet SSH. А в ОС Windows для реализации соединения через SSH протокол чаще всего используется приложение PuTTY.

Базовый синтаксис

Синтаксис команды для подключения из Linux к другому Linux выглядит следующим образом:

ssh [опции] имя пользователя@сервер [команда]

Я для такого подключения буду использовать терминал GIT для Windows, который я при установке настроил как консоль Linux. На самом деле версии Windows 10/11 содержат в себе урезанное ядро Linux, что и позволяет использовать некоторые базовые команды и синтаксис Linux.

На самом деле, все конфигурации ssh сервера находятся в папке /etc/ssh/, если хотите деталей, можете изучить их самостоятельно.

Из интересного там есть возможность изменить стандартный порт с 22, ограничить пользователей или группы, которые могут подключаться и т. д.

Для подключения нужно использовать команду:

ssh user@host

Где user - это имя пользователя, от чьего имени мы хотим подключиться.

А host - это IP или URL адрес машины, к которой мы хотим подключиться. На практике этот параметр чаще всего будет предоставлен компанией, у которой мы будем арендовать сервер (а чаще всего используется именно арендованные сервера), либо, если вам необходим собственный сервер, он должен быть обеспечен статическим IP адресом для выхода в интернет.

После такого запроса команда затребует пароль от пользователя. И как чаще всего бывает при введении пароля в Linux, никакие введённые символы отображаться не будут, но всё работает.

SSH ключи

Использовать вход по паролю можно, но чаще всего не нужно. :)

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

Поэтому чаще всего используются ssh ключи. Это специально сгенерированные 2 (чаще всего два) файла, причём сгенерированные так, что, имея один из ключей, можно при помощи специальных алгоритмов проверить, подходит ли он ко второму. Один из них называется public (публичный или открытый), второй - private (приватный или закрытый). Публичный ключ мы можем оставлять почти где угодно без особых переживаний, а вот приватный всегда должен оставаться в тайне (как и пароль, так как используется для этих же целей).

Как сгенерировать такие ключи?

Для этого в Linux существует специальная команда:

ssh-keygen -t rsa

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

После введения команды командная строка спросит нас о некоторых деталях. Куда именно сложить полученные файлы (по умолчанию будет использована папка ~/.ssh/, рекомендую не менять), и так называемую кодовую фразу, она не является обязательной, можно оставить пустую строку, по сути, эта фраза будет являться уже паролем от нашего закрытого ключа, на практике обычно нет особого смысла задавать эту фразу.

После генерации в указанной папке сгенерируются два файла: закрытый ключ some_key_name и публичный ключ some_key_name.pub.

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

cat some_key_name.pub >> ~/.ssh/authorized_keys

Файл оригинала обычно удаляется, и больше публичный ключ не трогается:

rm some_key_name.pub

Теперь достаточно скопировать файл публичного ключа (любым доступным способом, хоть вручную переписать, обычно там будет храниться 3-5 строк символов) туда, откуда мы собираемся подключаться.

Для подключения по ssh через ключи необходимо указать параметр -i, в котором указать путь к открытому ключу. Если мы скопировали такой файл в папку ~/.ssh/, как чаще всего и делается, то подключиться можно так:

ssh user@host -i ~/.ssh/some_key_name.pub

Арендованные сервера

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

Symlinks

Симлинк - это сокращение от «символическая ссылка».

Символическая («мягкая») ссылка (также «симлинк», от англ. Symbolic link) — специальный файл в файловой системе, в котором вместо пользовательских данных содержится путь к файлу, открываемому при обращении к данной ссылке (файлу).

Целью ссылки может быть любой объект: например, другая ссылка, файл, каталог или даже несуществующий файл (в последнем случае при попытке открыть его должно выдаваться сообщение об отсутствии файла). Ссылка, указывающая на несуществующий файл, называется висячей или битой.

Символические ссылки используются для более удобной организации структуры файлов на компьютере, так как:

  • позволяют для одного файла или каталога иметь несколько имён и различных атрибутов;
  • свободны от некоторых ограничений, присущих жёстким ссылкам (последние действуют только в пределах одной файловой системы (одного раздела) и не могут ссылаться на каталоги).

Такие типы файлов существуют в различных операционных системах, включая Windows.

Для создания такой ссылки в Linux используется команда ln:

ln -s файл имя_ссылки

Такие ссылки мы будем использовать для передачи северам файлов конфигурации.

Что такое curl и как работает эта команда?

Что такое curl? curl — это сокращение от “Client URL”. Утилита доступна в большинстве систем на основе Unix и предназначена для проверки подключения к URL-адресам. Кроме того, команда curl — отличный инструмент передачи данных. Давайте же узнаем, как ею пользоваться.

По факту curl - это тот же самый Postman прямо из командной строки.

Команда curl поддерживает следующий список протоколов:

  • HTTP и HTTPS
  • FTP и FTPS
  • IMAP и IMAPS
  • POP3 и POP3S
  • SMB и SMBS
  • SFTP
  • SCP
  • TELNET
  • GOPHER
  • LDAP и LDAPS
  • SMTP и SMTPS

Это наиболее важные поддерживаемые протоколы, но есть и другие. curl работает на libcurl, которая является бесплатной библиотекой для передачи URL на стороне клиента.

Проверка версии curl

Сначала давайте проверим её доступною версию с помощью следующей команды:

curl --version

В выводе вы должны увидеть версию и список поддерживаемых протоколов. Теперь мы можем взглянуть на некоторые примеры команд curl.

Основной синтаксис команды curl

Итак, давайте узнаем, как пользоваться утилитой. Основной синтаксис curl выглядит следующим образом:

curl [OPTIONS] [URL]

Список доступных флагов для команды curl можно посмотреть ТУТ.

Самый простой пример использования curl — отображение содержимого страницы. Приведённая ниже команда отобразит домашнюю страницу testdomain.com.

curl testdomain.com

Эта команда отобразит полный исходный код домашней страницы домена. Если протокол не указан, curl интерпретирует его как HTTP.

Команда curl для работы с файлами

Команды curl могут загружать файлы из удалённой локации. Есть два способа это сделать:

  • -O (--Output) сохранит файл в текущем рабочем каталоге с тем же именем, что и у удалённого;
  • -o (--output) позволяет указать другое имя файла или местоположение.

Вот пример:

curl -O http://testdomain.com/testfile.tar.gz

Приведённая выше команда сохранит файл как testfile.tar.gz.

curl -o newtestfile.tar.gz http://testdomain.com/testfile.tar.gz

А эта команда сохранит его как newtestfile.tar.gz.

Если по какой-либо причине загрузка будет прервана, вы можете возобновить её с помощью следующей команды (-C (--continue-at):

curl -C -O http://testdomain.com/testfile.tar.gz

curl также позволяет загрузить несколько файлов одновременно. Пример:

curl -O http://testdomain.com/testfile.tar.gz -O http://mydomain.com/myfile.tar.gz

Если вы хотите загрузить несколько файлов с нескольких URL, перечислите их все в файле. Команды Curl могут быть объединены с xargs для загрузки различных URL-адресов.

Например, если у нас есть файл allUrls.txt, который содержит список всех URL-адресов для загрузки, то приведённый ниже пример выполнит загрузку всех файлов с этих URL.

xargs –n 1 curl -O < allUrls.txt

Команды curl для HTTP

Типичный HTTP-запрос всегда содержит заголовок. Заголовок HTTP отправляет дополнительную информацию об удалённом веб-сервере вместе с фактическим запросом. С помощью инструментов разработчика в браузере вы можете посмотреть сведения о заголовке, а проверить их можно с помощью команды curl.

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

curl -I www.testdomain.com

Используя curl, вы можете сделать запрос GET и POST. Запрос GET будет выглядеть следующим образом:

curl http://mydomain.com

А вот пример запроса POST:

curl –data “text=Hello” https://myDomain.com/firstPage.jsp

Здесь text=Hello — это параметр запроса POST. Такое поведение похоже на HTML-формы.

Вы также можете указать несколько методов HTTP в одной команде curl. Сделайте это, используя опцию –next, например:

curl –data “text=Hello” https://myDomain.com/firstPage.jsp --next https://myDomain.com/displayResult.jsp

Команда содержит запрос POST, за которым следует запрос GET.

Каждый HTTP-запрос содержит агент пользователя, который отправляется как часть запроса. Он указывает информацию о браузере клиента. По умолчанию запрос содержит curl и номер версии в качестве информации об агенте пользователя. Пример вывода показан ниже:

“GET / HTTP/1.1” 200 “_” ”curl/7/29/0”

Вы можете изменить дефолтную информацию об агенте пользователя, используя следующую команду:

curl -I http://mydomain.com –-user-agent “My new Browser”

Теперь вывод будет выглядеть так:

“GET / HTTP/1.1” 200 “_” ”My new Browser”

При помощи параметра -U (--user) можно указать параметры авторизации:

curl -U username:password -O http://testdomain.com/testfile.tar.gz

Команда curl и Cookies

Утилиту можно использовать для проверки того, какие файлы cookie загружаются по URL. Допустим, вы зашли на https://www.samplewebsite.com, вы можете вывести и сохранить файлы cookie в файл, а затем получить к ним доступ, используя команду cat или редактор Vim.

Вот пример такой команды:

curl --cookie-jar Mycookies.txt https://www.samplewebsite.com /index.html -O

Точно также, если у вас есть файлы cookie в файле, вы можете отправить их на сайт. Вот, как это будет выглядеть:

curl --cookie Mycookies.txt https://www. samplewebsite.com

Что такое Cron и crontab?

Если в двух словах, то Cron – это планировщик задач. Если подробнее, то это утилита, позволяющая выполнять скрипты на сервере в назначенное время с заранее определенной периодичностью.

К примеру, у вас есть скрипт, который собирает какие-либо статистические данные каждый день в 6 часов вечера. Такие скрипты называют «заданиями», а их логика описывается в специальных файлах под названием сrontab.

crontab – это таблица с расписанием запуска скриптов и программ, оформленная в специальном формате, который умеет считывать компьютер. Для каждого пользователя системы создается отдельный crontab-файл со своим расписанием. Эта встроенная в Linux утилита доступна на низком уровне в каждом дистрибутиве.

В Linux-дистрибутивах с поддержкой systemd (о нём дальше) Cron считается устаревшим решением, его заменили утилитой systemd.timer. Ее предназначение и функциональность не отличаются, но фактически частота использования Cron все еще выше.

Для чего обычно используют Cron?

Обычно Cron заставляют повторять вполне очевидные задачи в духе регулярного создания резервных копий данных. Но это не все.

  • Некоторые пользователи с помощью планировщика корректируют системное время. На многих компьютерах оно настраивается через Network Time Protocol. А так как этот протокол настраивает только время ОС, время, установленное для «железа», может отличаться. Cron позволяет регулярно корректировать время, установленное для аппаратного обеспечения, в соответствии со временем ОС.

  • Еще один популярный сценарий – создание оповещений, появляющихся каждое утро и рассказывающих о состоянии компьютера. В эти сообщения может входить любая полезная для пользователя информация.

  • Cron иногда работает даже без ведома пользователя. Эту утилиту используют такие сервисы, как Logwatch, logrotate и Rootkit Hunter. Повторяющиеся задачи они настраивают, как и пользователи, через Cron. С помощью Cron пользователи автоматизируют самые разные задачи, сокращая вмешательство системного администратора в работу сервера.

Базовые принципы работы с Cron и crontab

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

Для работы с планировщиком в системе есть ряд команд, помогающих решать основные задачи:

  • crontab -e – открывает конфигурационный файл (поговорим о нем чуть подробнее в разделе с первичной настройкой).
  • crontab -l – показывает список задач из конфигурационного файла (все, что было запланировано).
  • crontab -r – удаляет конфигурационный файл вместе со всеми запланированными задачами.
  • сrontab -v – показывает, когда в последний раз открывался конфигурационный файл.

Чтобы запланировать задачи, используя командную строку, необходимо выполнить базовую настройку Cron, проверить, не установлены ли ограничения, и заполнить расписание задач в соответствии с синтаксисом сrontab.

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

Как мы уже выяснили ранее, планировщик черпает параметры для выполнения своих задач из crontab-файлов (таблиц с расписанием). У каждого пользователя, включая root, должен быть свой crontab-файл. По умолчанию он не существуют, поэтому придется создать его вручную.

Для этого существует команда crontab -e. Она автоматически генерирует таблицу в директории /var/spool/cron.

Вновь созданный файл будет пустым текстовым полем. Необходимо добавлять в него все параметры самостоятельно с нуля, опираясь на синтаксис сrontab (более подробно поговорим о нем ниже). После ввода параметров нужно сохранить параметры редактора, нажав на клавишу F2, а затем покинуть конфигурационный файл, нажав на клавишу F10. При введении корректных параметров в терминале отобразится строка crontab: installing new crontab.

Опытные разработчики и системные администраторы не рекомендуют использовать для редактирования расписания текстовые редакторы в духе Nano, Emacs или Vi. Команды crontab позволяют не только внести изменения в таблицу запланированных задач, но и перезапустить фоновый процесс crond, отвечающий за работу утилиты после сохранения настроек.

Ограничения Cron

У Cron есть функция установки ограничений на использование, задаваемых через два специальных файла: cron.allow и cron.deny.

Первый файл находится в директории /usr/lib/cron/cron.allow и содержит в себе список учетных записей (имен пользователей), которые имеют право на планирование задач с помощью встроенных системных утилит.

Второй файл находится в директории /usr/lib/cron/cron.deny. В нем указываются имена пользователей, которые не могут запускать встроенный в систему планировщик задач.

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

Синтаксис crontab

# crontab -e
SHELL=/bin/bash
[email protected]
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

# Детали смотрите в следующих разделах

# Примеры оформления задач в планировщике (формат данных):
# .---------------- минуты (0 - 59)
# |  .------------- часы (0 - 23)
# |  |  .---------- дни месяца (1 - 31)
# |  |  |  .------- сами месяцы (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- дни недели (0 - 6) (0 или 7 это воскресенье в зависимости от настроек системы) можно использовать сокращения типа mon,tue,wed,thu,fri,sat,sun
# |  |  |  |  |
# *  *  *  *  * имя пользователя  команда, которую нужно запустить

# создание копии всей операционной системы с помощью кастомного скрипта 
01 01 * * * /usr/local/bin/bckp -vbd1 ; /usr/local/bin/bckp -vbd2

# установка соответствия между временем операционной системы и "железа"
03 05 * * * /sbin/hwclock --systohc

# проведение обновления операционной системы в заданный период времени
25 04 1 * * /usr/bin/apt-get update

Первые три линии кода в таблице отвечают за первичную настройку. Сначала указывается оболочка, в которой будет работать Cron. У утилиты нет каких-либо предпочтений, поэтому можно указать любую на собственное усмотрение (в нашем примере это bash). Затем указывается адрес электронной почты, на который будут отправляться отчеты о работе планировщика. И напоследок указывается путь к окружению.

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

В нашем случае указаны команды:

02 04 5 * * /usr/local/bin/bckp -vbd1 ; /usr/local/bin/bckp -vbd2
04 06 * * * /sbin/hwclock –systohc
10 05 5 * * /usr/bin/apt-get update
05 * * * * rm /home/myusername/tmp/*

Примеры использования Cron в командной строке

Команда

02 04 5 * * /usr/local/bin/bckp -vbd1 ; /usr/local/bin/bckp -vbd2

создает в таблице расписания задачу на запуск скрипта под названием bckp (представим, что такой существует), который создает резервную копию всей системы на стороннем накопителе. Он выполняется 5 числа каждого месяца в 4 часа 2 минуты утра. Это видно по числовым значениям. Звездочки же указывают на отсутствие конкретного значения. Cron воспринимает их как «выполнять каждый раз», то есть каждый месяц, день или неделю.

Команда

04 06 * * * /sbin/hwclock –systohc

меняет время аппаратного обеспечения на то, что используется в системе. Делает это каждый день, каждую неделю и каждый месяц в 6 часов 4 минуты утра. Как видите, здесь пропущено третье значение. Поэтому команда и запускается ежедневно, так как нет более конкретных правил.

Команда

10 05 5 * * /usr/bin/apt-get update

запускает обновление пакетов с помощью пакетного менеджера apt каждый месяц 5 числа в 05:10.

Команда

05 * * * * rm /home/myusername/tmp/*

удаляет содержимое папки с временными файлами для конкретного пользователя (меня) на пятой минуте (первый пункт) каждого часа. Так как определенные значения отсутствуют для всех остальных пунктов, получается, что скрипт готов выполняться каждый день, каждый месяц и каждый час. Но первое значение указано, поэтому он будет дожидаться пятой минуты и запускаться в этот момент. То есть в 12:05, 13:05, 14:05 и т. п.

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

Nginx/Apache

Apache и Nginx — два самых широко распространенных веб-сервера с открытым исходным кодом в мире. Вместе они обслуживают более 60% трафика во всем интернете. Оба решения способны работать с разнообразными рабочими нагрузками и взаимодействовать с другими приложениями для реализации полного веб-стека.

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

Общий обзор

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

КРАТКИЙ ОБЗОР Apache

Apache был разработан для доставки веб-контента, доступ к которому осуществляется через Интернет. Он известен тем, что играл ключевую роль в начальном росте интернета. Apache - это программное обеспечение с открытым исходным кодом, разработанное и поддерживаемое открытым сообществом разработчиков и работающее в самых разных операционных системах. Архитектура включает в себя ядро Apache и модули. Основной компонент предоставляет базовую серверную функцию, поэтому он принимает соединения и управляет параллелизмом. Различные модули соответствуют различным функциям, которые выполняются по каждому запросу. Конкретное развертывание Apache может быть сконфигурировано для включения различных модулей, таких как функции безопасности, управление динамическим контентом или для базовой обработки HTTP-запросов.

Модель «один сервер делает все» стала ключом к раннему успеху Apache. Однако по мере увеличения уровня трафика и увеличения количества веб-страниц и ограничения производительности настройка Apache на работу с реальным трафиком усложнялась.

КРАТКИЙ ОБЗОР Nginx

Nginx был разработан специально для устранения ограничений производительности веб-серверов Apache. Производительность и масштабируемость Nginx обусловлены архитектурой, управляемой событиями. Он значительно отличается от подхода Apache. В Nginx каждый рабочий процесс может одновременно обрабатывать тысячи HTTP-соединений. Следовательно, Nginx - это легковесная, масштабируемая и высокопроизводительная реализация. Эта архитектура делает обработку больших и флуктуирующих нагрузок на данные гораздо более предсказуемой с точки зрения использования ОЗУ, использования ЦП и задержки.

Nginx также имеет богатый набор функций и может выполнять различные роли сервера:

  • Обратный прокси-сервер для протоколов HTTP, HTTPS, SMTP, POP3 и IMAP
  • Балансировщик нагрузки и HTTP-кеш
  • Интерфейсный прокси для Apache и других веб-серверов, сочетающий гибкость Apache с хорошей производительностью статического контента Nginx

APACHE ПРОТИВ NGINX: СРАВНЕНИЕ ИХ БОГАТЫХ НАБОРОВ ФУНКЦИЙ

ПРОСТОТА

Разрабатывать и обновлять приложения на Apache очень просто. Модель «одно соединение на процесс» позволяет очень легко вставлять модули в любой точке логики веб-обслуживания. Разработчики могут добавлять код таким образом, что в случае сбоев будет затронут только рабочий процесс, выполняющий код. Обработка всех других соединений будет продолжаться без помех.

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

ПРОИЗВОДИТЕЛЬНОСТЬ

Производительность измеряется тем, как сервер доставляет большие объемы контента в браузер клиента, и это важный фактор. Контент может быть статическим или динамическим. Давайте посмотрим статистику по этому вопросу.

СТАТИЧЕСКИЙ КОНТЕНТ

Nginx работает в 2,5 раза быстрее, чем Apache, согласно тесту производительности, выполняемому до 1000 одновременных подключений. Другой тест с 512 одновременными подключениями показал, что Nginx примерно в два раза быстрее и потребляет меньше памяти. Несомненно, Nginx имеет преимущество перед Apache со статическим контентом. Поэтому, если вам нужно обслуживать одновременный статический контент, Nginx является предпочтительным выбором.

ДИНАМИЧЕСКИЙ КОНТЕНТ

Результаты тестов Speedemy показали, что для динамического контента производительность серверов Apache и Nginx была одинаковой. Вероятная причина этого заключается в том, что почти все время обработки запросов расходуется в среде выполнения PHP, а не в основной части веб-сервера. Среда выполнения PHP довольно похожа для обоих веб-серверов.

Apache также может обрабатывать динамический контент, встраивая процессор языка, подобного PHP, в каждый из его рабочих экземпляров. Это позволяет ему выполнять динамический контент на самом веб-сервере, не полагаясь на внешние компоненты. Эти динамические процессоры могут быть включены с помощью динамически загружаемых модулей.

Nginx не имеет возможности обрабатывать динамический контент изначально. Чтобы обрабатывать PHP и другие запросы на динамический контент, Nginx должен перейти на внешний процессор для выполнения и дождаться отправки визуализированного контента. Однако этот метод также имеет некоторые преимущества. Поскольку динамический интерпретатор не встроен в рабочий процесс, его издержки будут присутствовать только для динамического содержимого.

ПОДДЕРЖКА ОС

Apache работает во всех операционных системах, таких как UNIX, Linux или BSD, и полностью поддерживает Microsoft Windows. Nginx также работает на нескольких современных Unix-подобных системах и поддерживает Windows, но его производительность в Windows не так стабильна, как на платформах UNIX.

БЕЗОПАСНОСТЬ

И Apache, и Nginx являются безопасными веб-серверами. Apache Security Team существует, чтобы предоставить помощь и советы проектам Apache по вопросам безопасности и координировать обработку уязвимостей безопасности. Важно правильно настроить серверы и знать, что делает каждый параметр в настройках.

ГИБКОСТЬ

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

Nginx Plus (Nginx Plus - это программный балансировщик нагрузки, веб-сервер и кэш контента, построенный на основе открытого исходного кода Nginx) также использует модульную архитектуру. Новые функции и возможности могут быть добавлены с программными модулями, которые могут быть подключены к работающему экземпляру Nginx Plus по требованию. Динамические модули добавляют в Nginx Plus такие функции, как геолокация пользователей по IP-адресу, изменение размеров изображений и встраивание сценариев Lua в модель обработки событий Nginx Plus. Модули создаются как Nginx, Inc., так и сторонними разработчиками.

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

ПОДДЕРЖКА И ДОКУМЕНТАЦИЯ

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

Наряду с документацией многие инструменты и веб-проекты содержат инструменты для начальной загрузки в среде Apache. Это может быть включено в сами проекты или в пакеты, поддерживаемые отделом упаковки вашего дистрибутива.

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

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

NGINX И APACHE - СОВМЕСТНАЯ РАБОТА

Для многих приложений Nginx и Apache хорошо дополняют друг друга. Очень распространенным начальным шаблоном является развертывание программного обеспечения Nginx с открытым исходным кодом в качестве прокси-сервера (или Nginx Plus в качестве платформы доставки приложений) перед веб-приложением на основе Apache. Nginx выполняет тяжелую работу, связанную с HTTP - обслуживает статические файлы, кэширует содержимое и разряжает медленные HTTP-соединения - так что сервер Apache может выполнять код приложения в безопасной и защищенной среде.

Дополнение

В случае с разворачиванием проектов на Python, мы будем использовать Nginx как прокси сервер, а вот в случае с обработкой данных, мы будем использовать совсем другие технологии, о них на следующем занятии.

Демонизация

Что или кто такие демоны с точки зрения линукса?

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

ЧТО ТАКОЕ ДЕМОНЫ В ПОНЯТИИ Linux?

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

Многие люди, перешедшие в Linux из Windows, знают демонов как службы или сервисы. В MacOS термин "Служба" имеет другое значение. Так как MacOS - это тоже Unix, в ней испольуpются демоны. А службами называются программы, которые находятся в меню "Службы".

Демоны выполняют определённые действия в запланированное время или в зависимости от определённых событий. В системе Linux работает множество демонов, и каждый из них предназначен для того, чтобы следить за своей небольшой частью операционной системы. Поскольку они не находятся под непосредственным контролем пользователя, они фактически невидимы, но, тем не менее, необходимы. Поскольку демоны выполняют большую часть своей работы в фоновом режиме, они могут казаться загадочными.

КАКИЕ ДЕМОНЫ РАБОТАЮТ НА ВАШЕМ КОМПЬЮТЕРЕ?

Обычно имена процессов демонов заканчиваются на букву d. В Linux принято называть демоны именно так. Есть много способов увидеть работающих демонов. Они попадаются в списке процессов, выводимом утилитами ps, top или htop. Но больше всего для поиска демонов подходит утилита pstree. Эта утилита показывает все процессы, запущенные в вашей системе в виде дерева. Откройте терминал и выполните такую команду:

pstree

Вы увидите полный список всех запущенных процессов. Вы можете не знать, за что отвечают эти процессы, но они все будут здесь перечислены. Вывод pstree - отличная иллюстрация того, что происходит с вашей машиной. Здесь удобно найти запущенные демоны Linux.

ЗАПУСК ДЕМОНОВ В Linux

Давайте разберемся, как запустить демона Linux. Ещё раз, демон - это процесс, работающий в фоновом режиме и находящийся вне контроля пользователя. Это значит, что демон не связан с терминалом, с помощью которого можно было бы им управлять. Процесс - это запущенная программа. В каждый момент времени он может быть запущенным, спящим или зомби (процесс выполнивший свою задачу, но ожидающий, пока родительский процесс примет результат).

В Linux существует три типа процессов: интерактивные, пакетные и демоны. Интерактивные процессы пользователь запускает из командной строки. Пакетные процессы обычно тоже не связаны с терминалом. Как правило, они запускаются в момент минимальной нагрузки на систему и делают свою работу. Это могут быть, например, скрипты резервного копирования или другие подобные обслуживающие сценарии.

Интерактивные и пакетные процессы нельзя считать демонами, хотя их можно запускать в фоновом режиме, и они делают определённую работу. Ключевое отличие в том, что оба вида процессов требуют участия человека. Демонам не нужен человек для того, чтобы их запускать.

Когда загрузка системы завершается, система инициализации, например, systemd, начинает создавать демонов. Этот процесс называется forking (разветвление). Программа запускается как обычный интерактивный процесс с привязкой к терминалу, но в определённый момент она делится на два идентичных потока. Первый процесс, привязанный к терминалу может выполняться дальше или завершиться, а второй, уже ни к чему не привязанный, продолжает работать в фоновом режиме.

Существуют и другие способы ветвления программ в Linux, но традиционно для создания дочерних процессов создается копия текущего. Термин forking появился не из ниоткуда. Его название походит от функции языка программирования C. Стандартная библиотека C содержит методы для управления службами, и один из них называется fork. Используется он для создания новых процессов. После создания процесса, процесс, на основе которого был создан демон, считается для него родительским процессом.

Когда система инициализации запускает демонов, она просто разделяется на две части. В таком случае система инициализации будет считаться родительским процессом. Однако в Linux есть ещё один метод запуска демонов. Когда процесс создает дочерний процесс демона, а затем завершается. Тогда демон остается без родителя, и его родителем становится система инициализации. Важно не путать такие процессы с зомби. Зомби - это процессы, завершившие свою работу и ожидающие пока родительский процесс примет их код выхода.

ПРИМЕРЫ ДЕМОНОВ В Linux

Самый простой способ определить демона - это буква d в конце его названия. Вот небольшой список демонов, которые работают в вашей системе. Каждый демон создан для выполнения определённой задачи.

  • systemd - основная задача этого демона унифицировать конфигурацию и поведение других демонов в разных дистрибутивах Linux.
  • udisksd - обрабатывает такие операции как: монтирование, размонтирование, форматирование, подключение и отключение устройств хранения данных, таких как жесткие диски, USB флешки и т.д.
  • logind - небольшой демон, управляющий авторизацией пользователей.
  • httpd - демон веб-сервера позволяет размешать на компьютере или сервере веб-сайты.
  • sshd - позволяет подключаться к серверу или компьютеру удалённо, по протоколу SSH.
  • ftpd - организует доступ к компьютеру по протоколу FTP для передачи файлов.
  • crond - демон планировщика, позволяющий выполнять нужные задачи в определённое время. (Да, cron работает не на чёрной магии)

Systemd

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

В этом руководстве мы обсудим команду systemctl, которая является инструментом центрального управления для контроля системы инициализации. Поговорим о том, как управлять службами, проверять статус, изменять состояние системы и работать с файлами конфигурации.

Обратите внимание, что хотя система systemd стала системой инициализации по умолчанию для многих дистрибутивов Linux, она не используется повсеместно во всех дистрибутивах.

Управление службами

Основополагающая цель системы инициализации заключается в инициализации компонентов, которые должны запускаться после загрузки ядра Linux (традиционно называются компоненты пользовательского пространства). Система инициализации также используется для управления службами и демонами для сервера и в любой момент времени работы системы. С учетом этого мы начнем с нескольких базовых операций по управлению службами.

В systemd целью большинства действий являются «модули», являющиеся ресурсами, которыми systemd знает, как управлять. Модули распределяются по категориям по типу ресурса, который они представляют, и определяются файлами, известными как файлы модулей. Тип каждого модуля можно вывести из суффикса в конце файла.

Для задач по управлению службами целевым модулем будут модули службы, которые имеют файлы модулей с суффиксом .service. Однако для большинства команд по управлению службами вы можете не использовать суффикс .service, поскольку systemd достаточно умна, чтобы знать, что вы, возможно, хотите работать со службой при использовании команд по управлению службами.

Запуск и остановка служб

Чтобы запустить службу systemd, используя инструкции в файле модуля службы, используйте команду start. Если вы работаете как пользователь без прав root, вам потребуется использовать sudo, поскольку это влияет на состояние операционной системы:

sudo systemctl start application.service

Как мы уже упомянули выше, systemd будет искать файлы *.service для команд управления службами, так что команду можно легко ввести следующим образом:

sudo systemctl start application

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

Чтобы остановить работающую в данный момент службу, можно использовать команду stop:

sudo systemctl stop application.service

Перезапуск и перезагрузка

Чтобы перезапустить работающую службу, можно использовать команду restart:

sudo systemctl restart application.service

Если данное приложение может перезагрузить файлы конфигурации (без перезапуска), вы можете выдать команду reload для инициализации этого процесса:

sudo systemctl reload application.service

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

sudo systemctl reload-or-restart application.service

Включение и отключение служб

Указанные выше команды полезны для запуска или остановки служб во время текущего сеанса. Чтобы дать команду systemd автоматически запускать службы при загрузке, их необходимо включить.

Для запуска службы во время загрузки используйте команду enable:

sudo systemctl enable application.service

При этом будет создана символическая ссылка из системной копии служебного файла (обычно в /lib/systemd/system или /etc/systemd/system) в месте на диске, где systemd ищет файлы для автозапуска (обычно /etc/systemd/system/some_target.target.wants; что такое цель, мы рассмотрим далее в этом руководстве).

Чтобы отключить автоматический запуск службы, можно ввести следующее:

sudo systemctl disable application.service

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

Помните, что включение службы не запустит ее в текущем сеансе. Если вы хотите запустить службу и включить ее при загрузке, необходимо дать обе команды, start и enable.

Проверка статуса служб

Чтобы проверить статус службы в вашей системе, можно использовать команду status:

systemctl status application.service

При этом вы получите статус службы, иерархию контрольных групп и первые несколько строк журнала.

Например, при проверке статуса сервера Nginx вы можете видеть следующий вывод:

Output
● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2015-01-27 19:41:23 EST; 22h ago
 Main PID: 495 (nginx)
   CGroup: /system.slice/nginx.service
           ├─495 nginx: master process /usr/bin/nginx -g pid /run/nginx.pid; error_log stderr;
           └─496 nginx: worker process
Jan 27 19:41:23 desktop systemd[1]: Starting A high performance web server and a reverse proxy server...
Jan 27 19:41:23 desktop systemd[1]: Started A high performance web server and a reverse proxy server.

Это дает вам хороший обзор текущего статуса приложения и уведомляет о наличии каких-либо проблем или необходимости выполнения каких-либо действий.

Также есть методы для проверки определенных статусов. Например, чтобы проверить, активен ли (работает ли) модуль в данный момент, можно использовать команду is-active:

systemctl is-active application.service

Это вернет текущий статус модуля, который обычно active или inactive. Код выхода будет «0», если он активен, и результат будет проще парсить в скрипты оболочки.

Чтобы увидеть, включен ли модуль, можно использовать команду is-enabled:

systemctl is-enabled application.service

Это выведет информацию о том, что служба enabled или disabled, и снова установит код выхода на «0» или «1» в зависимости от вопроса команды.

Третья проверка заключается в проверке того, находится ли модуль в состоянии сбоя. Это означает, что была проблема, которая запустила данный модуль:

systemctl is-failed application.service

Это вернет active, если он работает должным образом, или failed, если возникла ошибка. Если модуль был намеренно остановлен, может вернуться unknown или inactive. Статус выхода «0» означает, что произошел сбой, а статус выхода «1» указывает на какой-либо другой статус.

На самом деле, тема этого модуля гораздо шире, но пока нам этого достаточно.

Создание своего демона

А что делать, если нужно запустить какой-то скрипт, чтобы он работал постоянно (например, веб-сервер пусть работает, но не блокирует нам консоль), конечно же создавать свои юниты.

Systemd запускает сервисы, описанные в его конфигурации. Конфигурация состоит из множества файлов, которые по-модному называют юнитами.

Все эти юниты разложены в трех каталогах:

  • /usr/lib/systemd/system/ – юниты из установленных пакетов RPM — всякие nginx, apache, mysql и прочее
  • /run/systemd/system/ — юниты, созданные в runtime — тоже, наверное, нужная штука
  • /etc/systemd/system/ — юниты, созданные системным администратором — а вот сюда мы и положим свой юнит.

Юнит, представляет собой текстовый файл с форматом, похожим на файлы .ini Microsoft Windows.

[Название секции в квадратных скобках]
имя_переменной = значение

Для создания простейшего юнита надо описать три секции: [Unit], [Service], [Install]

В секции [Unit] описываем, что это за юнит. Добавляем описание юнита:

Description=MyUnit

Далее следует блок переменных, которые влияют на порядок загрузки сервисов.

Запускать юнит после какого-либо сервиса или группы сервисов (например, network.target):

After=syslog.target  //запустить после того, как запустится syslog
After=network.target //запустить после того, как появится доступ к интернету
After=nginx.service  //зустить после того, как запустится nginx
After=mysql.service  //зустить после того, как запустится mysql

Для запуска сервиса необходим запущенный сервис mysql:

Requires=mysql.service

Для запуска сервиса желателен запущенный сервис redis:

Wants=redis.service

В итоге переменная Wants получается чисто описательной. Если сервис есть в Requires, но нет в After, то наш сервис будет запущен параллельно с требуемым сервисом, а не после успешной загрузки требуемого сервиса.

В секции Service указываем, какими командами и под каким пользователем надо запускать сервис:

Тип сервиса:

Type=simple

(по умолчанию): systemd предполагает, что служба будет запущена незамедлительно. Процесс при этом не должен разветвляться. Не используйте этот тип, если другие службы зависят от очередности при запуске данной службы.

Type=forking

systemd предполагает, что служба запускается однократно и процесс разветвляется с завершением родительского процесса. Данный тип используется для запуска классических демонов. Также следует определить PIDFile=, чтобы systemd могла отслеживать основной процесс:

PIDFile=/work/www/myunit/shared/tmp/pids/service.pid

Рабочий каталог, он делается текущим перед запуском стартап команд:

WorkingDirectory=/work/www/myunit/current

Пользователь и группа, под которым надо стартовать сервис:

User=myunit
Group=myunit

Переменные окружения:

Environment=RACK_ENV=production

Команды на старт/стоп и перезапуск сервиса:

ExecStart=/usr/local/bin/bundle exec service -C /work/www/myunit/shared/config/service.rb --daemon
ExecStop=/usr/local/bin/bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state stop
ExecReload=/usr/local/bin/bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state restart

Тут есть тонкость — systemd настаивает, чтобы команда указывала на конкретный исполняемый файл. Надо указывать полный путь.

Таймаут в секундах, сколько ждать system отработки старт/стоп команд.

TimeoutSec=300

Попросим systemd автоматически рестартовать наш сервис, если он вдруг перестанет работать. Контроль ведется по наличию процесса из PID файла

Restart=always

В секции [Install] опишем, в каком уровне запуска должен стартовать сервис.

Уровень запуска:

WantedBy=multi-user.target

multi-user.target или runlevel3.target соответствует нашему привычному runlevel=3 «Многопользовательский режим без графики. Пользователи, как правило, входят в систему при помощи множества консолей или через сеть»

Вот и готов простейший стартап скрипт, он же unit для systemd:

myunit.service

[Unit]
Description=MyUnit
After=syslog.target
After=network.target
After=nginx.service
After=mysql.service
Requires=mysql.service
Wants=redis.service

[Service]
Type=forking
PIDFile=/work/www/myunit/shared/tmp/pids/service.pid
WorkingDirectory=/work/www/myunit/current

User=myunit
Group=myunit

Environment=RACK_ENV=production

ExecStart=/usr/local/bin/bundle exec service -C /work/www/myunit/shared/config/service.rb --daemon
ExecStop=/usr/local/bin/bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state stop
ExecReload=/usr/local/bin/bundle exec service -S /work/www/myunit/shared/tmp/pids/service.state restart
TimeoutSec=300

[Install]
WantedBy=multi-user.target 

Кладем этот файл в каталог /etc/systemd/system/

Смотрим его статус командой systemctl status myunit:

myunit.service - MyUnit
   Loaded: loaded (/etc/systemd/system/myunit.service; disabled)
   Active: inactive (dead)

Видим, что он disabled — разрешаем его systemctl enable myunit systemctl -l status myunit

Если нет никаких ошибок в юните, то вывод будет вот такой:

myunit.service - MyUnit
   Loaded: loaded (/etc/systemd/system/myunit.service; enabled)
   Active: inactive (dead)

Запускаем сервис systemctl start myunit

Смотрим красивый статус: systemctl -l status myunit

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

systemctl daemon-reload