This commit is contained in:
2024-11-07 11:23:57 +03:00
parent 3b2966ebe2
commit a9d73b7368
4 changed files with 1814 additions and 991 deletions

View File

@@ -0,0 +1,316 @@
---
title: 'Graylog'
summary: 'Краткое руководство по установки Graylog'
date: '11 07 2024'
draft: false
tags:
- Graylog
- log
---
# Введение
Graylog — это платформа с открытым исходным кодом, предназначенная для управления логами. Она собирает и извлекает важные данные из логов сервера, которые обычно отправляются с помощью протокола Syslog.
## Возможности Graylog:
- Поиск и визуализация логов в веб-интерфейсе.
- Настройка фильтрации и поиска логов.
- Мониторинг и отправка оповещений.
- Graylog позволяет отправлять логи и журналы событий с сотен сетевых устройств, включая серверы на Linux, Windows, сетевые устройства и другое оборудование.
## Архитектура Graylog
Стек Graylog включает следующие компоненты:
- Сервер Graylog — веб-интерфейс для визуализации и настройки.
- MongoDB — используется для хранения метаданных.
- ElasticSearch или его форк OpenSearch — для хранения и полнотекстового поиска в структурированных и неструктурированных логах.
- Java (OpenJDK) — среда выполнения для OpenSearch (Elasticsearch).
Мы будем использовать стек OpenSearch для хранения журналов, который является бесплатным аналогом стека ELK (Elasticsearch + Logstash + Kibana).
## Причины выбора Graylog
- Распространенность и проверенность временем.
- Открытый исходный код.
- Бесплатная версия включает все необходимое.
- Минимальный функционал, оптимальный для наших задач.
- "Из коробки" решение требует минимальных настроек.
- Низкая ресурсоемкость по сравнению с ELK.
# Подготовка сервера
| Параметры | Значения |
|------------------------|-----------------|
| Кол-во ядер процессора | 4 CPU |
| Размер ОЗУ | 8 GB |
| Размер DISK | 90 GB |
| Сетевой интерфейс |2 eth / 2 подсети|
Для стабильной работы используйте следующие версии
| Дистрибутив| Версия |
|------------|--------|
| Debian | 12 |
| MongoDB | 6.0 |
| Graylog | 5.2 |
| OpenSearch | 2.17 |
Проверьте архитектуру системы, поскольку MongoDB 6.0 поддерживает только x64 Debian:
```sh
uname -m
# Нужно получить
# x86_64
```
Авторизуемся под рутом
```sh
su -
Password:
```
Устанавливаем sudo
```sh
apt install sudo
# Сразу добавим пользователю права на будущее
nano /etc/sudoers
```
Ниже этой строки пользователя root добавляем своего `<username> ALL=(ALL:ALL) ALL`
```sh
# User privilege specification
root ALL=(ALL:ALL) ALL
<username> ALL=(ALL:ALL) ALL
```
### Настройка часового пояса (если не указано при установке ОС)
```sh
timedatectl set-timezone Asia/Yakutsk
```
## Установка необходимых пакетов
```sh
# Обновляем пакеты
apt update -y && apt upgrade -y && apt dist-upgrade -y
# Устанавливаем целевые пакеты
apt install -y net-tools mc htop git wget curl make gcc neofetch lsb-release ca-certificates gnupg gnupg2 tar lbzip2 zip unzip screen pwgen
```
Так же рекомендуется воспользоваться настройками для начальной защиты сервера на Linux
Если вы настроили firewalld то дополните настройки:
```sh
# Если не используем ipv6 - лучше отключить:
firewall-cmd --remove-service=dhcpv6-client
# Добавляем порты в файрвол
firewall-cmd --permanent --add-port=9000/tcp
firewall-cmd --permanent --add-port=514/tcp
firewall-cmd --permanent --add-port=514/udp
firewall-cmd --permanent --zone=itsoft --add-service=https
firewall-cmd --permanent --zone=itsoft --add-service=http
# После добавления/удаления перезагрузим сервис:
firewall-cmd --reload
```
Настойка neofetch
```sh
# Первый запуск для создания ~/.config/neofetch/config.conf
neofetch
# Далее добавляем в .bashrc в самый конец файла
echo "neofetch" >> ~/.bashrc
# Далее идем редактировать конфиг
nano ~/.config/neofetch/config.conf
```
Я использую вот такие параметры для вывода минимально необходимого при подключении к серверу.
```sh
print_info() {
info title
info underline
info "OS" distro
info "Host" model
info "Kernel" kernel
info "Uptime" uptime
#info "Packages" packages
info "Shell" shell
#info "Resolution" resolution
#info "DE" de
#info "WM" wm
#info "WM Theme" wm_theme
#info "Theme" theme
#info "Icons" icons
info "Terminal" term
info "Terminal Font" term_font
info "CPU" cpu
#info "GPU" gpu
info "Memory" memory
# info "GPU Driver" gpu_driver # Linux/macOS only
# info "CPU Usage" cpu_usage
info "Disk" disk
# info "Battery" battery
# info "Font" font
# info "Song" song
# [[ "$player" ]] && prin "Music Player" "$player"
info "Local IP" local_ip
# info "Public IP" public_ip
# info "Users" users
# info "Locale" locale # This only works on glibc systems.
#info cols
}
```
### Установка MongoDB 6
```sh
# Добавление публичного ключа:
curl -fsSL https://www.mongodb.org/static/pgp/server-6.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-6.0.gpg --dearmor
# Добавление репозитория:
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-6.0.gpg] http://repo.mongodb.org/apt/debian bullseye/mongodb-org/6.0 main" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list
# Обновление локальной базы пакетов:
sudo apt-get update
# Установка MongoDB:
sudo apt-get install -y mongodb-org
```
Если при установке вы получили сообщение об unmet dependencies
```sh
The following packages have unmet dependencies:
mongodb-org-mongos : Depends: libssl1.1 (>= 1.1.1) but it is not installable
mongodb-org-server : Depends: libssl1.1 (>= 1.1.1) but it is not installable
```
выполните следующие команды:
```sh
sudo wget http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_amd64.deb
sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2_amd64.deb
```
И повторяем установку `mongodb-org`
```sh
sudo apt-get install -y mongodb-org
```
Запуск сервиса MongoDB:
```sh
sudo systemctl daemon-reload
sudo systemctl enable mongod.service
sudo systemctl restart mongod.service
# Посмотреть статус сервиса
sudo systemctl --type=service --state=active | grep mongod
```
### Переходим к развёртыванию OpenSearch
```sh
# Добавление публичного ключа для OpenSearch:
curl -o- https://artifacts.opensearch.org/publickeys/opensearch.pgp | sudo gpg --dearmor --batch --yes -o /usr/share/keyrings/opensearch-keyring
# Добавление репозитория OpenSearch:
echo "deb [signed-by=/usr/share/keyrings/opensearch-keyring] https://artifacts.opensearch.org/releases/bundle/opensearch/2.x/apt stable main" | sudo tee /etc/apt/sources.list.d/opensearch-2.x.list
# Обновление локальной базы пакетов:
sudo apt-get update
```
Установка OpenSearch с генерацией пароля администратора:
```sh
sudo OPENSEARCH_INITIAL_ADMIN_PASSWORD=$(tr -dc A-Z-a-z-0-9_@#%^-_=+ < /dev/urandom | head -c${1:-32}) apt-get install opensearch
```
### Настройка OpenSearch
```sh
# Редактирование конфигурации OpenSearch:
sudo nano /etc/opensearch/opensearch.yml
```
```sh
cluster.name: graylog
node.name: ${HOSTNAME}
path.data: /var/lib/opensearch
path.logs: /var/log/opensearch
network.host: 0.0.0.0
# Добавляем в параметров перед plugins
discovery.type: single-node
action.auto_create_index: false
plugins.security.disabled: true
indices.query.bool.max_clause_count: 32768
```
Настройка параметров Java:
```sh
sudo nano /etc/opensearch/jvm.options
```
В параметрах `Xms` и `Xmx` установите половину объема ОЗУ сервера. Например, для сервера с 8 ГБ укажите:
```sh
-Xms4g
-Xmx4g
```
Изменение параметров виртуальной памяти:
```sh
sudo sysctl -w vm.max_map_count=262144
sudo echo 'vm.max_map_count=262144' >> /etc/sysctl.conf
```
Запуск OpenSearch:
```sh
sudo systemctl enable --now opensearch
```
### Установка Graylog
Есть две версии Graylog: бесплатная Graylog Open и enterprise версия Graylog Operations, доступная по подписке.
```sh
wget https://packages.graylog2.org/repo/packages/graylog-5.2-repository_latest.deb
sudo dpkg -i graylog-5.2-repository_latest.deb
sudo apt-get update && sudo apt-get install graylog-server
```
Сгенерируйте пароли для двух переменных password_secret и root_password_sha2, без которых Graylog не запустится.
Пароль password_secret должен содержать минимум 64 символа:
```sh
pwgen -N 1 -s 96
# Получаем сгенерированный пароль
XzN25fRfHv7NGbVODAGDcRWhzd6QAQQa11RXLIVgSXCgaDZexaxE4VlLA1abmEQjN25BlRVyEp3LNhN6HcJL8GYjV3RQgwkA
# Отправляем пароль для получения HEX ключа
echo -n "Enter Password: " && head -1 </dev/stdin | tr -d '\n' | sha256sum | cut -d" " -f1
```
Скопируйте полученные значения password_secret и root_password_sha2 в файл `/etc/graylog/server/server.conf`.
```sh
password_secret = <сгенерированный_пароль>
root_password_sha2 = <HEX_ключа>
http_bind_address = <IP_адрес_сервера>:9000
```
Запустите сервер graylog:
```sh
sudo systemctl enable --now graylog-server
sudo systemctl status graylog-server
```
### настройка Graylog
Теперь нужно посмотреть логи сервера GrayLog, там вы обнаружите интересное сообщение:
```sh
cat /var/log/graylog-server/server.log
# Получаем лог
It seems you are starting Graylog for the first time. To set up a fresh install, a setup interface has been started. You must log in to it to perform the initial configuration and continue.
Initial configuration is accessible at 0.0.0.0:9000, with username 'admin' and password 'eDluAYfeaX'.
Try clicking on http://admin:eDluAYfeaX@0.0.0.0:9000
```
Видна ссылка для первого входа по временному паролю `http://admin:eDluAYfeaX@0.0.0.0:9000`
В первый раз нужно зайти под временным паролем, который указан в лог файле. Воспользуйтесь простым мастером начальной конфигурации. Режим Graylog data node используется для настройки OpenSearch кластера из нескольких нод. Для простой конфигурации из одного сервера логов, этот этап можно пропустить.
После первой настройки рекомендуется создать отдельного пользователя в `System -> Users and Teams`, назначив ему роль admin. Некоторые настройки встроенного администратора нельзя кастомизировать, поэтому лучше работать под отдельным пользователя. Назначьте пользователю роль `admin` и задайте email адрес.
Создайте сборщики данных в виде Input для разных устройств, например, `Syslog UDP` для Linux. Для каждого класса устройств лучше делать отдельный `input` (Linux сервера, сетевое оборудование, Windows хосты и т.д.).
Нужно указать его название, и порт, на котором сервер будет принимать данные. Остальные настройки оставить по-умолчанию.
Создайте индекс для класса Linux в `System -> Indices`, указав имя и настройки хранения логов.
Нужно указать имя, описание и префикс (например `linux_indx` ). Здесь можно также настроить сколько дней нужно хранить старые логи, и когда можно удалять старые индекс, а также максимальный размер индекса.
Для каждого `input` лучше создать отдельный `Stream`. Так разные сообщений от разных классов устройства будут находится в разных индексах. Перейдите в `Stream -> Create Stream ->` укажите название потока и выберите индекс, который нужно использовать.
В настройках `Stream` добавьте новое правило. Правило определят какие логи нужно отнести к этому потоку. В нашем случае выбираем `match input ->` выберите ваш `Linux Input`.
После этого запустите `stream`.

View File

@@ -0,0 +1,230 @@
---
title: 'Начальная настройка Debian'
summary: 'Настройка debian server после установки'
date: '10 06 2024'
draft: false
tags:
- Debian
- Fail2ban
- firewalld
---
# Введение
## Настройка языка
Параметры локали (locale) в Linux определяют текущие региональные настройки операционной системы, используемые в терминале и в графическом интерфейсе (формат даты и времени, поддерживаемые наборы символов/кодировки). Рассмотрим, как получить или изменить текущие настройки локали в Linux на примере Ubuntu и Debian.
Вывести текущие настройки локали в Ubuntu и Debian можно с помощью команды:
```sh
locale
# ИЛИ
localectl status
```
```sh
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=en_US.UTF-8
LC_TIME=en_US.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=en_US.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=en_US.UTF-8
LC_NAME=en_US.UTF-8
LC_ADDRESS=en_US.UTF-8
LC_TELEPHONE=en_US.UTF-8
LC_MEASUREMENT=en_US.UTF-8
LC_IDENTIFICATION=en_US.UTF-8
LC_ALL=
```
- **LANG** — текущая системная локаль (`en_US.UTF-8`)
- **LC_NUMERIC** — формат чисел
- **LC_MONETARY** — валюта и формат денежных величин
- **LC_TIME** — формат даты и времени
Чтобы вывести список доступных локалей на хосте:
```sh
locale -a
# ИЛИ
localectl list-locales
```
Для детальной информации об установленных локалях:
```sh
locale -a -v
```
Системная локаль `C.UTF-8` всегда присутствует в списке (локаль по умолчанию).
Чтобы вывести информацию о переменной окружения для формата времени и даты:
```sh
locale -k LC_TIME
```
### Установить русскую local в Ubuntu и Debian
Добавим русскую локаль `ru_RU.UTF-8`.
Список локалей, доступных для установки, можно найти в файле `/etc/locale.gen`. Для генерации русской локали выполните:
```sh
sudo locale-gen ru_RU.UTF-8
```
Назначение русской локали по умолчанию:
```sh
sudo update-locale LANG=ru_RU.UTF-8
```
Или:
```sh
sudo localectl set-locale LANG=ru_RU.UTF-8
```
Эта команда запишет следующую строку в файл `/etc/default/locale`:
```sh
LANG=ru_RU.UTF-8
```
Перезагрузите хост Linux, чтобы применить изменения.
Если вы зададите локаль, которая не была сгенерирована, команда `locale` выведет ошибки:
```sh
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=fr_FR.utf8
```
Можно задать разные локали для различных региональных настроек:
```sh
sudo update-locale LC_NUMERIC=en_US.UTF-8 LC_TIME=en_US.UTF-8 LC_MONETARY=en_US.UTF-8
```
В некоторых случаях необходимо сначала установить нужную локаль:
```sh
sudo apt-get install language-pack-fr
```
Если локаль не задана, и команда `locale -a` возвращает только три записи:
```sh
C
C.UTF-8
POSIX
```
Сгенерируйте новую локаль и примените изменения:
```sh
sudo locale-gen ru_RU.UTF-8
sudo update-locale LANG=ru_RU.UTF-8
```
Перезагрузите систему или откройте новое окно терминала. Новые пользователи будут использовать локаль, указанную в файле `/etc/default/locale`.
Для изменения локали конкретного пользователя, отредактируйте файл `.bashrc` в его домашнем каталоге:
```sh
nano .bashrc
```
### Создание нерутового пользователя
Создание нерутового пользователя — важная мера безопасности. Для этого используйте команды:
```sh
useradd [options] <username>
```
Затем для него добавляется пароль командой `passwd`:
```sh
passwd <username>
```
Наконец, этого пользователя нужно добавить в группу, которая имеет право выполнять команды с повышением привилегий `sudo`.
```sh
usermod -aG sudo <username>
```
### Ключи вместо паролей SSH
Рекомендуется отключить аутентификацию по паролям в SSH и использовать ключи. Сначала установите OpenSSH:
```sh
sudo apt install openssh-client openssh-server
```
Запуск демона SSH (sshd) на сервере под Ubuntu:
```sh
sudo systemctl start sshd
# Автоматический запуск демона при каждой загрузке:
sudo systemctl enable sshd
```
Итак, нужно сгенерировать ключи SSH на компьютере, с которого вы будете заходить на сервер:
```sh
ssh-keygen -t rsa -b 4096
```
Публичный ключ хранится в файле `.pub` и выглядит как строка случайных символов, которые начинаются с `ssh-rsa`.
```sh
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ3GIJzTX7J6zsCrywcjAM/7Kq3O9ZIvDw2OFOSXAFVqilSFNkHlefm1iMtPeqsIBp2t9cbGUf55xNDULz/bD/4BCV43yZ5lh0cUYuXALg9NI29ui7PEGReXjSpNwUD6ceN/78YOK41KAcecq+SS0bJ4b4amKZIJG3JWm49NWvoo0hdM71sblF956IXY3cRLcTjPlQ84mChKL1X7+D645c7O4Z1N3KtL7l5nVKSG81ejkeZsGFzJFNqvr5DuHdDL5FAudW23me3BDmrM9ifUmt1a00mWci/1qUlaVFft085yvVq7KZbF2OP2NQACUkwfwh+iSTP username@hostname
```
Публичный ключ добавляется на сервер:
```sh
mkdir -p /home/<username>/.ssh && touch /home/<username>/.ssh/authorized_keys
vim /home/<username>/.ssh/authorized_keys
chmod 700 /home/<username>/.ssh && chmod 600 /home/<username>/.ssh/authorized_keys
chown -R <username>:<username> /home/<username>/.ssh
```
Затем настройте файл конфигурации SSH **/etc/ssh/sshd_config** :
```sh
PermitRootLogin no
PasswordAuthentication no
```
### SSH на клиенте Windows
SSH Agent может хранить закрытые ключи и предоставлять их в контексте безопасности текущего пользователя. Запустите службу ssh-agent и настройте автоматический запуск с помощью PowerShell команд управления службами:
```powershell
Set-service ssh-agent StartupType Automatic
Start-Service ssh-agent
```
Добавьте ваш закрытый ключ в базу ssh-agent:
```powershell
ssh-add "C:\Users\user\.ssh\id_key_ssh"
# или так
ssh-add.exe $ENV:UserProfile\.ssh\id_key_ssh
```
### Настройки Firewall
#### Установка и настройка Firewalld
Чтобы ограничить доступ на сервер, можно использовать Firewalld. Установка:
```sh
sudo apt install firewalld
```
Добавляем SSH в исключения:
```sh
sudo firewall-cmd --zone=public --add-service=ssh --permanent
```
Запускаем сервис systemd для firewalld:
```sh
sudo systemctl start firewalld
sudo systemctl enable firewalld
```
### Настройки Fail2Ban
Fail2Ban помогает предотвратить атаки перебором, блокируя IP-адреса после нескольких неудачных попыток авторизации.
#### Установка Fail2Ban
Для установки на Ubuntu и Debian выполните:
```sh
sudo apt install fail2ban
```
Запуск сервиса:
```sh
systemctl start fail2ban
systemctl enable fail2ban
```
Настройки находятся в файлах `/etc/fail2ban/fail2ban.conf` и `/etc/fail2ban/jail.conf`.
### Автоматические обновления безопасности
В Ubuntu автоматические обновления включены по умолчанию.
### Смена порта SSH
Изменение порта SSH — мера обфускации:
```sh
Port <custom_port>
```
Указывайте порт с параметром `-p` для SSH и `-P` для SFTP и SCP.
### Заключение
Все эти шаги позволяют значительно повысить безопасность Linux-сервера.

View File

@@ -0,0 +1,147 @@
---
title: 'Graylog'
summary: 'Краткое руководство по установки Graylog'
date: '10 05 2024'
draft: false
tags:
- Python
- OCR
- tensorflow
- pytesseract
- opencv-python
---
# Скрипт для перевода изображения в текст
# Устанавливаем библиотеки
```python
pip install opencv-python pytesseract tensorflow
```
Не забудьте дополнительно установить Tesseract OCR на ваш компьютер, так как pytesseract является только оболочкой для него. Инструкции по установке можно найти [здесь](https://github.com/tesseract-ocr/tesseract).
# Сам скрипт
```python
import cv2
import pytesseract
import os
class TextRecognizer:
def __init__(self, tesseract_cmd: str, languages: str = 'rus+eng'):
# Указываем путь к Tesseract и языки для распознавания
pytesseract.pytesseract.tesseract_cmd = tesseract_cmd
self.languages = languages
def recognize_text(self, image):
"""Распознавание текста на нескольких языках."""
text = pytesseract.image_to_string(image, config='--oem 3 --psm 6', lang=self.languages)
return text.strip()
class TextSaver:
def __init__(self, directory: str = '.'):
self.directory = directory
def save_text_to_file(self, text, filename='result.txt'):
"""Сохранение распознанного текста в файл."""
path = os.path.join(self.directory, filename)
with open(path, 'w', encoding='utf-8') as file:
file.write(text)
print(f"Распознанный текст сохранен в файл '{path}'.")
class ImageProcessor:
def __init__(self, recognizer: TextRecognizer, saver: TextSaver):
self.recognizer = recognizer
self.saver = saver
def ask_yes_no(self, question):
"""Запрос подтверждения (да/нет)."""
while True:
answer = input(f"{question} (да/д/y/yes, нет/н/n/no): ").strip().lower()
if answer in ('да', 'д', 'y', 'yes'):
return True
elif answer in ('нет', 'н', 'n', 'no'):
return False
else:
print("Пожалуйста, введите 'да', 'д', 'y', 'yes', 'нет', 'н', 'n' или 'no'.")
def save_image(self, image, filename):
"""Сохранение изображения."""
cv2.imwrite(filename, image)
print(f"Изображение сохранено как {filename}")
def preprocess_image(self, image):
"""Создание нескольких вариантов улучшенных изображений."""
# Преобразование в серый
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Вариант 1: Бинаризация
binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)[1]
self.save_image(binary, 'binary.png')
# Вариант 2: Гауссово размытие
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
self.save_image(blurred, 'blurred.png')
# Вариант 3: Адаптивное пороговое преобразование
adaptive_thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)
self.save_image(adaptive_thresh, 'adaptive_thresh.png')
return {
'1': ('binary.png', binary),
'2': ('blurred.png', blurred),
'3': ('adaptive_thresh.png', adaptive_thresh)
}
def process_image(self, image_path: str):
"""Основной процесс обработки изображения."""
if not os.path.isfile(image_path):
print("Указанный файл не найден. Пожалуйста, проверьте путь.")
return
image = cv2.imread(image_path)
if image is None:
print("Не удалось загрузить изображение. Убедитесь, что файл является изображением.")
return
# Предварительное улучшение изображения
if self.ask_yes_no("Хотите улучшить качество изображения перед распознаванием?"):
options = self.preprocess_image(image)
print("Варианты улучшения:")
print("1 - Бинаризация")
print("2 - Гауссово размытие")
print("3 - Адаптивное пороговое преобразование")
choice = input("Выберите вариант улучшения (1/2/3): ").strip()
if choice in options:
selected_image = options[choice][1]
print(f"Использование варианта {choice} для распознавания.")
else:
print("Некорректный выбор. Используется исходное изображение.")
selected_image = image
else:
selected_image = image
if self.ask_yes_no("Хотите распознать текст на изображении?"):
text = self.recognizer.recognize_text(selected_image)
print(f"Распознанный текст:\n{text}")
if self.ask_yes_no("Хотите сохранить текст?"):
self.saver.save_text_to_file(text)
# Убедитесь, что вы используете правильное условие для запуска основной функции
if __name__ == "__main__":
tesseract_cmd_path = r'C:\Users\<user>\AppData\Local\Programs\Tesseract-OCR\tesseract.exe'
# Инициализация классов
recognizer = TextRecognizer(tesseract_cmd=tesseract_cmd_path)
saver = TextSaver(directory='.')
processor = ImageProcessor(recognizer=recognizer, saver=saver)
# Запуск обработки изображения
image_path = input("Укажите путь до изображения (можно без кавычек): ").strip().strip('"')
processor.process_image(image_path)
```