Немножко скриптов для анализа нагрузки на DSpace

!NB. Здесь и далее я считаю что читатель знает что такое cat, grep, wc и еще пара команд, но больше особо ничего не знает.

Проблемы, описанные в этом посте никуда не делись. Более того, в середине 2026 года количество строчек в access.log с юзерагентом Googlebot и Bytespider может быть таким:

tomcat@elar:~# cat /var/log/apache2/access.log | grep Googlebot | wc -l
210373
tomcat@elar:~# cat /var/log/apache2/access.log | grep -E '(Bytedance|Bytespider)' | wc -l
910265


Приёмы, описанные в упоминавшемся выше посте, а именно:

  • Запрет конкретных useragent в robots.txt
  • Запрет доступа по useragent в .htaccess
  • Настройка fail2ban клетки apache-badbots

отчасти решают проблемы и создают иллюзию контроля, но как показывает практика, есть еще операторы DSpace, у которых на 80 и 443 порту опубликован Apache Tomcat и логи могут не вестись из соображений экономии места или каких-то иных соображений.

Текст ниже возможно заставит улыбнуться операторов, которые находятся за WAF или используют иные высоко/низкоуровневые системы мониторинга, балансировки и контроля нагрузки/вторжений, но есть и такие операторы, кого скрипты ниже могут напугать. Можно считать это Disclaimer’ом — текст ниже рассчитан скорее на библиотекаря-автоматизатора, который имеет базовые навыки администрирования и не имеет внешней ИТ-поддержки.

Для хоть какой-то иллюзии контроля (за тем кто нагружает сервер в конкретный момент времени) я предлагаю следующие скрипты, которые в основном работают либо с сетевой статистикой, либо с логами веб-сервера:

1. bad_networks.sh
Первый скрипт с именем bad_networks.sh и содержанием, представленным ниже:

cat /var/log/apache2/access.log | awk '{print $1}' | sort | uniq -c | sort -n  | tail -n 50
echo "--------"
cat /var/log/apache2/access.log | awk -F'.' -v OFS='.' '{print $1, $2}' | sort | uniq -c | sort -n  | tail -n 10

Возвращает TOP50 IP адресов клиентов по частоте вхождения в access.log веб-сервера Apache HTTPD (Apache2) и TOP10 подсетей (это не совсем /16 но смысл думаю понятен).

Если вдруг Apache HTTPD (Apache2) нет, а есть только Apache Tomcat, то скрипт приобретает такой вид:

cat /var/log/tomcat9/localhost_access_log.$(date +%F).txt | awk '{print $1}' | sort | uniq -c | sort -n  | tail -n 50
echo "--------"
cat /var/log/tomcat9/localhost_access_log.$(date +%F).txt | awk -F'.' -v OFS='.' '{print $1, $2}' | sort | uniq -c | sort -n  | tail -n 10

Здесь и далее, пути до логов стандартные для Debian like систем и дистрибутивных веб-серверов.

Вывод работы скрипта выглядит так:

tomcat@elar:~# ./bad_networks.sh
    573 40.77.167.116
    578 34.135.30.24
    578 40.77.167.29
    593 52.167.144.184
    595 136.112.244.145
    602 136.111.215.91
    604 34.132.50.205
    604 34.9.54.183
    604 35.253.219.192
    611 34.70.21.157
    612 136.111.114.76
    615 34.68.245.194
    616 136.115.171.242
    617 136.114.56.170
    621 35.222.134.22
    624 95.82.232.80
    630 104.155.157.61
    631 40.77.167.77
    632 34.57.253.15
    635 34.170.20.173
    635 34.59.22.121
    639 213.175.93.188
    640 40.77.167.35
    645 136.119.11.142
    654 34.173.253.6
    664 35.254.244.223
    683 40.77.167.243
    691 152.89.196.26
    698 52.167.144.221
    733 172.232.162.170
    748 40.77.167.151
    752 52.167.144.167
    787 66.249.75.200
    810 94.139.252.237
    819 52.167.144.166
    828 52.167.144.183
   1103 158.160.100.105
   1134 92.37.143.81
   1162 92.37.143.243
   1357 213.135.60.86
   1450 66.249.75.199
   3776 66.249.75.198
   3803 216.244.66.230
   7663 72.56.188.34
  11030 66.249.75.197
  12540 172.104.207.83
  15246 78.142.18.40
  23891 elar.urfu.ru:80
  30266 66.249.75.196
  95601 48.204.74.7
--------
   5016 120.241
   6535 157.148
   8875 72.56
  12127 52.167
  12540 172.104
  15246 78.142
  15459 40.77
  23891 elar.urfu
  48453 66.249
  95604 48.204
tomcat@elar:~#

Т.е. мы видим что с хоста 48.204.74.7 за не полные сутки было 95601 обращений и это какой-то не понятный хост.

Что мы можем про него уточнить? Ну как минимум что-то типа такого и что-то такое:

tomcat@elar:~# cat /var/log/apache2/access.log | grep 48.204.74.7 | tail -5
48.204.74.7 - - [23/May/2026:22:01:18 +0500] "GET /bitstream/10995/90700/1/10.17223-23062061-18-6.pdf HTTP/1.1" 200 366922 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
48.204.74.7 - - [23/May/2026:22:01:18 +0500] "GET /bitstream/10995/90705/1/10.21538-0134-4889-2019-25-2-9-20.pdf HTTP/1.1" 200 237841 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
48.204.74.7 - - [23/May/2026:22:01:15 +0500] "GET /bitstream/10995/90692/1/10.3390-min10060500.pdf HTTP/1.1" 200 5884296 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
48.204.74.7 - - [23/May/2026:22:01:16 +0500] "GET /bitstream/10995/90697/1/10.3390-su12125084.pdf HTTP/1.1" 200 2774376 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
48.204.74.7 - - [23/May/2026:22:01:11 +0500] "GET /bitstream/10995/79253/1/urfu2112_d.pdf HTTP/1.1" 200 2086920 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
tomcat@elar:~# host 48.204.74.7
Host 7.74.204.48.in-addr.arpa. not found: 3(NXDOMAIN)
tomcat@elar:~#

И что мы видим? 100 тысяч запросов с одного IP с гражданским UserAgent и без внятного указания на принадлежность хоста.

В принципе, такой подсказки порой достаточно для принятия решения.

Отдельно хотелось бы отметить строку «23891 elar.urfu». Это внутренние обращения хоста к SOLR/OAI и пр. сервлетам, а так же 30х переходы http-https. В зависимости от настроек тут может быть localhost или что-то иное. Эту строку можно исключить одним grep -v команде.


2. ports_stat.sh
Второй скрипт с именем ports_stat.sh и содержанием, представленным ниже:

tomcat@elar:~# cat ./ports_stat.sh
echo "--------------------"
echo "80 port"
echo "Total connections: $(netstat -anp | grep :80 | wc -l)"
echo "Most often IPs:"
netstat -tn 2>/dev/null | grep ':80 ' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head
echo "--------------------"
echo "443 port"
echo "Total connections: $(netstat -anp | grep :443 | wc -l)"
echo "Most often IPs:"
netstat -tn 2>/dev/null | grep ':443 ' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head
echo "--------------------"
echo "8009 port"
echo "Total connections: $(netstat -anp | grep :8009 | wc -l)"
echo "Most often IPs:"
netstat -tn 2>/dev/null | grep ':8009 ' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head
echo "--------------------"
echo "8080 port"
echo "Total connections: $(netstat -anp | grep :8080 | wc -l)"
echo "Most often IPs:"
netstat -tn 2>/dev/null | grep ':8080 ' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head
echo "--------------------"
echo "8000 port"
echo "Total connections: $(netstat -anp | grep :8000 | wc -l)"
echo "Most often IPs:"
netstat -tn 2>/dev/null | grep ':8000 ' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head
echo "--------------------"
echo "2641 port"
echo "Total connections: $(netstat -anp | grep :2461 | wc -l)"
echo "Most often IPs:"
netstat -tn 2>/dev/null | grep ':2641 ' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head
echo "--------------------"
tomcat@elar:~#

даёт такой вывод:

tomcat@elar:~# ./ports_stat.sh
--------------------
80 port
Total connections: 1108
Most often IPs:
      2 95.165.85.6
      1 95.182.125.137
      1 183.47.107.37
      1 172.104.207.83
      1 157.148.59.63
      1 157.148.43.43
      1 157.148.43.194
      1 157.148.43.169
      1 129.222.252.34
      1 120.233.109.79
--------------------
443 port
Total connections: 257
Most often IPs:
     30 172.104.207.83
      6 46.245.133.106
      6 183.247.185.37
      5 113.30.194.53
      4 185.25.17.86
      3 95.24.91.132
      3 88.80.60.251
      3 52.167.144.140
      3 46.242.8.25
      3 34.173.253.6
--------------------
8009 port
Total connections: 263
Most often IPs:
    262 127.0.0.1
--------------------
8080 port
Total connections: 824
Most often IPs:
    823 127.0.0.1
--------------------
8000 port
Total connections: 7
Most often IPs:
      1 92.62.119.124
      1 69.5.169.148
      1 31.14.254.11
      1 206.189.63.131
      1 193.32.209.231
      1 146.70.52.235
--------------------
2641 port
Total connections: 0
Most often IPs:
      4 134.76.30.195
--------------------
tomcat@elar:~#

Данный скрипт использует только netstat, grep, awk, sort, echo и еще какие-то мелочи. В логах не нуждается. Возвращает статистику по 80, 443, 8009, 8080, 8000 и 2641 портам.

Почему порты именно такие и почему такой набор будет не у всех? У нас на 80 и 443 порту опубликован Apache HTTPD (Apache2) в режиме ajp proxy. Именно эти порты видны из сети Интернет и цифры 1108 и 257 показывают соединения по этим портам. TOP10 клиентских IP (добавьте host и будут доменные имена) по портам в моменте так же отображаются с количеством соединений. Строка «30 172.104.207.83″ — это уже повод сделать так, понять что это Linode, а потом сделать так:

tomcat@elar:~# cat /var/log/apache2/access.log | grep 172.104.207.83 | tail -5
172.104.207.83 - - [24/May/2026:01:43:52 +0500] "GET /handle/10995/881 HTTP/1.1" 200 5709 "http://hdl.handle.net/10995/881" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
172.104.207.83 - - [24/May/2026:01:43:53 +0500] "GET /bitstream/10995/1653/2/1333422_methodinst.pdf HTTP/1.1" 200 105170 "https://elar.urfu.ru/handle/10995/1653" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
172.104.207.83 - - [24/May/2026:01:43:54 +0500] "GET /handle/10995/881 HTTP/1.1" 200 20017 "http://hdl.handle.net/10995/881" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
172.104.207.83 - - [24/May/2026:01:41:28 +0500] "GET /bitstream/10995/1671/6/1334937_exam.pdf HTTP/1.1" 200 220968 "https://elar.urfu.ru/handle/10995/1671" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
elar.urfu.ru:80 172.104.207.83 - - [24/May/2026:01:44:09 +0500] "GET /handle/10995/877 HTTP/1.1" 301 600 "https://elar.urfu.ru/handle/10995/877" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
tomcat@elar:~# cat /var/log/apache2/access.log | grep 172.104.207.83 | wc -l
16373
tomcat@elar:~#

И отметить для себя что хост с гражданским UserAgent был у нас 16373 раз, а время то всего 01:43:53 (в логе). Собственно, если в моменте сервер не вывозит нагрузку, то почему бы и не побанить? А если число в строе не 30, а 300 или 3000? В принципе, такой подсказки порой достаточно для принятия решения… кажется, я это сегодня уже говорил.

Следующая группа портов — это 8009 и 8080. По первому порту Apache HTTPD (Apache2) общается с Apache Tomcat и по сути количество коннектов на 8009 порт отражает пользовательские сессии. 8080 же порт — это SOLR и внутренняя активность DSpace. Порой интересно наблюдать за тем, как зрелый сервис в первых числах года отрабатывает команду dspace stats-util -s через призму количества коннекторв на 8080 порт.

Порты 8000 и 2641 — это порты handle сервера. Это не аткой уж часто используемый функционал, но у нас он куплен, оплачен и функционирует. Особенно не приятно то, что fail2ban через анализ логов очень тяжело подружить с handle server, а порой AI-краулеры приходят как раз по hdl.handle.net, а не по elar.urfu.ru и на это тоже бывает полезно посмотреть.

В итоге, два скрипта, показанных выше, позволяют получить определённую информацию о том, почему сервер с DSpace может сообщать о внутренней системной ошибке, показывать 50х ошибку веб-сервера или просто белый экран в ситуации когда никаких других инструментов для анализа логов/сети нет.

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

Запись опубликована в рубрике Библиотека с метками . Добавьте в закладки постоянную ссылку.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *