Введение
Как системный администратор или специалист по безопасности, вы часто будете сталкиваться с огромными файлами журналов (логов), генерируемыми веб-серверами, такими как Apache или Nginx. Вручную просматривать тысячи строк логов в поисках вредоносной активности — это неэффективно и чревато человеческими ошибками.
В этой лабораторной работе вы примерите на себя роль специалиста по реагированию на инциденты. Вы напишете скрипт на Python, предназначенный для обработки логов доступа веб-сервера Apache. Используя библиотеку регулярных выражений (re), вы сможете автоматически извлекать IP-адреса и обнаруживать известные сигнатуры атак типа SQL-инъекция (SQLi). В завершение вы экспортируете полученные данные в структурированный CSV-отчет для дальнейшего анализа.
Этот модуль показывает, как Python превращается из простого языка программирования в мощный инструмент аналитика. Логи — один из самых наглядных примеров работы, которая слишком монотонна для внимательного ручного просмотра, но достаточно структурирована для немедленной автоматизации.
Чтение файлов логов на Python
На этом этапе вы узнаете, как использовать Python для открытия и чтения файла логов. В вашей рабочей директории уже подготовлен пример файла лога Apache под названием access.log.
Построчное чтение файлов — это фундаментальный шаблон автоматизации. Он масштабируется гораздо лучше, чем ручное копирование данных, и позволяет в дальнейшем добавлять логику фильтрации, парсинга, подсчета и формирования отчетов, не меняя базовый подход к обработке данных.
Сначала давайте посмотрим содержимое файла лога, чтобы понять, с чем мы работаем. Используйте команду cat в терминале для вывода содержимого файла.
cat access.log
Вы увидите несколько строк стандартных логов доступа Apache. Некоторые из них содержат обычные веб-запросы, в то время как другие включают подозрительные попытки SQL-инъекций.
Теперь создадим скрипт на Python для программного чтения этого файла. Мы воспользуемся текстовым редактором nano для создания файла log_analyzer.py.
nano log_analyzer.py
В Python функция open() используется для открытия файла, а оператор with гарантирует, что файл будет корректно закрыт после завершения чтения. Скопируйте и вставьте следующий код Python в редактор nano:
def analyze_logs(file_path):
print(f"Opening log file: {file_path}")
## Open the file in read mode ('r')
with open(file_path, 'r') as file:
## Read the file line by line
for line in file:
## Print each line, stripping the extra newline character
print(line.strip())
if __name__ == "__main__":
log_file = "access.log"
analyze_logs(log_file)
Сохраните файл в nano, нажав Ctrl+O, а затем Enter для подтверждения имени файла. Если вы хотите продолжить доработку скрипта перед тестированием, вы можете остаться в nano и перейти к следующему шагу. Используйте Ctrl+X только тогда, когда будете готовы вернуться в терминал.
Запустите созданный скрипт на Python с помощью команды python3:
python3 log_analyzer.py
Вы увидите, что скрипт выводит те же самые строки логов, которые вы видели ранее при использовании команды cat. Это подтверждает, что ваш скрипт успешно считывает данные логов построчно.
Применение регулярных выражений для извлечения IP-адресов
На этом этапе вы улучшите свой скрипт, чтобы он автоматически извлекал IP-адрес из каждой строки лога. Для этого мы воспользуемся регулярными выражениями (Regex). Регулярные выражения — это мощный инструмент для поиска шаблонов в тексте.
Регулярные выражения полезны, потому что логи являются полуструктурированными: они следуют определенным шаблонам, но обычно не представлены в виде готовых объектов Python. Regex позволяет описать нужный текстовый шаблон и поручить интерпретатору выполнение рутинной работы по поиску совпадений.
В Python есть встроенный модуль re для работы с регулярными выражениями. Нам нужно импортировать этот модуль и определить шаблон, соответствующий IPv4-адресу. IPv4-адрес состоит из четырех чисел (от 0 до 255), разделенных точками.
Если log_analyzer.py все еще открыт в nano, продолжайте редактирование. В противном случае откройте его снова:
nano log_analyzer.py
Обновите скрипт, добавив модуль re и логику поиска IP-адресов. Замените все содержимое файла следующим кодом:
import re
def analyze_logs(file_path):
print(f"Analyzing log file: {file_path}\n")
## Define a Regex pattern for an IPv4 address
## \b ensures word boundaries, \d{1,3} matches 1 to 3 digits, \. matches a literal dot
ip_pattern = r'\b(?:\d{1,3}\.){3}\d{1,3}\b'
with open(file_path, 'r') as file:
for line in file:
## re.findall returns a list of all matches in the string
ips_found = re.findall(ip_pattern, line)
if ips_found:
## We take the first IP found in the line
source_ip = ips_found[0]
print(f"Extracted IP: {source_ip}")
if __name__ == "__main__":
log_file = "access.log"
analyze_logs(log_file)
Сохраните файл с помощью Ctrl+O и Enter. Если хотите протестировать эту промежуточную версию, выйдите через Ctrl+X и запустите скрипт. Если нет, можно сразу переходить к следующему шагу.
python3 log_analyzer.py
Вы должны увидеть вывод, похожий на этот:
Analyzing log file: access.log
Extracted IP: 192.168.1.10
Extracted IP: 10.0.0.15
Extracted IP: 172.16.0.5
Extracted IP: 192.168.1.22
Extracted IP: 10.0.0.25
Теперь скрипт успешно игнорирует остальной текст лога и выделяет только исходные IP-адреса благодаря возможностям регулярных выражений.
Обнаружение сигнатур SQL-инъекций
На этом этапе вы добавите в скрипт функцию обнаружения угроз. SQL-инъекция (SQLi) — это распространенная веб-атака, при которой вредоносные SQL-запросы вставляются в поля ввода.
Это превращает скрипт из простого парсера в детектор. Вместо того чтобы просто извлекать поля, вы теперь применяете логику безопасности, чтобы определить, какие строки заслуживают внимания. Этот переход от сбора данных к их интерпретации делает автоматизацию операционно ценной.
Злоумышленники часто используют ключевые слова, такие как UNION SELECT, для кражи данных или ' OR '1'='1 для обхода аутентификации. Мы можем использовать регулярные выражения для сканирования строк логов на наличие этих известных сигнатур атак.
Если вы все еще редактируете файл в nano, продолжайте работу. В противном случае откройте его:
nano log_analyzer.py
Мы определим новый шаблон регулярного выражения для поиска распространенных фраз SQLi. Мы будем использовать (?i), чтобы сделать поиск нечувствительным к регистру, что позволит находить UNION, union или uNiOn. Обновите скрипт следующим кодом:
import re
def analyze_logs(file_path):
print(f"Scanning log file for SQLi attacks: {file_path}\n")
ip_pattern = r'\b(?:\d{1,3}\.){3}\d{1,3}\b'
## Define a Regex pattern for SQL Injection signatures
## (?i) makes it case-insensitive
## It looks for 'union select' OR 'or 1=1' variations
sqli_pattern = r"(?i)(union.*select|or\s+1\s*=\s*1|'.*or.*')"
with open(file_path, 'r') as file:
for line in file:
ips_found = re.findall(ip_pattern, line)
source_ip = ips_found[0] if ips_found else "Unknown IP"
## re.search returns a match object if the pattern is found, otherwise None
if re.search(sqli_pattern, line):
print(f"[ALERT] SQL Injection detected from IP: {source_ip}")
print(f"Raw Log: {line.strip()}\n")
if __name__ == "__main__":
log_file = "access.log"
analyze_logs(log_file)
Сохраните файл с помощью Ctrl+O и Enter. Выходите из nano через Ctrl+X только тогда, когда будете готовы запустить скрипт из терминала.
python3 log_analyzer.py
Теперь ваш вывод должен содержать предупреждения о вредоносных запросах:
Scanning log file for SQLi attacks: access.log
[ALERT] SQL Injection detected from IP: 10.0.0.15
Raw Log: 10.0.0.15 - - [10/Oct/2026:13:55:45 -0700] "GET /login.php?user=admin' OR '1'='1 HTTP/1.1" 200 5120
[ALERT] SQL Injection detected from IP: 192.168.1.22
Raw Log: 192.168.1.22 - - [10/Oct/2026:13:56:12 -0700] "GET /products.php?id=1 UNION SELECT username, password FROM users HTTP/1.1" 200 4012
Ваш скрипт теперь работает как базовая система обнаружения вторжений (IDS), автоматически выявляя подозрительные запросы в файле логов.
Вывод в CSV-отчет
На этом заключительном этапе вы отформатируете результаты и сохраните их в файл CSV (Comma-Separated Values). Вывод в терминал удобен для тестирования, но командам безопасности нужны структурированные отчеты, которые можно открыть в табличном процессоре или передать другим инструментам.
В Python есть встроенный модуль csv, который значительно упрощает запись CSV-файлов.
Если файл открыт, продолжайте редактирование. В противном случае откройте его:
nano log_analyzer.py
Мы импортируем модуль csv, откроем новый файл report.csv в режиме записи ('w') и запишем в него наши результаты. Замените код этой финальной версией:
import re
import csv
def analyze_logs(file_path, output_csv):
print(f"Analyzing logs and generating report: {output_csv}...")
ip_pattern = r'\b(?:\d{1,3}\.){3}\d{1,3}\b'
sqli_pattern = r"(?i)(union.*select|or\s+1\s*=\s*1|'.*or.*')"
## Open the output CSV file in write mode
with open(output_csv, 'w', newline='') as csv_file:
writer = csv.writer(csv_file)
## Write the header row
writer.writerow(['Source IP', 'SQLi Detected', 'Raw Log'])
with open(file_path, 'r') as file:
for line in file:
clean_line = line.strip()
ips_found = re.findall(ip_pattern, clean_line)
source_ip = ips_found[0] if ips_found else "Unknown IP"
## Check if SQLi is detected
sqli_detected = "Yes" if re.search(sqli_pattern, clean_line) else "No"
## Write the data row to the CSV
writer.writerow([source_ip, sqli_detected, clean_line])
print("Report generation finished.")
if __name__ == "__main__":
log_file = "access.log"
report_file = "report.csv"
analyze_logs(log_file, report_file)
Сохраните файл и выполните скрипт:
python3 log_analyzer.py
Вы увидите сообщение о том, что генерация отчета завершена. Теперь давайте проверим, что файл CSV был создан, и просмотрим его содержимое с помощью команды cat:
cat report.csv
Вы должны увидеть аккуратно отформатированный CSV-вывод:
Source IP,SQLi Detected,Raw Log
192.168.1.10,No,192.168.1.10 - - [10/Oct/2026:13:55:36 -0700] "GET /index.html HTTP/1.1" 200 2326
10.0.0.15,Yes,10.0.0.15 - - [10/Oct/2026:13:55:45 -0700] "GET /login.php?user=admin' OR '1'='1 HTTP/1.1" 200 5120
172.16.0.5,No,172.16.0.5 - - [10/Oct/2026:13:56:01 -0700] "POST /api/data HTTP/1.1" 404 134
192.168.1.22,Yes,192.168.1.22 - - [10/Oct/2026:13:56:12 -0700] "GET /products.php?id=1 UNION SELECT username, password FROM users HTTP/1.1" 200 4012
10.0.0.25,No,10.0.0.25 - - [10/Oct/2026:13:57:00 -0700] "GET /about.html HTTP/1.1" 200 1024
Резюме
В этой лабораторной работе вы успешно перешли от ручного чтения логов к автоматизированному анализу с помощью Python. Вы узнали, как читать и обрабатывать текстовые файлы построчно, используя встроенные средства Python для работы с файлами. Вы также использовали модуль re для применения регулярных выражений при извлечении данных специфических форматов, таких как IP-адреса. Кроме того, вы реализовали логику обнаружения угроз, сопоставляя известные сигнатуры SQL-инъекций с данными логов. Наконец, вы научились экспортировать структурированные данные в CSV-отчет с помощью модуля csv, что делает результаты удобными для обмена и дальнейшего анализа.
Эти навыки составляют основу автоматизации безопасности и парсинга данных, позволяя вам эффективно работать с огромными массивами информации.



