Логи Apache (ч.1): Види та модулі журналів. Формат логів доступу Apache

6 квітня 2023 3 хвилин Автор: Endpool

Налаштування формату журналів Apache

Цей цикл статей присвячений файлам журналів (логам) веб-сервера Apache, розглядається їх налаштування, формат, команди, а також спеціальні програми для аналізу журналів веб-сервера. HTTP-сервер Apache надає безліч різних механізмів для реєстрації всього, що відбувається на вашому сервері, від початкового запиту та процесу зіставлення URL-адрес до остаточного дозволу з’єднання, включаючи будь-які помилки, які могли виникнути в процесі. На додаток до цього сторонні модулі можуть надавати можливості ведення журналів або вставляти записи в існуючі файли журналів, а програми, такі як програми CGI, сценарії PHP або інші обробники, також можуть надсилати повідомлення до журналу помилок сервера. Журнали веб-сервер містять багато цікавої інформації! За логами доступу сервера можна скласти збірний портрет аудиторії: в яких країнах і містах живуть, якими операційними системами користуються, якими браузерами переглядають сайт, в який час найбільше активні.

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

Види логів Apache

Різні види журналів Apache керуються різними модулями веб-сервера і мають різні директиви, що управляють, і можливості вказати формат рядка лога. Є такі види логів веб-сервера Apache:

  • Error Log (журнал помилок) – Журнал помилок сервера є найважливішим файлом журналу. Це місце, куди Apache httpd надсилатиме діагностичну інформацію та записуватиме будь-які помилки, з якими він стикається при обробці запитів. Це перше місце, де потрібно подивитися, коли виникає проблема із запуском сервера або роботою сервера, оскільки він часто містить подробиці, що пішло не так і як це виправити.
  • Access Log (журнал доступу) – Журнал доступу до сервера записує всі запити, оброблені сервером.
  • Forensic (криміналістичні логи) – Реєстрація ведеться до та після обробки запиту, тому журнал судової експертизи містить два рядки журналу для кожного запиту. Відрізняється підвищеною строгістю.
  • Журнали виконання CGI скриптів – Якщо не вказано ScriptLog, журнал помилок не створюється. Якщо ScriptLog встановлений, будь-які помилки CGI реєструються у файлі, вказаному як аргумент.

  • Per-module logging (журналювання подій модулів) – Директива LogLevel дозволяє вказувати рівень важливості журналу для кожного модуля. Таким чином, якщо ви вирішуєте проблему тільки з одним конкретним модулем, ви можете збільшити його обсяг у журналі, при цьому не отримуючи зайвої інформації про інші модулі, які вас не цікавлять. Це особливо корисно для таких модулів, як mod_proxy або mod_rewrite, де ви хочете дізнатися подробиці про те, що він намагається зробити.

  • Additional configurable debug logging (Додаткові журнали) – Ця директива змушує повідомлення користувача реєструватися в журналі помилок. Повідомлення може використовувати змінні та функції синтаксису ap_expr. Посилання на заголовки HTTP не призводять до додавання імен заголовків у заголовок Vary. Повідомлення реєструються лише на рівні лога.

Модулі логів Apache

В Apache є кілька модулів, які відповідають за веб-журнали:

  • mod_log_config – Веде журнал запитів до сервера. Це основний модуль, який включений за замовчуванням і він зберігає інформацію про запити. В основному, тут ми розглядатимемо саме цей модуль та його налаштування. Забезпечує роботу Access Log (журнал доступу).
  • mod_log_debug – Додаткові журнали налагодження, що настроюються. Забезпечує роботу  Additional configurable debug logging (Додаткові журнали налагодження, що настроюються). Має експериментальний статус.
  • mod_log_forensic – Криміналістична реєстрація запитів на сервер. Забезпечує роботу Forensic (Криміналістичні логи).
  • mod_logio – Реєстрація вхідних та вихідних байтів кожного запиту. Цей модуль повинен бути включений у конфігурації Apache, якщо ви хочете в журналі зберігати інформацію про кількість переданих та отриманих даних. Забезпечує роботу деяких можливостей формату Access Log (журнал доступу).
  • Apache Core Features — Основні функції Apache HTTP Server, які завжди доступні. У тому числі забезпечує роботу Error Log (журналу помилок) та Per-module logging (журналювання подій модулів).
  • mod_cgi та mod_cgid – Забезпечують роботу журналу виконання CGI скриптів.

Модуль mod_log_config

Модуль mod_log_config забезпечує гнучке журналування запитів клієнта. Логи пишуться у форматі, що настроюється і можуть бути записані безпосередньо у файл або у зовнішню програму. Надається запис логів за умови, тобто індивідуальні запити можуть бути включені або виключені з журналу на основі характеристики запиту. Цей модуль є ключовим для забезпечення роботи Access Log (журнал доступу). Цей модуль підтримує такі директиви:

  • TransferLog для створення файлу журналу.
  • LogFormat для встановлення формату користувача. Після цієї директиви вказується рядок формату логів, а також ім’я, яке можна використовувати як псевдонім для даного рядка. Після встановлення псевдоніма цією директивою його можна вказати в CustomLog.
  • CustomLog для визначення файлу та формату журналу за один крок. Встановлює спосіб збереження файлу журналу (наприклад, файл), а також використовуваний формат. Як формат може приймати псевдонім, встановлений директивою LogFormat, або рядок формату.
  • BufferedLogs Зберігати записи журналу в пам’яті перед записом на диск.
  • GlobalLog Встановлює ім’я файлу та формат файлу журналу.

Директиви TransferLog та CustomLog на кожному сервері можуть використовуватися кілька разів, щоб кожен запит реєструвався у кількох файлах.

Access Log (журнал доступу)

Журнал доступу до сервера записує всі запити, оброблені сервером. Розташування та вміст журналу доступу контролюються директивою CustomLog. Директиву LogFormat можна використовувати для спрощення вибору вмісту журналів. У цьому розділі описано, як настроїти сервер для запису інформації в журнал доступу. Звичайно, збереження інформації в журналі доступу – це лише початок керування журналом. Наступним кроком є ​​аналіз цієї інформації для отримання корисної статистики. Аналіз журналів загалом виходить не є частиною роботи самого веб-сервера, але буде розглянуто в одній із наступних статей цього циклу. Різні версії Apache httpd використовували інші модулі та директиви для керування журналом доступу, включаючи mod_log_referer, mod_log_agent та директиву TransferLog. Директива CustomLog тепер включає функціональність всіх старих директив. Формат журналу доступу легко налаштовується. Формат вказується з використанням рядка формату, який дуже схожий на рядок формату printf(1) у стилі C.

Тобто з практичної точки зору, Access Log (журнал доступу) це те саме, що і mod_log_config, оскільки саме цей модуль забезпечує функціональність Access Log. Додатково Access Log використовують модулі mod_logio та mod_setenvif для розширення функціональності. Наприклад, модуль mod_logio дозволяє записувати в журнал точний розмір переданих та/або отриманих даних під час запиту користувача та відповіді йому. Оскільки це те саме, то директиви у Access Log і mod_log_config однакові.

Як настроїти формат логів доступу Apache Користувальницькі формати журналів

Аргументом формату для директив LogFormat та CustomLog є рядок. На основі цього рядка буде сформовано запис у файл журналу для кожного запиту. Цей рядок може містити буквальні символи, які будуть скопійовані у файли журналу такими, як вони є, та керуючі символи в стилі C “n” і “t” для запису символів new-line (новий рядок) та tab (табуляція).

Буквальні лапки та зворотні слеші слід екранувати за допомогою зворотної косої межі (). Різні характеристики запиту позначаються рядками, які починаються із символу %. У файлі журналу такі рядки будуть замінені такими значеннями, наведеними у Скріншоті 1, Скріншоті 2, Скріншоті 3.

Скріншот 1.

Скріншот 2.

Скріншот 3.

Модифікатори

Окремі елементи можуть бути обмежені для друку тільки для відповідей з певними кодами стану HTTP, розміщуючи розділений комами список кодів стану відразу після “%”. Списку кодів стану може передувати “!” щоб вказати заперечення. Модифікатори «<» і «>» потрібні для вибору, чи слід записувати вихідний або остаточний запит. Це можна використовувати для запитів, які перенаправлені всередині (Скріншот 4). За замовчуванням % директиви %s, %U, %T, %D і %r дивляться на вихідний запит, а решта дивляться на остаточний запит.

Скріншот 4.

Так, наприклад, %>s можна використовувати для запису остаточного стану запиту, а % можна використовувати для запису вихідного автентифікованого користувача на запит, внутрішньо перенаправленому на неавтентифікований ресурс.

Примітки до форматів

З міркувань безпеки, починаючи з версії 2.0.46, недруковані та інші спеціальні символи %r, %i і %o екрануються за допомогою послідовностей xhh, де hh позначає шістнадцяткове уявлення необробленого байта. Винятками з цього правила є ” і , які екрануються шляхом додавання зворотної косої риси та всіх пробілових символів, які записуються з використанням нотації в стилі C (n, t і т. д.). У версіях, що передують 2.0.46, для цих рядків екранування не виконувалось, тому ви повинні бути досить обережними при роботі з необробленими лог-файлами в цих версіях. Оскільки в httpd 2.0, на відміну від 1.3, рядки формату %b і %B представляють не кількість байтів, відправлених клієнту, а просто розмір у байтах відповіді HTTP (який буде відрізнятися, наприклад, якщо з’єднання перервано) або якщо використовується SSL). Формат %O, що надається mod_logio, реєструє фактичну кількість байтів, надісланих по мережі. Примітка: mod_cache реалізований як швидкий обробник, а не стандартний обробник. Отже, рядок формату %R не повертатиме жодної інформації оброблювача, коли задіяно кешування вмісту. Символ «^» на початку трьохсимвольних форматів не має значення, але він має бути першим символом будь-якого новоствореного трисимвольного формату, щоб уникнути потенційних конфліктів з форматами журналів, у яких використовуються буквальні рядки, суміжні зі специфікатором формату, такі як %Dus.

Приклади: 

Common Log Format (CLF) – звичайний формат журналу.

Common Log Format with Virtual Host – звичайний формат журналу з вірт. хостами.

NCSA extended/combined log format — розширений/комбінований формат журналу.

Referer log format — формат запису Referer у правильній послідовності.

Agent (Browser) log format — формат запису користувача агента (браузера).

Мітка часу— вона робить те, що включає мілісекунди.

Директива BufferedLogs

Зберігає записи в пам’яті перед записом на диск.

Синтаксис:

Значення за замовчуванням:

Контекст:

Директива BufferedLogs змушує mod_log_config зберігати кілька записів журналу в пам’яті та записувати їх разом на диск, а не записувати їх після кожного запиту. У деяких системах це може призвести до більш ефективного доступу до диска і, отже, до більш високої продуктивності. Він може бути встановлений лише один раз для всього сервера; його не можна налаштувати для кожного віртуального хоста. Цю директиву слід використовувати обережно, оскільки збій може призвести до втрати даних журналу.

Директива CustomLog

Встановлює ім’я файлу та формат файлу журналу.

Синтаксис:

Контекст:

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

  • file – Ім’я файлу щодо ServerRoot.
  • pipe – Символ труби “|”, за яким слідує шлях до програми, яка отримає записи логів на її стандартному введенні. Для отримання додаткової інформації дивіться нижче розділ Piped Logs (конвеєрна обробка). Безпека: якщо використовується програма, вона буде запущена від імені користувача, який запустив httpd. Це буде root, якщо сервер був запущений від root; переконайтеся, що програма є безпечною. Примітка: при введенні шляху до файлу на платформах, відмінних від Unix, необхідно стежити за тим, щоб використовувалися лише прямі косі риси, навіть якщо платформа може дозволяти використання зворотних косих рис. Як правило, рекомендується використовувати прямі косі риси у файлах конфігурації.
  • provider – Модулі, які реалізують постачальників ErrorLog, також можуть використовуватися як ціль для повідомлень CustomLog. Щоб використовувати провайдера ErrorLog як ціль, необхідно використовувати синтаксис provider: argument. Наприклад, ви можете використовувати mod_journald або mod_syslog як провайдер:

Другий аргумент показує, що буде записано у файл журналу. Він може вказувати або псевдонім, визначений попередньою директивою LogFormat, або це може бути явний рядок формату. Наприклад, такі два набори директив мають абсолютно однаковий ефект:

Третій аргумент є необов’язковим та визначає, реєструвати чи ні конкретний запит. Умовою може бути наявність або відсутність (у разі пропозиції ‘env=!name‘) певної змінної серед сервера. Альтернативно, умова може бути виражена як довільний логічний вираз. Якщо умова не виконана, запит не буде зареєстровано. Посилання на заголовки HTTP у виразі не призводять до додавання імен заголовків у заголовок Vary. Змінні середовища можуть бути встановлені для кожного запиту за допомогою модулів mod_setenvif та/або mod_rewrite. Наприклад, якщо ви хочете записати запити для всіх зображень GIF на вашому сервері в окремий файл журналу, але не в основний журнал, ви можете використовувати:

Або, щоб відтворити поведінку старої директиви RefererIgnore, можна використовувати таке:

Директива GlobalLog

Встановлює ім’я файлу та формат журналу.

Синтаксис:

Контекст:

Сумісність: Доступна в Apache HTTP Server 2.4.19 та пізніших. Директива GlobalLog визначає журнал, загальний для конфігурації основного сервера та всіх налаштованих віртуальних хостів. Директива GlobalLog ідентична директиві CustomLog, за винятком таких відмінностей:

  • GlobalLog неприпустима у контексті віртуального хоста.

  • GlobalLog використовується віртуальними хостами, які визначають власний CustomLog, а не глобально визначений CustomLog.

Директива LogFormat

Описує формат для використання у файлі журналу.

Синтаксис:

Значення за замовчуванням:

Контекст:

Ця директива визначає формат файлу журналу доступу. Директива LogFormat може приймати одну із двох форм. У першій формі, де вказано лише один аргумент, ця директива встановлює формат журналу, який використовуватиметься журналами, зазначеними у наступних директивах TransferLog. Один аргумент може вказувати явний формат, як обговорювалося в розділі про формати користувача журналів вище. Крім того, він може використовувати псевдонім для посилання на формат журналу, визначений у попередній директиві LogFormat, як описано нижче. Друга форма директиви LogFormat пов’язує явний формат із псевдонімом. Цей псевдонім можна використовувати в наступних директивах LogFormat або CustomLog, а не повторювати весь рядок формату. Директива LogFormat, що визначає псевдонім, більше нічого не робить, тобто визначає лише псевдонім, фактично не застосовує формат і не встановлює його за умовчанням. Це не вплине на наступні директиви TransferLog. Крім того, LogFormat не може використовувати один псевдонім для визначення іншого псевдоніму. Зауважте, що псевдонім не повинен містити знаки відсотка (%).

Приклад:

Директива TransferLog

Визначає розміщення файлу журналу.

Синтаксис:

Контекст:

Ця директива має ті ж аргументи та ефект, що й директива CustomLog, за винятком того, що вона не дозволяє явно вказувати формат журналу або реєструвати запити на основі умов. Натомість формат журналу визначається останньою зазначеною директивою LogFormat, яка не визначає псевдонім. Загальний формат журналу використовується, якщо не вказано інший формат.

Приклад:

Формати журналів Apache

Common Log Format (загальний формат журналу)

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

Вона задає псевдонім common і пов’язує його з певним рядком формату журналу. Рядок формату складається з директив зі знаком відсотка, кожна з яких вказує серверу реєструвати певний фрагмент інформації. Буквальні символи також можуть бути поміщені у рядок формату та будуть скопійовані безпосередньо у виведення журналу. Символ лапки (“) повинен бути екранований шляхом розміщення зворотної косої межі перед ним, щоб він не інтерпретувався як кінець рядка формату. Рядок формату також може містити спеціальні керуючі символи “n” для нового рядка і “t” для табуляції. Директива CustomLog встановлює новий файл журналу, використовуючи певний псевдонім. Ім’я файлу для журналу доступу визначається щодо ServerRoot, якщо воно не починається з косої межі. Наведена вище конфігурація записуватиме записи журналу у форматі, відомому як Common Log Format (CLF). Цей стандартний формат може створюватися багатьма різними веб-серверами та зчитуватись багатьма програмами аналізу журналів. Записи файлу журналу, створені в CLF, будуть виглядати приблизно так:

Кожна частина запису журналу описана нижче.

  • 95.152.63.100 (%h) – Це IP-адреса клієнта (віддаленого хоста), яка зробила запит до сервера. Якщо для HostnameLookups встановлено значення On, сервер спробує визначити ім’я хоста та записати його замість IP-адреси. Однак така конфігурація не рекомендується, оскільки вона може сповільнити роботу сервера. Натомість найкраще використовувати постпроцесор журналу, такий як logressolve, для визначення імен хостів. Вказана тут IP-адреса не обов’язково є адресою машини, на якій сидить користувач. Якщо між користувачем та сервером існує проксі-сервер, ця адреса буде адресою проксі, а не вихідної машини.
  • – (%l) – “Дефіс” у вихідних даних вказує на те, що запитана частина інформації недоступна. У цьому випадку недоступна інформація є ідентифікаційною інформацією клієнта RFC 1413, визначеною за допомогою identd на клієнтському комп’ютері. Ця інформація вкрай ненадійна і майже ніколи не повинна використовуватися, крім жорстко контрольованих внутрішніх мереж. Apache httpd навіть не намагатиметься визначити цю інформацію, якщо для IdentityCheck не встановлено значення On.
  • frank (%u) – Це ідентифікатор користувача, який запитує документ, як він був визначений автентифікацією HTTP. Таке ж значення зазвичай надається сценаріям CGI в змінному середовищі REMOTE_USER. Якщо код стану для запиту дорівнює 401, цьому значенню не слід довіряти, оскільки користувач ще не автентифікований. Якщо документ не захищений паролем, ця частина буде “-“, як і попередня.
  • [18/Aug/2019:08:58:34 +0300] (%t) – Час отримання запиту. Формат такий:
  1. [день/місяць/рік:година:хвилина:секунда зона]

  2. день = 2 * цифри

  3. місяць = 3*літери

  4. рік = 4*цифри

  5. година = 2*цифри

  6. хвилина = 2 * цифри

  7. секунда = 2 * цифри

  8. зона = (`+’ | `-‘) 4*цифри

Можна відобразити час в іншому форматі, вказавши %{format}t у рядку формату журналу, де формат такий самий, як у strftime(3) зі стандартної бібліотеки C, або один із спеціальних маркерів, що підтримуються.

  • “GET /ru/?act=myip HTTP/1.1” (“%r”) – Рядок запиту від клієнта вказаний у подвійних лапках. Рядок запиту містить багато корисної інформації. По-перше, клієнт використовує метод GET. По-друге, клієнт запросив ресурс /ru/?act=myip, і по-третє, клієнт використовував протокол HTTP/1.1. Можна також зареєструвати одну або кілька частин рядка запиту незалежно. Наприклад, рядок формату “%m %U%q %H” реєструватиме метод, шлях, рядок запиту та протокол, що призведе до такого ж висновку, що і “%r”.
  • 200 (%>s) – Це код стану, який сервер надсилає назад клієнту. Ця інформація дуже цінна, оскільки вона показує, чи привів запит до успішної відповіді (коди починаються з 2), до перенаправлення (коди починаються з 3), до помилки, викликаної клієнтом (коди починаються з 4), або до помилок на сервері (коди починаються з 5).
  • 25858 (%b) – Остання частина вказує розмір об’єкта, який повертається клієнту, не включаючи заголовки відповіді. Якщо контент не було повернено клієнту, це значення буде “-“. Щоб записати «0» за відсутності вмісту, використовуйте %B.

Combined Log Format (Формат комбінованого журналу)

Інший широко використовуваний рядок формату називається Combined Log Format. Може використовуватися в такий спосіб:

Цей формат такий самий, як Common Log Format, з додаванням ще двох полів. Кожне з додаткових полів використовує директиву з відсотком %{header}i, де header може бути будь-яким заголовком HTTP-запиту. Журнал доступу в цьому форматі виглядатиме так:

Додатковими полями є:

  • “https://suip.biz/ru/?act=locatepicture” (“%{Referer}i”) – Це заголовок HTTP запиту “Referer”. У цьому рядку клієнт повідомляє сайту, з якого сайту і якої сторінки він прийшов (це має бути сторінка, на якій розміщено посилання на запитану адресу, або сторінка, яка включає запитаний файл (наприклад, зображення).
  • “Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36” (“%{User-agent}i”) – Заголовок HTTP-запиту User-Agent. Це ідентифікуюча інформація, яку клієнтський браузер повідомляє про себе.

Multiple Access Logs (Журнали множинного доступу)

Журнали множинного доступу можуть бути створені шляхом вказівки кількох директив CustomLog у файлі конфігурації. Наприклад, такі директиви створять три журнали доступу. Перший містить основну інформацію CLF, а другий і третій містять інформацію про реферера та браузер. Останні два рядки CustomLog показують, як імітувати ефекти директив ReferLog та AgentLog.

Цей приклад також показує, що немає потреби визначати псевдонім за допомогою директиви LogFormat. Натомість формат журналу може бути вказаний безпосередньо в директиві CustomLog.

Conditional Logs (логи з умовами)

Є моменти, коли зручно виключати певні записи журналів доступу на основі характеристик клієнтського запиту. Це легко зробити за допомогою змінних середовища. По-перше, необхідно встановити змінне середовище, щоб вказати, що запит задовольняє певним умовам. Зазвичай це досягається за допомогою SetEnvIf. Потім умова env= директиви CustomLog використовується для включення або виключення запитів, в яких встановлено змінне середовище. Деякі приклади:

Як інший приклад розглянемо запис запитів від англомовних користувачів до одного файлу журналу, а чи не говорять англійською — до іншого файл журналу.

У сценарії кешування хотілося б дізнатися про ефективність кешу. Дуже простий спосіб з’ясувати це буде:

mod_cache буде запущено до mod_env і, у разі успіху, доставить контент без нього. У цьому випадку кеш призведе до появи запису, а якщо кеш відсутній, то буде записано 1. Крім синтаксису env=, LogFormat підтримує значення реєстрації змінних, що залежать від коду відповіді HTTP:

У першому прикладі User-agent буде записано в журнал, якщо код стану HTTP дорівнює 400 або 501. В інших випадках замість нього буде записано буквальний рядок «-». Аналогічно, у другому прикладі Referer буде записано в журнал, якщо код стану HTTP не дорівнює 200, 204 або 302 (зверніть увагу на «!» перед кодами стану). Хоча ми щойно показали, що умовне ведення журналу є дуже потужним і гнучким, це єдиний спосіб управління вмістом журналів. Файли журналу корисніші, коли вони містять повний запис активності сервера. У більшості випадків простіше обробити повні файли журналів, щоб витягти з них лише потрібні вам дані або прибрати певну інформацію.

Ротація логів

Навіть на помірно завантаженому сервері кількість інформації, що зберігається у файлах журналу, дуже велика. Файл журналу доступу зазвичай збільшується на 1 МБ або більше 10 000 запитів. Отже, необхідно періодично ротувати файли журналів, переміщуючи чи видаляючи наявні журнали. Це неможливо зробити під час роботи сервера, оскільки Apache httpd продовжить запис до старого файлу журналу, поки він утримує цей файл відкритим. Натомість сервер має бути перезапущено після переміщення або видалення файлів журналу, щоб відкрити нові файли журналу. Використовуючи graceful перезапуск сервер може отримати команду відкривати нові файли журналу, не втрачаючи ні існуючих, ні очікуваних з’єднань від клієнтів. Однак для цього сервер повинен продовжувати запис у старі файли журналу до завершення обслуговування старих запитів. Тому потрібно почекати деякий час після перезапуску, перш ніж виконувати будь-яку обробку файлів журналу. Типовий сценарій, який просто ротує журнали та стискає старі журнали для економії місця:

Конвеєрна обробка (Piped Logs)

Apache httpd здатний записувати файли журналів доступу та помилок по трубі (через канал) до іншого процесу, а не безпосередньо у файл. Ця можливість значно підвищує гнучкість ведення журналу без додавання коду головний сервер. Щоб записувати журнали в трубу, просто замініть ім’я файлу на символ труби «|», за яким слідує ім’я файлу, що виконується, який повинен приймати записи журналу на своєму стандартному вході. Сервер при старті сервера запустить процес piped-log і перезапустить його, якщо він вийде з ладу під час роботи сервера (ця остання функція дозволяє назвати цю техніку “надійна передача журналу трубою”.) Процеси конвеєрного журналу породжуються батьківським процесом Apache httpd і успадковують ідентифікатор цього процесу. Це означає, що програми логів за конвеєром зазвичай запускаються з правами root. Тому дуже важливо, щоб програми були простими та безпечними. Одне з важливих застосувань конвеєрних журналів – дозволити ротацію журналів без перезавантаження сервера. HTTP-сервер Apache включає в себе просту програму rotatelogs для цієї мети. Наприклад, щоб ротувати журнали кожні 24 години, можна використовувати:

Зверніть увагу, що лапки використовуються для включення всієї команди, яка буде викликатись для труби. Хоча ці приклади належать до журналу доступу, той самий метод може бути використаний для журналу помилок. Як і у випадку з веденням логів з умовами, журнали конвеєра є дуже потужним інструментом, але їх не слід використовувати там, де доступне простіше рішення, таке як автономна постобробка. За умовчанням процес журналу, що передається по трубі, породжується без виклику оболонки. Використовуйте “|$” замість “|” для запуску з оболонкою (зазвичай з /bin/sh-c):

Це була поведінка за промовчанням для Apache 2.2. Залежно від специфіки оболонки це може призвести до додаткового процесу оболонки на час життя програми каналу журналу та проблем з обробкою сигналів під час перезапуску. З причин сумісності з Apache 2.2 позначення “||” також підтримується та еквівалентно використанню «|». Примітка для Windows: Зверніть увагу, що у Windows ви можете зіткнутися з проблемами під час запуску багатьох процесів журналювання, особливо коли HTTPD працює як служба. Це викликано нестачею heap space робочого столу. Простір робочого столу, який надається кожній службі, задається третім аргументом параметра SharedSection у значенні реєстру HKEY_LOCAL_MACHINESystemCurrentControlSetControlSessionManagerSubSystemsWindows. Змініть це значення з обережністю; застосовуються звичайні застереження для зміни реєстру Windows, але ви також можете вичерпати пул heap space робочого столу, якщо число буде встановлено занадто високо.

Віртуальні Хости

При запуску сервера з багатьма віртуальними хостами є кілька варіантів роботи з файлами журналів. По-перше, можна використовувати журнали так само, як на сервері з одним хостом. Просто розмістивши директиви ведення журналів за межами розділів <VirtualHost> у контексті основного сервера, можна зареєструвати всі запити в одному журналі доступу та журналі помилок. Цей метод не дозволяє легко збирати статистику з окремих віртуальних хостів. Якщо директиви CustomLog або ErrorLog містяться в розділі <VirtualHost>, всі запити або помилки для цього віртуального хоста записуватимуться лише у вказаний файл. Будь-який віртуальний хост, у якого немає директив журналування, все одно надсилатиме свої запити до журналів головного сервера. Цей метод дуже корисний для невеликої кількості віртуальних хостів, але якщо кількість хостів дуже велика, ним може бути складно керувати. Крім того, це часто може створювати проблеми з недостатньою кількістю файлових дескрипторів. Для журналу доступу є дуже непоганий компроміс. Додавши інформацію про віртуальний хост у рядок формату журналу, можна зареєструвати всі хости в одному журналі, а потім розділити журнал на окремі файли. Наприклад, розглянемо такі директиви.

%v використовується для запису до журналу імені віртуального хоста, який обслуговує запит. Потім таку програму, як split-logfile, можна використовувати для подальшого оброблення журналу доступу, щоб розділити його на один файл для кожного віртуального хоста.

Питання безпеки

Будь-хто, хто може писати в каталог, де Apache httpd пише файл журналу, майже напевно може отримати доступ до uid, з якого запущено сервер, який зазвичай є користувачем root. НЕ надавайте людям доступ до запису в каталог, де зберігаються журнали, не знаючи про наслідки. Крім того, файли журналів можуть містити інформацію, надану безпосередньо клієнтом, без екранування. Тому зловмисні клієнти можуть вставляти керуючі символи у файли журналів, тому необхідно бути обережними при роботі з необробленими журналами.

У звичайній роботі Apache запускається користувачем root і перемикається на користувача, визначеного директивою User, для обслуговування звернень. Як і у випадку з будь-якою командою, яку виконує користувач root, ви повинні подбати про те, щоб вона була захищена від зміни користувачами без повноважень root. Не тільки самі файли повинні бути доступні для запису лише root, а й каталоги та батьки всіх каталогів.

Наприклад, якщо ви вирішите помістити ServerRoot в /usr/local/apache, то рекомендується створити цей каталог як root за допомогою таких команд:

Передбачається, що /, /usr та /usr/local можуть бути змінені лише користувачем root. При встановленні файлу httpd, що виконується, ви повинні переконатися, що він захищений аналогічним чином:

Ви можете створити підкаталог htdocs, який може бути змінений іншими користувачами – оскільки root ніколи не виконує ніяких файлів звідти і не повинен створювати файли там. Якщо ви дозволяєте користувачам без повноважень root змінювати будь-які файли, які root виконує або виконує запис, ви відкриваєте свою систему для компрометації root. Наприклад, хтось може замінити двійковий файл httpd, щоб під час наступного запуску він виконував довільний код. Якщо каталог журналів доступний для запису (користувач без root), хтось може замінити файл журналу символічним посиланням на будь-який інший системний файл, а потім root може перезаписати цей файл довільними даними. Якщо самі файли журналу доступні для запису (користувач без root), то хтось може перезаписати сам журнал підробленими даними.

Інші статті по темі
Знайшли помилку?
Якщо ви знайшли помилку, зробіть скріншот і надішліть його боту.