Назад | Перейти на главную страницу

Как я могу объединить две команды для подсчета данных из сжатых и несжатых файлов журнала?

Я запускаю эту команду, чтобы получить подсчет неудачных попыток входа с сервера auth.log и это хорошо работает:

sudo cat /var/log/auth.{log,log.1} | grep 'Failed password' | grep sshd | awk '{print $1,$2}' | sort -k 1,1M -k 2n | uniq -c

Но проблема в том, как и на каждом сервере в мире, у меня есть несколько архивов GZip, созданных ротацией журналов, которые не будут анализироваться этой командой:

-rw-r----- 1 syslog adm  7822722 Oct 31 13:44 /var/log/auth.log
-rw-r----- 1 syslog adm 12532511 Oct 25 06:59 /var/log/auth.log.1
-rw-r----- 1 syslog adm  2250939 Oct 18 06:55 /var/log/auth.log.2.gz
-rw-r----- 1 syslog adm  2139669 Oct 11 07:06 /var/log/auth.log.3.gz
-rw-r----- 1 syslog adm  2769919 Oct  4 06:54 /var/log/auth.log.4.gz

Чтобы справиться с ними, у меня есть вариант команды, которая использует zcat вместо того cat но запускать две команды для получения этих данных - это немного неприятно. Есть ли способ объединить cat и zcat команды в одну команду, чтобы я мог получить комбинированные результаты? Я знаю, что могу написать сценарий Bash для фильтрации сжатых и несжатых файлов, но я использую этот текущий однострочник на разных серверах и хочу иметь однострочник, к которому я могу быстро обращаться и использовать при необходимости.

Подробнее.

Я проводил аудит безопасности и настраивал брандмауэр, и вот эта команда, которую я запускаю, дает мне хороший подсчет неудачных попыток ввода пароля из auth.log файлы на машине Ubuntu Linux:

sudo cat /var/log/auth.{log,log.1} | grep 'Failed password' | grep sshd | awk '{print $1,$2}' | sort -k 1,1M -k 2n | uniq -c

Отлично работает! Результат выглядит примерно так:

 5909 Oct 18
13444 Oct 19
  351 Oct 20
  162 Oct 21
  499 Oct 22
  377 Oct 23
  145 Oct 24
10897 Oct 25
   76 Oct 26
   54 Oct 27
  310 Oct 28
 1024 Oct 29
  208 Oct 30
   30 Oct 31

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

sudo zcat -q /var/log/auth.log* | grep 'Failed password' | grep sshd | awk '{print $1,$2}' | sort -k 1,1M -k 2n | uniq -c

И результат будет примерно таким:

gzip: /var/log/auth.log: not in gzip format

gzip: /var/log/auth.log.1: not in gzip format
  10413 Sep 27
  15977 Sep 28
  12297 Sep 29
  14438 Sep 30
  23394 Oct 1
  12912 Oct 2
  15844 Oct 3
  19697 Oct 4
  15350 Oct 5
  12358 Oct 6
  12692 Oct 7
   8377 Oct 8
  10875 Oct 9
    565 Oct 10
  16027 Oct 11
  10422 Oct 12
   6808 Oct 13
  26891 Oct 14
   9493 Oct 15
   5138 Oct 16
   9415 Oct 17
   2226 Oct 18

Как видите, вывод работает, когда работает, но было бы неплохо, если бы cat и zcat варианты этой команды можно было просто объединить в одну команду. Как это можно сделать?

Бонусные очки:

Это не критические проблемы, но было бы неплохо, если бы их каким-то образом можно было решить в решении:

Можешь использовать zgrep который при необходимости будет распакован и, следовательно, работает как с прямым текстом, так и со сжатым вводом. Также grep / zgrep может обрабатывать несколько файлов напрямую, что необходимо в этом случае, поскольку смешанное сжатие и текст для стандартного ввода не всегда работают должным образом. Подавить имена файлов в выводе grep с помощью -h или --no-filename.

sudo zgrep -h 'Failed password' /var/log/auth.* | grep sshd | awk '{print $1,$2}' | sort -k 1,1M -k 2n | uniq -c

Страница руководства:

ZGREP(1)                                                              ZGREP(1)

NAME
       zgrep - search possibly compressed files for a regular expression

SYNOPSIS
       zgrep [ grep_options ] [ -e ] pattern filename...

DESCRIPTION
       Zgrep  invokes grep on compressed or gzipped files.  All options specified
       are passed directly to grep.  If no file is specified, then  the  standard
       input  is  decompressed if necessary and fed to grep.  Otherwise the given
       files are uncompressed if necessary and fed to grep.

       If the GREP environment variable is set, zgrep uses it as the grep program
       to be invoked.

AUTHOR
       Charles Levert (charles@comm.polymtl.ca)

SEE ALSO
       grep(1), gzexe(1), gzip(1), zdiff(1), zforce(1), zmore(1), znew(1)

Хотя печатать каждый раз некрасиво, вы можете сделать что-нибудь вроде:

for log in /var/log/auth.log*; do if ! sudo zcat "$log" 2>/dev/null; then sudo cat "$log"; fi; done | grep 'Failed password' | grep sshd | awk '{print $1,$2}' | sort -k 1,1M -k 2n | uniq -c

Наверное, лучше было бы создать функцию хотя бы для cat часть, что-то вроде:

getLogs() {
    for log in /var/log/auth.log*; do
        if ! sudo zcat "$log" 2>&/dev/null; then
            sudo cat "$log"
        fi
    done
}

Тогда ваша команда может быть

getLogs | grep 'Failed password' | grep sshd | awk '{print $1,$2}' | sort -k 1,1M -k 2n | uniq -c

или вы можете сделать все это функцией:

getSSHFailures() {
    for log in /var/log/auth.log*; do
        if ! sudo zcat "$log" 2>/dev/null; then
            sudo cat "$log"
        fi
    done | grep 'Failed password' | grep sshd | awk '{print $1,$2}' | sort -k 1,1M -k 2n | uniq -c
}

Тогда просто позвони

getSSHFailures

Затем вы можете определить эту функцию в своем .bashrc и эта функция доступна в каждой запускаемой вами оболочке

Кроме того, это также должно исправить ваше наблюдение об ошибке при попытке zcat несжатые файлы (потому что мы перенаправляем zcat ошибки в /dev/null) и избавьтесь от повторяющейся записи, потому что мы печатаем все результаты вместе как единый поток перед их обработкой.

В заключение, awk действительно может выполнить сопоставление с образцом для нас, поэтому мы также можем избавиться от 2 grepкак:

getSSHFailures() {
    for log in /var/log/auth.log*; do
        if ! sudo zcat "$log" 2>/dev/null; then
            sudo cat "$log"
        fi
    done | awk '/sshd.*Failed password/ {print $1,$2}' | sort -k 1,1M -k 2n | uniq -c
}