#46. Linux. SSH. curl. cron. Daemons.

Linux. SSH. Symlinks. curl. сron. Nginx/Apache. Daemons.

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).

Клієнти

В ОС Windows для реалізації з’єднання через SSH протокол частіше використовують найбільше використовується додаток PuTTY. Ще з популярних: KiTTY, SecureCRT, ShellGuard. Вбудований SSH-клієнт Windows, заснований на OpenSSH, встановлено в ОС, починаючи з Windows 10 1809.
Для MacOS: CoreShell, iTerm 2
Кросплатформений: Hyper, Termius

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

Синтаксис команди для підключення з Linux до іншого Linux має такий вигляд:

ssh [опції] ім'я користувача@сервер [команда]

ssh user@host
ssh user@192.168.43.120

Де user - це ім’я користувача, від чийого імені ми хочемо підключитися.

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

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

SSH ключі

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

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

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

Як згенерувати такі ключі?

Generating a new SSH key and adding it to the ssh-agent
Для цього в 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

Орендовані сервери

Зазвичай, коли ми орендуємо машину в будь-якої компанії, нам одразу під час купівлі нададуть юзернейм, хост і файл відкритого ключа. Що дає нам змогу одразу під’єднатися до такої машини, не заморочуючись із налаштуванням підключення.

Symlink - це скорочення від “символічне посилання”.

Symlink - (від англ. Symbolic link, також soft link) - спеціальний файл у файловій системі, у якому замість користувацьких даних міститься шлях до файлу, що відкривається під час звернення до цього посилання (файлу).

Метою посилання може бути будь-який об’єкт: наприклад, інше посилання, файл, каталог або навіть неіснуючий файл (в останньому разі при спробі відкрити його має видаватися повідомлення про відсутність файлу). Посилання, що вказує на неіснуючий файл, називається висячою або битою.

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

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

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

Для створення такого посилання в Linux використовується команда ln:

ln -s <destination file or directory> <name of the symlink>

Такі посилання ми використовуватимемо для передавання северам файлів конфігурації.

Видалити символічне посилання, не порушуючи цільовий файл або каталог:
rm <name of the symlink>

Символічні посилання стосуються друкованих копій оригінальних файлів. Якщо вихідний файл видалено або пошкоджено, ви не зможете відновити цей файл за програмним посиланням.
Жорсткі посилання (Hard link) синхронізують усе з оригінальним файлом, хоча оригінальний файл видалено або пошкоджено, ми можемо відновити його за допомогою жорстких посилань.

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

У всіх сучасних версіях Windows, починаючи з Windows 10 (версія 1803) і Server 2019, файл 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 "_" "Мій новий браузер"

За допомогою параметра -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 - видаляє конфігураційний файл разом з усіма запланованими завданнями.

Щоб запланувати завдання, використовуючи командний рядок, необхідно виконати базове налаштування 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
MAILTO=mymail@someprovider.com
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 5 * * * /usr/bin/apt-get update
05 * * * * * rm /home/myusername/tmp/*

Приклади використання Cron у командному рядку

Команда

02 04 5 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 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

https://httpd.apache.org/

Apache був розроблений для доставки веб-контенту, доступ до якого здійснюється через Інтернет. Він відомий тим, що відігравав ключову роль у початковому зростанні інтернету. Apache - це програмне забезпечення з відкритим вихідним кодом, розроблене і підтримуване відкритим співтовариством розробників, яке працює в найрізноманітніших операційних системах.
Архітектура включає в себе ядро Apache і модулі. Основний компонент надає базову серверну функцію, тому він приймає з’єднання та керує паралелізмом. Різні модулі відповідають різним функціям, які виконуються за кожним запитом. Конкретне розгортання Apache може бути сконфігуровано для включення різних модулів, таких як як функції безпеки, управління динамічним контентом або для базової обробки HTTP-запитів.

Модель “один сервер робить усе” стала ключем до раннього успіху Apache. Однак у міру збільшення рівня трафіку і збільшення кількості веб-сторінок і обмеження продуктивності налаштування Apache на роботу з реальним трафіком ускладнювалася.

Короткий огляд Nginx

https://nginx.org/

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

Nginx також має багатий набір функцій і може виконувати різні ролі сервера:

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

Apache vs 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, у ній використовуються демони. А службами називаються програми, які знаходяться в меню “Служби”.

Демони виконують певні дії в запланований час або залежно від певних подій. У системі 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

Література

  1. What Is SSH & How Does the Secure Shell Protocol Work?