Я запускаю эту команду, чтобы получить подсчет неудачных попыток входа с сервера 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
варианты этой команды можно было просто объединить в одну команду. Как это можно сделать?
Бонусные очки:
Это не критические проблемы, но было бы неплохо, если бы их каким-то образом можно было решить в решении:
zcat
вывод есть две ошибки из zcat
пытается обработать два несжатых файла. Подавить это было бы хорошо.cat
и zcat
команды показывают данные за 18 октября; день, когда произошла ротация журнала. Есть ли способ сложить эти два значения в команде? В противном случае меня устраивает наличие двух строк данных за 18 октября с разными значениями, которые мне пришлось бы складывать вручную.Можешь использовать 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
}