Уже довольно-таки давно я свои данные не доверяю никому, а потому использую свой физический сервер ((Supermicro SYS-5019S-M: Debian 10 + Proxmox 6, ZFS разделы, 64Gb оперативной памяти (2 модуля 378A4G43MB1-CTD)), со всеми ресурсами который работают у меня дома, доступ к сервисам осуществляется либо через OpenVPN с VPS системы, либо через WireGuard также с VPS системы. Вот к примеру, есть в интернете VPS система с OpenVPN сервером на базе Ubuntu 22.04 Server которая связана с домашним Mikrotik RB2011UiAS-2HnD при обращении к которой я через функционал или по аналогии с заметкой "OpenVPN доступ к Proxmox через Nginx Proxy" получаю доступ к OwnCloud. Ну так вот, анализирую все ли в порядке натыкаюсь что в логах (/var/log/nginx/error.log) на VPS системе осуществляются попытки подставления различных URL обращений, как по теме использования OwnCloud так и нет. Значит нужно как-то это дело присечь, помню, что ранее использовал обработку логов через Fail2ban.

Шаг №1: На VPS системе Ubuntu 22.04 Server которая является OpenVPN сервером в качестве брандмауэера используется firewalld, у меня он настроен по заметке "Настройка связки Fail2ban + firewalld на Ubuntu 18.04"

Шаг №2: Обратный прокси настроен вот так, привожу свою конфигурацию для nginx при обращении к внутреннему сервису OwnCloud который в моей домашней сети:

ekzorchik@ekzorchik:~$ cat /etc/nginx/sites-available/owncloud.conf
server {
    server_name <vps_name>.ekzorchik.ru;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

location / {
    proxy_pass https://172.34.34.60;
    proxy_set_header Host $host;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    }
        listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/<vps_name>.ekzorchik.ru/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/<vps_name>.ekzorchik.ru/privkey.pem; # managed by Certbot

}
server {
    if ($host = <vps_name>.ekzorchik.ru) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
}

Шаг №3: На Ubuntu 22.04 Server вижу по логам, что осуществляется перебор:

ekzorchik@ekzorchik:~$ sudo tail -f /var/log/nginx/error.log
2024/01/29 03:04:40 [error] 315596#315596: *891254 directory index of "/usr/share/nginx/html/" is forbidden, client: 185.224.128.31, server: , request: "GET / HTTP/1.1", host: "185.240.103.236:80"
2024/01/29 03:05:11 [error] 315596#315596: *891255 directory index of "/usr/share/nginx/html/" is forbidden, client: 45.79.181.251, server: , request: "GET / HTTP/1.1", host: "185.240.103.236"
2024/01/29 03:52:33 [error] 315596#315596: *891257 directory index of "/usr/share/nginx/html/" is forbidden, client: 45.79.168.172, server: , request: "GET / HTTP/1.1", host: "185.240.103.236"
2024/01/29 04:24:16 [error] 315596#315596: *891263 open() "/usr/share/nginx/html/.env" failed (2: No such file or directory), client: 78.153.140.224, server: , request: "GET /.env HTTP/1.1", host: "185.240.103.236"
2024/01/29 04:26:12 [error] 315596#315596: *891264 directory index of "/usr/share/nginx/html/" is forbidden, client: 45.79.181.223, server: , request: "GET / HTTP/1.1", host: "185.240.103.236"
2024/01/29 04:27:56 [error] 315596#315596: *891267 directory index of "/usr/share/nginx/html/" is forbidden, client: 176.97.210.231, server: , request: "GET / HTTP/1.1", host: "185.240.103.236:80"
2024/01/29 04:40:20 [error] 315596#315596: *891268 open() "/usr/share/nginx/html/portal/redlion" failed (2: No such file or directory), client: 192.241.237.33, server: , request: "GET /portal/redlion HTTP/1.1", host: "185.240.103.236"
2024/01/29 04:43:07 [error] 315596#315596: *891269 directory index of "/usr/share/nginx/html/" is forbidden, client: 94.183.249.45, server: , request: "GET / HTTP/1.1", host: "185.240.103.236:80"
2024/01/29 04:49:13 [error] 315596#315596: *891270 directory index of "/usr/share/nginx/html/" is forbidden, client: 146.19.24.23, server: , request: "GET / HTTP/1.1", host: "185.240.103.236:80"
2024/01/29 05:39:42 [error] 315596#315596: *891284 directory index of "/usr/share/nginx/html/" is forbidden, client: 185.224.128.31, server: , request: "GET / HTTP/1.1", host: "185.240.103.236:80"
^C
ekzorchik@ekzorchik:~$

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

is forbidden

(2: No such file or directory),

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

Шаг №4: Устанавливаю в систему Ubuntu 22.04 Server утилиту fail2ban:

ekzorchik@ekzorchik:~$ apt-cache show firewalld | grep Version
Version: 1.1.1-1ubuntu1
ekzorchik@ekzorchik:~$ apt-cache show fail2ban | grep Version
Version: 0.11.2-6
ekzorchik@ekzorchik:~$
ekzorchik@ekzorchik:~$ sudo apt-get install -y fail2ban
ekzorchik@ekzorchik:~$ sudo systemctl enable fail2ban
Synchronizing state of fail2ban.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable fail2ban
Created symlink /etc/systemd/system/multi-user.target.wants/fail2ban.service → /lib/systemd/system/fail2ban.service.
ekzorchik@ekzorchik:~$
  • папка action.d — содержит файлы действий
  • папка filter.d — файлы фильтров
  • файл fail2ban.conf — основной файл конфигурации
  • файл jail.conf — файл настройки защиты конкретных сервисов
ekzorchik@ekzorchik:~$ sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Шаг №5: Редактирую jail.local для своей системы убирая все лишнее:

ekzorchik@ekzorchik:~$ sudo nano /etc/fail2ban/jail.local
[owncloud]
enabled = true
filter = owncloud
action = firewalld-owncloud
logpath = /var/log/nginx/error.log
maxretry = 3
findtime = 5m
bantime = 86400

Шаг №6: Создаю действие на обнаружение нарушителя и если он опознан, то заносится в зону drop:

ekzorchik@ekzorchik:~$ sudo nano /etc/fail2ban/action.d/firewalld-owncloud.conf
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = firewall-cmd --change-source=<ip> --zone=drop && firewall-cmd --runtime-to-permanent
actionunban = firewall-cmd --remove-source=<ip> --zone=drop && firewall-cmd --runtime-to-permanent

Шаг №7: Создаю фильтр обработки error.log на предмет совпадения с указанными строками:

[INCLUDES]
[Definition]
failregex = ^ \[error\].*open\(\).*failed.*No such file or directory\), client\: <HOST>\, server.*?$
            ^ \[error\].*is forbidden, client\: <HOST>\, server.*?$
ignoreregex =

Шаг №8: Проверяю, что созданный фильтр при парсинге error.log находит совпадения:

ekzorchik@ekzorchik:~$ sudo fail2ban-regex /var/log/nginx/error.log /etc/fail2ban/filter.d/owncloud.conf

Running tests
=============

Use   failregex filter file : owncloud, basedir: /etc/fail2ban
Use         log file : /var/log/nginx/error.log
Use         encoding : UTF-8


Results
=======

Failregex: 53 total
|-  #) [# of hits] regular expression
|   1) [21] ^ \[error\].*open\(\).*failed.*No such file or directory\), client\: <HOST>\, server.*?$
|   2) [32] ^ \[error\].*is forbidden, client\: <HOST>\, server.*?$
`-

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
|  [55] {^LN-BEG}ExYear(?P<_sep>[-/.])Month(?P=_sep)Day(?:T|  ?)24hour:Minute:Second(?:[.,]Microseconds)?(?:\s*Zone offset)?
`-

Lines: 55 lines, 0 ignored, 53 matched, 2 missed
[processed in 0.01 sec]

|- Missed line(s):
|  2024/01/29 02:52:15 [error] 315596#315596: *891249 "/usr/share/nginx/html/webui/index.html" is not found (2: No such file or directory), client: 184.105.139.67, server: , request: "GET /webui/ HTTP/1.1", host: "185.240.103.236"
|  2024/01/29 02:54:13 [error] 315596#315596: *891251 "/usr/share/nginx/html/geoserver/web/index.html" is not found (2: No such file or directory), client: 184.105.139.67, server: , request: "GET /geoserver/web/ HTTP/1.1", host: "185.240.103.236"
`-
ekzorchik@ekzorchik:~$

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

Шаг №9: Перезапускаем сервис fail2ban для принятия внесенных изменений:

ekzorchik@ekzorchik:~$ sudo systemctl restart fail2ban.service && sudo systemctl status fail2ban.service
● fail2ban.service - Fail2Ban Service
     Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2024-01-29 11:57:20 MSK; 49ms ago
       Docs: man:fail2ban(1)
   Main PID: 2416820 (fail2ban-server)
      Tasks: 1 (limit: 2234)
     Memory: 5.1M
        CPU: 27ms
     CGroup: /system.slice/fail2ban.service
             └─2416820 /usr/bin/python3 /usr/bin/fail2ban-server -xf start

Jan 29 11:57:20 ekzorchik.ru systemd[1]: fail2ban.service: Deactivated successfully.
Jan 29 11:57:20 ekzorchik.ru systemd[1]: Stopped Fail2Ban Service.
Jan 29 11:57:20 ekzorchik.ru systemd[1]: Started Fail2Ban Service.
Jan 29 11:57:20 ekzorchik.ru fail2ban-server[2416820]: Server ready
ekzorchik@ekzorchik:~$

Шаг №10: Вывожу на консоль какие задачи по анализу логов у меня выполняет fail2ban:

ekzorchik@ekzorchik:~$ sudo fail2ban-client status

Status

|- Number of jail:      2

`- Jail list:   owncloud, sshd

Шаг №11: Смотрю статистику обнаруженных совпадений по правилу owncloud:

ekzorchik@ekzorchik:~$ sudo fail2ban-client status owncloud
Status for the jail: owncloud
|- Filter
|  |- Currently failed: 2
|  |- Total failed:     2
|  `- File list:        /var/log/nginx/error.log
`- Actions
   |- Currently banned: 0
   |- Total banned:     0
   `- Banned IP list:
ekzorchik@ekzorchik:~$

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

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

На этом пока заметка завершена, будет чем дополнить я обязательно ее дополню, я пока собственно все, с уважением автор блога Олло Александр aka ekzorchik.